Autocomplete 自动补全
@lark-ui/core
import { Autocomplete } from "@lark-ui/core";

/** 基础自动补全(Autocomplete),使用扁平字符串列表。 */
export function AutocompleteDemo() {
  return (
    <Autocomplete items={fruits}>
      <Autocomplete.InputGroup placeholder="搜索水果…" />
      <Autocomplete.Content>
        <Autocomplete.List>
          {(item: string) => (
            <Autocomplete.Item key={item} value={item}>
              {item}
            </Autocomplete.Item>
          )}
        </Autocomplete.List>
      </Autocomplete.Content>
    </Autocomplete>
  );
}

安装

统一导出

import { Autocomplete } from "@lark-ui/core";

按需导出

import { Autocomplete } from "@lark-ui/core/components/autocomplete";

何时使用

当输入值可以是自由文本、建议项仅作为可选提示时,使用 Autocomplete。当所选值必须来自预定义列表时,请改用 Combobox。

受控

传入 value 和 onValueChange 即可使用受控模式。

import { useState } from "react";
import { Autocomplete } from "@lark-ui/core";

/** 受控自动补全,通过 value 和 onValueChange 驱动。 */
export function AutocompleteControlledDemo() {
  const [value, setValue] = useState("");

  return (
    <div className="flex w-80 flex-col gap-3">
      <Autocomplete
        items={fruits}
        value={value}
        onValueChange={(v) => setValue(v)}
      >
        <Autocomplete.InputGroup placeholder="输入水果名称…" />
        <Autocomplete.Content>
          <Autocomplete.List>
            {(item: string) => (
              <Autocomplete.Item key={item} value={item}>
                {item}
              </Autocomplete.Item>
            )}
          </Autocomplete.List>
        </Autocomplete.Content>
      </Autocomplete>
      {value && (
        <p className="text-sm text-lark-subtle">
          值:<span className="font-medium text-lark-default">{value}</span>
        </p>
      )}
    </div>
  );
}

搭配 Field 使用

添加 label、description 和 required 即可启用内置的 Field 包装器。

开始输入以筛选语言

import { useCallback } from "react";
import { Autocomplete } from "@lark-ui/core";
import { languages, Language } from "./data/languages";

/** 带标签、描述文字和 Field 包装器的自动补全。 */
export function AutocompleteWithFieldDemo() {
  const { contains } = Autocomplete.useFilter();

  const filter = useCallback(
    (item: Language, query: string) => contains(item.label, query),
    [contains],
  );

  return (
    <div className="w-80">
      <Autocomplete
        items={languages}
        label="语言"
        description="开始输入以筛选语言"
        filter={filter}
      >
        <Autocomplete.InputGroup placeholder="搜索语言…" />
        <Autocomplete.Content>
          <Autocomplete.List>
            {(item: Language) => (
              <Autocomplete.Item key={item.value} value={item}>
                {item.emoji} {item.label}
              </Autocomplete.Item>
            )}
          </Autocomplete.List>
        </Autocomplete.Content>
      </Autocomplete>
    </div>
  );
}

错误状态

通过 error 属性展示校验错误。

请输入有效的国家
import { useCallback } from "react";
import { Autocomplete } from "@lark-ui/core";

/** 通过 Field 包装器展示错误状态的自动补全。 */
export function AutocompleteErrorDemo() {
  const { contains } = Autocomplete.useFilter();

  const filter = useCallback(
    (item: Country, query: string) => contains(item.label, query),
    [contains],
  );

  return (
    <div className="w-80">
      <Autocomplete
        items={countries}
        label="国家"
        error={{ message: "请输入有效的国家", match: true }}
        filter={filter}
      >
        <Autocomplete.InputGroup placeholder="搜索国家…" />
        <Autocomplete.Content>
          <Autocomplete.List>
            {(item: Country) => (
              <Autocomplete.Item key={item.code} value={item}>
                {item.label}
              </Autocomplete.Item>
            )}
          </Autocomplete.List>
        </Autocomplete.Content>
      </Autocomplete>
    </div>
  );
}

分组

使用 Autocomplete.Group 和 Autocomplete.GroupLabel 将选项按类别分组。

import { Autocomplete } from "@lark-ui/core";

/** 使用 Group 和 GroupLabel 对条目分组的自动补全。 */
export function AutocompleteGroupedDemo() {
  return (
    <Autocomplete items={servers}>
      <Autocomplete.InputGroup placeholder="选择区域…" />
      <Autocomplete.Content>
        <Autocomplete.List>
          {(group: ServerGroup) => (
            <Autocomplete.Group key={group.value} items={group.items}>
              <Autocomplete.GroupLabel>{group.value}</Autocomplete.GroupLabel>
              <Autocomplete.Collection>
                {(item: ServerLocation) => (
                  <Autocomplete.Item key={item.value} value={item}>
                    {item.label}
                  </Autocomplete.Item>
                )}
              </Autocomplete.Collection>
            </Autocomplete.Group>
          )}
        </Autocomplete.List>
      </Autocomplete.Content>
    </Autocomplete>
  );
}

