AutocompleteInput
Search-as-you-type field for selecting a single item from a search source.
Examples
Section titled “Examples”Default
Section titled “Default”function AutocompleteInputStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} searchSource={source} value={value} /> );}
<AutocompleteInputStory {...args} />Custom Items
Section titled “Custom Items”function CustomItemsStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem<{role: string}> | null>( null, ); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} renderItem={(item, query) => ( <AutocompleteInputItem description={item.auxiliaryData?.role} icon={User} item={item} query={query} /> )} searchSource={source} value={value} /> );}
<CustomItemsStory {...args} />Disabled Results
Section titled “Disabled Results”function DisabledResultsStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem<{role: string}> | null>( null, ); const source = useMemo( () => createStaticSearchSource(peopleWithDisabledResult), [], ); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} renderItem={(item, query) => ( <AutocompleteInputItem description={item.auxiliaryData?.role} item={item} query={query} /> )} searchSource={source} value={value} /> );}
<DisabledResultsStory {...args} />Disabled
Section titled “Disabled”function AutocompleteInputStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} searchSource={source} value={value} /> );}
<AutocompleteInputStory {...args} />Validation Status
Section titled “Validation Status”Choose an assignee before continuing.
function AutocompleteInputStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} searchSource={source} value={value} /> );}
<AutocompleteInputStory {...args} />With Start Icon
Section titled “With Start Icon”function AutocompleteInputStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} searchSource={source} value={value} /> );}
<AutocompleteInputStory {...args} />Pre Selected Value
Section titled “Pre Selected Value”Clear Assignee
(args: AutocompleteInputProps) => { const [value, setValue] = useState<SearchableItem<{role: string}> | null>( people[1], ); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} searchSource={source} value={value} /> );}Without Clear Button
Section titled “Without Clear Button”(args: AutocompleteInputProps) => { const [value, setValue] = useState<SearchableItem<{role: string}> | null>( people[0], ); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} onChange={setValue} searchSource={source} value={value} /> );}(args: AutocompleteInputProps) => { const source = useMemo(() => createStaticSearchSource(people), []); const [small, setSmall] = useState<SearchableItem | null>(null); const [medium, setMedium] = useState<SearchableItem | null>(null); const [large, setLarge] = useState<SearchableItem | null>(null); return ( <div style={{display: 'grid', gap: 16}}> <AutocompleteInput {...args} debounceMs={0} label="Small" onChange={setSmall} searchSource={source} size="sm" value={small} /> <AutocompleteInput {...args} debounceMs={0} label="Medium" onChange={setMedium} searchSource={source} value={medium} /> <AutocompleteInput {...args} debounceMs={0} label="Large" onChange={setLarge} searchSource={source} size="lg" value={large} /> </div> );}Async Search Source
Section titled “Async Search Source”(args: AutocompleteInputProps) => { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createAsyncSource(manyPeople), []); return ( <AutocompleteInput {...args} debounceMs={200} onChange={setValue} searchSource={source} value={value} /> );}Search Error
Section titled “Search Error”(args: AutocompleteInputProps) => { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo<SearchSource<SearchableItem>>( () => ({ bootstrap: () => [], search: async () => Promise.reject(new Error('Network error')), }), [], ); return ( <AutocompleteInput {...args} debounceMs={0} onChange={setValue} searchSource={source} value={value} /> );}Empty Search Results
Section titled “Empty Search Results”function AutocompleteInputStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} searchSource={source} value={value} /> );}
<AutocompleteInputStory {...args} />With Description And Tooltip
Section titled “With Description And Tooltip”Search by name or role.
function AutocompleteInputStory( args: React.ComponentProps<typeof AutocompleteInput>,) { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createStaticSearchSource(people), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus onChange={setValue} searchSource={source} value={value} /> );}
<AutocompleteInputStory {...args} />Base Autocomplete Input Standalone
Section titled “Base Autocomplete Input Standalone”() => { const [value, setValue] = useState<SearchableItem | null>(null); const [query, setQuery] = useState(''); const source = useMemo(() => createStaticSearchSource(people), []); return ( <BaseAutocompleteInput debounceMs={0} hasEntriesOnFocus onChange={setValue} onQueryChange={setQuery} placeholder="Search people" query={query} searchSource={source} value={value} /> );}Large Item List
Section titled “Large Item List”(args: AutocompleteInputProps) => { const [value, setValue] = useState<SearchableItem | null>(null); const source = useMemo(() => createStaticSearchSource(manyPeople), []); return ( <AutocompleteInput {...args} debounceMs={0} hasEntriesOnFocus maxMenuItems={12} onChange={setValue} searchSource={source} value={value} /> );}Required And Optional
Section titled “Required And Optional”({ isOptional: _io, isRequired: _ir, ...args}: AutocompleteInputProps) => { const source = useMemo(() => createStaticSearchSource(people), []); const [required, setRequired] = useState<SearchableItem | null>(null); const [optional, setOptional] = useState<SearchableItem | null>(null); return ( <div style={{display: 'grid', gap: 16}}> <AutocompleteInput {...args} debounceMs={0} isRequired label="Required assignee" onChange={setRequired} searchSource={source} value={required} /> <AutocompleteInput {...args} debounceMs={0} isOptional label="Optional reviewer" onChange={setOptional} searchSource={source} value={optional} /> </div> );}Read Only
Section titled “Read Only”<AutocompleteInput {...args} onChange={() => {}} searchSource={createStaticSearchSource(people)} value={people[0]}/>AutocompleteInput
Section titled “AutocompleteInput”Search-as-you-type field for selecting a single item from a search source.
When isOptional: false, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the input wrapper. |
data-testid | string | — | Test ID applied to the input wrapper. |
debounceMs | number | 150 | Debounce delay in milliseconds before search runs. |
description | ReactNode | — | Supporting text rendered below the label. |
emptySearchResultsText | string | 'No results found' | Empty state text. |
errorText | string | 'Something went wrong' | Text shown in the menu when a search fails. |
hasAutoFocus | boolean | false | Whether to focus the input on mount. |
hasClear | boolean | true | Whether to show a clear button when a value is selected. |
hasEntriesOnFocus | boolean | false | Whether to show bootstrap results on focus before typing. |
isDisabled | boolean | false | Whether the input is disabled. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
label* | string | — | Field label. |
labelIcon | IconComponent | — | Icon shown before the label. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
maxMenuItems | number | 10 | Maximum number of menu items. |
onChange* | (item: T | null) => void | — | Called when selection changes. |
onOpenChange | (isOpen: boolean) => void | — | Called when the result popover opens or closes. |
onQueryChange | (query: string) => void | — | Called when the query changes. |
placeholder | string | — | Placeholder text. |
ref | Ref<HTMLDivElement> | — | Ref forwarded to the field root. |
renderItem | (item: T, query: string) => ReactNode | — | Custom result renderer. Receives the item and active query. |
searchSource* | SearchSource<T> | — | Provides results for the menu. Use createStaticSearchSource for in-memory data, or implement SearchSource for async/remote search. |
size | "sm" | "md" | "lg" | 'md' | Visual size. |
startIcon | IconComponent | — | Icon shown before the input. |
status | InputStatus | — | Validation status displayed below the selector. |
style | CSSProperties | — | Inline styles applied to the input wrapper. |
value* | T | null | — | Selected item. |
isOptional | false | — | |
isRequired | false | — |
When isOptional: true, isRequired: false
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the input wrapper. |
data-testid | string | — | Test ID applied to the input wrapper. |
debounceMs | number | 150 | Debounce delay in milliseconds before search runs. |
description | ReactNode | — | Supporting text rendered below the label. |
emptySearchResultsText | string | 'No results found' | Empty state text. |
errorText | string | 'Something went wrong' | Text shown in the menu when a search fails. |
hasAutoFocus | boolean | false | Whether to focus the input on mount. |
hasClear | boolean | true | Whether to show a clear button when a value is selected. |
hasEntriesOnFocus | boolean | false | Whether to show bootstrap results on focus before typing. |
isDisabled | boolean | false | Whether the input is disabled. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
label* | string | — | Field label. |
labelIcon | IconComponent | — | Icon shown before the label. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
maxMenuItems | number | 10 | Maximum number of menu items. |
onChange* | (item: T | null) => void | — | Called when selection changes. |
onOpenChange | (isOpen: boolean) => void | — | Called when the result popover opens or closes. |
onQueryChange | (query: string) => void | — | Called when the query changes. |
placeholder | string | — | Placeholder text. |
ref | Ref<HTMLDivElement> | — | Ref forwarded to the field root. |
renderItem | (item: T, query: string) => ReactNode | — | Custom result renderer. Receives the item and active query. |
searchSource* | SearchSource<T> | — | Provides results for the menu. Use createStaticSearchSource for in-memory data, or implement SearchSource for async/remote search. |
size | "sm" | "md" | "lg" | 'md' | Visual size. |
startIcon | IconComponent | — | Icon shown before the input. |
status | InputStatus | — | Validation status displayed below the selector. |
style | CSSProperties | — | Inline styles applied to the input wrapper. |
value* | T | null | — | Selected item. |
isOptional* | true | — | |
isRequired | false | — |
When isOptional: false, isRequired: true
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the input wrapper. |
data-testid | string | — | Test ID applied to the input wrapper. |
debounceMs | number | 150 | Debounce delay in milliseconds before search runs. |
description | ReactNode | — | Supporting text rendered below the label. |
emptySearchResultsText | string | 'No results found' | Empty state text. |
errorText | string | 'Something went wrong' | Text shown in the menu when a search fails. |
hasAutoFocus | boolean | false | Whether to focus the input on mount. |
hasClear | boolean | true | Whether to show a clear button when a value is selected. |
hasEntriesOnFocus | boolean | false | Whether to show bootstrap results on focus before typing. |
isDisabled | boolean | false | Whether the input is disabled. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
isLabelHidden | boolean | false | Whether to visually hide the label. |
label* | string | — | Field label. |
labelIcon | IconComponent | — | Icon shown before the label. |
labelTooltip | ReactNode | — | Tooltip content shown next to the label. |
maxMenuItems | number | 10 | Maximum number of menu items. |
onChange* | (item: T | null) => void | — | Called when selection changes. |
onOpenChange | (isOpen: boolean) => void | — | Called when the result popover opens or closes. |
onQueryChange | (query: string) => void | — | Called when the query changes. |
placeholder | string | — | Placeholder text. |
ref | Ref<HTMLDivElement> | — | Ref forwarded to the field root. |
renderItem | (item: T, query: string) => ReactNode | — | Custom result renderer. Receives the item and active query. |
searchSource* | SearchSource<T> | — | Provides results for the menu. Use createStaticSearchSource for in-memory data, or implement SearchSource for async/remote search. |
size | "sm" | "md" | "lg" | 'md' | Visual size. |
startIcon | IconComponent | — | Icon shown before the input. |
status | InputStatus | — | Validation status displayed below the selector. |
style | CSSProperties | — | Inline styles applied to the input wrapper. |
value* | T | null | — | Selected item. |
isOptional | false | — | |
isRequired* | true | — |
BaseAutocompleteInput
Section titled “BaseAutocompleteInput”Internal combobox engine used by AutocompleteInput and TagsInput.
| Prop | Type | Default | Description |
|---|---|---|---|
anchorRef | RefObject<HTMLElement | null> | — | Ref to the element the result popover should align to. |
ariaDescribedBy | string | — | IDs describing the input. |
ariaLabel | string | — | Accessible name for the input. Use when no visible <label> is tied to it, such as inside an InputGroup where the group owns the label. |
className | string | — | Additional CSS class names applied to the input. |
data-testid | string | — | Test ID applied to the input element. |
debounceMs | number | 150 | Debounce delay in milliseconds before search runs. |
emptySearchResultsText | string | 'No results found' | Empty state text. |
errorText | string | 'Something went wrong' | Text shown in the menu when a search fails. |
hasAutoFocus | boolean | false | Whether to focus the input on mount. |
hasEntriesOnFocus | boolean | false | Whether to show bootstrap results on focus before typing. |
hasReopenOnSelect | boolean | false | Whether to re-bootstrap results after selecting an item. Useful for multi-select comboboxes where the user picks several items in a row. |
inputId | string | — | Optional ID for the input. |
isDisabled | boolean | false | Whether the input is disabled. |
isReadOnly | boolean | false | Whether the value is displayed without allowing focus or interaction. |
isRequired | boolean | false | Whether the input is required. |
maxMenuItems | number | 10 | Maximum number of menu items. |
onChange* | (item: T | null) => void | — | Called when a result is selected. |
onKeyDown | (event: KeyboardEvent<HTMLInputElement>) => void | — | Keyboard handler invoked before internal navigation. |
onOpenChange | (isOpen: boolean) => void | — | Called when the result popover opens or closes. |
onQueryChange* | (query: string) => void | — | Called when the query changes. |
placeholder | string | 'Search...' | Placeholder text. |
query* | string | — | Current query string. |
ref | Ref<HTMLInputElement> | — | Ref forwarded to the input. |
renderItem | (item: T) => ReactNode | — | Custom result renderer. |
searchSource* | SearchSource<T> | — | Provides results for the menu. Use createStaticSearchSource for in-memory data, or implement SearchSource for async/remote search. |
size | "sm" | "md" | "lg" | 'md' | Visual size. |
style | CSSProperties | — | Inline styles applied to the input. |
value* | T | null | — | Selected item. |
AutocompleteInputItem
Section titled “AutocompleteInputItem”Default layout for AutocompleteInput and TagsInput result rows. When the item has a pre-rendered `element`, it is returned directly. Otherwise the component renders a flex row with an optional icon, primary label, and description.
When Variant 1
| Prop | Type | Default | Description |
|---|---|---|---|
item* | SearchableItem & {element: ReactNode} | — | Search result item with custom element content. |
query | string | string[] | — | Literal query or queries highlighted in the item label. |
When Variant 2
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | — | Additional CSS class names applied to the item layout. |
data-testid | string | — | Test ID applied to the item layout. |
description | ReactNode | — | Supporting text displayed below the label. |
icon | IconComponent | — | Icon or avatar rendered before the label. |
item* | SearchableItem & {element?: undefined} | — | Search result item without a custom element. |
ref | Ref<HTMLDivElement> | — | Ref forwarded to the item layout. |
style | CSSProperties | — | Inline styles applied to the item layout. |
query | string | string[] | — | Literal query or queries highlighted in the item label. |