Vitral 0.2
Layout

Splitter

Panels with a gutter between each pair that resizes them, by dragging or from the keyboard, within each panel's minimum.

Import

main.ts
import { Splitter } from '@vitral/vue';

Horizontal

Three panels, each with min-size 10. The panels show their own size, from the resize event.

25%
50%
25%
resizeend: —
<script setup lang="ts">import { Splitter, SplitterPanel, type SplitterResizeEvent } from '@vitral/vue';import { ref } from 'vue'; const sizes = ref([25, 50, 25]);const ended = ref<number[] | null>(null);const show = (value: number | undefined) => `${Math.round(value ?? 0)}%`;const onResize = (event: SplitterResizeEvent) => (sizes.value = event.sizes);</script> <template>    <Splitter class="demo-splitter" @resize="onResize" @resizeend="ended = $event.sizes">        <SplitterPanel :size="25" :min-size="10"><div class="cell c1">{{ show(sizes[0]) }}</div></SplitterPanel>        <SplitterPanel :size="50" :min-size="10"><div class="cell c2">{{ show(sizes[1]) }}</div></SplitterPanel>        <SplitterPanel :size="25" :min-size="10"><div class="cell c3">{{ show(sizes[2]) }}</div></SplitterPanel>    </Splitter>    <small style="color: var(--vt-text-muted-color)">resizeend: {{ ended ? ended.map((s) => show(s)).join(' · ') : '—' }}</small></template> <style scoped>.demo-splitter {    width: 100%;    height: 12rem;} .cell {    --c: var(--vt-chart-1);    display: flex;    align-items: center;    justify-content: center;    height: 100%;    font-size: 0.8125rem;    font-weight: 600;    color: var(--vt-text-color);    background: color-mix(in srgb, var(--c) 14%, transparent);} .c1 {    --c: var(--vt-chart-1);}.c2 {    --c: var(--vt-chart-2);}.c3 {    --c: var(--vt-chart-3);}</style>

Vertical

layout="vertical" stacks the panels; the arrow keys are Up and Down.

top
bottom (min-size 20)
<script setup lang="ts">import { Splitter, SplitterPanel } from '@vitral/vue';</script> <template>    <Splitter class="demo-splitter" layout="vertical" :gutter-size="6">        <SplitterPanel :size="40"><div class="cell c4">top</div></SplitterPanel>        <SplitterPanel :min-size="20"><div class="cell c5">bottom (min-size 20)</div></SplitterPanel>    </Splitter></template> <style scoped>.demo-splitter {    width: 100%;    height: 18rem;} .cell {    --c: var(--vt-chart-1);    display: flex;    align-items: center;    justify-content: center;    height: 100%;    font-size: 0.8125rem;    font-weight: 600;    color: var(--vt-text-color);    background: color-mix(in srgb, var(--c) 14%, transparent);} .c4 {    --c: var(--vt-chart-4);}.c5 {    --c: var(--vt-chart-5);}</style>

Nested

A splitter inside a panel fills it: an explorer beside an editor over a terminal.

explorer
editor
terminal
<script setup lang="ts">import { Splitter, SplitterPanel } from '@vitral/vue';</script> <template>    <Splitter class="demo-splitter">        <SplitterPanel :size="28" :min-size="15"><div class="cell c2">explorer</div></SplitterPanel>        <SplitterPanel>            <Splitter layout="vertical">                <SplitterPanel :size="65"><div class="cell c1">editor</div></SplitterPanel>                <SplitterPanel><div class="cell c3">terminal</div></SplitterPanel>            </Splitter>        </SplitterPanel>    </Splitter></template> <style scoped>.demo-splitter {    width: 100%;    height: 18rem;} .cell {    --c: var(--vt-chart-1);    display: flex;    align-items: center;    justify-content: center;    height: 100%;    font-size: 0.8125rem;    font-weight: 600;    color: var(--vt-text-color);    background: color-mix(in srgb, var(--c) 14%, transparent);} .c1 {    --c: var(--vt-chart-1);}.c2 {    --c: var(--vt-chart-2);}.c3 {    --c: var(--vt-chart-3);}</style>

API

Read from packages/vue/src/components/Splitter/types.ts, so it says what the component actually accepts.

Props

NameTypeDescription
layout'horizontal' | 'vertical'`horizontal` (the default) puts panels side by side; `vertical` stacks them and needs a height.
gutterSizenumberGutter thickness in pixels. Defaults to the `splitter.gutter.size` token.
stepnumberPercentage points an arrow key moves a gutter.
asstring | Component—

Plus pt, dt and unstyled from BaseProps, see pass-through and unstyled mode.

Emits

EventPayloadDescription
resizestartevent: SplitterResizeEvent—
resizeevent: SplitterResizeEvent—
resizeendevent: SplitterResizeEvent—

Slots

NameSlot propsDescription
default—`SplitterPanel`s; anything else is left out.