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[] }> | — | 选项;可以混入分组。 |
value | string | null | — | 选中的值(受控);null 表示没选。 |
defaultValue | string | null | null | 初始选中的值(非受控)。 |
onChange | (value: string, option: SelectOption) => void | — | 选了另一项时触发;再点已选项不触发。 |
placeholder | ReactNode | '请选择' | 没选时显示的文字。 |
size | 'sm' | 'md' | 'lg' | 'md' | 尺寸。 |
disabled | boolean | — | 禁用。 |
invalid | boolean | — | 标成校验未通过(aria-invalid + 描边)。 |
name | string | — | 配合表单:渲染隐藏 input 提交 name / value。 |
form | string | — | 隐藏 input 关联的表单 id。 |
open / defaultOpen / onOpenChange | boolean / boolean / (open) => void | — | 列表的展开状态。 |
placement | Placement | 'bottom-start' | 列表相对触发框的位置。 |
id / aria-label / aria-labelledby / aria-describedby | string | — | 落在触发框(按钮)上。其余属性、className、style 和 ref 落在外层 div 上。 |
SelectOption
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value* | string | — | 选项的值。 |
label* | ReactNode | — | 显示的内容。 |
textValue | string | — | 筛选和首字母跳转用的纯文字;label 不是字符串时请提供。 |
disabled | boolean | — | 禁用这一项。 |
icon | IconName | ReactNode | — | 前置图标。 |
tone | 'neutral' | 'success' | 'warning' | 'danger' | 'info' | — | 状态色。 |
meta | ReactNode | — | 右侧的辅助文字。 |
无障碍
- 触发框是
<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关联。