跳转到内容

选择器 select

数据录入组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。

示例

基础用法

collection 是条目的事实源:显示文本与禁用都写在数据里,结构由组件铺开

水果

当前值:(未选)

多选

multiple 下点中即在集合里增删该项、浮层不收起,触发器上的文本把选中项连起来

水果(多选)

已选:apple

受控

传了 value 就由宿主说了算:组件只发 value-change,宿主写回它才变,这里把樱桃挡在门外

水果

宿主持有的值:banana

禁用

根部件的 disabled 把触发器转成原生 disabled,浮层展不开、也不占 Tab 位

水果

形态

variant 只改触发器的颜色槽位,浮层与键盘行为三档一致

outline
subtle
ghost

语气

tone 决定用哪族颜色,与 variant 正交;这里固定 outline 只看语气的差别

brand
neutral
success
warning
danger
info

尺寸

触发器与浮层条目一起换档,不传 size 即默认档

默认

异步加载选项

首次展开才去取数据:open-change 报出展开意图,数据到达前用一条禁用条目占位

曲目

当前值:(未选)

宽度

触发器与浮层各有自己的宽度槽位,写在根部件上即可;装不下的文本在行内以省略号收口

缺省宽度
加宽

选项里的自定义内容

条目与触发器显示都是插槽:内容想写什么写什么,选中与键盘行为不变

负责人

插槽里的操作入口

根部件把 open、value 与 setOpen、setValue 交给插槽,浮层之外的按钮据此展开或清空

水果

当前值:(未选)

大量选项

浮层高度封顶后自行滚动;敲首字母连打检索直接跳到该字母开头的条目,方向键照常可用

仓位

当前值:(未选)

分组

条目分段展示:段落壳与段标题由作者写,条目照旧归到同一份集合,方向键与连打检索跨段贯通

食材

当前值:(未选)

多选标签

触发器的显示是插槽:只摆前两个标签、其余折成 +N;可删除的标签行放在触发器之外,删除按钮调根插槽的 setValue

技术栈
Vue Svelte Solid

校验状态

校验结论由宿主给出:告警描边写进触发器的使用者令牌,错误文案用 aria-describedby 挂到触发器上

所属部门

这一项必填

滚动加载

浮层的滚动容器就是 content:@scroll 直接落在它身上,滚到底就把下一页并进选项

工单

已加载 20 / 80 条

命令式聚焦

在触发器上取模板 ref,实例的 $el 就是那个按钮,focus 与 blur 直接调它

优先级

产物

自定义元素<xh-select>
Vue 组件XhSelectContent XhSelectIndicator XhSelectItem XhSelectItemIndicator XhSelectItemText XhSelectLabel XhSelectPositioner XhSelectRoot XhSelectTrigger XhSelectValueText
组合式函数useSelect
状态机selectMachine
皮肤@xihan-ui/styles/select.css

解剖

部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。

data-scope="select"root · label · trigger · value-text · indicator · positioner · content · item · item-text · item-indicator · hidden-select

Props

属性类型必填说明
collectionSelectNode[]条目数据,显示文本与禁用的事实源。给了它,条目部件只需报 value, 显示文本也不再从活 DOM 现查。缺省即回到「文本写在条目里、现查 DOM」的老路。
valuestring | string[] | null选中值。裸串是单选的简写,null 是「受控且无选中」,缺省(undefined)才是非受控;内部一律按数组处理。 受控时 cell 直读 prop,写只发 onValueChange 不落内部值。
defaultValuestring | string[] | null非受控初始选中值。与 value 同样接受裸串与 null。
multipleboolean允许选中多项。单选时选完即收起,多选时保持展开继续选。
openboolean展开态。给定即受控:内部不再自改,只发 onOpenChange。
defaultOpenboolean
disabledboolean整个控件禁用:trigger 用原生 disabled,隐藏 select 不参与提交。
requiredboolean原生表单校验:无选中值时提交被拦下。
namestring表单字段名。给定后隐藏 select 才带 name,选中值随表单一并提交。
placeholderstring无选中时 value-text 显示的占位文字。
placementPlacement
offsetnumber
loopboolean方向键走到尽头是否回绕,默认 true。
dirDirection文字方向,默认 ltr。
variantControlVariant形态:outline / subtle / ghost,决定触发器的描边与底色怎么用。
toneTone语气:brand / neutral / success / warning / danger / info,决定聚焦与选中强调用哪族颜色。
sizeSize尺寸:sm / md / lg,决定触发器高度、内边距与字号档位。
onValueChange(details: SelectValueChangeDetails) => voidvalue 变化意图回调;受控时是唯一出口,非受控随内部写入一并通知。
onOpenChange(details: SelectOpenChangeDetails) => voidopen 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。

