跳到主要内容

Select 选择器Select

从一列选项里选一个,平时只占一行。选项在五个以内且都值得一眼看到时用 Radio 或 Segmented;选项很多、需要打字筛选时用 Combobox;要选多个用 MultiSelect。

基本用法

options 是 { value, label } 的数组。点开后选中项加粗并带对勾,点下立即收起。没有可见标签时给 aria-label。

分组与禁用项

options 里可以混入 { label, options } 分组。单个选项用 disabled 禁用,键盘会跳过它。

图标、状态色与辅助文字

选项还可以带 icon、tone(状态色)和 meta(右侧的辅助文字)。label 不是字符串时请提供 textValue,供首字母跳转使用。

尺寸与状态

受控用法

onChange 的第一个参数是新值,第二个是整个选项对象。value 传 null 表示没选。展开状态也可以用 open / onOpenChange 受控。

value:banana · 列表已收起

表单提交

传 name 会渲染一个隐藏 input,随表单一起提交。Select 放进 Field 会自动接上 id、aria-describedby、aria-invalid 和必填,并默认撑满宽度;标签点击和错误播报都是通的。下面的示例用函数子节点手动接线,两种写法等价。

规格

进场
淡入 + 下移 6px · 150ms ease-out,不缩放
高亮块
90ms ease-out · 紧跟指针,不回弹
选中
选中项加粗(600)+ 中性色对勾 · 点下立即收起,不等对勾画完
宽度
列表不窄于触发框;打开前按“全部加粗”量一次宽度并锁住
退场
90ms ease-in

API

Select

属性类型默认值说明
options*Array<SelectOption | { label: string; options: SelectOption[] }>—选项;可以混入分组。
valuestring | null—选中的值(受控);null 表示没选。
defaultValuestring | nullnull初始选中的值(非受控)。
onChange(value: string, option: SelectOption) => void—选了另一项时触发;再点已选项不触发。
placeholderReactNode'请选择'没选时显示的文字。
size'sm' | 'md' | 'lg''md'尺寸。
disabledboolean—禁用。
invalidboolean—标成校验未通过(aria-invalid + 描边)。
namestring—配合表单:渲染隐藏 input 提交 name / value。
formstring—隐藏 input 关联的表单 id。
open / defaultOpen / onOpenChangeboolean / boolean / (open) => void—列表的展开状态。
placementPlacement'bottom-start'列表相对触发框的位置。
id / aria-label / aria-labelledby / aria-describedbystring—落在触发框(按钮)上。其余属性、className、style 和 ref 落在外层 div 上。

SelectOption

属性类型默认值说明
value*string—选项的值。
label*ReactNode—显示的内容。
textValuestring—筛选和首字母跳转用的纯文字;label 不是字符串时请提供。
disabledboolean—禁用这一项。
iconIconName | ReactNode—前置图标。
tone'neutral' | 'success' | 'warning' | 'danger' | 'info'—状态色。
metaReactNode—右侧的辅助文字。

无障碍

  • 触发框是 <button role="combobox" aria-haspopup="listbox">,列表是 role="listbox",选项是 role="option"。焦点始终留在触发框上,高亮项通过 aria-activedescendant 告诉读屏。
  • 收起时:Enter / Space / ↓ / ↑ 展开(高亮当前选中项),直接打字母会展开并跳到匹配项。
  • 展开时:↑ ↓ 移动(跳过禁用项),Home / End 到两端,打字母跳转,Enter / Space 选中并收起,Esc 收起不改值,Tab 收起并移到下一个控件。
  • 必须有可读名称:aria-label,或像上面的表单示例那样把 Field 给的 id 接上(标签的 for 会指向触发框)。
  • 校验失败时设置 aria-invalid;错误文字用 aria-describedby 关联。