跳转到内容

Splitter 分栏 ​

将内容区域拆分为可调整大小的面板。

用法 ​

调整侧栏和编辑区域的比例

组件结构 ​

加粗的是必需部件。

data-scope="splitter":root · panel · resize-trigger

示例 ​

垂直与折叠 ​

垂直调整并折叠面板

禁用 ​

禁止调整面板比例

嵌套分栏 ​

组合水平和垂直面板

设计指引 ​

何时使用 ​

  • 构建编辑器、文件管理器或预览界面。
  • 保存用户调整后的面板比例。

何时不用 ​

特性 ​

  • 支持水平、垂直和嵌套分栏。
  • 支持最小/最大尺寸和面板折叠。
  • 支持方向键、Shift、Enter 和 Escape。
  • 调整中和调整结束分别提供回调。

组合 ​

最佳实践 ​

  • 为每个面板设置合理的最小尺寸。
  • 使用 onSizesChangeEnd 保存最终布局。

反模式 ​

  • 不要用于固定比例布局。
  • 不要缩小分隔条的交互区域。

API 参考 ​

产物 ​

层值
自定义元素<xh-splitter>
Vue 组件XhSplitterPanel XhSplitterResizeTrigger XhSplitterRoot
组合式函数useSplitter
状态机splitterMachine
皮肤@xihan-ui/styles/splitter.css

Props ​

属性类型必填说明
sizesnumber[]每块面板的百分比。提供即受控:内部不再自行修改,只发 onSizesChange。
defaultSizesnumber[]非受控初值;未提供时按面板数等分。
panelsSplitterPanelProps[]逐块的约束;数组长度同时决定面板块数。
orientationOrientation面板的排布轴,默认 horizontal(并排,左右拖动);vertical 是上下堆叠,上下拖动。
dirDirection文字方向,默认 ltr;只对调水平排布下的左右两键与指针位移的正负。
disabledboolean禁用:分隔条退出 Tab 序列、不可拖动也不可推动。
stepnumber方向键的步长(百分比),默认 1。
largeStepnumberShift + 方向键的步长(百分比),默认 10。
translationsPartial<SplitterTranslations>
onSizesChange(details: SplitterSizesChangeDetails) => void每次尺寸变化都发出;拖动过程中连续发出。
onSizesChangeEnd(details: SplitterSizesChangeEndDetails) => void只在一次操作结束时发出一次,适合用于保存布局。

SplitterPanelProps ​

panels 的元素。

字段类型必填说明
idstring是作者给该面板起的名字,用于派生它的 DOM id(分隔条的 aria-controls 指向它)。
minnumber百分比下界,默认 0。
maxnumber百分比上界,默认 100。
collapsibleboolean是否允许折叠,默认 false。
collapsedSizenumber折叠后的百分比,默认 0;collapsible 为假时不使用。

事件 ​

自定义元素将载荷放在 detail;Vue 使用同名 emit。

事件载荷说明
sizes-changeSplitterSizesChangeDetails布局变化(拖动途中连续发出);detail 为 { sizes: number[] }
sizes-change-endSplitterSizesChangeEndDetails一次拖拽收尾时发出一次;detail 为 { sizes: number[], index: number }

插槽 ​

仅列出带载荷的插槽。

Vue 组件插槽载荷说明
XhSplitterRootdefaultSplitterRootSlotProps

React 适配器 props ​

只列各组件自己声明的那些:继承自 ComponentPropsWithRef 的 DOM 属性不在其中,根组件上与上面 Props 表同名的也不重复列。Vue 的对应物是上面的插槽表。

React 组件属性类型必填说明
XhSplitterPanelindexnumber | string第几块面板;多块时必须逐个写明。兼收字符串。
XhSplitterResizeTriggerindexnumber | string第几条分隔条;它位于第 index 与第 index+1 块面板之间,调整的是前一块。兼收字符串。
XhSplitterRootchildrenSlotChildren<SplitterRootSlotProps>

状态 ​

以下名称仅用于内部状态机。

状态: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 · DRAG.CANCEL

判据:canResize

connect API ​

getXxxProps() 返回对应部件的宿主属性。

