import React, {useCallback, useRef, useEffect, forwardRef} from 'react'; import {VscArrowDown} from '@react-icons/all-files/vsc/VscArrowDown'; import {VscArrowUp} from '@react-icons/all-files/vsc/VscArrowUp'; import {VscCaseSensitive} from '@react-icons/all-files/vsc/VscCaseSensitive'; import {VscClose} from '@react-icons/all-files/vsc/VscClose'; import {VscRegex} from '@react-icons/all-files/vsc/VscRegex'; import {VscWholeWord} from '@react-icons/all-files/vsc/VscWholeWord'; import clsx from 'clsx'; import type {SearchBoxProps} from '../../typings/hyper'; type SearchButtonColors = { foregroundColor: string; selectionColor: string; backgroundColor: string; }; type SearchButtonProps = React.PropsWithChildren< { onClick: () => void; active: boolean; title: string; } & SearchButtonColors >; const SearchButton = ({ onClick, active, title, foregroundColor, backgroundColor, selectionColor, children }: SearchButtonProps) => { const handleKeyUp = useCallback( (event: React.KeyboardEvent) => { if (event.key === 'Enter' || event.key === ' ') { onClick(); } }, [onClick] ); return (
{children}
); }; const SearchBox = forwardRef((props, ref) => { const { caseSensitive, wholeWord, regex, results, toggleCaseSensitive, toggleWholeWord, toggleRegex, next, prev, close, backgroundColor, foregroundColor, borderColor, selectionColor, font } = props; const searchTermRef = useRef(''); const inputRef = useRef(null); const handleChange = useCallback( (event: React.KeyboardEvent) => { searchTermRef.current = event.currentTarget.value; if (event.shiftKey && event.key === 'Enter') { prev(searchTermRef.current); } else if (event.key === 'Enter') { next(searchTermRef.current); } }, [prev, next] ); useEffect(() => { inputRef.current?.focus(); }, [inputRef.current]); const searchButtonColors: SearchButtonColors = { backgroundColor: borderColor, selectionColor, foregroundColor }; return (
{results === undefined ? '' : results.resultCount === 0 ? 'No results' : `${results.resultIndex + 1} of ${results.resultCount}`}
prev(searchTermRef.current)} active={false} title="Previous Match" {...searchButtonColors} > next(searchTermRef.current)} active={false} title="Next Match" {...searchButtonColors} >
); }); SearchBox.displayName = 'SearchBox'; export default SearchBox;