Autocomplete

Text input + dropdown: searchable single-select.
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.
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.
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.
Use value with onValueChange to control the selection, and use "" for a controlled empty value. The callback reports selections and clearing the field. onSelect remains a selection-only notification. The independent query/onQueryChange pair controls filtering; choosing an option resets the query to "".
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.
Assigned to
iOS
Assigned to
Android
Assigned to
Web
tsx
<Autocomplete label="Assigned to" placeholder="Search a person…" options={["Ada Lovelace", "Grace Hopper", "Kira Tanaka", "Liang Bao", "Noor Park"]} />

Props

Prop
Description
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
string[]
The full list of selectable option labels.
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
Prompt shown in the field when there is no query or value.
open
boolean
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
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
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
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.
small
boolean
Size (pick one; default is the medium field, matching Input's h-9).
large
boolean
Size (pick one; default is the medium field, matching Input's h-9).
style
LayoutStyle
Composition within a parent only, never a restyle hook and never a width: the parent layout container provides the bounds.
xxxs
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
xxs
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
xs
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
sm
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
md
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
lg
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
xl
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
xxl
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
xxxl
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
wide
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
wider
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
widest
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
page
boolean
Measure (pick one; omit to take the parent's bounds). Caps the component at a step of the width scale, centered in its column; `start` pins it to the leading edge.
start
boolean
Pin a capped component to the leading edge instead of centering it in its column.
ref
React.Ref<RNTextInput>
Ref to the underlying React Native host. Supports object refs and callback refs; native methods follow the platform's behavior.

Do & Don’t

When to use

Don’t
Size
Type or click: a search field for three fixed options is overhead with nothing to filter.
Do
Size
A plain select for short, fixed lists; reserve the autocomplete for long, searchable ones.

Filtering

Don’t
Assigned to
Try typing: a plain dropdown wearing a search placeholder ignores every keystroke, so a long list stays as long as it started.
Do
Assigned to
Type a few letters: the list narrows as you go, so a long list stays usable.

Selection

Don’t
Assigned to
Click an option: the field is pinned to an empty value, so the list closes on nothing and you can't tell what you picked.
Do
Assigned to
Click an option: it fills the input and stays marked as selected.

With label

Don’t
Once a value replaces the placeholder, an unlabeled field has nothing left to name it.
Do
Assigned to
A persistent label keeps the field named after a selection has filled the input.

With helper text

Don’t
Assigned to
Type a letter: guidance crammed into the placeholder vanishes the moment you start.
Do
Assigned to
Deactivated users are hidden from the list.
A short placeholder plus persistent helper text keeps the rule visible while you type.

Disabled

Don’t
Assigned to
An empty, dimmed field with no value reads as broken, not as intentionally locked.
Do
Assigned to
Set by the project owner and can't be changed here.
Show the locked value and say why it's fixed, so disabled reads as a settled choice.