Autocomplete

Atom
Text input + dropdown: searchable single-select.

Playground

Every control sets a real prop of AutocompleteProps. The JSX below updates as you go.
Component
Props
label
string
query
string
placeholder
string
open
boolean
helperText
string
Size
pick one
required
boolean
disabled
boolean
JSX · AutocompleteProps
<Autocomplete
label="Component"
query="ra"
placeholder="Search components"
open
/>

Variants

5 examples from src/atoms/autocomplete/autocomplete.md, each rendered live from its own JSX.
Assigned to
Required field
<Autocomplete label="Assigned to" required placeholder="Search a person…" options={["Ada Lovelace", "Grace Hopper", "Kira Tanaka"]} />
Assigned to
The person responsible for this account.
With helper text
<Autocomplete label="Assigned to" helperText="The person responsible for this account." placeholder="Search a person…" options={["Ada Lovelace", "Grace Hopper", "Kira Tanaka"]} />
Assigned to
Disabled
<Autocomplete label="Assigned to" placeholder="Search a person…" disabled options={["Ada Lovelace", "Grace Hopper", "Kira Tanaka"]} />
Assigned to
Controlled selection
<Stateful initial="Grace Hopper">
{(value, setValue) => (
<Autocomplete label="Assigned to" options={["Ada Lovelace", "Grace Hopper", "Kira Tanaka"]} value={value} onValueChange={setValue} />
)}
</Stateful>
Measure
<Column snug>
<Autocomplete xs start options={["Ada Lovelace", "Grace Hopper"]} placeholder="xs step, pinned to the start (320)" />
<Autocomplete lg start options={["Ada Lovelace", "Grace Hopper"]} placeholder="lg step, pinned to the start (512)" />
<Container lg start><Autocomplete options={["Ada Lovelace", "Grace Hopper"]} placeholder="Bare, in an lg Container: fills it (512)" /></Container>
</Column>

Sizes

Component
small
Component
default
Component
large

States

Hover, focus and press are pinned so they can be compared side by side; the rest are real props.
Component
default
Component
focus
Component
disabled

Anatomy

Component
1
Label
2
Field
3
Query
4
Listbox
5
Match highlight
Dimmed parts appear only in some states or variants.

Props

21 props on AutocompleteProps, grouped as they are declared in source. Required props are marked *.
Prop
Type
Default
Description
Props
18 props
query
string
–
The text typed into the field (controlled). Filters the option list. Omit and use defaultQuery for uncontrolled use: a bare Autocomplete is typeable out of the box.
defaultQuery
string
–
Initial query for uncontrolled use.
onQueryChange
(query: string) => void
–
Fired with the new query on each keystroke, and with "" when a select resets the filter (both modes).
options
Array<string | AutocompleteOption>
–
The full list of selectable options: bare labels, or { label, detail } objects whose detail sits muted at the row's end (a version, a platform). The label is what the query matches and what value holds.
value
string
–
The selected option label (CONTROLLED), or "" for no selection. Omit for uncontrolled use.
defaultValue
string
–
Initial selected option for uncontrolled use (selecting a row updates it).
onValueChange
(value: string) => void
–
Fired on selection and with "" when the field is cleared, in both controlled and uncontrolled modes.
placeholder
string
"Search…"
Prompt shown in the field when there is no query or value.
open
boolean
false
Whether the option list is open (CONTROLLED). Uncontrolled and closed by default; focusing or typing in the field opens it, the chevron toggles it. Pass open to pin it open, or defaultOpen to render it open initially while staying interactive. A disabled control stays closed regardless.
defaultOpen
boolean
false
Render the list open initially for uncontrolled use (selecting or the chevron closes it).
onOpenChange
(open: boolean) => void
–
Fired when the open state changes (focus, typing, chevron, select).
label
string
–
The field's persistent label. Its placement is platform-adaptive: iOS and web render it ABOVE the field; Android renders the Material 3 in-container FLOATING label (centered like a placeholder at rest, floating to the top once the list opens or a value fills the field). The label names the field for assistive tech.
required
boolean
false
Marks the field as required: appends a destructive "*" to the label (decorative, never in the accessible name) and announces the field as required, through aria-required on the web and with the word in its name ("Assigned to, required") on iOS and Android. The star and the spoken word take effect only alongside label.
helperText
string
–
Optional muted helper line rendered below the option list.
disabled
boolean
false
Dims the control and blocks interaction.
onSelect
(option: string) => void
–
Called when an option is chosen by touch, pointer, or keyboard. Clearing only fires onValueChange.
testID
string
–
E2E hook forwarded to the text field.
ref
React.Ref<RNTextInput>
–
Ref to the underlying React Native host. Supports object refs and callback refs; native methods follow the platform's behavior.
Size
pick one
3 props
small
boolean
false
large
boolean
false
style
LayoutStyle
–
Composition within a parent only, never a restyle hook and never a width: the parent layout container provides the bounds.
MeasureProps · width steps xxxs 192 · xxs 256 · xs 320 · sm 384 · md 448 · lg 512 · xl 576 · xxl 672 · xxxl 768 · wide 896 · wider 1024 · widest 1152 · page 1280, plus start to pin to the leading edge.