成员类型说明
sizesnumber[]
panelsSplitterPanelState[]
draggingboolean
disabledboolean
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 / ArrowDownfocus in resize-trigger, not disabled把这条分隔条前面那块面板按 step(默认 1%)撑大;水平排布认左右键、竖直排布认上下键,另一条轴上的方向键原样放行
ArrowLeft / ArrowUpfocus in resize-trigger, not disabled按 step 压小,同上的轴向规则;rtl 下左右两键对调,语义恒是"撑大 / 压小前一块"
Shift+ArrowRight / Shift+ArrowDownfocus in resize-trigger, not disabled按 largeStep(默认 10%)撑大
Shift+ArrowLeft / Shift+ArrowUpfocus in resize-trigger, not disabled按 largeStep 压小
Homefocus in resize-trigger, not disabled把前一块面板收到它眼下能到的最小尺寸
Endfocus in resize-trigger, not disabled把前一块面板撑到它眼下能到的最大尺寸
Escape拖动中放弃这一场拖拽,布局退回按下那一刻;收尾回调不发
Enterfocus in resize-trigger 且它调整的面板 collapsible,not disabled折叠 / 展开该面板;展开回到折叠前的尺寸。面板不可折叠时不接这个键

ARIA ​

以下属性由 connect 生成。

部件属性值
rootaria-labeltranslations?.root
rootrole'group'
resize-triggeraria-controlspanel 部件的 id
resize-triggeraria-disabled'true' | 'false'
resize-triggeraria-labeltranslations?.resizeTrigger?.(boundary, Math.max(0, l…
resize-triggeraria-orientation'horizontal' | 'vertical'
resize-triggeraria-valuemaxString(panel.max)
resize-triggeraria-valueminString(panel.min)
resize-triggeraria-valuenowString(panel.size)
resize-triggerrole'separator'

样式参考 ​

皮肤 ​

@xihan-ui/styles/splitter.css 使用 [data-scope="splitter"][data-part="root"] 部件选择器,位于 xihan.components 层。覆盖样式使用 xihan.overrides。

forced-colors: active 下另有一套规则:颜色交给系统,边框与状态标记改用系统色关键字。

数据属性 ​

由 connect 生成;条件不成立时不输出无值属性。

部件属性值
rootdata-disabled''(条件成立时才出现)
rootdata-dragging''(条件成立时才出现)
rootdata-orientationprops.orientation
paneldata-collapsed''(条件成立时才出现)
paneldata-disabled''(条件成立时才出现)
paneldata-dragging''(条件成立时才出现)
paneldata-indexString(panel.index)
paneldata-orientationprops.orientation
resize-triggerdata-disabled''(条件成立时才出现)
resize-triggerdata-dragging''(条件成立时才出现)
resize-triggerdata-indexString(boundary)
resize-triggerdata-orientationprops.orientation

CSS 变量 ​

本组件公开覆盖槽由独立皮肤的实际消费位生成;默认来源、作用部件和状态均与 CSS 同源。

变量部件CSS 属性状态默认来源说明
--xh-splitter-disabled-opacityrootopacitydisabled0.6splitter 的 root 部件 opacity 覆盖槽。
--xh-splitter-radiusrootborder-radiusdefault--xh-shape-surfacesplitter 的 root 部件 border-radius 覆盖槽。
--xh-splitter-trigger-bgresize-triggerbackgrounddefault--xh-border-defaultsplitter 的 resize-trigger 部件 background 覆盖槽。
--xh-splitter-trigger-bg-disabledresize-triggerbackgrounddisabled--xh-border-subtlesplitter 的 resize-trigger 部件 background 覆盖槽。
--xh-splitter-trigger-bg-draggingresize-triggerbackgrounddragging--xh-bg-brandsplitter 的 resize-trigger 部件 background 覆盖槽。
--xh-splitter-trigger-bg-hoverresize-triggerbackgroundhover--xh-border-controlsplitter 的 resize-trigger 部件 background 覆盖槽。
--xh-splitter-trigger-thicknessresize-triggerblock-size
inline-size
orientation=horizontal
orientation=vertical
--xh-space-1splitter 的 resize-trigger 部件 block-size、inline-size 覆盖槽。

动效 ​

动效角色:状态(见动效规范)。

background-color 走 transition 过渡。时长与缓动读动效令牌,改令牌即改全局节奏。

系统开启减弱动效时由令牌层统一收敛,皮肤不另作判断。

Released under The MIT License