尺寸

Autocomplete.InputGroup 上的 size 属性支持四种尺寸变体,与输入框(Input)组件保持一致:xs、sm、base(默认)和 lg。

import { Autocomplete } from "@lark-ui/core";

/** 演示自动补全的四种尺寸变体:xs、sm、base 和 lg。 */
export function AutocompleteSizesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-4">
      <Autocomplete items={fruits.slice(0, 10)}>
        <Autocomplete.InputGroup size="xs" placeholder="xs" />
        <Autocomplete.Content>
          <Autocomplete.List>
            {(item: string) => (
              <Autocomplete.Item key={item} value={item}>
                {item}
              </Autocomplete.Item>
            )}
          </Autocomplete.List>
        </Autocomplete.Content>
      </Autocomplete>
      <Autocomplete items={fruits.slice(0, 10)}>
        <Autocomplete.InputGroup size="sm" placeholder="sm" />
        <Autocomplete.Content>
          <Autocomplete.List>
            {(item: string) => (
              <Autocomplete.Item key={item} value={item}>
                {item}
              </Autocomplete.Item>
            )}
          </Autocomplete.List>
        </Autocomplete.Content>
      </Autocomplete>
      <Autocomplete items={fruits.slice(0, 10)}>
        <Autocomplete.InputGroup size="base" placeholder="base(默认)" />
        <Autocomplete.Content>
          <Autocomplete.List>
            {(item: string) => (
              <Autocomplete.Item key={item} value={item}>
                {item}
              </Autocomplete.Item>
            )}
          </Autocomplete.List>
        </Autocomplete.Content>
      </Autocomplete>
      <Autocomplete items={fruits.slice(0, 10)}>
        <Autocomplete.InputGroup size="lg" placeholder="lg" />
        <Autocomplete.Content>
          <Autocomplete.List>
            {(item: string) => (
              <Autocomplete.Item key={item} value={item}>
                {item}
              </Autocomplete.Item>
            )}
          </Autocomplete.List>
        </Autocomplete.Content>
      </Autocomplete>
    </div>
  );
}

过滤

默认情况下,过滤不区分大小写和重音符号,底层由 Intl.Collator 提供支持。对于字符串选项,无需自定义 filter。

当需要按对象选项的某个属性进行过滤时,请使用 Autocomplete.useFilter() 以保留内置的不区分重音符号的匹配能力:

function LanguagePicker() {
  const { contains } = Autocomplete.useFilter();

  const filter = useCallback(
    (item: Language, query: string) => contains(item.label, query),
    [contains],
  );

  return (
    <Autocomplete items={languages} filter={filter}>
      {/* ... */}
    </Autocomplete>
  );
}

如需完全关闭过滤(例如结果来自服务端),传入 filter={null}:

<Autocomplete items={results} filter={null}>
  ...
</Autocomplete>

API 参考

Autocomplete

根组件。包裹所有子组件并管理状态。

属性类型默认值说明
items*unknown[]-下拉菜单中要展示的选项数组
valuestring | number | string[]-受控的输入值
openboolean-弹出层是否展开(受控)
childrenReactNode-自动补全的内容(输入框组、弹出层内容)
classNamestring-额外的 CSS 类名
labelReactNode-标签内容(用于启用 Field 包裹层)
requiredboolean-该字段是否必填
labelTooltipReactNode-显示在标签旁的工具提示内容
descriptionReactNode-显示在字段下方的辅助说明文字
errorstring | object-错误信息或校验错误对象

Autocomplete.InputGroup

自包含的输入容器,同时渲染文本输入框、清除按钮和下拉触发器。

属性类型默认值
classNamestring-
sizeLarkAutocompleteSize-
placeholderstring-

Autocomplete.Content

下拉弹层容器。包裹 Portal、Positioner 和 Popup。

属性类型默认值
childrenReactNode-
classNamestring-
alignAutocompleteBase.Positioner.Props["align"]-
alignOffsetAutocompleteBase.Positioner.Props["alignOffset"]-
sideAutocompleteBase.Positioner.Props["side"]-
sideOffsetAutocompleteBase.Positioner.Props["sideOffset"]-

Autocomplete.Item

列表中的单个建议项。

属性类型默认值

该组件没有专有属性,支持标准 HTML 属性。

其他子组件

  • Autocomplete.List — 支持 render 属性的可滚动列表容器
  • Autocomplete.Group — 将选项归入某个标题之下
  • Autocomplete.GroupLabel — 分组的标题标签
  • Autocomplete.Collection — 分组内的选项容器
  • Autocomplete.Separator — 选项之间的水平分隔线