#AutoComplete 自动完成
在输入文本时提供建议,帮助快速完成填写。
#基础输入
通过 options 设置建议,默认按显示文本进行不区分大小写的包含匹配。onChange 响应输入和选择,onSelect 仅响应选择建议。
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="项目名称">
<AutoComplete
aria-label="项目名称"
placeholder="输入 Leaf 或自由填写"
options={options}
value={value}
onChange={setValue}
onSelect={setSelected}
/>
</FormField>
<Text tone="muted">
输入:{value || '空'} · 最近选中:{selected || '无'}
</Text>
<FormField label="禁用建议">
<AutoComplete aria-label="禁用建议" options={options} disabled defaultValue="Leaf Garden" />
</FormField>
</Form>
);
}
#动态建议
onSearch 接收用户输入。建议由你生成或从服务端获取时,可设置 filterOption={false} 直接展示传入结果。
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="邮箱地址">
<AutoComplete
aria-label="邮箱地址"
placeholder="输入邮箱前缀"
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">建议由输入动态生成,也可以直接填写完整地址。</Text>
</Form>
);
}
异步搜索时,在应用中处理请求防抖和响应顺序,避免旧查询覆盖新结果。输入过程中允许保留自由文本。
#富文本分组与加载状态
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')}>
{'已加载'}
</Button>
<Button size="sm" variant="outline" onClick={() => setState('loading')}>
{'加载中'}
</Button>
<Button size="sm" variant="outline" onClick={() => setState('error')}>
{'加载失败'}
</Button>
</Space>
<AutoComplete
aria-label={'团队邮箱'}
options={state === 'ready' ? options : []}
loading={state === 'loading'}
errorContent={
state === 'error' ? (
<Button size="sm" variant="ghost" onClick={() => setState('ready')}>
{'重新加载'}
</Button>
) : undefined
}
allowClear
notFoundContent={'没有匹配的成员'}
/>
</Space>
);
}
#AutoComplete API
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
options | readonly (AutoCompleteOption|AutoCompleteOptionGroup)[] | 必填 | 必需。建议列表 |
value | string | '' | 受控文本 / 非受控初始文本 |
defaultValue | string | '' | 受控文本 / 非受控初始文本 |
size | 'sm' | 'md' | 'lg' | 'md' | 输入框尺寸 |
status | 'error' | 'warning' | — | 校验状态 |
filterOption | false | ((query: string, option: AutoCompleteOption) => boolean) | 包含匹配 | false 关闭本地过滤;函数可定制过滤 |
onChange | (value: string) => void | — | 输入或选择后的文本 |
onSelect | (value: string, option: AutoCompleteOption) => void | — | 选择建议时触发 |
onSearch | (query: string) => void | — | 用户输入时触发,选择建议时不触发 |
open | boolean | — | 控制面板是否展开。 |
defaultOpen | boolean | — | 面板初始展开状态。 |
onOpenChange | (open: boolean) => void | — | 面板展开或收起时调用。 |
loading | boolean | — | 展示加载状态。 |
notFoundContent | ReactNode | — | 没有匹配选项时的内容。 |
errorContent | ReactNode | — | 展示加载错误和重试内容。 |
optionRender | (option: AutoCompleteOption) => ReactNode | — | 自定义选项内容。 |
allowClear | boolean | — | 展示清除操作。 |
virtual | boolean | — | 启用虚拟滚动;大量选项默认启用。 |
listHeight | number | 248 | 可视列表高度。 |
optionHeight | number | 32 | 跟随区域控件高度和密度的预估行高;实际行会被测量。 |
popupPlacement | PopupOptions['popupPlacement'] | — | 浮层相对触发控件的位置。 |
popupClassName | string | — | 浮层的自定义类名。 |
popupStyle | PopupOptions['popupStyle'] | — | 浮层的自定义样式。 |
popupRender | PopupOptions['popupRender'] | — | 包装或补充面板内容,保留传入的内容以维持交互。 |
getPopupContainer | PopupOptions['getPopupContainer'] | — | 返回浮层的挂载容器,也可返回 ShadowRoot。 |
disabled | boolean | false | 禁用交互。 |
readOnly | boolean | false | 锁定业务值,禁止输入、选择、清除和删除。 |
ref | Ref<HTMLInputElement> | — | 输入框引用 |
label 默认为 value;选中后输入框中的文本始终是 value。placeholder、name、required、form、maxLength、aria-* 等原生文本框属性直接透传,className / style 作用于外层容器。
#类型
AutoCompleteProps 用于定义组件属性。单独组装建议列表时,可以使用 AutoCompleteOption:
import type { AutoCompleteProps, AutoCompleteOption, ControlSize, ControlStatus } from '@ifhover/leaf-ui';
const options: AutoCompleteOption[] = [
{ value: 'leaf@example.com' },
{ value: 'hello@example.com', label: '联系团队' },
];#AutoCompleteOption
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string | 必填 | 唯一建议值,选择后填入输入框 |
label | string | — | 建议的显示文字,也用于默认的本地过滤 |
disabled | boolean | false | 禁用该建议 |
#键盘与表单
输入框聚焦或输入时展开建议。↑ / ↓ 高亮可用选项,Enter 选择,Escape 收起,Tab 继续访问后续控件。中文输入法合成期间的 Enter 不会选择建议。没有匹配项时可以继续填写。
输入框可以直接参与 FormData、原生必填校验和表单 reset。建议面板跟随输入框宽度并继承局部主题;为输入框提供 label 或 aria-label。
#AutoCompleteOption
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | string | — | 必需。受控值。 |
label | ReactNode | — | 展示文字或内容。 |
searchLabel | string | — | 搜索时使用的纯文本。 |
disabled | boolean | — | 禁用交互。 |
#AutoCompleteOptionGroup
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
label | ReactNode | — | 必需。展示文字或内容。 |
options | readonly AutoCompleteOption[] | — | 必需。可供选择的选项。 |