SearchInput
Status: Experimental
SearchInput is a native search field that works with ordinary form submission and optionally enhances populated-value clearing. It does not own filtering strategy or query state.
Preview
Section titled “Preview”---import { SearchInput } from '@freightpx/frasto';---
<form action="/customers" method="get" role="search"> <SearchInput id="customer-search" name="query" label="Search customers" placeholder="Name, company, or email" value={Astro.url.searchParams.get('query') ?? ''} /></form>Responsibilities
Section titled “Responsibilities”- The application owns the surrounding form, query parameter, URL synchronization, debounce policy, result updates, and persistence.
- SearchInput owns the label, search affordance, populated state, loading presentation, and clear interaction.
- SearchInput does not submit automatically, debounce input, fetch results, or decide between local and remote filtering.
SearchInput forwards relevant native input attributes—including id, name, value, required, disabled, autocomplete, and aria-describedby—to its internal type="search" input.
| Prop | Type | Default | Purpose |
|---|---|---|---|
label |
string |
required | accessible and optionally visible field label |
labelVisible |
boolean |
false |
displays the label above the control |
clearable |
boolean |
true |
enables the progressive clear control |
clearLabel |
string |
"Clear search" |
accessible clear-button name |
loading |
boolean |
false |
shows a restrained loading indicator without changing input ownership |
size |
"sm" | "md" | "lg" |
"md" |
matches Input sizing |
fullWidth |
boolean |
true |
controls root width behavior |
invalid |
boolean |
false |
applies invalid treatment and forwards aria-invalid |
class |
string |
— | styles the component root |
inputClass |
string |
— | styles the internal native input |
Client enhancement
Section titled “Client enhancement”- Without JavaScript, the native search input remains usable and submits normally.
- The clear control is visible and keyboard reachable only when
clearableis true and the input has a value. - Activating clear empties the input, restores focus to it, dispatches a bubbling native
inputevent, and emitsfrasto:search-clear. - Input events keep clear-button visibility synchronized for uncontrolled typing.
loadingis presentational and does not disable or mark results busy. The application appliesaria-busyto the result region it actually updates.- Escape-to-clear is deferred so SearchInput does not conflict with dialogs, drawers, popovers, or application shortcuts.
Composition
Section titled “Composition”<form action="/customers" method="get" role="search"> <SearchInput id="customer-search" name="query" label="Search customers" placeholder="Name, company, or email" value={Astro.url.searchParams.get('query') ?? ''} /></form>The component composes existing Input, IconButton, Icon, and Spinner primitives. It does not introduce a second control styling system.
Accessibility and keyboard behavior
Section titled “Accessibility and keyboard behavior”- Placeholder text never replaces the required
label. - The clear button is keyboard reachable only while available.
- Clear restores focus predictably to the search input.
- Disabled and invalid semantics remain on the native input.
- Loading indicators are decorative unless the application supplies separate result-status messaging.
Responsive behavior
Section titled “Responsive behavior”The control can fill its available width and never assumes a fixed toolbar size. Visible labels and long localized placeholders wrap or clip according to native input behavior without moving the clear control outside the control boundary.
States and edge cases
Section titled “States and edge cases”- empty and populated values
- clearable and non-clearable modes
- loading with empty and populated values
- disabled and invalid
- visible and visually hidden labels
- server submission without JavaScript
- clear-button mouse and keyboard activation
- narrow toolbar, light theme, and dark theme
Best practices
Section titled “Best practices”- Put SearchInput in a native GET form when the query belongs in the URL.
- Keep labels specific to the result set; placeholder examples should supplement, not repeat, the label.
- Choose debounce and live-result policy in the application according to request cost and result behavior.
- Pair
loadingwith application-owned result status messaging when updates are asynchronous. - Listen for native
inputfor query changes; usefrasto:search-clearonly when clear-specific behavior matters.

