JGuang / HeroUI

Autocomplete 自动完成

自动完成将选择与过滤结合,让用户可以搜索并从选项列表中选择。

引入

import { Autocomplete, useFilter } from "@heroui/react";

用法

HeroUI 示例

组件结构

导入 Autocomplete 组件后,可通过点语法访问各个子部分。

import {Autocomplete, Label, Description, SearchField, ListBox} from "@heroui/react";

export default () => (
  <Autocomplete>
    <Label />
    <Autocomplete.Trigger>
      <Autocomplete.Value />
      <Autocomplete.ClearButton />
      <Autocomplete.Indicator />
    </Autocomplete.Trigger>
    <Description />
    <Autocomplete.Popover>
      <Autocomplete.Filter>
        <SearchField>
          <SearchField.Group>
            <SearchField.SearchIcon />
            <SearchField.Input />
          </SearchField.Group>
        </SearchField>
        <ListBox>
          <ListBox.Item>
            <Label />
            <ListBox.ItemIndicator />
          </ListBox.Item>
        </ListBox>
      </Autocomplete.Filter>
    </Autocomplete.Popover>
  </Autocomplete>
);

带描述

HeroUI 示例

多选

HeroUI 示例

分组

HeroUI 示例

含禁用选项

HeroUI 示例

允许空集合

allowsEmptyCollection prop 让自动完成在集合中没有任何条目时仍可使用。适用于列表初始可能为空,或过滤后没有结果等场景。

HeroUI 示例

自定义指示器

HeroUI 示例

必填

HeroUI 示例

全宽

HeroUI 示例

变体

Autocomplete 支持两种视觉变体:

  • primary(默认)— 带阴影的标准样式,适用于大多数场景
  • secondary — 低强调、无阴影,适合用于 Surface 组件
HeroUI 示例

在 Surface 中

在 Surface 内使用时,请使用 variant="secondary",以应用适合表面背景的低强调变体。

HeroUI 示例

自定义值

你可以使用渲染 prop 自定义展示的值:

HeroUI 示例

受控

HeroUI 示例

受控多选

HeroUI 示例

受控展开状态

HeroUI 示例

异步过滤

HeroUI 示例

虚拟化

Autocomplete 通过 Virtualizer 支持虚拟化,仅渲染视口内可见的行,从而高效展示大数据集。

HeroUI 示例

禁用

HeroUI 示例

进阶示例

用户选择

HeroUI 示例

用户多选

HeroUI 示例

地点搜索

HeroUI 示例

Tag Group 选择

HeroUI 示例

邮件收件人

HeroUI 示例

样式

传入 Tailwind CSS 类

import {Autocomplete, SearchField, ListBox} from "@heroui/react";

function CustomAutocomplete() {
  return (
    <Autocomplete className="w-full">
      <Label>State</Label>
      <Autocomplete.Trigger className="rounded-lg border bg-surface p-2">
        <Autocomplete.Value />
        <Autocomplete.ClearButton />
        <Autocomplete.Indicator />
      </Autocomplete.Trigger>
      <Autocomplete.Popover>
        <Autocomplete.Filter>
          <SearchField>
            <SearchField.Group>
              <SearchField.SearchIcon />
              <SearchField.Input placeholder="Search..." />
            </SearchField.Group>
          </SearchField>
          <ListBox>
            <ListBox.Item id="1" textValue="Item 1" className="hover:bg-surface-secondary">
              Item 1
            </ListBox.Item>
          </ListBox>
        </Autocomplete.Filter>
      </Autocomplete.Popover>
    </Autocomplete>
  );
}

自定义组件类

要自定义 Autocomplete 的组件类,可使用 @layer components 指令。

了解更多.

@layer components {
  .autocomplete {
    @apply flex flex-col gap-1;
  }

  .autocomplete__trigger {
    @apply rounded-lg border border-border bg-surface p-2;
  }

  .autocomplete__value {
    @apply text-current;
  }

  .autocomplete__clear-button {
    @apply text-muted hover:text-foreground;
  }

  .autocomplete__indicator {
    @apply text-muted;
  }

  .autocomplete__popover {
    @apply rounded-lg border border-border bg-surface p-2;
  }

  .autocomplete__popover-dialog {
    @apply outline-none;
  }
}

HeroUI 遵循 BEM 方法论,确保组件变体与状态可复用且易于自定义。

CSS 类

Autocomplete 使用以下 CSS 类(查看源码样式):

基础类

  • .autocomplete - 自动完成根容器
  • .autocomplete__trigger - 触发自动完成的按钮
  • .autocomplete__value - 显示的值或占位符
  • .autocomplete__clear-button - 清除已选值的按钮
  • .autocomplete__indicator - 下拉指示图标
  • .autocomplete__popover - 弹出层容器
  • .autocomplete__popover-dialog - 弹出层内部的 dialog 包裹层,用于焦点管理(与 Popover 行为一致)
  • .autocomplete__filter - 过滤区域包裹层

变体类

  • .autocomplete--primary - 主变体,带阴影(默认)
  • .autocomplete--secondary - 次变体,无阴影,适合用于 Surface

状态类

  • .autocomplete[data-invalid="true"] - 无效状态
  • .autocomplete__trigger[data-focus-visible="true"] - 触发器聚焦状态
  • .autocomplete__trigger[data-disabled="true"] - 触发器禁用状态
  • .autocomplete__value[data-placeholder="true"] - 占位符状态
  • .autocomplete__clear-button[data-empty="true"] - 无选中时隐藏清除按钮
  • .autocomplete__indicator[data-open="true"] - 展开时的指示器状态

