import React, { type JSX, useCallback, useEffect, useMemo, useRef, } from 'react'; import type { GetInputProps } from '../interfaces/downshift'; type Props = { searchKeyword: string; onChange?: (text: string) => void; onSubmit?: () => void; getInputProps: GetInputProps; }; export const SearchForm = (props: Props): JSX.Element => { const { searchKeyword, onChange, onSubmit, getInputProps } = props; const inputRef = useRef(null); const changeSearchTextHandler = useCallback( (e: React.ChangeEvent) => { onChange?.(e.target.value); }, [onChange], ); const submitHandler = useCallback( (e: React.FormEvent) => { e.preventDefault(); const isEmptyKeyword = searchKeyword.trim().length === 0; if (isEmptyKeyword) { return; } onSubmit?.(); }, [searchKeyword, onSubmit], ); // Prevent Downshift from intercepting Home/End keys so they move // the cursor within the input field instead of navigating the list const keyDownHandler = useCallback( (e: React.KeyboardEvent) => { if (e.key === 'Home' || e.key === 'End') { (e.nativeEvent as { preventDownshiftDefault?: boolean }).preventDownshiftDefault = true; } }, [], ); const inputOptions = useMemo(() => { return getInputProps({ type: 'text', placeholder: 'Search...', className: 'form-control', ref: inputRef, value: searchKeyword, onChange: changeSearchTextHandler, onKeyDown: keyDownHandler, }); }, [getInputProps, searchKeyword, changeSearchTextHandler, keyDownHandler]); useEffect(() => { if (inputRef.current != null) { inputRef.current.focus(); } }); return (
); };