import { twMerge } from "tailwind-merge"; import Input from "../form/Input"; import Button from "../layout/Button"; import Row from "../layout/Row"; import { Search as SearchIcon } from "lucide-react"; import React, { DetailedHTMLProps, InputHTMLAttributes, TextareaHTMLAttributes, } from "react"; let timeout: any; export type SearchProps = DetailedHTMLProps< React.HTMLAttributes<HTMLDivElement>, HTMLDivElement > & { dispatch?: (value?: string) => void; delay?: number; inputProps?: DetailedHTMLProps< InputHTMLAttributes<HTMLInputElement>, HTMLInputElement > & DetailedHTMLProps< TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement >; buttonProps?: DetailedHTMLProps< React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement >; }; /** * # Search Component * @className_wrapper twui-search-wrapper * @className_circle twui-search-input * @className_circle twui-search-button */ export default function Search({ dispatch, delay = 500, inputProps, buttonProps, ...props }: SearchProps) { const [input, setInput] = React.useState(""); React.useEffect(() => { clearTimeout(timeout); timeout = setTimeout(() => { dispatch?.(input); }, delay); }, [input]); const inputRef = React.useRef<HTMLInputElement>(); React.useEffect(() => { if (props.autoFocus) { inputRef.current?.focus(); } }, []); return ( <Row {...props} className={twMerge( "relative xl:flex-nowrap items-stretch gap-0", "twui-search-wrapper", props?.className )} > <Input type="search" placeholder="Search" {...inputProps} value={input} onChange={(e) => setInput(e.target.value)} className={twMerge( "rounded-r-none", "twui-search-input", inputProps?.className )} wrapperProps={{ className: "rounded-r-none", }} componentRef={inputRef} /> <Button {...buttonProps} variant="outlined" color="gray" className={twMerge( "rounded-l-none my-[1px]", "twui-search-button", buttonProps?.className )} onClick={() => { dispatch?.(input); }} > <SearchIcon className="text-slate-800 dark:text-white" size={20} /> </Button> </Row> ); }