From 8e81246b36352b3775a90a862a19636174f2a55b Mon Sep 17 00:00:00 2001 From: Nathan Walker Date: Sun, 3 Aug 2025 12:04:53 -0700 Subject: [PATCH] feat(ios): ListView showSearch for built-in search behavior --- apps/toolbox/src/pages/list-page-model.ts | 45 +++++- apps/toolbox/src/pages/list-page.xml | 37 +---- packages/core/ui/index.ts | 2 +- packages/core/ui/list-view/index.d.ts | 44 ++++++ packages/core/ui/list-view/index.ios.ts | 142 +++++++++++++++++- .../core/ui/list-view/list-view-common.ts | 12 +- 6 files changed, 244 insertions(+), 38 deletions(-) diff --git a/apps/toolbox/src/pages/list-page-model.ts b/apps/toolbox/src/pages/list-page-model.ts index aa7d9646b..9a1f87aff 100644 --- a/apps/toolbox/src/pages/list-page-model.ts +++ b/apps/toolbox/src/pages/list-page-model.ts @@ -1,7 +1,7 @@ -import { Observable, Dialogs, DialogStrings, View, EventData } from '@nativescript/core'; - +import { Observable, Dialogs, DialogStrings, View, EventData, SearchEventData } from '@nativescript/core'; +type CountryListType = Array<{ title: string; items: Array<{ name: string; code: string; flag: string; isVisible?: boolean }> }>; export class ListPageModel extends Observable { - components: Array = [ + countries: CountryListType = [ { title: 'A', items: [ @@ -1373,9 +1373,10 @@ export class ListPageModel extends Observable { ], }, ]; + private _originalCountries: CountryListType; selectItemTemplate(item: any, index: number, items: Array) { - return index == items.length - 1 ? 'last' : 'not-last'; + return 'main'; // index == items.length - 1 ? 'last' : 'not-last'; } componentsItemTap(args): void { @@ -1389,4 +1390,40 @@ export class ListPageModel extends Observable { itemLoading(args: EventData): void { (args.object as View).backgroundColor = 'transparent'; } + + onSearchTextChange(evt: SearchEventData): void { + if (!this._originalCountries) { + this._originalCountries = this.countries; + } + const searchText = evt.text.toLowerCase(); + console.log('Search text:', searchText); + if (searchText) { + this.countries = this.filterCountryGroups(this._originalCountries, searchText); + } else { + this.countries = this._originalCountries; // reset to original if no search text + } + this.notifyPropertyChange('countries', this.countries); + } + + /** + * Filter a grouped array of countries by search query. + * @param {Array<{ title: string; items: { name: string; code: string; flag: string; }[] }>} groups + * @param {string} query + * @returns Filtered groups with the same shape, omitting any with no matches. + */ + filterCountryGroups(groups: CountryListType, query: string): CountryListType { + const q = query.trim().toLowerCase(); + if (!q) return groups; // no query → all groups + + return ( + groups + .map((group) => { + // keep only items whose name includes the query + const items = group.items.filter((item) => item.name.toLowerCase().includes(q)); + return { ...group, items }; + }) + // drop any group that ended up with 0 items + .filter((group) => group.items.length > 0) + ); + } } diff --git a/apps/toolbox/src/pages/list-page.xml b/apps/toolbox/src/pages/list-page.xml index 67f1ecf72..32a67af34 100644 --- a/apps/toolbox/src/pages/list-page.xml +++ b/apps/toolbox/src/pages/list-page.xml @@ -6,11 +6,13 @@ - + -