// // SymbolPickerView.swift // Haru_Danim // // SF Symbols 아이콘 선택기 (검색 + 카테고리 탐색) // import SwiftUI struct SymbolPickerView: View { @Environment(\.dismiss) private var dismiss @Binding var selection: String @State private var searchText = "" @State private var category: String init(selection: Binding) { _selection = selection _category = State(initialValue: SymbolCatalog.categories.first?.name ?? "") } private var symbols: [String] { let trimmed = searchText.trimmingCharacters(in: .whitespaces).lowercased() if !trimmed.isEmpty { return SymbolCatalog.allSymbols.filter { $0.contains(trimmed) } } return SymbolCatalog.categories.first { $0.name == category }?.symbols ?? [] } var body: some View { NavigationStack { VStack(spacing: 0) { if searchText.isEmpty { categoryBar } ScrollView { LazyVGrid(columns: [GridItem(.adaptive(minimum: 52), spacing: 10)], spacing: 10) { ForEach(symbols, id: \.self) { symbol in Button { selection = symbol dismiss() } label: { Image(systemName: symbol) .font(.system(size: 22)) .foregroundStyle(symbol == selection ? Color.white : AppTheme.green) .frame(width: 52, height: 52) .background( symbol == selection ? AppTheme.green : AppTheme.surface, in: RoundedRectangle(cornerRadius: 12, style: .continuous) ) } .buttonStyle(.plain) .accessibilityLabel(Text(verbatim: symbol)) } } .padding() } } .background(AppTheme.background) .navigationTitle("아이콘 선택") .navigationBarTitleDisplayMode(.inline) .searchable(text: $searchText, prompt: "심볼 이름 검색 (영문)") .toolbar { ToolbarItem(placement: .cancellationAction) { Button("닫기") { dismiss() } } } } } private var categoryBar: some View { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 8) { ForEach(SymbolCatalog.categories) { cat in Button { category = cat.name } label: { Text(cat.name) .font(.subheadline.weight(category == cat.name ? .semibold : .regular)) .padding(.horizontal, 14) .padding(.vertical, 7) .background( category == cat.name ? AppTheme.green : AppTheme.surface, in: Capsule() ) .foregroundStyle(category == cat.name ? Color.white : Color.primary) } .buttonStyle(.plain) } } .padding(.horizontal) .padding(.vertical, 8) } } }