#AutoComplete
Suggest values while allowing free-text input.
#Examples
Use options for suggestions and onChange for typed or selected text. onSelect fires only when choosing a suggestion; onSearch fires only for typing. Set filterOption=false for server-generated suggestions. Handle debouncing and request order in your application.
basic.tsx
import { AutoComplete, Form, FormField, Text } from '@ifhover/leaf-ui';
import { useState } from 'react';
const options = [
{ value: 'Leaf Garden' },
{ value: 'Leaf Studio' },
{ value: 'Pine Forest' },
{ value: 'Archived Garden', disabled: true },
];
export function AutoCompleteBasic() {
const [value, setValue] = useState('');
const [selected, setSelected] = useState('');
return (
<Form layout="vertical">
<FormField label="Project name">
<AutoComplete
aria-label="Project name"
placeholder="Type Leaf or enter any text"
options={options}
value={value}
onChange={setValue}
onSelect={setSelected}
/>
</FormField>
<Text tone="muted">
Input:{value || 'Empty'} · Last selection:{selected || 'None'}
</Text>
<FormField label="Disabled suggestions">
<AutoComplete
aria-label="Disabled suggestions"
options={options}
disabled
defaultValue="Leaf Garden"
/>
</FormField>
</Form>
);
}
search.tsx
import { AutoComplete, type AutoCompleteOption, Form, FormField, Text } from '@ifhover/leaf-ui';
import { useState } from 'react';
export function AutoCompleteSearch() {
const [options, setOptions] = useState<AutoCompleteOption[]>([]);
return (
<Form layout="vertical">
<FormField label="Email address">
<AutoComplete
aria-label="Email address"
placeholder="Enter the first part of an email"
options={options}
filterOption={false}
onSearch={(query) => {
const prefix = query.split('@')[0] ?? '';
setOptions(
prefix
? ['gmail.com', 'outlook.com', 'icloud.com'].map((domain) => ({
value: `${prefix}@${domain}`,
}))
: [],
);
}}
/>
</FormField>
<Text tone="muted">
Suggestions are generated as you type. You can also enter a complete address.
</Text>
</Form>
);
}
#Rich groups and loading states
capabilities.tsx
import { AutoComplete, Button, Space } from '@ifhover/leaf-ui';
import { useState } from 'react';
const options = [
{
label: 'Team',
options: [
{
value: 'alice@example.com',
label: (
<>
<strong>Alice</strong> · Design
</>
),
searchLabel: 'Alice Design',
},
{
value: 'bob@example.com',
label: (
<>
<strong>Bob</strong> · Engineering
</>
),
searchLabel: 'Bob Engineering',
},
],
},
];
export function Capabilities() {
const [state, setState] = useState<'ready' | 'loading' | 'error'>('ready');
return (
<Space direction="vertical" align="stretch">
<Space>
<Button size="sm" onClick={() => setState('ready')}>
{'Ready'}
</Button>
<Button size="sm" variant="outline" onClick={() => setState('loading')}>
{'Loading'}
</Button>
<Button size="sm" variant="outline" onClick={() => setState('error')}>
{'Error'}
</Button>
</Space>
<AutoComplete
aria-label={'Team email'}
options={state === 'ready' ? options : []}
loading={state === 'loading'}
errorContent={
state === 'error' ? (
<Button size="sm" variant="ghost" onClick={() => setState('ready')}>
{'Retry'}
</Button>
) : undefined
}
allowClear
notFoundContent={'No matching teammate'}
/>
</Space>
);
}
#AutoComplete API
| Property | Type | Default | Description |
|---|---|---|---|
options | readonly (AutoCompleteOption|AutoCompleteOptionGroup)[] | Required | Required. Suggestion options |
value | string | Required | Unique suggestion value; inserted into the input on selection |
defaultValue | string | '' | Controlled text / uncontrolled initial text |
size | 'sm' | 'md' | 'lg' | 'md' | Control size |
status | 'error' | 'warning' | — | Validation appearance |
filterOption | false | ((query: string, option: AutoCompleteOption) => boolean) | Substring match | false disables local filtering; a function customizes matching |
onChange | (value: string) => void | — | Text after typing or selecting |
onSelect | (value: string, option: AutoCompleteOption) => void | — | Runs when selecting a suggestion |
onSearch | (query: string) => void | — | Runs on typing, not on selection |
open | boolean | — | Control whether the panel is open. |
defaultOpen | boolean | — | Initial open state. |
onOpenChange | (open: boolean) => void | — | Called when the panel opens or closes. |
loading | boolean | — | Show a loading state. |
notFoundContent | ReactNode | — | Content when no options match. |
errorContent | ReactNode | — | Content for loading errors and retry actions. |
optionRender | (option: AutoCompleteOption) => ReactNode | — | Customize option content. |
allowClear | boolean | — | Show a clear action. |
virtual | boolean | — | Enable virtual scrolling; enabled by default for large option sets. |
listHeight | number | 248 | Height of the visible list. |
optionHeight | number | 32 | Estimated virtual row height; follows the regional height and density. Actual rows are measured. |
popupPlacement | PopupOptions['popupPlacement'] | — | Placement relative to the trigger. |
popupClassName | string | — | Custom class for the popup. |
popupStyle | PopupOptions['popupStyle'] | — | Custom popup styles. |
popupRender | PopupOptions['popupRender'] | — | Wrap or extend popup content; retain the supplied content to preserve interaction. |
getPopupContainer | PopupOptions['getPopupContainer'] | — | Return a popup container, including a ShadowRoot. |
disabled | boolean | false | Disable interaction. |
readOnly | boolean | false | Lock the value against typing, selection, clearing and removal. |
ref | Ref<HTMLInputElement> | — | DOM reference |
#AutoCompleteOption
| Property | Type | Default | Description |
|---|---|---|---|
value | string | Required | Unique suggestion value; inserted into the input on selection |
label | string | — | Suggestion label, also used by the default filter |
disabled | boolean | false | Disable the suggestion |
#Types
Import AutoCompleteProps to describe component props. Option types in the API table link to their detailed fields above.
import type { AutoCompleteProps, AutoCompleteOption } from '@ifhover/leaf-ui';#Forms and localization
Use name to include values in FormData. Uncontrolled fields follow form reset; reset controlled values in application state. Place controls in FormField for labels, help and errors. ConfigProvider supplies regional themes and translated built-in UI. Application labels and options are your responsibility.
#AutoCompleteOption
| Property | Type | Default | Description |
|---|---|---|---|
value | string | — | Required. Controlled value. |
label | ReactNode | — | Visible label or content. |
searchLabel | string | — | Plain text used for searching. |
disabled | boolean | — | Disable interaction. |
#AutoCompleteOptionGroup
| Property | Type | Default | Description |
|---|---|---|---|
label | ReactNode | — | Required. Visible label or content. |
options | readonly AutoCompleteOption[] | — | Required. Available options. |