TagBarView.swift 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. //
  2. // TagBarView.swift
  3. // Todos
  4. //
  5. // Created by Sam Jaffe on 2/28/26.
  6. //
  7. import SwiftUI
  8. import SwiftData
  9. struct TagBarView: View {
  10. @Environment(\.modelContext) private var modelContext
  11. @Binding var task: Task
  12. @AppStorage(UserDefaultsKeys.UrlHints) var allHints = CodableArray<URLHint>()
  13. @State private var active: String = ""
  14. @FocusState private var isFocused: Bool
  15. var body: some View {
  16. HStack {
  17. ForEach($task.tags) { tag in
  18. if let url = allHints.filter({ $0.matches(tag.wrappedValue) })
  19. .first?.url(tag.wrappedValue) {
  20. Link(destination: url) {
  21. Label("", systemImage: "link")
  22. }
  23. .padding(.leading, -8)
  24. .padding(.trailing, -10)
  25. }
  26. TextField("", text: tag.id)
  27. .focused($isFocused)
  28. .onChange(of: isFocused) {
  29. task.tags.removeAll(where: { $0.id.isEmpty })
  30. }
  31. }
  32. .scaledToFit()
  33. TextField("Tag", text: $active)
  34. .onSubmit(addItem)
  35. }
  36. }
  37. private func addItem() {
  38. if !active.isEmpty && !task.tags.contains(where: { $0.like(active) }) {
  39. let newTag = Tag(id: active, parent: task)
  40. modelContext.insert(newTag)
  41. task.tags.append(newTag)
  42. }
  43. active = ""
  44. }
  45. }
  46. #Preview {
  47. @Previewable @State var task = Task()
  48. TagBarView(task: $task)
  49. }