Autocomplete
A controlled search field with inline, sheet, or fullscreen result presentation and explicit loading, error, empty, and disabled states.
Implementation previewEvery example. In one place.
Explore every named example, including states, compositions, and theme variants.
Example source
packages/design-system/src/components/forms/Autocomplete/Autocomplete.stories.tsxExport PlaygroundImplementation preview Local Storybook build 0.2.0-preview.1. Source specification status does not approve this runtime.
Stories + source JSON ↗Local specification source status: preview. Implementation preview pending sign-off.
A controlled search field with inline, sheet, or fullscreen result presentation and explicit loading, error, empty, and disabled states.
Implementation API 1 entry point · source-derived preview
Read the actual callable API and preserve its composition constraints. Each union branch is a complete alternative; props marked forbidden cannot be supplied.
import { Autocomplete } from '@cloakedinc/design-system';AutocompleteAutocompleteProps
packages/design-system/src/components/forms/Autocomplete/Autocomplete.tsx:80
| Prop | Type | Presence | Notes |
|---|---|---|---|
query | string | Required | Text shown in the search field. Display only: `items` is never filtered by it. |
onQueryChange | (query: string) => void | Required | Called with the new text on each keystroke, and with `''` when the clear action fires. |
items | AutocompleteItem[] | Required | Results to render, already filtered and ordered by the app. |
onSelect | (item: AutocompleteItem) => void | Required | Called with the tapped item. Disabled items never reach it. |
loading | boolean | undefined | Optional | Replaces the list with a spinner and sets `aria-busy`. Wins over `error` and `items`. |
error | React.ReactNode | Optional | Error copy shown instead of results. |
emptyState | React.ReactNode | Optional | Empty state shown when there are no results.Source default: 'No results found.' |
displayMode | AutocompleteDisplayMode | undefined | Optional | Result presentation mode. Defaults to `inline`.Source default: 'inline' |
placeholder | string | undefined | Optional | Placeholder in the search field. Defaults to `Search`.Source default: 'Search' |
size | AutocompleteSize | Required | Search field and result row size. |
surface | import("@cloakedinc/design-system").InputSurface | undefined | Optional | Search field background treatment. Defaults to `default`; use `raised` inside a raised form.Source default: 'default' |
enterBehavior | InputEnterBehavior | undefined | Optional | Return-key behavior for the search field. Left unset, `SearchField`'s `callback` applies. |
enterKeyHint | InputEnterKeyHint | undefined | Optional | Native on-screen keyboard return key hint for the search field. |
ariaLabel | string | Required | Accessible label for the search field. |
disabled | boolean | undefined | Optional | Prevents query and selection interaction. |
haptic | HapticFeedback | undefined | Optional | Haptic feedback for result selection. Defaults to `true` (`selection`).Source default: true |
className | string | undefined | Optional | |
style | React.CSSProperties | undefined | Optional | |
testId | string | undefined | Optional | Optional test selector. Result rows derive `${testId}-${item.value}`. |
Only explicit destructured parameter initializers are extracted. Other runtime defaults remain in implementation source.
Overview
A controlled type-ahead field: a search input over a role="listbox" of results. You own the
query state, debouncing, and fetching, and feed it items; it renders the loading, error,
and emptyState for you.
When to use
Reach for Autocomplete when the option set is too long or too dynamic to show at once and the
user needs to type to narrow it — broker search, address lookup, anything backed by a query. It is
presentation only: fetching and filtering stay in the app.
- Short, fixed list of a handful of options? Use
Select— no typing needed. - A list of one-off commands rather than values to filter? That's a
Menu(selectionMode="none").
error and emptyState are distinct: error means the fetch failed, emptyState means it
succeeded with no matches. In-app it powers the address lookup in the data-removal profile
(AddressesField.tsx), where it also joins keyboard next-field navigation.
Component specification
$schema
../../../specs/component-spec.schema.jsonParts
- Id
- root
- Label
- Root
- Description
- Stacks the search field and result surface at the selected density.
- Id
- search-field
- Label
- Search field
- Description
- Owns the query, search semantics, loading indicator, clear action, and the surface treatment.
- Id
- result-surface
- Label
- Result surface
- Description
- Provides the labelled listbox and selected display mode.
- Id
- option
- Label
- Option
- Description
- Pressable result row with optional leading, description, and trailing content.
- Id
- feedback
- Label
- Feedback
- Description
- Replaces options with loading, error, or empty-state content.
Allowed Design Choices
- Variants
- Base
- Label
- Base
- Description
- One controlled search-and-pick pattern configured through mode and size axes.
- Sizes
- Sm
- Label
- Small
- Md
- Label
- Medium
- Modes
- Inline
- Label
- Inline
- Description
- Keeps a bounded result list directly below the search field.
- Sheet
- Label
- Sheet
- Description
- Uses a taller result surface with top-only rounding for sheet composition.
- Fullscreen
- Label
- Fullscreen
- Description
- Uses an unrounded, minimum-height result surface for a full-screen composition.
Variants
- Id
- base
- Label
- Base
- Description
- Controlled search and listbox composition with mode, size, and async feedback kept orthogonal.
- Platforms
- ios
- android
- web
Sizes
- Id
- sm
- Label
- Small
- Description
- Compact search shell, 4-unit stack gap, and tighter result-row padding.
- Id
- md
- Label
- Medium
- Description
- Standard search shell, 8-unit stack gap, and roomier result rows.
Measurements
- Id
- small-stack-gap
- Label
- Small search-to-results gap
- Kind
- exact
- Token
- --cds-space-4
- Value
- 4
- Unit
- px
- Applies To
- root
- sm
- Id
- medium-stack-gap
- Label
- Medium search-to-results gap
- Kind
- exact
- Token
- --cds-space-8
- Value
- 8
- Unit
- px
- Applies To
- root
- md
- Id
- medium-option-horizontal-padding
- Label
- Medium option horizontal padding
- Kind
- exact
- Token
- --cds-space-16
- Value
- 16
- Unit
- px
- Applies To
- option
- md
Layout
- Alignment
- The search field and result surface fill the root width; option visuals align to the row start.
- Flow
- Search field precedes one listbox whose contents are options or a single feedback state.
- Notes
- Keep data fetching and debouncing outside the component.
- Leading and trailing option content never consume the flexible copy column.
Typography And Color
- Typography
- Label
- Option label
- Description
- Medium rows use body text; compact rows use body-small text.
- Token
- --cds-type-body-size
- Colors
- Label
- Result surface
- Description
- Uses the raised semantic surface.
- Token
- --cds-bg-surface
- Label
- Primary copy
- Description
- Uses primary text emphasis for option labels.
- Token
- --cds-text-primary
- Label
- Secondary copy
- Description
- Uses secondary emphasis for descriptions and neutral feedback.
- Token
- --cds-text-secondary
- Label
- Error copy
- Description
- Uses the semantic danger text role.
- Token
- --cds-status-danger-solid
States
- Id
- results
- Label
- Results
- Description
- Shows enabled and disabled options for the current query.
- Id
- loading
- Label
- Loading
- Description
- Marks the listbox busy and replaces options with a labelled spinner.
- Id
- empty
- Label
- Empty
- Description
- Shows calm no-results copy after a successful query with no matches.
- Id
- error
- Label
- Error
- Description
- Shows failure copy instead of empty-state copy or stale results.
- Id
- disabled
- Label
- Disabled
- Description
- Blocks query editing and every option press.
Behavior
- Label
- Controlled query
- Description
- Request each query update while the parent owns filtering, fetching, and the rendered query.
- Label
- Selection
- Description
- Emit the complete selected item exactly once and ignore disabled options.
- Label
- Presentation modes
- Description
- Change only result-surface composition; mode does not alter search or selection semantics.
- Label
- Surface treatment
- Description
- The search field forwards a surface treatment (default or raised). Use raised inside a raised form so the field reads as an input rather than blending into the container.
Accessibility
- Label
- Search name
- Description
- Require a stable accessible name for the search field.
- Label
- Result relationship
- Description
- Connect the search field to the labelled listbox and expose busy state during loading.
- Label
- Options
- Description
- Expose each result as an option and preserve native disabled behavior.
Content Adaptation
- Label
- Long result copy
- Description
- Allow labels and descriptions to wrap within the flexible copy column.
- Label
- Distinct feedback
- Description
- Use empty copy only for successful zero-result queries and error copy only for failures.
Motion Haptics
- Motion
- Label
- Stable replacement
- Description
- Replace result and feedback content without moving the search field.
- Haptics
- Label
- Selection feedback
- Description
- Request the selection haptic after an enabled option is chosen.
Platform Differences
- Platforms
- ios
- android
- Description
- Sheet and fullscreen modes should use the host platform presentation container while web applies the documented result-surface geometry in place.
- Rationale
- The interaction contract is shared, but native containers provide expected focus, keyboard, and dismissal behavior.