交互状态

组件同时支持 CSS 伪类与 data 属性,便于灵活编写样式:

  • 悬停:触发器上 :hover 或 [data-hovered="true"]
  • 聚焦:触发器上 :focus-visible 或 [data-focus-visible="true"]
  • 禁用:自动完成上 :disabled 或 [data-disabled="true"]
  • 展开:指示器上 [data-open="true"]

API 参考

Autocomplete Props

Prop类型默认值描述
placeholderstring'Select an item'自动完成为空时显示的占位文本
selectionMode"single" | "multiple""single"启用单选或多选
allowsEmptyCollectionbooleanfalse是否允许空集合。为 true 时,即使没有任何条目也可使用自动完成。
isOpenboolean-设置弹出层的打开状态(受控)
defaultOpenboolean-设置弹出层的默认打开状态(非受控)
onOpenChange(isOpen: boolean) => void-打开状态变化时触发的事件处理函数
disabledKeysIterable-禁用条目的 key
isDisabledboolean-是否禁用自动完成
valueKey | Key[] | null-当前值(受控)
defaultValueKey | Key[] | null-默认值(非受控)
onChange(value: Key | Key[] | null) => void-值变化时触发的事件处理函数
isRequiredboolean-是否要求用户输入
isInvalidboolean-自动完成的值是否无效
namestring-输入的 name,用于提交 HTML 表单
fullWidthbooleanfalse自动完成是否占满容器宽度
variant"primary" | "secondary""primary"视觉变体。primary 为默认带阴影样式;secondary 为低强调、无阴影,适合用于 Surface。
classNamestring-额外的 CSS 类
childrenReactNode | RenderFunction-自动完成内容或渲染函数

Autocomplete.Trigger Props

Prop类型默认值描述
classNamestring-额外的 CSS 类
childrenReactNode | RenderFunction-触发器内容或渲染函数

Autocomplete.Value Props

Prop类型默认值描述
classNamestring-额外的 CSS 类
childrenReactNode | RenderFunction-值区域内容或渲染函数

Autocomplete.Indicator Props

Prop类型默认值描述
classNamestring-额外的 CSS 类
childrenReactNode-自定义指示器内容

Autocomplete.ClearButton Props

Prop类型默认值描述
classNamestring-额外的 CSS 类
onClick(e: MouseEvent) => void-点击按钮时触发的事件处理函数
refRefObject-清除按钮元素的 ref

Autocomplete.Popover Props

Prop类型默认值描述
placement"bottom" | "bottom left" | "bottom right" | "bottom start" | "bottom end" | "top" | "top left" | "top right" | "top start" | "top end" | "left" | "left top" | "left bottom" | "start" | "start top" | "start bottom" | "right" | "right top" | "right bottom" | "end" | "end top" | "end bottom""bottom"弹出层相对触发器的位置
classNamestring-额外的 CSS 类
childrenReactNode-子内容。内部会包裹在 dialog 元素中以管理焦点,样式类为 .autocomplete__popover-dialog。

Autocomplete.Filter Props

Prop类型默认值描述
filter(text: string, input: string) => boolean-自定义过滤函数
inputValuestring-受控的输入值
onInputChange(value: string) => void-输入值变化时触发的事件处理函数
childrenReactNode-过滤内容(SearchField 与 ListBox)

useFilter Hook

React Aria 的 useFilter hook 为自动完成提供过滤函数。

import {useFilter} from "@heroui/react";

const {contains} = useFilter({sensitivity: "base"});

<Autocomplete.Filter filter={contains}>
  <SearchField>...</SearchField>
  <ListBox>...</ListBox>
</Autocomplete.Filter>

选项:

选项类型默认值描述
sensitivity"base" | "accent" | "case" | "variant""base"匹配的本地化敏感度

返回值:

函数类型描述
contains(string: string, substring: string) => boolean判断字符串是否包含给定子串
startsWith(string: string, substring: string) => boolean判断字符串是否以给定子串开头
endsWith(string: string, substring: string) => boolean判断字符串是否以给定子串结尾

RenderProps

对 Autocomplete.Value 使用渲染函数时,会提供以下值:

Prop类型描述
defaultChildrenReactNode默认渲染的值
isPlaceholderboolean值是否为占位符
stateSelectState自动完成的状态
selectedItemsNode[]当前选中的条目

无障碍

Autocomplete 实现带过滤的 ARIA 选择模式,并提供:

  • 完整键盘导航支持
  • 选择变化时的屏幕阅读器播报
  • 与 Popover 一致的焦点管理:Autocomplete.Popover 会在内部用 dialog 包裹内容,避免触摸交互时在弹出层 overlay 上出现多余的焦点环
  • 禁用状态支持
  • 可搜索与过滤
  • HTML 表单集成

若希望在弹出层打开时不立即唤起移动端键盘,可在 SearchField 上设置 autoFocus={false}。用户聚焦搜索输入框后仍可正常过滤。

更多信息见 React Aria Select 文档。

本地来源: vendor/zh/react/components/(pickers)/autocomplete.mdx

文档根据 HeroUI v3 固定提交生成,已调整内部链接与交互预览以适配 JGuang。

On this page