| import { useState, KeyboardEvent } from 'react'; | |
| import { Input } from '@/components/ui/input'; | |
| import { Button } from '@/components/ui/button'; | |
| import { Search, Loader2 } from 'lucide-react'; | |
| import { cn } from '@/lib/utils'; | |
| interface SearchInputProps { | |
| onSearch: (query: string) => void; | |
| isLoading?: boolean; | |
| initialValue?: string; | |
| autoFocus?: boolean; | |
| large?: boolean; | |
| } | |
| export function SearchInput({ | |
| onSearch, | |
| isLoading = false, | |
| initialValue = '', | |
| autoFocus = false, | |
| large = false, | |
| }: SearchInputProps) { | |
| const [query, setQuery] = useState(initialValue); | |
| const handleSubmit = () => { | |
| if (query.trim() && !isLoading) { | |
| onSearch(query.trim()); | |
| } | |
| }; | |
| const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => { | |
| if (e.key === 'Enter') { | |
| handleSubmit(); | |
| } | |
| }; | |
| return ( | |
| <div className="relative flex w-full items-center gap-2"> | |
| <div className="relative flex-1"> | |
| <Search className={cn( | |
| "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground", | |
| large ? "h-5 w-5" : "h-4 w-4" | |
| )} /> | |
| <Input | |
| value={query} | |
| onChange={(e) => setQuery(e.target.value)} | |
| onKeyDown={handleKeyDown} | |
| placeholder="Ask anything..." | |
| className={cn( | |
| "pl-10 pr-4 transition-all duration-200", | |
| large && "h-12 text-lg rounded-lg", | |
| "focus-visible:ring-2 focus-visible:ring-primary" | |
| )} | |
| disabled={isLoading} | |
| autoFocus={autoFocus} | |
| /> | |
| </div> | |
| <Button | |
| onClick={handleSubmit} | |
| disabled={!query.trim() || isLoading} | |
| className={cn( | |
| "min-w-[80px] shadow-sm", | |
| large && "h-12 px-6 text-lg rounded-lg" | |
| )} | |
| > | |
| {isLoading ? ( | |
| <Loader2 className={cn("animate-spin", large ? "h-5 w-5" : "h-4 w-4")} /> | |
| ) : ( | |
| 'Search' | |
| )} | |
| </Button> | |
| </div> | |
| ); | |
| } |