Use cases
- Standalone search bar — Employee Lookup, global search.
- Filter input inside list-driven widgets (CheckboxGrid, TransferList).
- Type-ahead combobox base (pair with a popover list).
When NOT to use
- For a regular form input → use Input.
- For a tag-style search with chips → wrap your own composition.
Controlled only
SearchField is intentionally controlled — you own the value:
const [query, setQuery] = useState('');
<SearchField value={query} onValueChange={setQuery} />For uncontrolled use, wrap with useState in a parent.
Sizes
| Size | Height | Use when |
|---|---|---|
sm | 36 px | Inside dense widgets (filter inputs). |
md | 40 px | Default for most desktop bars. |
lg | 48 px | Mobile-primary search or prominent page filters. |
Clear button
The clear button appears automatically when value is non-empty. Pass noClear to suppress it (rare — when the field's onValueChange clears its own state asynchronously, e.g. behind a 300 ms debounce, and you don't want a flicker).
SearchField also suppresses the browser-native search cancel affordance. That keeps the control to one clear button in every browser, and noClear now means no visible clear affordance at all.
Trailing slot
trailingSlot accepts any node placed after the clear button — typically a keyboard-shortcut hint:
<SearchField
value={query}
onValueChange={setQuery}
trailingSlot={<kbd className="text-[10px] text-muted-foreground">⌘K</kbd>}
/>Composition
- SearchField is controlled-only — pass
valueandonValueChange. - Debounce
onValueChange(300 ms) to avoid firing a search on every keystroke. - Use
trailingSlotfor keyboard shortcut hints (e.g.⌘K) that open a Command palette. - Pair with a results dropdown via Combobox for autocomplete search.
- Use
inputClassNamefor inner input overrides andclassNamefor the field wrapper. Both should use Tailwind utilities backed by MiHCM tokens.