分栏 splitter
数据展示组件。三层同源:无头内核给出解剖与状态机,Vue 组件与自定义元素只是它的两层外壳,行为完全一致。
示例
基础用法
panels 数组的长度决定面板块数,每条分隔条调的是它前面那一块
侧栏:min 20% / max 60%,拖到底也留得住 20%。
正文:min 25%,侧栏再撑也吃不掉它这一份。
受控
传了 sizes 就由宿主说了算;sizes-change 拖动途中连着发,sizes-change-end 松手才发一次
侧栏
正文
竖排与折叠
orientation 换轴后方向键跟着换,collapsible 的面板在它的分隔条上按 Enter 折叠
顶栏:min 10%,不可折叠。
中间这栏可折叠:焦点落到它下面那条分隔条上按 Enter 折叠,再按一次回到折叠前的尺寸。
底栏:min 10%。
禁用
disabled 后拖不动也推不动,分隔条整个退出 Tab 序列,方向键放行给页面
侧栏
正文
嵌套
面板里再放一套分栏即可拆出第二根轴,里外两层各管各的尺寸,互不干涉
侧栏
编辑区
输出区
分隔条里放内容
分隔条的默认插槽收作者写的把手,粗细由 --xh-splitter-trigger-thickness 让出位置
列表
详情
产物
| 层 | 值 |
|---|---|
| 自定义元素 | <xh-splitter> |
| Vue 组件 | XhSplitterPanel XhSplitterResizeTrigger XhSplitterRoot |
| 组合式函数 | useSplitter |
| 状态机 | splitterMachine |
| 皮肤 | @xihan-ui/styles/splitter.css |
解剖
部件名即 data-part 属性值,也是皮肤的选择器。加粗的是必备部件,不渲染它组件不工作(Web Components 适配器会在诊断通道上报 wc.missing-part)。
data-scope="splitter":root · panel · resize-trigger
Props
| 属性 | 类型 | 必填 | 说明 |
|---|---|---|---|
sizes | number[] | 每块面板的百分比。给定即受控:内部不再自改,只发 onSizesChange。 | |
defaultSizes | number[] | 非受控初值;不给就按面板数等分。 | |
panels | SplitterPanelProps[] | 逐块的约束;数组长度同时决定面板块数。 | |
orientation | Orientation | 面板的排布轴,默认 horizontal(并排,拖左右);vertical 是上下堆叠,拖上下。 | |
dir | Direction | 文字方向,默认 ltr;只对调水平排布下的左右两键与指针位移的正负。 | |
disabled | boolean | 禁用:分隔条退出 Tab 序列、拖不动也推不动。 | |
step | number | 方向键的步长(百分比),默认 1。 | |
largeStep | number | Shift + 方向键的步长(百分比),默认 10。 | |
onSizesChange | (details: SplitterSizesChangeDetails) => void | 每次尺寸变化都发;拖动过程中会连续发很多次。 | |
onSizesChangeEnd | (details: SplitterSizesChangeEndDetails) => void | 只在一次操作结束时发一次,适合拿来存布局。 |
状态机
状态:idle · dragging
事件:SIZES.SET · BOUNDARY.STEP · BOUNDARY.TO_MIN · BOUNDARY.TO_MAX · BOUNDARY.SET · BOUNDARY.FOCUS · PANEL.COLLAPSE · PANEL.EXPAND · DRAG.START · DRAG.MOVE · DRAG.END
判据:canResize
connect API
useSplitter 产出的对象。getXxxProps() 铺到对应部件的宿主元素上,其余是可读状态与操作入口。
| 成员 | 类型 | 说明 |
|---|---|---|
sizes | number[] | |
panels | SplitterPanelState[] | |
dragging | boolean | |
disabled | boolean | |
setSizes | (next: number[]) => void | 整份赋值:逐块夹进约束、总和归位到 100 之后才落地。 |
setPanelSize | (index: number, next: number) => void | 把第 index 块调到 next,缺的那部分从它后面的面板里取。 最后一块没有属于自己的分隔条,它的尺寸是其余面板的余数,调不动。 |
collapsePanel | (index: number) => void | |
expandPanel | (index: number) => void | |
togglePanel | (index: number) => void | 折叠着就展开、展开着就折叠;不可折叠的面板上是空操作。 |
getRootProps | () => T['element'] | |
getPanelProps | (index: number) => T['element'] | |
getResizeTriggerProps | (index: number) => T['element'] | 第 index 条分隔条坐在第 index 与第 index+1 块面板之间,调整的是前一块。 |
键盘
规格出处:W3C APG
| 按键 | 生效条件 | 行为 |
|---|---|---|
ArrowRight / ArrowDown | focus in resize-trigger, not disabled | 把这条分隔条前面那块面板按 step(默认 1%)撑大;水平排布认左右键、竖直排布认上下键,另一条轴上的方向键原样放行 |
ArrowLeft / ArrowUp | focus in resize-trigger, not disabled | 按 step 压小,同上的轴向规则;rtl 下左右两键对调,语义恒是"撑大 / 压小前一块" |
Shift+ArrowRight / Shift+ArrowDown | focus in resize-trigger, not disabled | 按 largeStep(默认 10%)撑大 |
Shift+ArrowLeft / Shift+ArrowUp | focus in resize-trigger, not disabled | 按 largeStep 压小 |
Home | focus in resize-trigger, not disabled | 把前一块面板收到它眼下能到的最小尺寸 |
End | focus in resize-trigger, not disabled | 把前一块面板撑到它眼下能到的最大尺寸 |
Enter | focus in resize-trigger 且它调整的面板 collapsible,not disabled | 折叠 / 展开该面板;展开回到折叠前的尺寸。面板不可折叠时不接这个键 |
