Lzh on GitHub

Splitter

将您的布局划分为可调整大小的部分的组件。
<script setup lang="ts">
import { SplitterGroup, SplitterPanel, SplitterResizeHandle } from 'reka-ui'
</script>

<template>
  <div class="w-full h-64 px-8 md:px-16 text-green9 font-semibold text-sm">
    <SplitterGroup
      id="splitter-group-1"
      direction="horizontal"
    >
      <SplitterPanel
        id="splitter-group-1-panel-1"
        :min-size="20"
        class="bg-white border rounded-xl flex items-center justify-center"
      >
        Panel A
      </SplitterPanel>
      <SplitterResizeHandle
        id="splitter-group-1-resize-handle-1"
        class="w-2"
      />
      <SplitterPanel
        id="splitter-group-1-panel-2"
        :min-size="20"
      >
        <SplitterGroup
          id="splitter-group-2"
          direction="vertical"
        >
          <SplitterPanel
            id="splitter-group-2-panel-1"
            :min-size="20"
            class="bg-white border rounded-xl flex items-center justify-center"
          >
            Panel B
          </SplitterPanel>
          <SplitterResizeHandle
            id="splitter-group-2-resize-handle-1"
            class="h-2"
          />
          <SplitterPanel
            id="splitter-group-2-panel-2"
            :min-size="20"
            class="bg-white border rounded-xl flex items-center justify-center"
          >
            Panel C
          </SplitterPanel>
        </SplitterGroup>
      </SplitterPanel>
    </SplitterGroup>
  </div>
</template>

功能特点

  • 支持键盘交互。
  • 支持水平/垂直布局。
  • 支持嵌套布局。
  • 支持从右到左的方向。
  • 可以跨另一个面板调整大小。
  • 可以有条件地挂载。

安装

从命令行安装组件。

$ npm add reka-ui

结构

导入所有部分并将其组合在一起。

<script setup>
  import { SplitterGroup, SplitterPanel, SplitterResizeHandle } from 'reka-ui'
</script>

<template>
  <SplitterGroup>
    <SplitterPanel />
    <SplitterResizeHandle />
  </SplitterGroup>
</template>

API 参考

Group

包含 Splitter 的所有部分。

属性默认值类型描述
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
autoSaveIdnullstring | null用于通过 localStorage 自动保存组排列的唯一 ID。
direction*'vertical' | 'horizontal'分割器组的方向。
idnullstring | null组 ID;未提供时回退到 useId
keyboardResizeBy10number | null按下箭头键时的步长。
storagedefaultStoragePanelGroupStorage自定义存储 API;默认为 localStorage

触发事件 (Emit)

事件名称Payload描述
layout[val: number[]]组布局更改时调用的事件处理程序。

默认插槽

插槽参数插槽参数类型描述
layoutnumber[]当前布局大小

数据属性

属性
[data-orientation]"vertical" | "horizontal"
[data-state]"collapsed" | "expanded" | "Present when collapsbile"

Panel

一个可折叠部分。

属性默认值类型描述
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
collapsedSizenumber面板折叠时的大小。
collapsiblefalseboolean当调整大小超出其 minSize 时,面板是否应折叠。当为 true 时,它将折叠到 collapsedSize
defaultSizenumber面板的初始大小(1-100 之间的数字值)。
idstring面板 ID(组内唯一);未提供时回退到 useId
maxSize100number面板的最大允许大小(1-100 之间的数字值);默认为 100
minSize10number面板的最小允许大小(1-100 之间的数字值);默认为 10
ordernumber面板在组中的顺序;对于有条件渲染面板的组是必需的。

触发事件 (Emit)

事件名称Payload描述
collapse[]面板折叠时调用的事件处理程序。
expand[]面板展开时调用的事件处理程序。
resize[size: number, prevSize: number]面板调整大小时调用的事件处理程序;size 参数是 1-100 之间的数字值。

默认插槽

插槽参数插槽参数类型描述
isCollapsedboolean面板是否已折叠
isExpandedboolean面板是否已展开
collapse(): void如果面板可折叠,则完全折叠它。
expand(): void如果面板当前已折叠,则将其展开到最近的大小。
resize(size: number): void将面板调整为指定百分比(1 - 100)。

方法

方法名称类型描述
collapse() => void如果面板可折叠,则完全折叠它。
expand() => void如果面板当前已折叠,则将其展开到最近的大小。
getSize() => number获取面板当前大小的百分比(1 - 100)。
resize(size: number) => void将面板调整为指定百分比(1 - 100)。

Resize Handle

用于调整大小的把手。

