Select
从候选项中选择一个或多个值。中文惯用名:选择器。
稳定本期新增已接入
元信息
| 字段 | 值 |
|---|---|
| 规范 ID | component.select |
| 名称 | Select |
| 二级分类 | 数据录入(data-entry) |
| 用途 | 从候选项中选择一个或多个值 |
| 描述 | 中文惯用名:选择器。 |
预览
静态结构:Select 为触发器(vendored shadcn Select,data-slot="select-trigger",内 data-slot="select-value" 显示选中项 label 或 placeholder)+ 弹层(data-slot="select-content" 内 data-slot="select-item" 列表,选项级 disabled 灰化不可选)。选中值经 Root 的 items 映射回 label,表单初始值回填、弹层尚未渲染过时触发器同样显示 label。allowClear 且已有选中值且未禁用时,触发器右侧追加 × 清除按钮(点击清空并触发 onChange(undefined))。Form 内声明非空 name 时外层为 data-slot="form-item" 容器(label 经 htmlFor 关联控件 useId + data-slot="form-error"),不走 FieldShell。
DSL 结构
{
"type": "Select",
"props": {
"name": "status",
"label": "状态",
"placeholder": "选择状态",
"options": [
{
"label": "全部",
"value": "all"
},
{
"label": "进行中",
"value": "doing"
},
{
"label": "已完成",
"value": "done"
},
{
"label": "已归档(禁用)",
"value": "archived",
"disabled": true
}
]
}
}何时用
何时使用
- 从少而固定的候选集合中选一个值:状态、类型、优先级、负责人。
- 候选可枚举、无需输入过滤,且下拉列表可完整浏览(建议 10 项以内)。
- 表单内的单选字段:声明 name 即自动注册,参与校验与提交。
何时不用
- 候选多(数十项以上)或需要输入关键字过滤:使用 Combobox;候选少而固定才用 Select。
- 层级候选数据:使用 Cascader / TreeSelect。
- 选项需平铺对比且数量 2-5 个:使用 RadioGroup(表单内)或 Segmented(视图切换),少一次点击。
- 需要多选:当前实现为单选,多选用 Checkbox 组或 Transfer。
变体
| 变体 | 视觉形态 | 适用场景 |
|---|---|---|
| 默认(单选) | 描边触发器 + 下拉选项列表 | 常规枚举单选 |
| 选项级 disabled | 单个选项灰化不可选 | 无权限 / 不可用的候选项(如已归档状态) |
| allowClear 可清空 | 已选值时触发器右侧出现 × 按钮 | 非必填筛选项,需要回到「未选」态 |
| placeholder 空态 | 未选时触发器显示弱化提示文案 | 非必填字段、需要引导选择的必填字段 |
| Form 表单项 | form-item 容器:label + 触发器 + 校验错误行 | 表单内单选字段(声明 name 自动注册) |
| disabled 禁用 | 触发器半透明不可点开 | 联动未就绪或只读场景 |
API 属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | string | — | 字段名;在 Form 内声明即自动成为表单项 |
label | string | — | 表单项标签(Form 内由 label 标签呈现) |
rules | FieldRule[] | — | 校验规则 |
options | SelectOption[] | [] | 选项列表(可含表达式解析后的数组);项结构 { label, value: string |
value | `string | number | boolean` |
placeholder | string | — | 空态提示文案 |
disabled | boolean | false | 禁用触发器;选项级禁用用 options 项的 disabled |
allowClear | boolean | false | 已选值且未禁用时显示清除按钮(清空为 undefined) |
onChange | (value: unknown) => void | — | 选中变化事件,传出选中项的原始 value;清空传出 undefined(Renderer 绑定 events.onChange;DSL 语义值) |
controlClassName | string | — | 控件本体 class(无论是否在 Form 内都挂控件包裹节点;独立渲染时与 className 同点合并) |
className / style | string / CSSProperties | — | 通用:根节点 class 合并 / 内联样式(Form 内为 form-item 容器,独立渲染时为控件包裹节点) |
使用规范
- 候选少且固定用 Select;候选多、需要输入过滤改用 Combobox——不要给 Select 塞几十个选项让用户翻找。
- options 的 value 类型保持一致(string / number / boolean 不混用),否则回填与选中态匹配会错位。
- 选项文案完整可读(如「进行中」而非「3」);状态码到文案的映射在 options 层完成。
- 禁用选项需说明原因(如「已归档(不可选)」),不要让用户反复尝试点不开的项。
- Form 内声明非空 name 才注册字段;初始值回填依赖 items 映射,options 必须在首次渲染时可用。
正例
- ✓ 筛选项「状态」:options 枚举全部业务状态,非必填配 allowClear,change 后刷新列表。
- ✓ Form 内「优先级」:name + label + rules 必填,校验失败在触发器下方提示。
- ✓ 编辑回显:value 传已存状态码,options 就绪时触发器直接显示对应 label。
反例
- ✕ 用 Select 承载数十上百个候选让用户滚动查找(应使用 Combobox 提供搜索)。
- ✕ 省市区等层级数据用扁平 Select 平铺(应使用 Cascader / TreeSelect 保留层级)。
- ✕ options 中 value 混用字符串与数字,回填时选中态丢失或匹配到错误项。
Design Token 映射
不适用:组件 tokenRefs 为空:样式 Token 数据尚未接入,三层映射(Primitive → Semantic → Component)待样式 Token 接入后回填。