oficina / docs Public

Clone
git clone https://amadan.net/oficina/docs

Plain git — no account needed to clone.

Download

Download this file

1import SwiftUI
2
3@MainActor
4struct DocsToolsControls: View {
5 let projection: CRDTProjection
6 let content: NSAttributedString
7 let selection: NSRange
8 @State private var showingCount = false
9 @State private var showingShortcuts = false
10
11 var body: some View {
12 Menu {
13 Button { showingCount = true } label: {
14 Label { Text("docs.editor.wordcount.title", bundle: DocsResources.bundle) } icon: { Image(systemName: "number") }
15 }
16 Button { showingShortcuts = true } label: {
17 Label { Text("docs.editor.shortcuts.title", bundle: DocsResources.bundle) } icon: { Image(systemName: "keyboard") }
18 }
19 } label: {
20 Label { Text("docs.editor.menu.tools", bundle: DocsResources.bundle) } icon: { Image(systemName: "wrench.and.screwdriver") }
21 }
22 .sheet(isPresented: $showingShortcuts) {
23 NavigationStack {
24 Form {
25 ForEach(DocumentKeyboardBindings.all) { binding in
26 LabeledContent {
27 Text(binding.display).monospaced()
28 } label: {
29 Text(LocalizedStringKey(binding.titleKey), bundle: DocsResources.bundle)
30 }
31 }
32 }
33 .navigationTitle(Text("docs.editor.shortcuts.title", bundle: DocsResources.bundle))
34 .toolbar {
35 ToolbarItem(placement: .confirmationAction) {
36 Button { showingShortcuts = false } label: { Text("docs.editor.shortcuts.close", bundle: DocsResources.bundle) }
37 }
38 }
39 }
40 #if os(macOS)
41 .frame(minWidth: 420, minHeight: 420)
42 #endif
43 }
44 .sheet(isPresented: $showingCount) {
45 let count = DocumentWordCounts(projection: projection, content: content, selection: selection)
46 NavigationStack {
47 Form {
48 row("docs.editor.wordcount.words", count.words)
49 row("docs.editor.wordcount.characters", count.characters)
50 row("docs.editor.wordcount.charactersnospaces", count.charactersNoSpaces)
51 row("docs.editor.wordcount.paragraphs", count.paragraphs)
52 if let selected = count.selectedWords { row("docs.editor.wordcount.selection", selected) }
53 }
54 .navigationTitle(Text("docs.editor.wordcount.title", bundle: DocsResources.bundle))
55 .toolbar {
56 ToolbarItem(placement: .confirmationAction) {
57 Button { showingCount = false } label: { Text("docs.editor.wordcount.close", bundle: DocsResources.bundle) }
58 }
59 }
60 }
61 #if os(macOS)
62 .frame(minWidth: 360, minHeight: 290)
63 #else
64 .presentationDetents([.medium])
65 #endif
66 }
67 }
68
69 private func row(_ key: LocalizedStringKey, _ value: Int) -> some View {
70 LabeledContent { Text(value, format: .number).monospacedDigit() } label: { Text(key, bundle: DocsResources.bundle) }
71 }
72}
73