属性默认值类型描述
as'div'AsTag | Component此组件应渲染为的元素或组件。可以通过 asChild 覆盖。
asChildfalseboolean将默认渲染的元素更改为作为子元素传递的元素,合并它们的 props 和行为。有关详细信息,请阅读我们的组合指南
disabledfalseboolean禁用拖动把手。
hitAreaMarginsPointerHitAreaMargins确定可调整大小把手命中检测时允许的边距。
idstring调整大小把手 ID(组内唯一);未提供时回退到 useId
noncestring将为 style 标签添加 nonce 属性,可用于内容安全策略(CSP)。
如果未设置,则会从全局的 ConfigProvider 继承。
tabindex0number把手的 Tab 索引。

触发事件 (Emit)

事件名称Payload描述
dragging[isDragging: boolean]拖动处理程序时调用的事件处理程序。

数据属性

属性
[data-state]"drag" | "hover" | "inactive"
[data-disabled]禁用时存在
[data-orientation]"vertical" | "horizontal"

示例

可折叠

使用 collapsible prop 允许面板在达到 minSize 时折叠到 collapsedSize。(collapsedSizeminSize prop 是必需的。)

<template>
  <SplitterGroup>
    <SplitterPanel
      collapsible
      :collapsed-size="10"
      :min-size="35"
    >
      Panel A
    </SplitterPanel>
    <SplitterResizeHandle />
    <SplitterPanel>
      Panel B
    </SplitterPanel>
  </SplitterGroup>
</template>

持久化到 localStorage

使用 autoSaveId prop 将布局数据保存到 localStorage

<template>
  <SplitterGroup auto-save-id="any-id">
  </SplitterGroup>
</template>

SSR 持久化布局

默认情况下,Splitter 使用 localStorage 来持久化布局。在服务器渲染中,当默认布局(在服务器上渲染)被持久化布局(在 localStorage 中)替换时,这可能会导致闪烁。避免这种闪烁的方法是也通过 cookie 持久化布局,如下所示:

<!-- with Nuxt -->
<script setup lang="ts">
  const layout = useCookie<number[]>('splitter:layout')
</script>

<template>
  <SplitterGroup
    direction="horizontal"
    @layout="layout = $event"
  >
    <SplitterPanel :default-size="layout[0]">
    </SplitterPanel>
    <SplitterResizeHandle />
    <SplitterPanel :default-size="layout[1]">
    </SplitterPanel>
  </SplitterGroup>
</template>

程序化折叠/展开

有时面板需要响应用户操作来调整大小或折叠/展开。SplitterPanel 暴露了 collapseexpand 方法来实现这一点。

<script setup lang="ts">
  const panelRef = ref<InstanceType<typeof SplitterPanel>>()
</script>

<template>
  <button
    @click="panelRef?.isCollapsed ? panelRef?.expand() : panelRef?.collapse() "
  >
    {{ panelRef?.isCollapsed ? 'Expand' : 'Collapse' }}
  </button>
  <SplitterGroup>
    <SplitterPanel
      ref="panelRef"
      collapsible
      :collapsed-size="10"
      :min-size="35"
    >
    </SplitterPanel>
    <SplitterResizeHandle />
    <SplitterPanel>
    </SplitterPanel>
  </SplitterGroup>
</template>

自定义把手

通过将任何元素作为插槽传递来定制把手。

<template>
  <SplitterGroup>
    <SplitterPanel>
    </SplitterPanel>
    <SplitterResizeHandle>
      <Icon icon="radix-icons-drag-handle-dots-2" />
    </SplitterResizeHandle>
    <SplitterPanel>
    </SplitterPanel>
  </SplitterGroup>
</template>

SSR

Splitter 组件严重依赖唯一的 id,然而对于 Vue < 3.4,我们没有可靠的方法来生成 SSR-friendlyid

因此,如果您正在使用 Nuxt 或其他 SSR 框架,则需要手动为所有 Splitter 组件添加 id。或者,您可以使用 <ClientOnly> 包装组件。

<template>
  <SplitterGroup id="group-1">
    <SplitterPanel id="group-1-panel-1">
    </SplitterPanel>
    <SplitterResizeHandle id="group-1-resize-1">
      <Icon icon="radix-icons-drag-handle-dots-2" />
    </SplitterResizeHandle>
    <SplitterPanel id="group-1-panel-2">
    </SplitterPanel>
  </SplitterGroup>
</template>

可访问性

遵循 Window Splitter WAI-ARIA 设计模式

键盘交互

按键描述
Enter如果主窗格未折叠,则折叠窗格。如果窗格已折叠,则将分割器恢复到其先前的位置。
ArrowDown将水平分割器向下移动。
ArrowUp将水平分割器向上移动。
ArrowRight将垂直分割器向右移动。
ArrowLeft将垂直分割器向左移动。
Home将分割器移动到使主窗格具有其允许的最小大小的位置。
End将分割器移动到使主窗格具有其允许的最大大小的位置。