跳转到内容

列表框 listbox

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

示例

基础用法

交一份 collection 就够:方向键只搬焦点,Enter 或空格才落值;整组只占一个 Tab 位

城市
Beijing 北京
Berlin 柏林
Busan 釜山(禁用)
London 伦敦

已选:beijing

多选

multiple 下空格改成切换该条,Shift + 方向键顺手扩选,Ctrl / Cmd + A 全选或全不选

常去城市
Beijing 北京
Berlin 柏林
Chengdu 成都
London 伦敦

已选:beijing、london

分组

item-group 把条目分段,group-label 是这一段的可及名字,不参与选中也不接方向键

城市
亚洲
Bangkok 曼谷
Beijing 北京
Chengdu 成都
欧洲
Berlin 柏林
London 伦敦

已选:(无)

选择模式

selection-mode 直接指定三种模式,extended 是「单击换一条、Ctrl 与 Shift 才扩选」

文件(extended)
report.pdf
cover.png
notes.md
data.csv

已选:a

弹出式选择

把列表装进浮层:触发器显示当前选中项,落值即收起,浮层底部还能放操作按钮

已选:song1

定高滚动

用 --xh-listbox-content-max-h 压住列表高度,条目多了就在容器里滚;方向键走到哪条,视图跟到哪条

曲目
第 1 首
第 2 首
第 3 首
第 4 首
第 5 首
第 6 首
第 7 首
第 8 首
第 9 首
第 10 首
第 11 首
第 12 首
第 13 首
第 14 首
第 15 首
第 16 首
第 17 首
第 18 首
第 19 首
第 20 首
第 21 首
第 22 首
第 23 首
第 24 首
第 25 首
第 26 首
第 27 首
第 28 首
第 29 首
第 30 首
第 31 首
第 32 首
第 33 首
第 34 首
第 35 首
第 36 首
第 37 首
第 38 首
第 39 首
第 40 首

已选:track-1

空态

条目筛空时收起列表、亮出空态节点:它挂在 content 之外,方向键、连打检索与全选都看不见它

成员
刘一
陈二
张三
李四

已选:(无)

产物

自定义元素<xh-listbox>
Vue 组件XhListboxContent XhListboxItem XhListboxItemGroup XhListboxItemGroupLabel XhListboxItemIndicator XhListboxItemText XhListboxLabel XhListboxRoot
组合式函数useListbox
状态机listboxMachine
皮肤@xihan-ui/styles/listbox.css

解剖

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

data-scope="listbox"root · label · content · item · item-text · item-indicator · item-group · item-group-label

Props

属性类型必填说明
collectionListboxNode[]条目数据,显示文本与禁用的事实源。给了它,条目部件只需报 value。 缺省即回到「文本与禁用都写在条目部件上」的老路。
valuestring | string[]选中值,给定即受控;单选可写成裸串,内部归一成数组。
defaultValuestring | string[]
multiplebooleanselectionMode='multiple' 的简写;两者同时给时以 selectionMode 为准。
selectionModeListboxSelectionMode
disabledboolean整个列表禁用,键盘与点击都不再改选中值。
loopboolean方向键走到尽头是否回绕,默认 true。
dirDirection文字方向,默认 ltr。
orientationOrientation方向键轴向,默认 vertical。
typeaheadboolean连打检索,默认开。
onValueChange(details: ListboxValueChangeDetails) => voidvalue 变化意图回调。

状态机

状态idle

事件VALUE.SET · ITEM.SELECT · ITEM.TOGGLE · ITEM.FOCUS · LIST.BLUR

connect API

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

成员类型说明
valuestring[]选中集合;单选模式下长度 ≤ 1。
collectionreadonly ListboxNodeMeta[]collection 推出的条目元信息,按数据顺序排列;没给 collection 即空数组。
selectionModeListboxSelectionMode生效的选择模式。
focusedValuestring | null焦点锚点;焦点不在列表内时为 null。
disabledboolean
isSelected(value: string) => boolean
setValue(next: string[]) => void
select(value: string) => void只留这一个;加选用 toggle。
toggle(value: string) => void
getRootProps() => T['element']
getLabelProps() => T['element']
getContentProps() => T['element']
getItemGroupProps(props: ListboxItemGroupProps) => T['element']
getItemGroupLabelProps(props: ListboxItemGroupProps) => T['element']
getItemProps(props: ListboxItemProps) => T['element']
getItemTextProps(props: ListboxItemProps) => T['element']
getItemIndicatorProps(props: ListboxItemProps) => T['element']

键盘

规格出处:W3C APG

按键生效条件行为
Tab / Shift+Tabfocus outside the listbox整个列表只占一个 Tab 位:焦点进入锚点条目,无锚点时先落容器再由它转投
ArrowDownfocus in listbox, orientation=vertical焦点移到下一个可停留条目(禁用项跳过、尽头按 loop 回绕);orientation=horizontal 时改由 ArrowRight 承担,dir=rtl 再对调左右
ArrowUpfocus in listbox, orientation=vertical焦点移到上一个可停留条目(禁用项跳过、尽头按 loop 回绕);orientation=horizontal 时改由 ArrowLeft 承担,dir=rtl 再对调左右
Homefocus in listbox焦点移到首个可停留条目
Endfocus in listbox焦点移到末个可停留条目
Enter / Spacefocus on item, selectionMode 为 single 或 extended只选中焦点条目,替换原有选中;条目自报禁用则不认
Space / Enter / Ctrl+Spacefocus on item, 可多选(multiple;extended 下须按住 Ctrl/Cmd)切换焦点条目的选中态,其余选中不动
Shift+ArrowDown / Shift+ArrowUpfocus in listbox, 可多选焦点移到相邻条目并切换它的选中态;往回走即把刚扩进来的那个摘掉
Ctrl+A / Cmd+Afocus in listbox, 可多选选中全部可选条目;已经全选则把它们一并取消(禁用但已选中的不动)
单个可打印字符focus in listbox, typeahead 未关连打检索把焦点移到首字母匹配的条目,不改选中值

Released under The MIT License