import { Combobox } from '@headlessui/react' import { CustomIcon } from 'components/CustomIcon' import decamelize from 'decamelize' import Fuse from 'fuse.js' import { useSettingsAuthContext } from 'hooks/useSettingsAuthContext' import { Setting } from 'lib/settings/initialSettings' import { useEffect, useMemo, useRef, useState } from 'react' import { useHotkeys } from 'react-hotkeys-hook' import { useNavigate } from 'react-router-dom' export function SettingsSearchBar() { const inputRef = useRef(null) useHotkeys( 'Ctrl+.', (e) => { e.preventDefault() inputRef.current?.focus() }, { enableOnFormTags: true } ) const navigate = useNavigate() const [query, setQuery] = useState('') const { settings } = useSettingsAuthContext() const settingsAsSearchable = useMemo( () => Object.entries(settings.state.context).flatMap( ([category, categorySettings]) => Object.entries(categorySettings).flatMap(([settingName, setting]) => { const s = setting as Setting return ['project', 'user'] .filter((l) => s.hideOnLevel !== l) .map((l) => ({ category: decamelize(category, { separator: ' ' }), settingName: settingName, settingNameDisplay: decamelize(settingName, { separator: ' ' }), setting: s, level: l, })) }) ), [settings.state.context] ) const [searchResults, setSearchResults] = useState(settingsAsSearchable) const fuse = new Fuse(settingsAsSearchable, { keys: ['category', 'settingNameDisplay', 'setting.description'], includeScore: true, }) useEffect(() => { const results = fuse.search(query).map((result) => result.item) setSearchResults(query.length > 0 ? results : settingsAsSearchable) }, [query]) function handleSelection({ level, settingName, }: { category: string settingName: string setting: Setting level: string }) { navigate(`?tab=${level}#${settingName}`) } return (
setQuery(event.target.value)} className="w-full bg-transparent focus:outline-none selection:bg-primary/20 dark:selection:bg-primary/40 dark:focus:outline-none" placeholder="Search settings (^.)" autoCapitalize="off" autoComplete="off" autoCorrect="off" spellCheck="false" autoFocus />
{searchResults?.map((option) => (

{option.level} ·{' '} {decamelize(option.category, { separator: ' ' })} ·{' '} {option.settingNameDisplay}

{option.setting.description && (

{option.setting.description}

)}
))}
) }