状态机

状态open · closed

事件OPEN · TOGGLE · CLOSE · CONTROLLED.OPEN · CONTROLLED.CLOSE · ITEM.HIGHLIGHT · ITEM.LOST · ITEM.SELECT · VALUE.SET · FORM.RESET

判据isOpenControlled · isMultiple

connect API

useSelect 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。

成员类型说明
openboolean
collectionreadonly SelectNodeMeta[]collection 推出的条目元信息,按数据顺序排列;没给 collection 即空数组。
valuestring[]选中集合,按选中先后排列而非文档顺序。单选恒为长度 ≤ 1。
valueTextstring[]选中项的文本,与 value 逐项等长对应;某项在 DOM 里查不到条目时该项退回值本身。
displayTextstringvalue-text 实际显示的文字:有选中取其文本(多选按半角逗号加空格连起来),否则取 placeholder。
multipleboolean是否允许多选。
highlightedValuestring | null高亮锚点;收起时为 null。
setOpen(next: boolean) => void
setValue(next: string | string[]) => void
getRootProps() => T['element']
getLabelProps() => T['element']
getTriggerProps() => T['button']
getValueTextProps() => T['element']
getIndicatorProps() => T['element']
getPositionerProps() => T['element']
getContentProps() => T['element']
getItemProps(props: SelectItemProps) => T['element']
getItemTextProps(props: SelectItemProps) => T['element']
getItemIndicatorProps(props: SelectItemProps) => T['element']
getHiddenSelectProps() => T['select']表单出口:一份视觉隐藏的原生 select,由根部件自行渲染(作者不必手写)。 选项由适配器按当前值补齐,原生提交与 required 校验据此拿到值。

键盘

规格出处:W3C APG

按键生效条件行为
Enter / Spaceclosed, focus in trigger展开列表并把高亮落到当前选中项(无选中则落首个可用条目)
ArrowDownclosed, focus in trigger展开列表并把高亮落到选中项的下一个可用条目
ArrowUpclosed, focus in trigger展开列表并把高亮落到选中项的上一个可用条目
单个可打印字符closed, focus in trigger连打检索命中的条目直接成为选中值(多选是加进集合,已在集合里则不动),列表不展开
ArrowDownopen, focus in content高亮移到下一个条目(禁用项跳过、尽头按 loop 回绕)
ArrowUpopen, focus in content高亮移到上一个条目(禁用项跳过、尽头按 loop 回绕)
Homeopen, focus in content高亮移到首个可用条目
Endopen, focus in content高亮移到末个可用条目
单个可打印字符open, focus in content连打检索移动高亮,不改选中值
Enter / Spaceopen, 单选, 高亮条目未禁用选中高亮条目并关闭列表,焦点归还 trigger
Enter / Spaceopen, 多选, 高亮条目未禁用切换高亮条目的选中态,列表不收起、焦点留在条目上
Escapeopen关闭列表并把焦点归还 trigger,选中值不变
Tab / Shift+Tabopen关闭列表,焦点不归还 trigger,按 Tab 序列自然离开

Released under The MIT License