diff options
Diffstat (limited to 'Sources/NorgUI/Views/NorgTaskView.swift')
| -rw-r--r-- | Sources/NorgUI/Views/NorgTaskView.swift | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/Sources/NorgUI/Views/NorgTaskView.swift b/Sources/NorgUI/Views/NorgTaskView.swift new file mode 100644 index 0000000..cfe48c0 --- /dev/null +++ b/Sources/NorgUI/Views/NorgTaskView.swift @@ -0,0 +1,63 @@ +import NorgKit +import SwiftUI + +public struct NorgTaskView: View { + @Environment(\.norgTheme) private var theme + + let status: TaskStatus + let text: AttributedString + var font: Font + let onToggle: () -> Void + let onSetStatus: (TaskStatus) -> Void + + public init( + status: TaskStatus, + text: AttributedString, + font: Font = .body, + onToggle: @escaping () -> Void, + onSetStatus: @escaping (TaskStatus) -> Void + ) { + self.status = status + self.text = text + self.font = font + self.onToggle = onToggle + self.onSetStatus = onSetStatus + } + + public var body: some View { + HStack(alignment: .firstTextBaseline, spacing: 8) { + statusButton + Text(text) + .font(font) + .strikethrough(isResolved, color: .secondary) + .foregroundStyle(isResolved ? .secondary : .primary) + } + } + + private var statusButton: some View { + Button(action: onToggle) { + Image(systemName: theme.statusSymbol(status)) + .font(font) + .foregroundStyle(theme.statusTint(status)) + } + .buttonStyle(.plain) + .contextMenu { + ForEach(TaskStatus.allCases) { option in + Button { + onSetStatus(option) + } label: { + Label { + Text(theme.statusLabel(option)) + } icon: { + Image(systemName: theme.statusSymbol(option)) + } + } + } + } + .accessibilityLabel(Text("Task status: \(Text(theme.statusLabel(status)))", bundle: .module)) + } + + private var isResolved: Bool { + status == .done || status == .cancelled + } +} |