()
| 6 | import { useLayoutStore } from '../../../stores/layoutStore' |
| 7 | |
| 8 | export function SearchInput(): React.JSX.Element { |
| 9 | const { query, setQuery, options, setOptions, clearSearch, triggerSearch, focusRequestKey } = |
| 10 | useGlobalSearchStore() |
| 11 | const activePanel = useLayoutStore((state) => state.activePanel) |
| 12 | const inputRef = useRef<InputRef>(null) |
| 13 | |
| 14 | // 当切换到搜索面板或收到快捷键请求时自动聚焦并全选 |
| 15 | useEffect(() => { |
| 16 | if (activePanel !== 'search') { |
| 17 | return undefined |
| 18 | } |
| 19 | |
| 20 | const timer = setTimeout(() => { |
| 21 | inputRef.current?.focus() |
| 22 | inputRef.current?.select() |
| 23 | }, 50) |
| 24 | |
| 25 | return () => clearTimeout(timer) |
| 26 | }, [activePanel, focusRequestKey]) |
| 27 | |
| 28 | const handleChange = useCallback( |
| 29 | (e: React.ChangeEvent<HTMLInputElement>) => { |
| 30 | setQuery(e.target.value) |
| 31 | }, |
| 32 | [setQuery] |
| 33 | ) |
| 34 | |
| 35 | const handleClear = useCallback(() => { |
| 36 | clearSearch() |
| 37 | inputRef.current?.focus() |
| 38 | }, [clearSearch]) |
| 39 | |
| 40 | const handleKeyDown = useCallback( |
| 41 | (e: React.KeyboardEvent) => { |
| 42 | if (e.key === 'Escape') { |
| 43 | handleClear() |
| 44 | } else if (e.key === 'Enter') { |
| 45 | e.preventDefault() |
| 46 | triggerSearch() |
| 47 | } |
| 48 | }, |
| 49 | [handleClear, triggerSearch] |
| 50 | ) |
| 51 | |
| 52 | const toggleOption = useCallback( |
| 53 | (key: 'matchCase' | 'useRegex' | 'matchWholeWord') => { |
| 54 | setOptions({ [key]: !options[key] }) |
| 55 | }, |
| 56 | [options, setOptions] |
| 57 | ) |
| 58 | |
| 59 | return ( |
| 60 | <div className="search-input-container"> |
| 61 | <Input |
| 62 | ref={inputRef} |
| 63 | value={query} |
| 64 | onChange={handleChange} |
| 65 | onKeyDown={handleKeyDown} |
nothing calls this directly
no outgoing calls
no test coverage detected