跳转到内容

树选择 tree-select

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

示例

基础用法

收起时整个控件只占触发器一个 Tab 位,展开那一刻焦点真的进树、落在已选中的那行上

文档

已选:(无)

选中与展开双受控

两份集合都由宿主持有:组件只发事件,宿主写回它才动,回显的就是写回的那两份

文档

已选:guide · 展开:docs

多选与表单

multiple 下确认键是切换、浮层不收起;写了 hidden-input 才随表单提交,多个值按逗号拼成一串

提交范围

已选:index

形态

variant 只换触发框的描边与底色,浮层与树的长相不跟着变

outline
subtle
ghost

语气

tone 决定用哪族颜色,与 variant 正交,这里统一用 subtle 形态

brand
neutral
success
warning
danger
info

尺寸

size 换掉行高、内边距与字号,不写就是缺省档

sm
缺省
lg

禁用、只读与校验失败

disabled 连键盘入口都没有;readOnly 照常展开浏览但值改不动也清不掉;invalid 只报校验态,交互一切照旧

禁用
只读
校验失败

异步加载子节点

展开某个分支才去要它的子节点:先摆一行禁用占位,数据回来就地换掉,显示文本随之取到新 label

投放城市

已选:(无)

浮层里的操作区

content 里除了树还能放别的:在浮层内点按钮不算点在外面,浮层不会因此收起

文档

级联勾选与回显策略

multiple 加 cascade 内建父子传导:点分支整枝勾上、子全勾父勾、部分勾中半选;对外值按 checked-strategy 收敛,parent 档整组选满只报组名

权限

对外值(parent 收敛):user:view

浮层内关键词过滤

输入框是树的兄弟节点,树的键盘处理器挂在 tree 上,打字不会被连打检索收走;换掉 collection 可见行与方向键顺序跟着重算

投放城市

只挑文件不挑目录

选中值与展开态双受控:目录的值不写回,紧跟着那一次收起意图也一并吞掉,点目录就只剩展开收起

附件

已选:(无)

产物

自定义元素<xh-tree-select>
Vue 组件XhTreeSelectBranch XhTreeSelectBranchContent XhTreeSelectBranchControl XhTreeSelectBranchIndicator XhTreeSelectBranchText XhTreeSelectBranchTrigger XhTreeSelectClearTrigger XhTreeSelectContent XhTreeSelectHiddenInput XhTreeSelectIndicator XhTreeSelectItem XhTreeSelectItemIndicator XhTreeSelectItemText XhTreeSelectLabel XhTreeSelectPositioner XhTreeSelectRoot XhTreeSelectTree XhTreeSelectTrigger XhTreeSelectValueText
组合式函数useTreeSelect
状态机treeSelectMachine
皮肤@xihan-ui/styles/tree-select.css

解剖

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

data-scope="tree-select"root · label · trigger · value-text · indicator · clear-trigger · positioner · content · tree · item · item-text · item-indicator · branch · branch-control · branch-trigger · branch-indicator · branch-text · branch-content · hidden-input

Props

属性类型必填说明
collectionTreeNode[]树数据,层级元信息与显示文本的唯一事实源。缺省为空树。
valuestring | string[]选中值。给定即受控:cell 直读 prop,写只发 onValueChange 不落内部值。 单选写成裸串是简写,内部一律归一成数组。
defaultValuestring | string[]
expandedValuestring[]展开集合。给定即受控,语义同上。
defaultExpandedValuestring[]
openboolean展开态。给定即受控:内部不再自改,只发 onOpenChange。
defaultOpenboolean
multipleboolean多选:选中是集合,选中后浮层不收起、焦点留在树里以便接着挑。
cascadeboolean多选下父子级联勾选:点分支整枝传导、子全勾父勾、部分勾中半选, 禁用子树整棵冻结。默认 false(朴素切换);单选下无效。
checkedStrategyCascadeStrategy级联下对外值的收敛策略,默认 child(只收叶);parent = 最高整枝,all = 全部勾中节点。
disabledboolean整个控件禁用:trigger 用原生 disabled,表单出口不参与提交。
readOnlyboolean只读:浮层照常展开、树照常浏览与展开收起,但选中值改不动、也清不掉。 disabled 则连键盘入口都没有。
invalidboolean校验失败:trigger 报 aria-invalid,各角色节点带 data-invalid。
variantControlVariant形态:outline / subtle / ghost,决定触发框的描边与底色怎么用。
toneTone语气:brand / neutral / success / warning / danger / info,决定聚焦与选中用哪族颜色。
sizeSize尺寸:sm / md / lg,决定触发框与树节点行的几何档位。
placeholderstring无选中时 value-text 显示的占位文字。
placementPlacement
offsetnumber
loopboolean上下键走到首尾是否回绕,默认 false。
dirDirection文字方向,默认 ltr;只对调左右方向键的「展开/收起」语义。
namestring表单字段名。给定后表单出口才带 name,选中值随表单一并提交。
onValueChange(details: TreeSelectValueChangeDetails) => voidvalue 变化意图回调;受控时是唯一出口,非受控随内部写入一并通知。
onExpandedChange(details: TreeSelectExpandedChangeDetails) => void展开集合变化意图回调;语义同上。
onOpenChange(details: TreeSelectOpenChangeDetails) => voidopen 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。

