ui · Primitive
Autocomplete
@devalok/shilp-sutra/ui/autocompleteView in Storybook Preview
Variants
custom emptyText
disabled
Reference
- Import: @devalok/shilp-sutra/ui/autocomplete
- Server-safe: No
- Category: ui
Props
options: AutocompleteOption[] (REQUIRED) — { value: string, label: string }
value?: AutocompleteOption | null (controlled)
defaultValue?: AutocompleteOption | null (uncontrolled initial)
onValueChange?: (option: AutocompleteOption) => void
placeholder?: string
emptyText?: string (default: "No options")
disabled?: boolean
size?: (forwarded to Input)
state?: 'default' | 'error' | 'warning' | 'success' (forwarded to Input)
isLoading?: boolean
loadingText?: string (default: "Loading…")
renderOption?: (option, query) => ReactNode
className?: string
id?: string
Defaults
emptyText="No options"
loadingText="Loading…"
Example
<Autocomplete
options={[{ value: 'mumbai', label: 'Mumbai' }]}
value={selectedCity}
onValueChange={setSelectedCity}
placeholder="Search cities..."
/>Composability
- Composes
Input— the field is the DSInput, so it inheritssize, error/statepainting, read-only, hover, and FormField wiring. Autocomplete owns only the dropdown + behavior. - Autocomplete vs Combobox: Autocomplete allows free-text input (users can type anything); Combobox enforces selection from the list.
- Value shape is an object (
{ value, label }), not a plain string. Controlled viavalue, or uncontrolled viadefaultValue. - FormField: auto-consumes FormField state (via the composed Input) — inside a FormField, error border +
aria-invalid/aria-describedby/requiredare wired automatically. Passstateto override. - Async / "type to search": set
isLoadingto show a spinner (in the field + the listbox) withloadingText. - Matched-text highlight: the query substring is bolded in each option by default; override the whole row with
renderOption. - Portal rendering: Dropdown portals to body with z-popover (1400) — stacks above Dialog/Sheet.
- Keyboard: ArrowDown/Up/Home/End navigate, Enter selects, Esc closes.
Gotchas
- Allows free-text input (no forced selection) — use Combobox for forced selection
- value is an object { value, label }, NOT just a string
- Client-side filtering only (known list). For huge/remote lists, drive
optionsyourself withisLoading— no built-in virtualization.
Changes
v0.53.0
- Changed Re-parented onto the DS
Inputprimitive — inheritssize, error/statepainting, read-only, hover, and FormField auto-consumption (previously re-rolled its own<input>and read FormField error but never painted it). - Added
defaultValue(uncontrolled),size,state,isLoading/loadingText(async),renderOption, and matched-substring highlighting. - Fixed Doc corrected — it DOES auto-consume FormField (via Input). Dropped a keystroke-frequency stagger animation + a dead effect.
v0.18.0
- Fixed Added
useEffectto sync query when external value changes
v0.14.0
- Changed z-index promoted from
z-dropdown(1000) toz-popover(1400) — fixes dropdown rendering behind Sheet/Dialog overlays
v0.3.0
- Changed (BREAKING)
onChangerenamed toonValueChange
v0.1.1
- Fixed
focus:ringchanged tofocus-visible:ring— focus ring no longer shows on mouse click
v0.1.0
- Added Initial release