ProComponents, templates & AI tooling
HeroUI
27.7k

Select 选择器

Select 展示可折叠的选项列表,并允许用户从中选择一项。

引入

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

用法

import {Label, ListBox, Select} from "@heroui/react";

export function Default() {
  return (
    <Select className="w-[256px]" placeholder="请选择">

组件结构

引入 Select 组件,并通过点语法访问各部分。

import {Select, Label, Description, Header, ListBox, Separator} from "@heroui/react";

export default () => (
  <Select>
    <Label />
    <Select.Trigger>
      <Select.Value />
      <Select.Indicator />
    </Select.Trigger>
    <Description />
    <Select.Popover>
      <ListBox>
        <ListBox.Item>
          <Label />
          <Description />
          <ListBox.ItemIndicator />
        </ListBox.Item>
        <ListBox.Section>
          <Header />
          <ListBox.Item>
            <Label />
          </ListBox.Item>
        </ListBox.Section>
      </ListBox>
    </Select.Popover>
  </Select>
);

带描述

请选择居住州
import {Description, Label, ListBox, Select} from "@heroui/react";

export function WithDescription() {
  return (
    <Select className="w-[256px]" placeholder="请选择">

多选

拟访问国家
import {Label, ListBox, Select} from "@heroui/react";

export function MultipleSelect() {
  return (
    <Select className="w-[256px]" placeholder="请选择国家" selectionMode="multiple">

分区

国家
import {Header, Label, ListBox, Select, Separator} from "@heroui/react";

export function WithSections() {
  return (
    <Select className="w-[256px]" placeholder="请选择国家">

含禁用项

动物
import {Label, ListBox, Select} from "@heroui/react";

export function WithDisabledOptions() {
  return (
    <Select className="w-[256px]" disabledKeys={["cat", "kangaroo"]} placeholder="请选择动物">

自定义指示器

import {ChevronsExpandVertical} from "@gravity-ui/icons";
import {Label, ListBox, Select} from "@heroui/react";

export function CustomIndicator() {
  return (

必填

国家
"use client";

import {Button, FieldError, Form, Label, ListBox, Select} from "@heroui/react";

export function Required() {

全宽

喜爱的动物
import {Label, ListBox, Select} from "@heroui/react";

export function FullWidth() {
  return (
    <div className="w-[400px] space-y-4">

变体

Select 组件支持两种视觉变体:

  • primary(默认)— 带阴影的标准样式,适用于大多数场景
  • secondary — 低强调、无阴影,适合在 Surface 等表面背景上使用
主要变体
次要变体
import {Label, ListBox, Select} from "@heroui/react";

export function Variants() {
  return (
    <div className="flex flex-col gap-4">

在 Surface 内

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

国家
"use client";

import {Button, FieldError, Form, Label, ListBox, Select, Surface} from "@heroui/react";

export function OnSurface() {

自定义展示值

用户
"use client";

import {
  Avatar,
  AvatarFallback,

受控

州(受控)

已选:加利福尼亚

"use client";

import type {Key} from "@heroui/react";

import {Label, ListBox, Select} from "@heroui/react";

受控多选

州(受控多选)

已选:california, texas

"use client";

import type {Key} from "@heroui/react";

import {Label, ListBox, Select} from "@heroui/react";

受控展开状态

选择框已关闭

"use client";

import {Button, Label, ListBox, Select} from "@heroui/react";
import {useState} from "react";

异步加载

选择宝可梦
"use client";

import {Label, ListBox, Select, Spinner} from "@heroui/react";
import {useAsyncList} from "@react-stately/data";
import {Collection, ListBoxLoadMoreItem} from "react-aria-components";

禁用

拟访问国家
import {Label, ListBox, Select} from "@heroui/react";

export function Disabled() {
  return (
    <div className="flex flex-col gap-4">

自定义渲染函数

"use client";

import {Label, ListBox, Select} from "@heroui/react";

export function CustomRenderFunction() {

样式

传入 Tailwind CSS 类

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

function CustomSelect() {
  return (
    <Select className="w-full">
      <Label>State</Label>
      <Select.Trigger className="rounded-lg border bg-surface p-2">
        <Select.Value />
        <Select.Indicator />
      </Select.Trigger>
      <Select.Popover>
        <ListBox>
          <ListBox.Item id="1" textValue="Item 1" className="hover:bg-surface-secondary">
            Item 1
          </ListBox.Item>
        </ListBox>
      </Select.Popover>
    </Select>
  );
}

自定义组件类

若要自定义 Select 组件类,可以使用 @layer components 指令。


了解更多

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

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

  .select__value {
    @apply text-current;
  }

  .select__indicator {
    @apply text-muted;
  }

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

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

CSS 类

Select 组件使用以下 CSS 类(查看源码样式):

基础类

  • .select - Select 根容器
  • .select__trigger - 打开下拉的触发按钮
  • .select__value - 当前显示的值或占位符
  • .select__indicator - 下拉指示图标
  • .select__popover - 弹出层容器

变体类

  • .select--primary - Primary 变体,带阴影(默认)
  • .select--secondary - Secondary 变体,无阴影,适合在 Surface 上使用

状态类

  • .select[data-invalid="true"] - 无效状态
  • .select__trigger[data-focus-visible="true"] - 触发器聚焦状态
  • .select__trigger[data-disabled="true"] - 触发器禁用状态
  • .select__value[data-placeholder="true"] - 占位符状态
  • .select__indicator[data-open="true"] - 展开时的指示器状态

交互状态

该组件同时支持 CSS 伪类与 data 属性,以提供更灵活的状态控制:

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

API 参考

Select Props

Prop类型默认值描述
placeholderstring'Select an item'Select 为空时显示的占位符文本。
selectionMode"single" | "multiple""single"启用单选或多选。
isOpenboolean-设置菜单是否打开(受控)。
defaultOpenboolean-设置菜单默认是否打开(非受控)。
onOpenChange(isOpen: boolean) => void-展开状态变化时的事件处理函数。
disabledKeysIterable<Key>-禁用条目的 key。
isDisabledboolean-Select 是否禁用。
valueKey | Key[] | null-当前值(受控)。
defaultValueKey | Key[] | null-默认值(非受控)。
onChange(value: Key | Key[] | null) => void-值变化时的事件处理函数。
isRequiredboolean-用户输入是否必填。
isInvalidboolean-Select 的值是否无效。
namestring-输入框名称,用于提交 HTML 表单。
autoCompletestring-描述自动完成行为类型。
fullWidthbooleanfalseSelect 是否占满容器宽度。
variant"primary" | "secondary""primary"视觉变体。primary 为默认带阴影样式。secondary 为低强调、无阴影变体,适合在 Surface 上使用。
classNamestring-额外的 CSS 类。
childrenReactNode | RenderFunction-Select 内容或渲染函数。
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, SelectRenderProps>-使用自定义渲染函数覆盖默认 DOM 元素。

Select.Trigger Props

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

Select.Value Props

Prop类型默认值描述
classNamestring-额外的 CSS 类。
childrenReactNode | RenderFunction-值区域内容或渲染函数。
renderDOMRenderFunction<keyof React.JSX.IntrinsicElements, SelectValueRenderProps>-使用自定义渲染函数覆盖默认 DOM 元素。

Select.Indicator Props

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

Select.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-子内容。

RenderProps

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

Prop类型描述
defaultChildrenReactNode默认渲染的值。
isPlaceholderboolean是否为占位符状态。
stateSelectStateSelect 的状态。
selectedItemsNode[]当前已选中的条目。

无障碍

Select 组件实现 ARIA 列表框模式,并提供:

  • 完整的键盘导航支持
  • 选择变化时的屏幕阅读器播报
  • 合理的焦点管理
  • 禁用状态支持
  • 输入首字母快速定位(typeahead)
  • 与 HTML 表单的集成

更多信息见 React Aria Select 文档

本页目录