TreeSelect 树选择
浮层内放一棵树的选择器,适用于层级不规整、深浅不一的数据。
用法
收起时整个控件只占触发器一个 Tab 位,展开时焦点真正进入树、落在已选中的行上
已选:(无)
组件结构
加粗的是必需部件。
data-scope="tree-select":root · label · control · trigger · value-text · indicator · clear-trigger · positioner · content · tree · item · item-text · item-description · item-suffix · item-indicator · branch · branch-control · branch-trigger · branch-indicator · branch-text · branch-content · branch-loading · branch-error · branch-retry-trigger · branch-empty · empty · loading · footer · hidden-input
示例
选中与展开双受控
两份集合都由宿主持有:组件只发事件,宿主写回后才变化,回显的就是写回的两份
已选:guide · 展开:docs
多选与表单
multiple 下确认键是切换、浮层不收起;写了 hidden-input 才随表单提交,多个值按逗号拼接为一串
已选:index
变体
variant 只更换触发框的描边与底色,浮层与树的外观不随之变化
颜色
tone 决定使用哪族颜色,与 variant 正交,这里统一使用 subtle 形态
尺寸
size 更换行高、内边距与字号,不写即默认档
禁用、只读与校验失败
disabled 连键盘入口都没有;readOnly 照常展开浏览但值不可修改也不可清空;invalid 只报告校验态,交互一切照常
首次全量加载与空集合
第一次展开才取整棵树;正式 Loading/Empty 与候选树互斥,状态文字不进入选值或键盘导航,底部按钮可重放有数据与零集合响应
已选:(无)
浮层中的操作区
footer 写在 content 中、tree 的兄弟:它不进入 role=tree 的拥有关系,方向键也无法到达;在浮层内点击按钮不算点击外部,浮层不会因此收起
级联勾选与回显策略
multiple 加 cascade 内建父子传导:点击分支整枝勾选、子全勾则父勾、部分勾选为半选;对外值按 checked-strategy 收敛,parent 档整组选满只报告组名
对外值(parent 收敛):user:view
浮层内关键词过滤
输入框是树的兄弟节点,树的键盘处理器挂在 tree 上,输入不会被连打检索接管;更换 collection 后可见行与方向键顺序随之重算
只选文件不选目录
选中值与展开态双受控:目录的值不写回,紧随其后的收起意图也一并忽略,点击目录只剩展开收起
已选:(无)
只提供数据自动渲染
Vue 未写默认插槽时按 collection 铺开整套部件:带 children 的节点渲染为 branch、其余渲染为 item,文本与禁用都查询数据;label 提供标题,clearable 带上清空按钮(手写部件不使用它),产出的 DOM 与手写全套部件完全一致;Web Components 没有自动铺树,节点部件照常手写、只报告 value
已选:guide
设计指引
何时使用
- 选项是任意形状的树(组织架构、目录、权限节点)。
- 需要在浮层内展开、勾选,并把选中项回显在触发器上。
何时不用
特性
- 选中与展开两套值各自可受控。
- 原生表单按每个选中值生成一个同名隐藏字段;
['a,b', 'c']用FormData.getAll(name)读取为两个原值,不使用逗号拼接。零选中没有提交项,禁用不提交,只读仍提交。 - 声明
HiddenInput部件才参与原生表单。form可指定外部表单 ID,提交与重置使用同一所有者;显式 ID 不存在时不回退祖先表单。非受控 reset 恢复defaultValue,受控值由业务响应重置请求。 - 单选、多选、分支与叶子统一用末端对号表示选中,级联半选使用横线;正文保持正常颜色和字重,中性底只用于悬停和键盘高亮。展开箭头位于行首,与选择标记分开。
cascade与checkedStrategy决定勾选是否带子级、回显给哪一层。- 节点可逐条声明语气,不向下传导;叶子行与分支行同样表达。
- 节点可写副文本,第 2 行放一句解释,不进连打检索串。
- 节点行尾留一格给作者(计数、徽标);行首那一格归勾选框与展开箭头。
- 支持只选叶子不选分支、浮层内关键词过滤、子节点异步加载:节点用
hasChildren: true声明懒分支,首次展开由loadChildren({ node, signal })获取直接子项;失败保留 cause,默认branch-error与branch-retry-trigger直接可用。 - 整树空(
empty)与在途(loading)默认自动渲染;collection 看有效树长度,手写节点由适配器只上报挂载事实、Headless 统一判空。loading为真时树报aria-busy,空态让位;作者写同名部件时保留作者结构与文案。 - 输入框保持实体;浮层使用 M2 磨砂材质、内侧顶光和四向短位移,不缩放树中文字。树、空态与加载态共用一个外壳,底部操作使用同材质分隔线;增强对比度时材质自动实体化。面板宽度受定位后的可用空间约束,触发器更宽时也不撑大面板。
- 仅
{ hasChildren: true, children: undefined }触发loadChildren({ node, signal });children: []是已知为空目录,永不请求。成功子项、可见行、键盘导航与级联选择由 headless 的同一有效树计算,三端不各自缓存结果。 - 分支状态不互相降级:
api.branchLoadState(value)公开idle/loading/loaded/error;loaded的empty明确区分成功空数组,error保留原始 cause。默认结构提供branch-loading、branch-error、branch-retry-trigger、branch-empty,也可用同名部件替换文案;错误分支行上的 Enter/Space 是不破坏 tree roving 的正式键盘重试入口。 onBranchLoadStart、onBranchLoad、onBranchLoadError(三端事件为branch-load-start/branch-load/branch-load-error)公开有效请求生命周期。分支或整浮层收起、重试、节点移除/同 value 换代、组件卸载都会中止并作废旧请求;迟到兑现或拒绝不能写回当前树,也不发成功/失败事件。
组合
- 外层放表单字段。
最佳实践
- 大树必须开启浮层内过滤,逐级展开查找节点很慢。
- 无头用法需要按
api.value遍历,为每个值调用api.getHiddenInputProps({ value })并渲染原生 input;旧的无参调用与 CSV 提交合同已删除。Vue/React 的HiddenInput部件自动铺开,Web Components 仍只需声明一个原生input[data-xh-part="hidden-input"],额外字段由宿主管理。 - 明确只能选叶子还是分支也可选,并在界面上让分支的可点性可见。
- 自定义
branch-control与item都应包含item-indicator,分支标记直接读取所属分支的选择与半选状态,不另写状态判定或自绘复选框。Vue / React 自动结构已提供此部件。
反模式
- 一次把整棵大树放进浮层,首屏即卡顿。
- 勾选策略与后端理解不一致。
API 参考
产物
| 层 | 值 |
|---|---|
| 自定义元素 | <xh-tree-select> |
| Vue 组件 | XhTreeSelectBranch XhTreeSelectBranchContent XhTreeSelectBranchControl XhTreeSelectBranchEmpty XhTreeSelectBranchError XhTreeSelectBranchIndicator XhTreeSelectBranchLoading XhTreeSelectBranchRetryTrigger XhTreeSelectBranchText XhTreeSelectBranchTrigger XhTreeSelectClearTrigger XhTreeSelectContent XhTreeSelectControl XhTreeSelectEmpty XhTreeSelectFooter XhTreeSelectHiddenInput XhTreeSelectIndicator XhTreeSelectItem XhTreeSelectItemDescription XhTreeSelectItemIndicator XhTreeSelectItemSuffix XhTreeSelectItemText XhTreeSelectLabel XhTreeSelectLoading XhTreeSelectPositioner XhTreeSelectRoot XhTreeSelectTree XhTreeSelectTrigger XhTreeSelectValueText |
| 组合式函数 | useTreeSelect |
| 状态机 | treeSelectMachine |
| 皮肤 | @xihan-ui/styles/tree-select.css |
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
collection | TreeSelectNode[] | 树数据,层级元信息与显示文本的唯一事实源。hasChildren 且未提供 children 是懒分支;已提供 children 时它优先。默认为空树。 | |
loadChildren | (request: TreeSelectLoadChildrenRequest) => Promise<TreeSelectNode[] | undefined | void> | TreeSelectNode[] | undefined | void | 取回 hasChildren: true 分支的直接子项。首次展开自动调用,失败后用 api.retryBranch 显式重试。旧请求的兑现或拒绝不会覆盖更新的一轮,也不会写回已移除的分支。 | |
value | string | string[] | 选中值。提供即受控:cell 直读 prop,写入只发 onValueChange 不落内部值。 单选写为裸串是简写,内部一律归一为数组。 | |
defaultValue | string | string[] | ||
expandedValue | string[] | 展开集合。提供即受控,语义同上。 | |
defaultExpandedValue | string[] | ||
open | boolean | 展开态。提供即受控:内部不再自行修改,只发 onOpenChange。 | |
defaultOpen | boolean | ||
multiple | boolean | 多选:选中为集合,选中后浮层不收起、焦点留在树中以便继续选择。 | |
cascade | boolean | 多选下父子级联勾选:点击分支整枝传导、子全勾父勾、部分勾选半选, 禁用子树整棵冻结。默认 false(朴素切换);单选下无效。 | |
checkedStrategy | CascadeStrategy | 级联下对外值的收敛策略,默认 child(只收叶);parent = 最高整枝,all = 全部勾选节点。 | |
disabled | boolean | 整个控件禁用:trigger 使用原生 disabled,表单出口不参与提交。 | |
readOnly | boolean | 只读:浮层照常展开、树照常浏览与展开收起,但选中值不可修改、也不可清空。 disabled 则连键盘入口都没有。 | |
invalid | boolean | 校验失败:trigger 报告 aria-invalid,各角色节点带 data-invalid。 | |
loading | boolean | 节点加载中:树报告 aria-busy,显示在途占位、隐藏空态占位。 | |
variant | ControlVariant | 形态:outline / subtle / ghost,决定触发框的描边与底色使用方式。默认 outline。 | |
tone | Tone | 语气:brand / neutral / success / warning / danger / info,决定聚焦与选中使用哪族颜色。 | |
size | Size | 尺寸:sm / md / lg,决定触发框与树节点行的几何档位。 | |
placeholder | string | 无选中时 value-text 显示的占位文字。 | |
translations | Partial<TreeSelectTranslations> | 读屏文案,默认英文。 | |
placement | Placement | ||
offset | number | ||
loop | boolean | 上下键到达首尾是否回绕,默认 false。 | |
dir | Direction | 文字方向,默认 ltr;只对调左右方向键的展开 / 收起语义。 | |
name | string | 表单字段名。提供后表单出口才带 name,选中值随表单一并提交。 | |
form | string | 原生表单 ID;显式关联外部表单,提交与 reset 使用同一所有者。 | |
onValueChange | (details: TreeSelectValueChangeDetails) => void | value 变化意图回调;受控时是唯一出口,非受控时随内部写入一并通知。 | |
onExpandedValueChange | (details: TreeSelectExpandedValueChangeDetails) => void | 展开集合变化意图回调;语义同上。 | |
onOpenChange | (details: TreeSelectOpenChangeDetails) => void | open 变化意图回调;受控时是唯一出口,非受控时随内部转移一并通知。 | |
onBranchLoadStart | (details: TreeSelectBranchLoadStartDetails) => void | 一轮有效分支请求开始;retry 与首次展开由 reason 区分。 | |
onBranchLoad | (details: TreeSelectBranchLoadDetails) => void | 一轮有效分支请求成功;children 为空仍是成功,不转换为错误或全局空态。 | |
onBranchLoadError | (details: TreeSelectBranchLoadErrorDetails) => void | 一轮有效分支请求失败;保留 loader 给出的原始 error。 |
TreeSelectNode
collection 的元素。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
children | TreeSelectNode[] | ||
hasChildren | boolean | ||
value | string | 是 | |
label | string | 展示名,也是连打检索与分支可及名的取字来源;默认回退为 value。 | |
disabled | boolean | 节点禁用:方向键与连打检索跳过它,但它仍可聚焦、仍是导航起点。不向下传导给子节点。 | |
tone | Tone | 该节点自身的性质:已失效的写 danger、需要留意的写 warning。不写即与其余节点同档, 也不向下传导给子节点——每一层各自声明。只换字色与悬停 / 按下的面,不改字重与缩进, 也不表达选中或校验;选中的标记与禁用都压过它。彩字不是唯一通道,要紧的差别仍要配图标。 | |
description | string | 副文本,写入 item-description 部件;未提供时本条不铺该部件。 它是第 2 行的说明,跟着条目走 muted 档,不跟语气;放不下一行的解释才用它, 一句话能说清的写进 label。 | |
childrenOrientation | Orientation | 该层子节点的排布方式,由作者在数据上标注。提供后以它为准,vertical 也优先于树级的 leafOrientation;未提供时才回退为 leafOrientation 加子节点全是叶子的结构判据。 标注在哪一层,横向排布就只落在哪一层:菜单授权中标注在按钮的父菜单上,其他目录不受影响, 也不随子节点增减漂移。只影响排布,不改变键盘。 |
事件
自定义元素将载荷放在 detail;Vue 使用同名 emit。
| 事件 | 载荷 | 说明 |
|---|---|---|
value-change | TreeSelectValueChangeDetails | 选中集合变化;detail 为 { value: string[] } |
expanded-value-change | TreeSelectExpandedValueChangeDetails | 展开集合变化;detail 为 { value: string[] } |
open-change | TreeSelectOpenChangeDetails | open 状态变化;detail 为 { open: boolean } |
branch-load-start | TreeSelectBranchLoadStartDetails | 分支请求开始;detail 为 { value, node, reason } |
branch-load | TreeSelectBranchLoadDetails | 分支请求成功;detail 为 { value, node, children } |
branch-load-error | TreeSelectBranchLoadErrorDetails | 分支请求失败;detail 为 { value, node, error } |
插槽
仅列出带载荷的插槽。
| Vue 组件 | 插槽 | 载荷 | 说明 |
|---|---|---|---|
XhTreeSelectRoot | default | TreeSelectRootSlotProps | |
XhTreeSelectRoot | label | — |
React 适配器 props
只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。
| React 组件 | 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
XhTreeSelectBranch | value | string | 是 | |
XhTreeSelectItem | value | string | 是 | |
XhTreeSelectPositioner | container | () => Element | null | 浮层挂载的容器;未提供时按全局配置,再未提供时挂载到 body。 | |
XhTreeSelectRoot | label | ReactNode | 标题文字。提供后不必再写 label 部件。 | |
XhTreeSelectRoot | clearable | boolean | 自动渲染树中是否带清空按钮;手写部件不使用它,写了节点即可清空。 | |
XhTreeSelectRoot | children | SlotChildren<TreeSelectRootSlotProps> |
状态
公开状态写入 data-state。
| 部件 | 取值 |
|---|---|
root | 'open' | 'closed' |
control | 'open' | 'closed' |
trigger | 'open' | 'closed' |
indicator | 'open' | 'closed' |
positioner | 'open' | 'closed' |
content | 'open' | 'closed' |
tree | 'open' | 'closed' |
branch | 'open' | 'closed' |
branch-control | 'open' | 'closed' |
branch-trigger | 'open' | 'closed' |
branch-indicator | 'open' | 'closed' |
branch-text | 'open' | 'closed' |
branch-content | 'open' | 'closed' |
branch-loading | 'open' | 'closed' |
branch-error | 'open' | 'closed' |
branch-retry-trigger | 'open' | 'closed' |
branch-empty | 'open' | 'closed' |
empty | 'open' | 'closed' |
loading | 'open' | 'closed' |
footer | 'open' | 'closed' |
以下名称仅用于内部状态机。
状态: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 · BRANCH.RETRY · NODE.MOUNT · NODE.UNMOUNT · NODES.SYNC · FORM.RESET · PRESS.START · PRESS.END
判据:isOpenControlled · isMultiple · canPress
connect API
getXxxProps() 返回对应部件的宿主属性。
| 成员 | 类型 | 说明 |
|---|---|---|
open | boolean | |
collection | readonly TreeSelectNode[] | 当前有效树:含 headless 已成功取回的懒分支子项。 |
visibleNodes | readonly TreeVisibleNode[] | 当前可见行序列(收起分支的子树不在其中)。 方向键、Home/End 与连打检索都在它上面移动,不在原始树上移动。 |
value | string[] | 选中集合;单选下长度 ≤ 1,形状不随模式变化。 |
expandedValue | string[] | |
valueText | string | null | 选中项的显示文本(多选用逗号加空格连接);无选中时为 null。取自 collection 的 label。 |
displayText | string | value-text 实际显示的文字:有选中时取其文本,否则取 placeholder。 |
focusedValue | string | null | 焦点锚点;收起、或它已被收起而不可见时为 null。 |
empty | boolean | 整树当前是否没有任何节点;collection 与手写节点统一由 Headless 判定。 |
loading | boolean | 外部整树 loading 状态。懒分支 loading 由 branchLoadState 单独表达。 |
translations | TreeSelectTranslations | |
multiple | boolean | |
disabled | boolean | |
readOnly | boolean | |
invalid | boolean | |
canClear | boolean | 清空按钮当前是否可按。 |
isSelected | (value: string) => boolean | |
isIndeterminate | (value: string) => boolean | 级联模式下该分支是否半选(有效叶后代部分勾选);非级联恒为 false。 |
isExpanded | (value: string) => boolean | |
branchLoadState | (value: string) => TreeSelectBranchLoadSnapshot | null | 非懒分支返回 null;懒分支即使尚未请求也返回 idle。 |
setOpen | (next: boolean) => void | |
setValue | (next: string[]) => void | |
setExpandedValue | (next: string[]) => void | |
expand | (value: string) => void | |
collapse | (value: string) => void | |
retryBranch | (value: string) => void | 失败后重新取该分支;非懒分支与未知 value 不产生副作用。 |
select | (value: string) => void | 单选替换、多选切换,与点击节点同一语义。 |
clear | () => void | |
getRootProps | () => T['element'] | |
getLabelProps | () => T['element'] | |
getControlProps | () => 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'] | |
getItemDescriptionProps | (props: TreeSelectNodeProps) => T['element'] | |
getItemSuffixProps | (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'] | |
getBranchLoadingProps | (props: TreeSelectNodeProps) => T['element'] | |
getBranchErrorProps | (props: TreeSelectNodeProps) => T['element'] | |
getBranchRetryTriggerProps | (props: TreeSelectNodeProps) => T['button'] | |
getBranchEmptyProps | (props: TreeSelectNodeProps) => T['element'] | |
getEmptyProps | () => T['element'] | 空态占位:放在 content 中、tree 的兄弟。 collection 与手写节点都由连接层按 Headless 空态收放;作者可更换内容,不必自行重新计算。 |
getLoadingProps | () => T['element'] | 在途占位:与空态占位同一位置,两者不同时显示:加载期间显示它,空态让位。 collection 与手写节点都由连接层按 Headless 空态收放。 |
getFooterProps | () => T['element'] | 浮层底部的操作区:放在 content 中、tree 的兄弟,不进入树的拥有关系,方向键也无法到达。 |
getHiddenInputProps | (props: { value: string }) => T['input'] | 单值表单出口;按 api.value 逐个调用并生成同名 input,零选中不生成提交项。 |
无障碍
键盘
规格出处:W3C APG
| 按键 | 生效条件 | 行为 |
|---|---|---|
Enter / Space | closed, focus in trigger | 展开浮层并把焦点落到选中节点(无选中或它藏在收起的分支里则落首个可用行) |
ArrowDown | closed, focus in trigger | 展开浮层并把焦点落到选中节点的下一个可用行 |
ArrowUp | closed, focus in trigger | 展开浮层并把焦点落到选中节点的上一个可用行 |
Delete | focus in trigger, 有值且未禁用/只读 | 清空全部选中值,焦点留在 trigger |
Backspace | focus in trigger, 有值且未禁用/只读 | 单选清空;多选去掉最后一个选中值 |
ArrowDown | open, focus in content | 焦点移到下一个可见行(禁用行跳过;loop 默认关,末行不回绕) |
ArrowUp | open, focus in content | 焦点移到上一个可见行(禁用行跳过;loop 默认关,首行不回绕) |
Home | open, focus in content | 焦点移到首个可见行 |
End | open, focus in content | 焦点移到末个可见行(展开着的子树也算行) |
ArrowRight | open, focus on branch(dir=rtl 时改由 ArrowLeft 承担) | 收起的分支就地展开;已展开则把焦点移到首个子节点;叶子上什么都不做且不吞键 |
ArrowLeft | open, focus in content(dir=rtl 时改由 ArrowRight 承担) | 展开的分支就地收起;收起的分支与叶子则把焦点移到父节点;根层的行什么都不做 |
Enter / Space | open, 焦点节点未禁用且不是错误分支 | 选中焦点节点:单选替换并收起浮层、焦点归还 trigger;多选切换且浮层不收起 |
Enter / Space | held in item / branch / clear-trigger, 未禁用、未只读、未加载 | 按住期间叶子行、分支行(branch-control)或清空按钮投影 data-pressed,与指针 :active 同一副按压面;抬起或失焦撤下,节点随浮层收起一并撤下;没有值可清时清空按钮不进 |
Enter / Space | open, focus on branch, 分支加载失败 | 重试该分支,焦点留在分支行;不改变选中值与展开集合 |
* | open, focus in content | 展开与焦点行同一父级的全部分支(已展开与禁用的不动);同级没有可展开的分支时不吞这个键 |
单个可打印字符 | open, focus in content | 连打检索在可见行上按 label 首字母搬焦点,不改选中值,也不展开任何分支 |
Escape | open | 收起浮层并把焦点归还 trigger,选中值与展开集合都不变 |
Tab / Shift+Tab | open | 收起浮层,焦点不归还 trigger,按 Tab 序列自然离开 |
ARIA
以下属性由 connect 生成。
| 部件 | 属性 | 值 |
|---|---|---|
trigger | aria-controls | tree 部件的 id |
trigger | aria-expanded | 'true' | 'false' |
trigger | aria-haspopup | 'tree' |
trigger | aria-invalid | 'true' | 'false' |
trigger | aria-labelledby | label 部件的 id value-text 部件的 id |
trigger | aria-readonly | 'true' | 'false' |
trigger | role | 'combobox' |
indicator | aria-hidden | 'true' |
clear-trigger | aria-label | translations.clearTrigger |
content | aria-hidden | !open || undefined |
tree | aria-busy | 'true' | undefined |
tree | aria-disabled | 'true' | 'false' |
tree | aria-label | translations.tree |
tree | aria-labelledby | label 部件的 id value-text 部件的 id |
tree | aria-multiselectable | 'true' | 'false' |
tree | role | 'tree' |
item | aria-checked | 'true' | 'mixed' | 'false' | undefined |
item | aria-disabled | 'true' | 'false' |
item | aria-level | meta?.level |
item | aria-posinset | meta?.posInSet |
item | aria-selected | 'true' | 'false' |
item | aria-setsize | meta?.setSize |
item | role | 'treeitem' |
item-indicator | aria-hidden | 'true' |
branch | aria-busy | 'true' | undefined |
branch | aria-checked | 'true' | 'mixed' | 'false' | undefined |
branch | aria-disabled | 'true' | 'false' |
branch | aria-expanded | 'true' | 'false' |
branch | aria-label | metaOf(node.value)?.label |
branch | aria-level | meta?.level |
branch | aria-posinset | meta?.posInSet |
branch | aria-selected | 'true' | 'false' |
branch | aria-setsize | meta?.setSize |
branch | role | 'treeitem' |
branch-trigger | aria-hidden | 'true' |
branch-indicator | aria-hidden | 'true' |
branch-content | role | 'group' |
branch-loading | role | 'status' |
branch-error | role | 'alert' |
branch-retry-trigger | aria-label | translations.retry |
branch-empty | role | 'status' |
empty | role | 'status' |
loading | role | 'status' |
样式参考
皮肤
@xihan-ui/styles/tree-select.css 使用 [data-scope="tree-select"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。
数据属性
由 connect 生成;条件不成立时不输出无值属性。
| 部件 | 属性 | 值 |
|---|---|---|
root | data-disabled | ''(条件成立时才出现) |
root | data-invalid | ''(条件成立时才出现) |
root | data-loading | ''(条件成立时才出现) |
root | data-readonly | ''(条件成立时才出现) |
root | data-size | props.size |
root | data-state | 'open' | 'closed' |
root | data-tone | props.tone |
root | data-variant | props.variant |
label | data-disabled | ''(条件成立时才出现) |
control | data-disabled | ''(条件成立时才出现) |
control | data-invalid | ''(条件成立时才出现) |
control | data-readonly | ''(条件成立时才出现) |
control | data-state | 'open' | 'closed' |
control | data-variant | props.variant |
control | data-xh-field-chrome | '' |
control | data-xh-field-size | props.size |
trigger | data-disabled | ''(条件成立时才出现) |
trigger | data-invalid | ''(条件成立时才出现) |
trigger | data-placeholder | ''(条件成立时才出现) |
trigger | data-readonly | ''(条件成立时才出现) |
trigger | data-state | 'open' | 'closed' |
value-text | data-disabled | ''(条件成立时才出现) |
value-text | data-placeholder | ''(条件成立时才出现) |
indicator | data-clearable | ''(条件成立时才出现) |
indicator | data-disabled | ''(条件成立时才出现) |
indicator | data-state | 'open' | 'closed' |
clear-trigger | data-pressed | ''(条件成立时才出现) |
clear-trigger | data-xh-action-control | '' |
clear-trigger | data-xh-action-display | 'has-value' |
clear-trigger | data-xh-action-has-value | ''(条件成立时才出现) |
clear-trigger | data-xh-action-profile | 'field-inset' |
clear-trigger | data-xh-action-size | props.size |
clear-trigger | data-xh-action-variant | 'ghost' |
positioner | data-hidden | ''(条件成立时才出现) |
positioner | data-placement | 定位引擎算出的实际落位 |
positioner | data-positioned | ''(条件成立时才出现) |
positioner | data-size | props.size |
positioner | data-state | 'open' | 'closed' |
positioner | data-tone | props.tone |
positioner | data-variant | props.variant |
content | data-placement | 定位引擎算出的实际落位 |
content | data-state | 'open' | 'closed' |
content | data-xh-material | 'frosted' |
tree | data-disabled | ''(条件成立时才出现) |
tree | data-empty | ''(条件成立时才出现) |
tree | data-state | 'open' | 'closed' |
item | data-disabled | ''(条件成立时才出现) |
item | data-highlighted | ''(条件成立时才出现) |
item | data-indeterminate | ''(条件成立时才出现) |
item | data-pressed | ''(条件成立时才出现) |
item | data-selected | ''(条件成立时才出现) |
item | data-tone | metaOf(v)?.tone |
item | data-xh-collection-context | 'overlay' |
item | data-xh-collection-item | '' |
item | data-xh-collection-size | props.size |
item-text | data-disabled | ''(条件成立时才出现) |
item-text | data-highlighted | ''(条件成立时才出现) |
item-text | data-indeterminate | ''(条件成立时才出现) |
item-text | data-selected | ''(条件成立时才出现) |
item-text | data-xh-collection-slot | 'text' |
item-description | data-disabled | ''(条件成立时才出现) |
item-description | data-highlighted | ''(条件成立时才出现) |
item-description | data-indeterminate | ''(条件成立时才出现) |
item-description | data-selected | ''(条件成立时才出现) |
item-description | data-xh-collection-slot | 'description' |
item-suffix | data-disabled | ''(条件成立时才出现) |
item-suffix | data-highlighted | ''(条件成立时才出现) |
item-suffix | data-indeterminate | ''(条件成立时才出现) |
item-suffix | data-selected | ''(条件成立时才出现) |
item-suffix | data-xh-collection-slot | 'suffix' |
item-indicator | data-disabled | ''(条件成立时才出现) |
item-indicator | data-highlighted | ''(条件成立时才出现) |
item-indicator | data-indeterminate | ''(条件成立时才出现) |
item-indicator | data-selected | ''(条件成立时才出现) |
item-indicator | data-xh-collection-slot | 'indicator' |
branch | data-disabled | ''(条件成立时才出现) |
branch | data-empty | ''(条件成立时才出现) |
branch | data-error | ''(条件成立时才出现) |
branch | data-highlighted | ''(条件成立时才出现) |
branch | data-indeterminate | ''(条件成立时才出现) |
branch | data-load-state | branchLoadState(v)?.status |
branch | data-loading | ''(条件成立时才出现) |
branch | data-selected | ''(条件成立时才出现) |
branch | data-state | 'open' | 'closed' |
branch-control | data-disabled | ''(条件成立时才出现) |
branch-control | data-empty | ''(条件成立时才出现) |
branch-control | data-error | ''(条件成立时才出现) |
branch-control | data-highlighted | ''(条件成立时才出现) |
branch-control | data-indeterminate | ''(条件成立时才出现) |
branch-control | data-load-state | branchLoadState(v)?.status |
branch-control | data-loading | ''(条件成立时才出现) |
branch-control | data-pressed | ''(条件成立时才出现) |
branch-control | data-selected | ''(条件成立时才出现) |
branch-control | data-state | 'open' | 'closed' |
branch-control | data-tone | metaOf(v)?.tone |
branch-control | data-xh-collection-context | 'overlay' |
branch-control | data-xh-collection-item | '' |
branch-control | data-xh-collection-size | props.size |
branch-trigger | data-disabled | ''(条件成立时才出现) |
branch-trigger | data-empty | ''(条件成立时才出现) |
branch-trigger | data-error | ''(条件成立时才出现) |
branch-trigger | data-highlighted | ''(条件成立时才出现) |
branch-trigger | data-indeterminate | ''(条件成立时才出现) |
branch-trigger | data-load-state | branchLoadState(v)?.status |
branch-trigger | data-loading | ''(条件成立时才出现) |
branch-trigger | data-selected | ''(条件成立时才出现) |
branch-trigger | data-state | 'open' | 'closed' |
branch-trigger | data-xh-collection-slot | 'prefix' |
branch-indicator | data-disabled | ''(条件成立时才出现) |
branch-indicator | data-empty | ''(条件成立时才出现) |
branch-indicator | data-error | ''(条件成立时才出现) |
branch-indicator | data-highlighted | ''(条件成立时才出现) |
branch-indicator | data-indeterminate | ''(条件成立时才出现) |
branch-indicator | data-load-state | branchLoadState(v)?.status |
branch-indicator | data-loading | ''(条件成立时才出现) |
branch-indicator | data-selected | ''(条件成立时才出现) |
branch-indicator | data-state | 'open' | 'closed' |
branch-indicator | data-xh-collection-slot | 'prefix' |
branch-text | data-disabled | ''(条件成立时才出现) |
branch-text | data-empty | ''(条件成立时才出现) |
branch-text | data-error | ''(条件成立时才出现) |
branch-text | data-highlighted | ''(条件成立时才出现) |
branch-text | data-indeterminate | ''(条件成立时才出现) |
branch-text | data-load-state | branchLoadState(v)?.status |
branch-text | data-loading | ''(条件成立时才出现) |
branch-text | data-selected | ''(条件成立时才出现) |
branch-text | data-state | 'open' | 'closed' |
branch-text | data-xh-collection-slot | 'text' |
branch-content | data-disabled | ''(条件成立时才出现) |
branch-content | data-empty | ''(条件成立时才出现) |
branch-content | data-error | ''(条件成立时才出现) |
branch-content | data-highlighted | ''(条件成立时才出现) |
branch-content | data-indeterminate | ''(条件成立时才出现) |
branch-content | data-load-state | branchLoadState(v)?.status |
branch-content | data-loading | ''(条件成立时才出现) |
branch-content | data-selected | ''(条件成立时才出现) |
branch-content | data-state | 'open' | 'closed' |
branch-loading | data-disabled | ''(条件成立时才出现) |
branch-loading | data-empty | ''(条件成立时才出现) |
branch-loading | data-error | ''(条件成立时才出现) |
branch-loading | data-highlighted | ''(条件成立时才出现) |
branch-loading | data-indeterminate | ''(条件成立时才出现) |
branch-loading | data-load-state | branchLoadState(v)?.status |
branch-loading | data-loading | ''(条件成立时才出现) |
branch-loading | data-selected | ''(条件成立时才出现) |
branch-loading | data-state | 'open' | 'closed' |
branch-error | data-disabled | ''(条件成立时才出现) |
branch-error | data-empty | ''(条件成立时才出现) |
branch-error | data-error | ''(条件成立时才出现) |
branch-error | data-highlighted | ''(条件成立时才出现) |
branch-error | data-indeterminate | ''(条件成立时才出现) |
branch-error | data-load-state | branchLoadState(v)?.status |
branch-error | data-loading | ''(条件成立时才出现) |
branch-error | data-selected | ''(条件成立时才出现) |
branch-error | data-state | 'open' | 'closed' |
branch-retry-trigger | data-disabled | ''(条件成立时才出现) |
branch-retry-trigger | data-empty | ''(条件成立时才出现) |
branch-retry-trigger | data-error | ''(条件成立时才出现) |
branch-retry-trigger | data-highlighted | ''(条件成立时才出现) |
branch-retry-trigger | data-indeterminate | ''(条件成立时才出现) |
branch-retry-trigger | data-load-state | branchLoadState(v)?.status |
branch-retry-trigger | data-loading | ''(条件成立时才出现) |
branch-retry-trigger | data-selected | ''(条件成立时才出现) |
branch-retry-trigger | data-state | 'open' | 'closed' |
branch-empty | data-disabled | ''(条件成立时才出现) |
branch-empty | data-empty | ''(条件成立时才出现) |
branch-empty | data-error | ''(条件成立时才出现) |
branch-empty | data-highlighted | ''(条件成立时才出现) |
branch-empty | data-indeterminate | ''(条件成立时才出现) |
branch-empty | data-load-state | branchLoadState(v)?.status |
branch-empty | data-loading | ''(条件成立时才出现) |
branch-empty | data-selected | ''(条件成立时才出现) |
branch-empty | data-state | 'open' | 'closed' |
empty | data-state | 'open' | 'closed' |
loading | data-state | 'open' | 'closed' |
footer | data-state | 'open' | 'closed' |
CSS 变量
本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。
| 变量 | 部件 | CSS 属性 | 状态 | 默认来源 | 说明 |
|---|---|---|---|---|---|
--xh-tree-select-action-bg | clear-trigger | --xh-ink-surfacebackground-color | defaultxh-ink-surface | --xh-_action-variant-bg-rest | tree-select 的 clear-trigger 部件 --xh-ink-surface、background-color 覆盖槽。 |
--xh-tree-select-action-bg-active | clear-trigger | background-color | disabledis(:active, [data-pressed])loadingnot([data-disabled])not([data-loading])pressed | --xh-_action-variant-bg-pressed | tree-select 的 clear-trigger 部件 background-color 覆盖槽。 |
--xh-tree-select-action-bg-hover | clear-trigger | background-color | disabledhoverloadingnot([data-disabled])not([data-loading]) | --xh-_action-variant-bg-hover | tree-select 的 clear-trigger 部件 background-color 覆盖槽。 |
--xh-tree-select-action-fg | clear-trigger | color | default | --xh-fg-muted | tree-select 的 clear-trigger 部件 color 覆盖槽。 |
--xh-tree-select-action-fg-hover | clear-trigger | color | disabledhoverloadingnot([data-disabled])not([data-loading]) | --xh-fg-default | tree-select 的 clear-trigger 部件 color 覆盖槽。 |
--xh-tree-select-action-font-size | clear-trigger | font-size | default | --xh-text-secondary-size | tree-select 的 clear-trigger 部件 font-size 覆盖槽。 |
--xh-tree-select-action-radius | clear-trigger | border-radius | default | --xh-shape-inset | tree-select 的 clear-trigger 部件 border-radius 覆盖槽。 |
--xh-tree-select-action-size | clear-trigger | block-sizeinline-sizemin-inline-size | defaultxh-action-profile=field-inset | --xh-_action-profile-visual-size | tree-select 的 clear-trigger 部件 block-size、inline-size、min-inline-size 覆盖槽。 |
--xh-tree-select-branch-content-gap | branch-content | gap | default | --xh-list-option-gap | tree-select 的 branch-content 部件 gap 覆盖槽。 |
--xh-tree-select-branch-gap | branch | gap | default | --xh-list-option-gap | tree-select 的 branch 部件 gap 覆盖槽。 |
--xh-tree-select-branch-indicator-fg | branch-indicatorbranch-trigger | color | default | --xh-fg-subtle | tree-select 的 branch-indicator、branch-trigger 部件 color 覆盖槽。 |
--xh-tree-select-branch-indicator-size | branch-indicatorbranch-triggeritem | --xh-icon-sizeinline-size | default | --xh-control-indicator-size | tree-select 的 branch-indicator、branch-trigger、item 部件 --xh-icon-size、inline-size 覆盖槽。 |
--xh-tree-select-content-backdrop | content | -webkit-backdrop-filterbackdrop-filter | xh-material=frosted | --xh-_material-backdrop | tree-select 的 content 部件 -webkit-backdrop-filter、backdrop-filter 覆盖槽。 |
--xh-tree-select-content-bg | content | background | not([data-xh-action-control])xh-material=frosted | --xh-_material-bg | tree-select 的 content 部件 background 覆盖槽。 |
--xh-tree-select-content-border | content | border | not([data-xh-action-control])xh-material=frosted | --xh-_material-border | tree-select 的 content 部件 border 覆盖槽。 |
--xh-tree-select-content-fg | content | color | not([data-xh-action-control])xh-material=frosted | --xh-_material-fg | tree-select 的 content 部件 color 覆盖槽。 |
--xh-tree-select-content-highlight | content | background | not([data-xh-action-control])xh-material=frosted | --xh-_material-highlight | tree-select 的 content 部件 background 覆盖槽。 |
--xh-tree-select-content-max-h | content | max-block-size | default | --xh-overlay-max-h | tree-select 的 content 部件 max-block-size 覆盖槽。 |
--xh-tree-select-content-max-w | content | max-inline-size | default | --xh-overlay-max-w | tree-select 的 content 部件 max-inline-size 覆盖槽。 |
--xh-tree-select-content-min-w | content | min-inline-size | default | --xh-overlay-min-w | tree-select 的 content 部件 min-inline-size 覆盖槽。 |
--xh-tree-select-content-px | content | padding-inline | default | --xh-space-1 | tree-select 的 content 部件 padding-inline 覆盖槽。 |
--xh-tree-select-content-py | content | padding-block | default | --xh-space-1 | tree-select 的 content 部件 padding-block 覆盖槽。 |
--xh-tree-select-content-radius | content | border-radius | default | --xh-shape-overlay | tree-select 的 content 部件 border-radius 覆盖槽。 |
--xh-tree-select-content-shadow | content | box-shadow | not([data-xh-action-control])xh-material=frosted | --xh-_material-shadow | tree-select 的 content 部件 box-shadow 覆盖槽。 |
--xh-tree-select-control-bg | control | background-color | xh-field-chrome | --xh-_field-variant-bg-rest | tree-select 的 control 部件 background-color 覆盖槽。 |
--xh-tree-select-control-bg-disabled | control | background-color | disabledxh-field-chrome | --xh-_field-variant-bg-disabled | tree-select 的 control 部件 background-color 覆盖槽。 |
--xh-tree-select-control-bg-hover | control | background-color | disabledhoverinvalidloadingnot([data-disabled])not([data-invalid])not([data-loading])not([data-readonly])readonlyxh-field-chrome | --xh-_field-variant-bg-hover | tree-select 的 control 部件 background-color 覆盖槽。 |
--xh-tree-select-control-bg-readonly | control | background-color | readonlyxh-field-chrome | --xh-_field-variant-bg-read-only | tree-select 的 control 部件 background-color 覆盖槽。 |
--xh-tree-select-control-border | control | border | xh-field-chrome | --xh-_field-variant-border-rest | tree-select 的 control 部件 border 覆盖槽。 |
--xh-tree-select-control-border-focus | control | border-color | disabledfocus-withinnot([data-disabled])xh-field-chrome | --xh-_field-variant-border-focus | tree-select 的 control 部件 border-color 覆盖槽。 |
--xh-tree-select-control-border-hover | control | border-color | disabledhoverinvalidloadingnot([data-disabled])not([data-invalid])not([data-loading])not([data-readonly])readonlyxh-field-chrome | --xh-_field-variant-border-hover | tree-select 的 control 部件 border-color 覆盖槽。 |
--xh-tree-select-control-border-invalid | control | border-color | invalidxh-field-chrome | --xh-_field-variant-border-invalid | tree-select 的 control 部件 border-color 覆盖槽。 |
--xh-tree-select-control-fg | control | color | xh-field-chrome | --xh-fg-default | tree-select 的 control 部件 color 覆盖槽。 |
--xh-tree-select-control-gap | control | gap | xh-field-chrome | --xh-_tree-select-gap | tree-select 的 control 部件 gap 覆盖槽。 |
--xh-tree-select-control-h | control | block-sizemin-block-size | has([data-xh-field-input][data-xh-field-layout='multi-tag'])has([data-xh-field-input][data-xh-field-layout='single-line'])has([data-xh-field-input][data-xh-field-layout='textarea'])xh-field-chromexh-field-inputxh-field-layout=multi-tagxh-field-layout=single-linexh-field-layout=textarea | --xh-_tree-select-h | tree-select 的 control 部件 block-size、min-block-size 覆盖槽。 |
--xh-tree-select-control-min-w | controlroot | min-inline-size | defaultxh-field-chrome | --xh-control-min-w | tree-select 的 control、root 部件 min-inline-size 覆盖槽。 |
--xh-tree-select-control-px | control | padding-inline | xh-field-chrome | --xh-_tree-select-px | tree-select 的 control 部件 padding-inline 覆盖槽。 |
--xh-tree-select-control-radius | control | border-radius | xh-field-chrome | --xh-shape-control | tree-select 的 control 部件 border-radius 覆盖槽。 |
--xh-tree-select-control-shadow | control | box-shadow | xh-field-chrome | none | tree-select 的 control 部件 box-shadow 覆盖槽。 |
--xh-tree-select-control-w | root | inline-sizemin-inline-size | default | --xh-control-w | tree-select 的 root 部件 inline-size、min-inline-size 覆盖槽。 |
--xh-tree-select-empty-fg | empty | color | default | --xh-material-frosted-fg-muted | tree-select 的 empty 部件 color 覆盖槽。 |
--xh-tree-select-empty-font-size | empty | font-size | default | --xh-_tree-select-font-size | tree-select 的 empty 部件 font-size 覆盖槽。 |
--xh-tree-select-empty-px | empty | padding-inline | default | --xh-_tree-select-row-px | tree-select 的 empty 部件 padding-inline 覆盖槽。 |
--xh-tree-select-empty-py | empty | padding-block | default | --xh-space-3 | tree-select 的 empty 部件 padding-block 覆盖槽。 |
--xh-tree-select-footer-border | footer | border-block-start | default | --xh-material-frosted-separator | tree-select 的 footer 部件 border-block-start 覆盖槽。 |
--xh-tree-select-footer-fg | footer | color | default | --xh-material-frosted-fg-muted | tree-select 的 footer 部件 color 覆盖槽。 |
--xh-tree-select-footer-font-size | footer | font-size | default | --xh-text-secondary-size | tree-select 的 footer 部件 font-size 覆盖槽。 |
--xh-tree-select-footer-gap | footer | gap | default | --xh-space-2 | tree-select 的 footer 部件 gap 覆盖槽。 |
--xh-tree-select-footer-px | footer | padding-inline | default | --xh-space-2 | tree-select 的 footer 部件 padding-inline 覆盖槽。 |
--xh-tree-select-footer-py | footer | padding-block | default | --xh-space-2 | tree-select 的 footer 部件 padding-block 覆盖槽。 |
--xh-tree-select-gap | root | gap | default | --xh-space-1 | tree-select 的 root 部件 gap 覆盖槽。 |
--xh-tree-select-icon-size | branch-controlcontrolitempositionerroot | --xh-icon-size | defaultis([data-part='root'], [data-part='positioner'])size=lgsize=smxh-field-chrome | --xh-_collection-glyph-size--xh-_field-size-glyph-size--xh-glyph-size-lg--xh-glyph-size-md--xh-glyph-size-sm | tree-select 的 branch-control、control、item、positioner、root 部件 --xh-icon-size 覆盖槽。 |
--xh-tree-select-indent | branch-content | padding-inline-start | default | --xh-space-4 | tree-select 的 branch-content 部件 padding-inline-start 覆盖槽。 |
--xh-tree-select-indicator-fg | indicator | color | default | --xh-fg-muted | tree-select 的 indicator 部件 color 覆盖槽。 |
--xh-tree-select-item-bg-hover | branchbranch-controlitem | background-color | disablederrorfocus-visiblehighlightedhoveris(:focus-visible, [data-highlighted])is(:hover, [data-highlighted])is([aria-selected='true'], [data-selected])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])not([data-disabled])selectedxh-collection-context=overlay | --xh-bg-subtle | tree-select 的 branch、branch-control、item 部件 background-color 覆盖槽。 |
--xh-tree-select-item-bg-pressed | branch-controlitem | background-color | disablederroris(:active, [data-pressed])is([aria-selected='true'], [data-selected])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])not([data-disabled])pressedselectedxh-collection-context=overlay | --xh-bg-subtle-hover | tree-select 的 branch-control、item 部件 background-color 覆盖槽。 |
--xh-tree-select-item-check-fg | branch-controlitem | color | disablederrorhighlightedhoveris(:active, [data-pressed])is(:focus-visible, [data-highlighted])is([aria-selected='true'], [data-selected])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedselectedstate=checkedxh-collection-context=overlayxh-collection-slot=indicator | --xh-tree-select-item-indicator-fg | tree-select 的 branch-control、item 部件 color 覆盖槽。 |
--xh-tree-select-item-fg | branch-controlitem | color | defaultdisablederrorhighlightedhoveris(:active, [data-pressed])is(:focus-visible, [data-highlighted])is([aria-selected='true'], [data-selected])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedselectedxh-collection-context=overlay | --xh-material-frosted-fg | tree-select 的 branch-control、item 部件 color 覆盖槽。 |
--xh-tree-select-item-fg-selected | branch-controlitem | color | disablederrorhighlightedhoveris(:active, [data-pressed])is(:focus-visible, [data-highlighted])is([aria-selected='true'], [data-selected])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedselectedxh-collection-context=overlay | --xh-tree-select-item-fg | tree-select 的 branch-control、item 部件 color 覆盖槽。 |
--xh-tree-select-item-font-size | branch-controlitem | font-size | default | --xh-_tree-select-font-size | tree-select 的 branch-control、item 部件 font-size 覆盖槽。 |
--xh-tree-select-item-font-weight-selected | branch-controlitem | font-weight | disablederrorhighlightedhoveris(:active, [data-pressed])is(:focus-visible, [data-highlighted])is([aria-selected='true'], [data-selected])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedselectedxh-collection-context=overlay | --xh-font-weight-regular | tree-select 的 branch-control、item 部件 font-weight 覆盖槽。 |
--xh-tree-select-item-gap | branch-controlitem | margin-inline-endmargin-inline-start | defaultxh-collection-slot=indicatorxh-collection-slot=prefixxh-collection-slot=shortcutxh-collection-slot=suffix | --xh-_tree-select-gap | tree-select 的 branch-control、item 部件 margin-inline-end、margin-inline-start 覆盖槽。 |
--xh-tree-select-item-indicator-fg | branch-controlitem | color | disablederrorhighlightedhoveris(:active, [data-pressed])is(:focus-visible, [data-highlighted])is([aria-selected='true'], [data-selected])not([aria-disabled='true'], [data-disabled], [aria-busy='true'], [data-error])pressedselectedstate=checkedxh-collection-context=overlayxh-collection-slot=indicator | --xh-_tree-select-accent | tree-select 的 branch-control、item 部件 color 覆盖槽。 |
--xh-tree-select-item-indicator-size | item-indicator | --xh-icon-sizeblock-sizeinline-size | default | --xh-control-indicator-size | tree-select 的 item-indicator 部件 --xh-icon-size、block-size、inline-size 覆盖槽。 |
--xh-tree-select-item-leading | branch-controlitem | line-height | default | --xh-leading-normal | tree-select 的 branch-control、item 部件 line-height 覆盖槽。 |
--xh-tree-select-item-px | branch-controlitem | padding-inline | default | --xh-_tree-select-row-px | tree-select 的 branch-control、item 部件 padding-inline 覆盖槽。 |
--xh-tree-select-item-py | branch-controlitem | padding-block | default | --xh-_tree-select-row-py | tree-select 的 branch-control、item 部件 padding-block 覆盖槽。 |
--xh-tree-select-item-radius | branch-controlitem | border-radius | default | --xh-shape-control | tree-select 的 branch-control、item 部件 border-radius 覆盖槽。 |
--xh-tree-select-label-fg | label | color | default | --xh-fg-default | tree-select 的 label 部件 color 覆盖槽。 |
--xh-tree-select-label-font-size | label | font-size | default | --xh-text-label-size | tree-select 的 label 部件 font-size 覆盖槽。 |
--xh-tree-select-label-font-weight | label | font-weight | default | --xh-text-label-weight | tree-select 的 label 部件 font-weight 覆盖槽。 |
--xh-tree-select-layer | positioner | z-index | default | --xh-_layer | tree-select 的 positioner 部件 z-index 覆盖槽。 |
--xh-tree-select-loading-fg | loading | color | default | --xh-material-frosted-fg-muted | tree-select 的 loading 部件 color 覆盖槽。 |
--xh-tree-select-loading-font-size | loading | font-size | default | --xh-_tree-select-font-size | tree-select 的 loading 部件 font-size 覆盖槽。 |
--xh-tree-select-loading-px | loading | padding-inline | default | --xh-_tree-select-row-px | tree-select 的 loading 部件 padding-inline 覆盖槽。 |
--xh-tree-select-loading-py | loading | padding-block | default | --xh-space-3 | tree-select 的 loading 部件 padding-block 覆盖槽。 |
--xh-tree-select-placeholder-fg | value-text | color | placeholder | --xh-fg-subtle | tree-select 的 value-text 部件 color 覆盖槽。 |
--xh-tree-select-tree-gap | tree | gap | default | --xh-list-option-gap | tree-select 的 tree 部件 gap 覆盖槽。 |
--xh-tree-select-trigger-fg | trigger | color | default | --xh-fg-default | tree-select 的 trigger 部件 color 覆盖槽。 |
--xh-tree-select-trigger-font-size | trigger | font-size | default | --xh-_tree-select-font-size | tree-select 的 trigger 部件 font-size 覆盖槽。 |
--xh-tree-select-trigger-gap | trigger | gap | default | --xh-_tree-select-gap | tree-select 的 trigger 部件 gap 覆盖槽。 |
--xh-tree-select-value-leading | value-text | line-height | default | --xh-leading-normal | tree-select 的 value-text 部件 line-height 覆盖槽。 |
动效
动效角色:按压 · 状态 · 切换 · 出现(锚定列表)(见动效规范)。
共享关键帧 xh-overlay-slide-in · xh-overlay-slide-out 由 family/motion.css 提供,皮肤 @import 它,单独引入仍成立;rotate 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。
皮肤之外还有一段:退场由适配器的退场闸门把关,动画播完才真收起。
系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。
RTL
皮肤用逻辑属性排布(inline-start 一族),dir="rtl" 下自动镜像;另有按 dir 分支的规则。
