import SwiftUI @MainActor struct DocsToolsControls: View { let projection: CRDTProjection let content: NSAttributedString let selection: NSRange @State private var showingCount = false @State private var showingShortcuts = false var body: some View { Menu { Button { showingCount = true } label: { Label { Text("docs.editor.wordcount.title", bundle: DocsResources.bundle) } icon: { Image(systemName: "number") } } Button { showingShortcuts = true } label: { Label { Text("docs.editor.shortcuts.title", bundle: DocsResources.bundle) } icon: { Image(systemName: "keyboard") } } } label: { Label { Text("docs.editor.menu.tools", bundle: DocsResources.bundle) } icon: { Image(systemName: "wrench.and.screwdriver") } } .sheet(isPresented: $showingShortcuts) { NavigationStack { Form { ForEach(DocumentKeyboardBindings.all) { binding in LabeledContent { Text(binding.display).monospaced() } label: { Text(LocalizedStringKey(binding.titleKey), bundle: DocsResources.bundle) } } } .navigationTitle(Text("docs.editor.shortcuts.title", bundle: DocsResources.bundle)) .toolbar { ToolbarItem(placement: .confirmationAction) { Button { showingShortcuts = false } label: { Text("docs.editor.shortcuts.close", bundle: DocsResources.bundle) } } } } #if os(macOS) .frame(minWidth: 420, minHeight: 420) #endif } .sheet(isPresented: $showingCount) { let count = DocumentWordCounts(projection: projection, content: content, selection: selection) NavigationStack { Form { row("docs.editor.wordcount.words", count.words) row("docs.editor.wordcount.characters", count.characters) row("docs.editor.wordcount.charactersnospaces", count.charactersNoSpaces) row("docs.editor.wordcount.paragraphs", count.paragraphs) if let selected = count.selectedWords { row("docs.editor.wordcount.selection", selected) } } .navigationTitle(Text("docs.editor.wordcount.title", bundle: DocsResources.bundle)) .toolbar { ToolbarItem(placement: .confirmationAction) { Button { showingCount = false } label: { Text("docs.editor.wordcount.close", bundle: DocsResources.bundle) } } } } #if os(macOS) .frame(minWidth: 360, minHeight: 290) #else .presentationDetents([.medium]) #endif } } private func row(_ key: LocalizedStringKey, _ value: Int) -> some View { LabeledContent { Text(value, format: .number).monospacedDigit() } label: { Text(key, bundle: DocsResources.bundle) } } }