Add search to the currency picker
Filters by code or display name, case-insensitively, across all three sections (current, selected, and remaining currencies) — a section disappears entirely once nothing in it matches. The matching logic lives in shared code (matchesCurrencySearch) so Compose and SwiftUI stay in sync; SwiftUI wires it into the native .searchable() field, Compose gets a plain search text field with a clear button. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FXcrACM5sok3M1KQJ8kByy
This commit is contained in:
@@ -11,28 +11,43 @@ struct CurrencyPickerSheet: View {
|
||||
let onToggle: (String) -> Void
|
||||
|
||||
@Environment(\.dismiss) private var dismiss
|
||||
@State private var searchQuery = ""
|
||||
|
||||
private func matches(_ info: CurrencyInfo) -> Bool {
|
||||
SystemCurrenciesKt.matchesCurrencySearch(info: info, query: searchQuery)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
List {
|
||||
Section(IosLocalizationKt.localizedString(resource: MR.strings.shared.current_currency_section_title)) {
|
||||
currencyRow(for: currentCurrency, isSelected: true, onTap: nil)
|
||||
if matches(currentCurrency) {
|
||||
Section(IosLocalizationKt.localizedString(resource: MR.strings.shared.current_currency_section_title)) {
|
||||
currencyRow(for: currentCurrency, isSelected: true, onTap: nil)
|
||||
}
|
||||
}
|
||||
|
||||
if !selectedOtherCurrencies.isEmpty {
|
||||
let matchingSelectedOthers = selectedOtherCurrencies.filter(matches)
|
||||
if !matchingSelectedOthers.isEmpty {
|
||||
Section(IosLocalizationKt.localizedString(resource: MR.strings.shared.selected_currencies_section_title)) {
|
||||
ForEach(selectedOtherCurrencies, id: \.code) { info in
|
||||
ForEach(matchingSelectedOthers, id: \.code) { info in
|
||||
currencyRow(for: info, isSelected: true, onTap: { onToggle(info.code) })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Section(IosLocalizationKt.localizedString(resource: MR.strings.shared.currencies_section_title)) {
|
||||
ForEach(unselectedCurrencies, id: \.code) { info in
|
||||
currencyRow(for: info, isSelected: false, onTap: { onToggle(info.code) })
|
||||
let matchingUnselected = unselectedCurrencies.filter(matches)
|
||||
if !matchingUnselected.isEmpty {
|
||||
Section(IosLocalizationKt.localizedString(resource: MR.strings.shared.currencies_section_title)) {
|
||||
ForEach(matchingUnselected, id: \.code) { info in
|
||||
currencyRow(for: info, isSelected: false, onTap: { onToggle(info.code) })
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.searchable(
|
||||
text: $searchQuery,
|
||||
prompt: IosLocalizationKt.localizedString(resource: MR.strings.shared.search_currencies_placeholder)
|
||||
)
|
||||
.navigationTitle(IosLocalizationKt.localizedString(resource: MR.strings.shared.currencies_section_title))
|
||||
#if os(iOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
|
||||
Reference in New Issue
Block a user