Getting Started

Usage

All usage options available in Vue Split Panel

Anatomy

The splitter component is rendered as a single Vue component with two slots, one for each panel.

Panel A
Panel B
<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

size
number
The current size of the start panel.
collapsed
boolean
Whether the primary panel is currently collapsed.

Props

orientation
'horizontal' | 'vertical'
Set the rendering orientation.
Defaults to 'horizontal'
direction
'ltr' | 'rtl'
Sets the panels text direction.
Defaults to 'ltr'
primary
'start' | 'end'
If no primary panel is designated, both panels will resize equally.
dividerHitArea
string
A CSS size to define the hitbox area around the divider slot.
Defaults to '12px'
sizeUnit
'%' | 'px'
Whether size, minSize, maxSize, and collapseThreshold are configured in percentages (0-100) or pixel values.
Defaults to '%'
disabled
boolean
Disable the manual resizing/collapsing of the panels.
Defaults to false
minSize
number
Minimum allowed size of the primary panel. Requires primary to be set.
Defaults to false
maxSize
number
Maximum allowed size of the primary panel. Requires primary to be set.
Defaults to false
collapsible
boolean
Whether to allow the primary panel to be collapsed on enter key on divider or when the collapse threshold is met.
Defaults to false
collapseThreshold
number
How far to drag beyond the minSize to collapse/expand the primary panel.
collapsedSize
number
How much of the collapsed panel is visible in its collapsed state.
transitionDuration
number
Duration of the collapse/expand transition in ms.
Defaults to 0
transitionTimingFunctionExpand
string
CSS timing function for the expand transition.
Defaults to "cubic-bezier(0, 0, 0.2, 1)"
transitionTimingFunctionCollapse
string
CSS timing function for the collapse transition.
Defaults to "cubic-bezier(0.4, 0, 0.6, 1)"
snapPoints
number[]
Where to snap the primary panel to during dragging operations.
Defaults to []
snapThreshold
number
How close the divider must be to a snap point for snapping to occur.
Defaults to 12
ui
{ start?: string, divider?: string, end?: string }
Inject additional classes in the slot container elements.

Examples

% / Pixels

By setting sizeUnit to px, the component will use pixel values for minSize, maxSize, and size.

Panel A
Panel B
<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>

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.

Panel A
Panel B
<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:

Panel A
Panel B
<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.

Panel A
Panel B
<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.

Panel A
Panel B
Panel C
<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.

Panel A
Panel B
<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>
Resize your browser window to see primary in action.

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.

Panel A
Panel B
<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.

Panel A
Panel B
<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

KeyDescription
ENTERToggles the collapse state of the primary pane
ARROWDOWNMoves a horizontal panel down
ARROWUPMoves a horizontal panel up
ARROWRIGHTMoves a vertical splitter right
ARROWLEFTMoves a vertical splitter left
HOMEMoves the splitter to the configured min-size
ENDMoves the splitter to the configured max-size
The divider by default has no styling. Please add your own divider element to handle focus styles.