Usage
Anatomy
The splitter component is rendered as a single Vue component with two slots, one for each panel.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel>
<template #start>
<div class="h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
API Reference
Model
Props
Defaults to
'horizontal'Defaults to
'ltr'Defaults to
'12px'size, minSize, maxSize, and collapseThreshold are configured in percentages (0-100) or pixel values.Defaults to
'%'Defaults to
falseprimary to be set.Defaults to
falseprimary to be set.Defaults to
falseDefaults to
falseDefaults to
0Defaults to
"cubic-bezier(0, 0, 0.2, 1)"Defaults to
"cubic-bezier(0.4, 0, 0.6, 1)"Defaults to
[]Defaults to
12Examples
% / Pixels
By setting sizeUnit to px, the component will use pixel values for minSize, maxSize, and size.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel
size-unit="%"
:min-size="20"
:size="30"
:max-size="40"
>
<template #start>
<div class="h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel
size-unit="px"
:min-size="300"
:size="400"
:max-size="500"
>
<template #start>
<div class="h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
Collapsible
By setting collapsible to true, you can allow the primary panel to be collapsed by either dragging the divider the collapseThreshold beyond the minSize or using Enter when focussed on the divider.
Both minSize and collapsibleThreshold have to be defined.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel
collapsible
size-unit="px"
:min-size="250"
:size="350"
:max-size="500"
:collapse-threshold="50"
>
<template #start>
<div class="h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
Collapse / Expand Programmatically
To collapse or expand the primary panel programmatically, you can either use the collapsed model:
<script lang="ts" setup>
import { ref } from 'vue';
import { SplitPanel } from '@directus/vue-split-panel';
const collapsed = ref(false);
</script>
<template>
<SplitPanel v-model:collapsed="collapsed">
<!-- ... -->
</SplitPanel>
</template>
or use the exposed collapse, expand, and toggle functions:
<script lang="ts" setup>
import { useTemplateRef } from 'vue';
import { SplitPanel } from '@directus/vue-split-panel';
const panelComponent = useTemplateRef('panel-component');
// panelComponent.value.expand();
// panelComponent.value.collapse();
// panelComponent.value.toggle();
</script>
<template>
<SplitPanel ref="panel-component">
<!-- ... -->
</SplitPanel>
</template>
Customize Divider
Customize the divider element by passing any element into the divider slot:
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel
collapsible
size-unit="px"
:min-size="200"
:size="350"
:max-size="500"
>
<template #start>
<div class="h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #divider>
<div class="h-full bg-muted hover:bg-primary w-4" />
</template>
<template #end>
<div class="h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
Vertical Split Orientation
The panels can be oriented vertically by setting the orientation prop to "vertical". Make sure to add a height to the parent split component.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel
orientation="vertical"
class="h-128"
>
<template #start>
<div class="w-full h-full bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="w-full h-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
Nested Split Panels
While a SplitPanel only holds two panels at a time, you can nest multiple split panels to create rich layouts.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel primary="start" class="h-128 w-full">
<template #start>
<div class="w-full h-full bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<SplitPanel orientation="vertical" class="h-full">
<template #start>
<div class="w-full h-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
<template #end>
<div class="w-full h-full bg-green-100 dark:bg-green-100 flex items-center justify-center">Panel C</div>
</template>
</SplitPanel>
</template>
</SplitPanel>
</template>
Primary Panel
By setting primary to either start or end, you can make sure that the primary panel doesn't resize when the parent container resizes. This is particularly helpful for layouts where you have a primary sidebar that you'd like to remain a fixed size, with a page view that takes up the remaining space.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel class="w-full" primary="start" :size="350" size-unit="px">
<template #start>
<div class="w-full h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="w-full h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
Transitions
By setting the transitionDuration prop, you can control the duration of the transition. Use the transitionTimingFunctionExpand and transitionTimingFunctionCollapse properties to fine-tune the timing functions of the expand and collapse transition respectively.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel
class="w-full"
collapsible
size-unit="px"
:min-size="250"
:size="350"
:max-size="500"
:collapse-threshold="50"
:transition-duration="150"
>
<template #start>
<div class="h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
Snapping
To snap the divider to a given point while dragging, pass an array of points in the snapPoints property.
<script lang="ts" setup>
import { SplitPanel } from '@directus/vue-split-panel';
</script>
<template>
<SplitPanel class="w-full" :snap-points="[25, 50]">
<template #start>
<div class="h-16 bg-orange-100 dark:bg-orange-900 flex items-center justify-center">Panel A</div>
</template>
<template #end>
<div class="h-16 bg-blue-100 dark:bg-blue-900 flex items-center justify-center">Panel B</div>
</template>
</SplitPanel>
</template>
Accessibility
Uses the Window Splitter WAI-ARIA pattern.
Keyboard Interactions
| Key | Description |
|---|---|
| ENTER | Toggles the collapse state of the primary pane |
| ARROWDOWN | Moves a horizontal panel down |
| ARROWUP | Moves a horizontal panel up |
| ARROWRIGHT | Moves a vertical splitter right |
| ARROWLEFT | Moves a vertical splitter left |
| HOME | Moves the splitter to the configured min-size |
| END | Moves the splitter to the configured max-size |