({
status,
autoFocus = false,
autoSubmit = false,
}: {
status: 'idle' | 'pending' | 'success' | 'error'
autoFocus?: boolean
autoSubmit?: boolean
})
| 7 | import { StatusButton } from './ui/status-button.tsx' |
| 8 | |
| 9 | export function SearchBar({ |
| 10 | status, |
| 11 | autoFocus = false, |
| 12 | autoSubmit = false, |
| 13 | }: { |
| 14 | status: 'idle' | 'pending' | 'success' | 'error' |
| 15 | autoFocus?: boolean |
| 16 | autoSubmit?: boolean |
| 17 | }) { |
| 18 | const id = useId() |
| 19 | const [searchParams] = useSearchParams() |
| 20 | const submit = useSubmit() |
| 21 | const isSubmitting = useIsPending({ |
| 22 | formMethod: 'GET', |
| 23 | formAction: '/users', |
| 24 | }) |
| 25 | |
| 26 | const handleFormChange = useDebounce((form: HTMLFormElement) => { |
| 27 | submit(form) |
| 28 | }, 400) |
| 29 | |
| 30 | return ( |
| 31 | <Form |
| 32 | method="GET" |
| 33 | action="/users" |
| 34 | className="flex flex-wrap items-center justify-center gap-2" |
| 35 | onChange={(e) => autoSubmit && handleFormChange(e.currentTarget)} |
| 36 | > |
| 37 | <div className="flex-1"> |
| 38 | <Label htmlFor={id} className="sr-only"> |
| 39 | Search |
| 40 | </Label> |
| 41 | <Input |
| 42 | type="search" |
| 43 | name="search" |
| 44 | id={id} |
| 45 | defaultValue={searchParams.get('search') ?? ''} |
| 46 | placeholder="Search" |
| 47 | className="w-full" |
| 48 | autoFocus={autoFocus} |
| 49 | /> |
| 50 | </div> |
| 51 | <div> |
| 52 | <StatusButton |
| 53 | type="submit" |
| 54 | status={isSubmitting ? 'pending' : status} |
| 55 | className="flex w-full items-center justify-center" |
| 56 | > |
| 57 | <Icon name="magnifying-glass" size="md" /> |
| 58 | <span className="sr-only">Search</span> |
| 59 | </StatusButton> |
| 60 | </div> |
| 61 | </Form> |
| 62 | ) |
| 63 | } |
nothing calls this directly
no test coverage detected