import SwiftUI import OnyxDesign import OnyxWidgetKit /// Kurze Notizen, direkt in der Kachel zu schreiben. public struct NotesView: View { private let store: NotesStore private let compact: Bool @State private var editing: Note? @State private var draft = "" @FocusState private var isWriting: Bool public init(store: NotesStore, compact: Bool = false) { self.store = store self.compact = compact } public var body: some View { VStack(alignment: .leading, spacing: Onyx.Space.sm) { if let editing { editor(for: editing) } else { list } } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) } private var list: some View { VStack(alignment: .leading, spacing: 0) { HStack { Text("notes.name", bundle: .module) .font(Onyx.Font.title) .foregroundStyle(Onyx.Color.textPrimary) Spacer() Button { begin(store.makeDraft()) } label: { Image(systemName: "square.and.pencil") .font(.system(size: Onyx.Symbol.small)) } .buttonStyle(.plain) .foregroundStyle(Onyx.Color.accent) } .padding(.bottom, Onyx.Space.sm) if store.notes.isEmpty { OnyxNotice(symbol: "note.text", text: String(localized: "notes.empty", bundle: .module)) } else { ScrollView { LazyVStack(spacing: 0) { ForEach(Array(store.notes.prefix(compact ? 4 : 20).enumerated()), id: \.element.id) { index, note in if index > 0 { OnyxHairline() } Button { begin(note) } label: { HStack { Text(NoteRules.title(of: note)) .font(Onyx.Font.footnote) .foregroundStyle(Onyx.Color.textPrimary) .lineLimit(1) Spacer(minLength: Onyx.Space.xs) } .padding(.vertical, Onyx.Space.sm) .contentShape(.rect) } .buttonStyle(.plain) } } } .scrollIndicators(.never) } } } private func editor(for note: Note) -> some View { VStack(alignment: .leading, spacing: Onyx.Space.sm) { HStack { Button { finish() } label: { Image(systemName: "chevron.left") .font(.system(size: Onyx.Symbol.small)) } .buttonStyle(.plain) .foregroundStyle(Onyx.Color.accent) Spacer() Button { store.remove(note); editing = nil } label: { Image(systemName: "trash") .font(.system(size: Onyx.Symbol.small)) } .buttonStyle(.plain) .foregroundStyle(Onyx.Color.textTertiary) } // `TextEditor` ohne eigenen Hintergrund: der Standardhintergrund // ist hell und stünde als weißer Block in der schwarzen Kachel. TextEditor(text: $draft) .font(Onyx.Font.footnote) .foregroundStyle(Onyx.Color.textPrimary) .scrollContentBackground(.hidden) .focused($isWriting) .frame(maxWidth: .infinity, maxHeight: .infinity) } .onAppear { isWriting = true } } private func begin(_ note: Note) { editing = note draft = note.text } private func finish() { if var note = editing { note.text = draft store.update(note) } editing = nil draft = "" } } public struct NotesWidget: OnyxWidget { public let id = "notes" public var displayName: String { String(localized: "notes.name", bundle: .module) } public let symbolName = "note.text" private let store: NotesStore public init(store: NotesStore) { self.store = store } public func makeView() -> AnyView { AnyView(NotesView(store: store)) } }