状态机

状态open · closed

事件OPEN · TOGGLE · CLOSE · CONTROLLED.OPEN · CONTROLLED.CLOSE · NODE.FOCUS · NODE.LOST · NODE.SELECT · VALUE.SET · VALUE.CLEAR · EXPANDED.SET · BRANCH.EXPAND · BRANCH.COLLAPSE · BRANCH.TOGGLE · FORM.RESET

判据isOpenControlled · isMultiple

connect API

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

成员类型说明
openboolean
collectionreadonly TreeNode[]作者给的原始树数据。
visibleNodesreadonly TreeVisibleNode[]当前可见行序列(收起分支的子树不在其中)。 方向键、Home/End 与连打检索都在它上面走,不是在原始树上走。
valuestring[]选中集合;单选下长度 ≤ 1,形状不随模式变。
expandedValuestring[]
valueTextstring | null选中项的显示文本(多选用逗号加空格连接);无选中时为 null。取自 collection 的 label。
displayTextstringvalue-text 实际显示的文字:有选中取其文本,否则取 placeholder。
focusedValuestring | null焦点锚点;收起、或它已被收起而不可见时为 null。
multipleboolean
disabledboolean
readOnlyboolean
invalidboolean
canClearboolean清空按钮此刻可不可按。
isSelected(value: string) => boolean
isIndeterminate(value: string) => boolean级联模式下该分支是否半选(有效叶后代有勾有不勾);非级联恒 false。
isExpanded(value: string) => boolean
setOpen(next: boolean) => void
setValue(next: string[]) => void
setExpandedValue(next: string[]) => void
expand(value: string) => void
collapse(value: string) => void
select(value: string) => void单选替换、多选切换,与点节点同一语义。
clear() => void
getRootProps() => T['element']
getLabelProps() => T['element']
getTriggerProps() => T['button']
getValueTextProps() => T['element']
getIndicatorProps() => T['element']
getClearTriggerProps() => T['button']
getPositionerProps() => T['element']
getContentProps() => T['element']
getTreeProps() => T['element']
getItemProps(props: TreeSelectNodeProps) => T['element']
getItemTextProps(props: TreeSelectNodeProps) => T['element']
getItemIndicatorProps(props: TreeSelectNodeProps) => T['element']
getBranchProps(props: TreeSelectNodeProps) => T['element']
getBranchControlProps(props: TreeSelectNodeProps) => T['element']
getBranchTriggerProps(props: TreeSelectNodeProps) => T['element']
getBranchIndicatorProps(props: TreeSelectNodeProps) => T['element']
getBranchTextProps(props: TreeSelectNodeProps) => T['element']
getBranchContentProps(props: TreeSelectNodeProps) => T['element']
getHiddenInputProps() => T['input']表单出口:一份 type=hidden 的原生 input,选中值按逗号拼成一串随表单提交。

键盘

规格出处:W3C APG

按键生效条件行为
Enter / Spaceclosed, focus in trigger展开浮层并把焦点落到选中节点(无选中或它藏在收起的分支里则落首个可用行)
ArrowDownclosed, focus in trigger展开浮层并把焦点落到选中节点的下一个可用行
ArrowUpclosed, focus in trigger展开浮层并把焦点落到选中节点的上一个可用行
ArrowDownopen, focus in tree焦点移到下一个可见行(禁用行跳过;loop 默认关,末行不回绕)
ArrowUpopen, focus in tree焦点移到上一个可见行(禁用行跳过;loop 默认关,首行不回绕)
Homeopen, focus in tree焦点移到首个可见行
Endopen, focus in tree焦点移到末个可见行(展开着的子树也算行)
ArrowRightopen, focus on branch(dir=rtl 时改由 ArrowLeft 承担)收起的分支就地展开;已展开则把焦点移到首个子节点;叶子上什么都不做且不吞键
ArrowLeftopen, focus in tree(dir=rtl 时改由 ArrowRight 承担)展开的分支就地收起;收起的分支与叶子则把焦点移到父节点;根层的行什么都不做
Enter / Spaceopen, 焦点节点未禁用选中焦点节点:单选替换并收起浮层、焦点归还 trigger;多选切换且浮层不收起
*open, focus in tree展开与焦点行同一父级的全部分支(已展开与禁用的不动);同级没有可展开的分支时不吞这个键
单个可打印字符open, focus in tree连打检索在可见行上按 label 首字母搬焦点,不改选中值,也不展开任何分支
Escapeopen收起浮层并把焦点归还 trigger,选中值与展开集合都不变
Tab / Shift+Tabopen收起浮层,焦点不归还 trigger,按 Tab 序列自然离开

Released under The MIT License