> Leaf UI 0.6.0 · Package: @ifhover/leaf-ui · Source: b30c3d3a8fa9c5e15d0d0522cebfbd33f60c6b06
> Browser documentation: https://ifhover.github.io/leaf-ui/v/0.6.0/components/auto-complete.html

> For AI agents: the complete documentation index is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms.txt, the full documentation bundle is available at https://ifhover.github.io/leaf-ui/v/0.6.0/llms-full.txt.

# AutoComplete 自动完成

在输入文本时提供建议，帮助快速完成填写。

## 基础输入

通过 `options` 设置建议，默认按显示文本进行不区分大小写的包含匹配。`onChange` 响应输入和选择，`onSelect` 仅响应选择建议。


项目名称

输入：空 · 最近选中：无

禁用建议

basic.tsx

复制代码

```tsx lineNumbers file="../../src/examples/auto-complete/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

复制代码

```tsx lineNumbers file="../../src/examples/auto-complete/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

复制代码

```tsx lineNumbers file="../../src/examples/auto-complete/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`](#autocompleteoption)`\|`[`AutoCompleteOptionGroup`](#autocompleteoptiongroup)`)[]` | 必填      | 必需。建议列表                    |
| `value`             | `string`                                                                                                              | `''`    | 受控文本 / 非受控初始文本             |
| `defaultValue`      | `string`                                                                                                              | `''`    | 受控文本 / 非受控初始文本             |
| `size`              | `'sm' \| 'md' \| 'lg'`                                                                                                | `'md'`  | 输入框尺寸                      |
| `status`            | `'error' \| 'warning'`                                                                                                | —       | 校验状态                       |
| `filterOption`      | `false \| ((query: string, option: `[`AutoCompleteOption`](#autocompleteoption)`) => boolean)`                        | 包含匹配    | `false` 关闭本地过滤；函数可定制过滤     |
| `onChange`          | `(value: string) => void`                                                                                             | —       | 输入或选择后的文本                  |
| `onSelect`          | `(value: string, option: `[`AutoCompleteOption`](#autocompleteoption)`) => void`                                      | —       | 选择建议时触发                    |
| `onSearch`          | `(query: string) => void`                                                                                             | —       | 用户输入时触发，选择建议时不触发           |
| `open`              | `boolean`                                                                                                             | —       | 控制面板是否展开。                  |
| `defaultOpen`       | `boolean`                                                                                                             | —       | 面板初始展开状态。                  |
| `onOpenChange`      | `(open: boolean) => void`                                                                                             | —       | 面板展开或收起时调用。                |
| `loading`           | `boolean`                                                                                                             | —       | 展示加载状态。                    |
| `notFoundContent`   | `ReactNode`                                                                                                           | —       | 没有匹配选项时的内容。                |
| `errorContent`      | `ReactNode`                                                                                                           | —       | 展示加载错误和重试内容。               |
| `optionRender`      | `(option: `[`AutoCompleteOption`](#autocompleteoption)`) => ReactNode`                                                | —       | 自定义选项内容。                   |
| `allowClear`        | `boolean`                                                                                                             | —       | 展示清除操作。                    |
| `virtual`           | `boolean`                                                                                                             | —       | 启用虚拟滚动；大量选项默认启用。           |
| `listHeight`        | `number`                                                                                                              | `248`   | 可视列表高度。                    |
| `optionHeight`      | `number`                                                                                                              | `32`    | 跟随区域控件高度和密度的预估行高；实际行会被测量。  |
| `popupPlacement`    | [`PopupOptions`](https://ifhover.github.io/leaf-ui/v/0.6.0/api/popup-options.md#popupoptions)`['popupPlacement']`     | —       | 浮层相对触发控件的位置。               |
| `popupClassName`    | `string`                                                                                                              | —       | 浮层的自定义类名。                  |
| `popupStyle`        | [`PopupOptions`](https://ifhover.github.io/leaf-ui/v/0.6.0/api/popup-options.md#popupoptions)`['popupStyle']`         | —       | 浮层的自定义样式。                  |
| `popupRender`       | [`PopupOptions`](https://ifhover.github.io/leaf-ui/v/0.6.0/api/popup-options.md#popupoptions)`['popupRender']`        | —       | 包装或补充面板内容，保留传入的内容以维持交互。    |
| `getPopupContainer` | [`PopupOptions`](https://ifhover.github.io/leaf-ui/v/0.6.0/api/popup-options.md#popupoptions)`['getPopupContainer']`  | —       | 返回浮层的挂载容器，也可返回 ShadowRoot。 |
| `disabled`          | `boolean`                                                                                                             | `false` | 禁用交互。                      |
| `readOnly`          | `boolean`                                                                                                             | `false` | 锁定业务值，禁止输入、选择、清除和删除。       |
| `ref`               | `Ref<HTMLInputElement>`                                                                                               | —       | 输入框引用                      |

label 默认为 value；选中后输入框中的文本始终是 value。`placeholder`、`name`、`required`、`form`、`maxLength`、`aria-*` 等原生文本框属性直接透传，`className` / `style` 作用于外层容器。

## 类型

[`AutoCompleteProps`](#autocomplete-api) 用于定义组件属性。单独组装建议列表时，可以使用 [`AutoCompleteOption`](#autocompleteoption)：

```ts
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`](#autocompleteoption)`[]` | —   | 必需。可供选择的选项。 |