Accessibility and keyboard

Keyboard
ArrowDown
Opens the list
ArrowUp
ArrowDown
Moves through options
Enter
Commits the active option
Escape
Closes the list, keeps the text
Semantics
Roles
button
combobox
option
States
disabled
expanded
selected
ARIA on web
aria-activedescendant
aria-autocomplete
aria-controls
aria-disabled
aria-expanded
aria-haspopup
aria-label
aria-required
aria-selected
Below the platform minimum, the touch area grows to 44 pt on iOS and 48 dp on Android without moving the layout.
From the docs
Pass label (and required) to name the field: iOS and web render the label above the field, while Android floats the Material 3 in-container label once the list opens or a value fills the field. On Android the field grows with the user's text size, and a label longer than the field truncates on one line clear of the toggle while the field's accessible name stays the whole label. The required star is decorative: a screen reader hears the field as required, from aria-required on the web and from its name ("Assig
Arrow Down and Arrow Up open the list and highlight an option while focus stays in the text field. Navigation stops at the first and last matches. Home and End jump to those limits once an option is highlighted; otherwise they retain their text-editing behavior. Enter chooses the highlighted option, Escape closes the list without changing the query, and Tab closes it while moving focus. Typing resets the highlight. Confirming an input-method candidate does not select an option or submit a surrounding Form.
The disclosure button has a real target of at least 24px on web, 44pt on iOS, and 48dp on Android. The small iOS field keeps a 44pt height so its touch target fits inside the field; its typography remains compact.

Platform skins

The playground's props on each platform: same tree, native shapes, type and touch sizes.
Web
control 10 · field 10 · card 16 · Instrument Sans
iOS
capsule controls · field 8 · card 12 · SF Pro · 44 pt
Android
Material 3 stadium · field 4 · card 12 · Roboto · 48 dp

Usage

<Autocomplete label="Assigned to" placeholder="Search a person…" options={["Ada Lovelace", "Grace Hopper", "Kira Tanaka", "Liang Bao", "Noor Park"]} />
Pass label (and required) to name the field: iOS and web render the label above the field, while Android floats the Material 3 in-container label once the list opens or a value fills the field. On Android the field grows with the user's text size, and a label longer than the field truncates on one line clear of the toggle while the field's accessible name stays the whole label. The required star is decorative: a screen reader hears the field as required, from aria-required on the web and from its name ("Assigned to, required") on iOS and Android. The field fills the parent it is given; a step of its own (xs, lg, …, with start to pin it to the leading edge) or a Container step sets its measure.
On web the field is the Canvas v4 search field: 40px tall (32 small, 48 large) on the sunken fill behind the field-border hairline, a leading 16px search glyph, a 400 14px value (13 small) and a 15px chevrons-up-down 10px from its end. The pointer darkens the edge to the subtle ink, and focus rings it in the accent with a 4px halo. The suggestions are a card 6px under the field with a 4px inset and 34px rows; the typed letters are marked in each suggestion on the accent's soft wash, and the chosen suggestion sits on the muted wash. iOS ships no combo box, so it draws the same field and card at the iOS corners. Android keeps the Material 3 exposed dropdown: the filled field with its active indicator and drop-down triangle, and the Material menu whose active and chosen rows take the state layer.
In glass mode the suggestion list is a dense-layer glass card under the field (or above it when it fits there); the field, its caret and its toggle stay in place, and picking a suggestion commits the value at once. Solid mode paints the skin's own list.

Tokens

Read from the playground render. Values follow the scheme and the ion hue.
--bg2
--fd
--ft
--ion-soft
--ion-tx
--ln
--ln2
--sf
--sf3
--sh-md
--tx2
--tx3

Related components