Components
Splitter

Splitter

A component that divides your interface into resizable sections

A
B

Anatomy

To set up the splitter correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Examples

Learn how to use the Splitter component in your project. Let's take a look at the most basic example:

<script setup lang="ts">
import { Splitter } from '@ark-ui/vue/splitter'
</script>

<template>
  <Splitter.Root :panels="[{ id: 'a' }, { id: 'b' }]">
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" aria-label="Resize" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
</template>

Using Render Props

The Splitter component allows you to pass a function as a child to gain direct access to its API. This provides more control and allows you to modify the size of the panels programmatically:

<script setup lang="ts">
import { Splitter } from '@ark-ui/vue/splitter'
</script>

<template>
  <Splitter.Root :panels="[{ id: 'a' }, { id: 'b' }]">
    <Splitter.Context v-slot="splitter">
      <Splitter.Panel id="a">
        <button @click="splitter.resizePanel('a', 10)">Set A to 10%</button>
      </Splitter.Panel>
      <Splitter.ResizeTrigger id="a:b" aria-label="Resize" />
      <Splitter.Panel id="b">
        <button @click="splitter.resizePanel('b', 10)">Set B to 10%</button>
      </Splitter.Panel>
    </Splitter.Context>
  </Splitter.Root>
</template>

Handling Events

Splitter also provides onResizeStart, onResize, and onResizeEnd events which can be useful to perform some actions during the start and end of the resizing process:

<script setup lang="ts">
import { Splitter } from '@ark-ui/vue/splitter'
</script>

<template>
  <Splitter.Root
    :panels="[{ id: 'a' }, { id: 'b' }]"
    @resize="(details) => console.log('onResize', details)"
    @resize-start="() => console.log('onResizeStart')"
    @resize-end="(details) => console.log('onResizeEnd', details)"
    @expand="(details) => console.log('onExpand', details)"
    @collapse="(details) => console.log('onCollapse', details)"
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" aria-label="Resize" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
</template>

Vertical Splitter

By default, the Splitter component is horizontal. If you need a vertical splitter, use the orientation prop:

<script setup lang="ts">
import { Splitter } from '@ark-ui/vue/splitter'
</script>

<template>
  <Splitter.Root orientation="vertical" :panels="[{ id: 'a' }, { id: 'b' }]">
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" aria-label="Resize" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
</template>

Collapsible Panels

To make a panel collapsible, set the collapsible prop to true on the panel you want to make collapsible. Additionally, you can use the collapsedSize prop to set the size of the panel when it's collapsed.

This can be useful for building sidebar layouts.

<script setup lang="ts">
import { Splitter } from '@ark-ui/vue/splitter'
</script>

<template>
  <Splitter.Root
    :default-size="[15, 20]"
    :panels="[
      { id: 'a', collapsible: true, collapsedSize: 5, minSize: 10, maxSize: 20 },
      { id: 'b', minSize: 50 },
    ]"
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" aria-label="Resize" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
</template>

Multiple Panels

Here's an example of how to use the Splitter component with multiple panels.

<script setup lang="ts">
import { Splitter } from '@ark-ui/vue/splitter'
</script>

<template>
  <Splitter.Root
    :panels="[
      { id: 'a', minSize: 20 },
      { id: 'b', minSize: 40 },
      { id: 'c', minSize: 20 },
    ]"
    :default-size="[20, 60, 20]"
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" aria-label="Resize" />
    <Splitter.Panel id="b">B</Splitter.Panel>
    <Splitter.ResizeTrigger id="b:c" aria-label="Resize" />
    <Splitter.Panel id="c">C</Splitter.Panel>
  </Splitter.Root>
</template>

Using the Root Provider

The RootProvider component provides a context for the splitter. It accepts the value of the useSplitter hook. You can leverage it to access the component state and methods from outside the splitter.

<script setup lang="ts">
import { Splitter, useSplitter } from '@ark-ui/vue/splitter'

const splitter = useSplitter({
  defaultSize: [50, 50],
  panels: [{ id: 'a' }, { id: 'b' }],
})
</script>

<template>
  <button @click="splitter.setSizes([100, 0])">Maximize a</button>

  <Splitter.RootProvider :value="splitter">
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" aria-label="Resize" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.RootProvider>
</template>

If you're using the RootProvider component, you don't need to use the Root component.

API Reference

Root

PropDefaultType
panels
PanelData[]

The size constraints of the panels.

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
defaultSize
number[]

The initial size of the panels when rendered. Use when you don't need to control the size of the panels.

id
string

The unique identifier of the machine.

ids
Partial<{ root: string resizeTrigger(id: string): string label(id: string): string panel(id: string | number): string }>

The ids of the elements in the splitter. Useful for composition.

keyboardResizeBy
number

The number of pixels to resize the panel by when the keyboard is used.

nonce
string

The nonce for the injected splitter cursor stylesheet.

orientation'horizontal'
'horizontal' | 'vertical'

The orientation of the splitter. Can be `horizontal` or `vertical`

size
number[]

The controlled size data of the panels

EmitEvent
collapse
[details: ExpandCollapseDetails]

Function called when a panel is collapsed.

expand
[details: ExpandCollapseDetails]

Function called when a panel is expanded.

resize
[details: ResizeDetails]

Function called when the splitter is resized.

resizeEnd
[details: ResizeEndDetails]

Function called when the splitter resize ends.

resizeStart
[]

Function called when the splitter resize starts.

update:size
[size: number[]]

The callback fired when the model value changes.

Data AttributeValue
[data-scope]splitter
[data-part]root
[data-orientation]The orientation of the splitter

Panel

PropDefaultType
id
string

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
Data AttributeValue
[data-scope]splitter
[data-part]panel
[data-orientation]The orientation of the panel
[data-id]
[data-index]The index of the item

ResizeTrigger

PropDefaultType
id
`${string}:${string}`

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.
disabled
boolean

Data AttributeValue
[data-scope]splitter
[data-part]resize-trigger
[data-id]
[data-orientation]The orientation of the resizetrigger
[data-focus]Present when focused
[data-disabled]Present when disabled

RootProvider

PropDefaultType
value
SplitterApi<PropTypes>

asChild
boolean

Use the provided child element as the default rendered element, combining their props and behavior.

For more details, read our Composition guide.

Accessibility

Complies with the Window Splitter WAI-ARIA design pattern.