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
false
primary
to be set.Defaults to
false
primary
to be set.Defaults to
false
Defaults to
false
Defaults to
0
Defaults to
"cubic-bezier(0, 0, 0.2, 1)"
Defaults to
"cubic-bezier(0.4, 0, 0.6, 1)"
Defaults to
[]
Defaults to
12
Examples
% / 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">
<!-- ... -->
</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 |