UNPKG

@spaced-out/ui-design-system

Version:
82 lines (70 loc) 2.38 kB
// @flow strict import * as React from 'react'; export type GroupTitleOption<V> = { groupTitle: React.Node, options?: V[], showLineDivider?: boolean, }; // TODO: V should generic with constraints. export function useFilteredOptions<V>({ searchTerm, options = [], excludedKeys = [], groupTitleOptions = [], searchOptionsBy = (option: V, searchTerm: string): boolean => { // $FlowFixMe const {label, key}: {label: string, key: string} = option; return ( key.toLowerCase().includes(searchTerm) || (label ? label.toLowerCase().includes(searchTerm) : false) ); }, }: { searchTerm: string, options?: V[], groupTitleOptions?: GroupTitleOption<V>[], excludedKeys?: string[], searchOptionsBy?: (option: V, searchTerm: string) => boolean, }): {filteredOptions?: V[], filteredGroupTitleOptions?: GroupTitleOption<V>[]} { // Memoize the filterExcluded function for performance const filterExcluded = React.useCallback( (list?: V[]): V[] => // $FlowFixMe - list has key property list ? list.filter((option) => !excludedKeys.includes(option.key)) : [], [excludedKeys], ); return React.useMemo(() => { const trimmedValue = (searchTerm || '').trim().toLowerCase(); // Initialize filteredOptions as an empty array if options are not provided let filteredOptions: V[] = []; if (options.length) { filteredOptions = filterExcluded(options); // Apply search term filtering if (trimmedValue) { filteredOptions = filteredOptions.filter((option) => searchOptionsBy(option, trimmedValue), ); } } let filteredGroupTitleOptions: GroupTitleOption<V>[] = []; // Process groupTitleOptions if provided if (Array.isArray(groupTitleOptions) && groupTitleOptions.length) { filteredGroupTitleOptions = groupTitleOptions .map((group) => { const filtered = filterExcluded(group.options).filter( (option) => !trimmedValue || searchOptionsBy(option, trimmedValue), ); return {...group, options: filtered}; }) .filter((group) => (group.options ? group.options.length > 0 : false)); } return {filteredOptions, filteredGroupTitleOptions}; }, [ searchTerm, options, excludedKeys, groupTitleOptions, searchOptionsBy, filterExcluded, ]); }