SearchableSelect
带搜索下拉的选择器,支持单选/多选与清除。中文惯用名:可搜索选择器。
稳定本期新增已接入
元信息
| 字段 | 值 |
|---|---|
| 规范 ID | component.searchable-select |
| 名称 | SearchableSelect |
| 二级分类 | 业务组件(business) |
| 用途 | 带搜索下拉的选择器,支持单选/多选与清除 |
| 描述 | 中文惯用名:可搜索选择器。 |
预览
静态结构:Popover + Command(Base UI)组合——触发器为原生 button(role="combobox"、aria-expanded,选中显示 label、未选 placeholder、hover 出清除按钮 span[role=button]);弹层内 CommandInput 搜索框(CommandItem 以 label 过滤,按过滤后无匹配展示 emptyText「无匹配结果」、options 为空展示「无选项」);选中项 Check 图标高亮。单选选中即关闭弹层、清除回传 ""(注释:RHF 下 undefined 会被移除回退 defaultValue);多选为 toggle(选中不关弹层),触发器内渲染 chips(bg-muted + × 删除)。fullOptionText 时选项不截断、弹层宽度自适应内容。弹层 portal 到 body,Content 上 onWheel / onTouchMove stopPropagation(规避外层 Dialog / Drawer 滚动锁);宽度变量为 --anchor-width(Base UI 定位变量)。
DSL 结构
{
"type": "SearchableSelect",
"props": {
"value": "${state.fruit}",
"placeholder": "选择水果(可搜索)",
"options": [
{
"label": "苹果",
"value": "apple"
},
{
"label": "香蕉",
"value": "banana"
},
{
"label": "橙子",
"value": "orange"
}
]
},
"events": {
"onChange": {
"action": "setState",
"params": {
"fruit": "${event}"
}
}
}
}何时用
何时使用
- 选项较多(默认 >8 自动出搜索框)的下拉选择。
- 表单场景需要单选 / 多选、清除与空态文案定制。
- 作为其他 business 组件的内嵌控件(ExpressionEditor / FieldCondition 的字段与选项选择)。
何时不用
- 选项极少(≤8)且无需搜索:使用基础 Select。
- 级联 / 树形选择:使用 Cascader / TreeSelect。
变体
| 变体 | 视觉形态 | 适用场景 |
|---|---|---|
| 单选 | 选中即关、hover 清除按钮 | 单值选择(默认) |
| 多选 | chips + toggle 选中 | 多值集合选择 |
| 搜索开关 | showSearch 显式控制,缺省 >8 条自动展示 | 选项数量决定是否出搜索框 |
| 完整选项文本 | fullOptionText:不截断 + 弹层自适应宽度 | 长选项文案 |
API 属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
value | `string | string[]` | — |
onChange | `(value: string | string[] | undefined) => void` |
options | Array<{ label: string; value: string }> | — | 选项列表(必填) |
placeholder / searchPlaceholder | string | '请选择' / '搜索…' | 触发器 / 搜索框占位文案 |
emptyText | string | '无匹配结果' | 过滤无匹配的空态文案 |
disabled | boolean | false | 禁用 |
id | string | — | 触发器 DOM 的 id |
showSearch | boolean | undefined(>8 自动) | 是否展示搜索框;缺省按 options.length > 8 自动 |
multiple | boolean | false | 多选模式 |
fullOptionText | boolean | false | 选项完整显示:不截断,弹层宽度自适应内容 |
listClassName / className | string | — | 下拉列表(CommandList)/ 触发器样式 |
使用规范
- 选项过滤按 label(CommandItem value=label):label 命名要可检索(含关键词),不依赖 value。
- 单选清除约定回传 "":表单库(RHF)下 undefined 会被移除并回退 defaultValue。
- 弹层内列表滚动依赖组件内置的滚动锁规避,不要在外层再包 scroll-lock 容器。
正例
- ✓ 字段选择:options 传 datasource 字段(featureCode → value、featureName → label),>8 条自动出搜索。
- ✓ 多选标签:multiple + value 数组,触发器 chips 逐个删除。
反例
- ✕ 用 SearchableSelect 承载级联 / 树形数据(应使用 Cascader / TreeSelect)。
- ✕ 期望 value 用数字类型(选项 value 约定 string,需自行转换)。
Design Token 映射
不适用:组件 tokenRefs 为空:样式 Token 数据尚未接入,三层映射(Primitive → Semantic → Component)待样式 Token 接入后回填。