import { useCallback, type ComponentType } from 'react' import { IconButton, type SvgIconProps } from '@mui/material' import { Search as SearchIcon } from '@mui/icons-material' import { Tooltip } from '../../../components' import { getWidgetStore, useSingleTransform, useWidget, useWidgetId, } from '../../stores' import { filterBySearchText } from './filter' import { DEFAULT_SEARCHER_LABELS, type SearcherLabels } from './labels' import { styles } from './style' const SEARCHER_DESCRIPTOR = { id: 'searcher', type: 'data' as const, order: 20, disables: ['lock-selection'], } export interface SearcherToggleProps { labels?: Partial icon?: ComponentType iconProps?: SvgIconProps /** * Whether the searcher transform is enabled on first mount. Defaults * to `false` so the toggle renders un-pressed and the * `filterBySearchText` transform stays dormant until the user clicks * it. Set to `true` for search-first widgets where the input is the * primary affordance. */ initialEnabled?: boolean } export function SearcherToggle({ labels, icon: Icon = SearchIcon, iconProps, initialEnabled = false, }: SearcherToggleProps) { const id = useWidgetId() const resolved = { ...DEFAULT_SEARCHER_LABELS, ...labels } const text = useWidget( id, (s) => (s.transformStates.searcher?.searchText as string | undefined) ?? '', ) // The transform fn closes over `text`. Memoize via useCallback so identity // only changes when text changes, allowing useTransform to re-register. const fn = useCallback( (data: unknown) => filterBySearchText(data, text), [text], ) const { enabled, toggle } = useSingleTransform(id, SEARCHER_DESCRIPTOR, fn, { initialEnabled, }) return ( ) } /** * Imperatively writes the search text into the widget store. Used by the * Searcher input to update text inside transformStates without going through * a re-rendered React subscription. */ export function setSearcherText(widgetId: string, value: string): void { getWidgetStore(widgetId).setState((s) => ({ transformStates: { ...s.transformStates, searcher: { enabled: s.transformStates.searcher?.enabled ?? false, ...s.transformStates.searcher, searchText: value, }, }, })) }