Splitter
A component that divides your interface into resizable sections
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-partattribute 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:
import { Splitter } from '@ark-ui/react'
export const Basic = () => (
  <Splitter.Root
    defaultSize={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
)
import { Splitter } from '@ark-ui/solid'
export const Basic = () => (
  <Splitter.Root
    size={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
)
<script setup lang="ts">
import { ref } from 'vue'
import { Splitter } from '@ark-ui/vue'
const size = ref([
  { id: 'a', size: 50 },
  { id: 'b', size: 50 },
])
</script>
<template>
  <Splitter.Root :size="size">
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <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:
import { Splitter } from '@ark-ui/react'
export const RenderProp = () => (
  <Splitter.Root
    defaultSize={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    <Splitter.Context>
      {(splitter) => (
        <>
          <Splitter.Panel id="a">
            <button type="button" onClick={() => splitter.setSize('a', 10)}>
              Set to 10%
            </button>
          </Splitter.Panel>
          <Splitter.ResizeTrigger id="a:b" />
          <Splitter.Panel id="b">
            <button type="button" onClick={() => splitter.setSize('b', 10)}>
              Set to 10%
            </button>
          </Splitter.Panel>
        </>
      )}
    </Splitter.Context>
  </Splitter.Root>
)
import { Splitter } from '@ark-ui/solid'
export const RenderProp = () => (
  <Splitter.Root
    size={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    <Splitter.Context>
      {(api) => (
        <>
          <Splitter.Panel id="a">
            <button type="button" onClick={() => api().setSize('a', 10)}>
              Set to 10%
            </button>
          </Splitter.Panel>
          <Splitter.ResizeTrigger id="a:b" />
          <Splitter.Panel id="b">
            <button type="button" onClick={() => api().setSize('b', 10)}>
              Set to 10%
            </button>
          </Splitter.Panel>
        </>
      )}
    </Splitter.Context>
  </Splitter.Root>
)
<script setup lang="ts">
import { ref } from 'vue'
import { Splitter } from '@ark-ui/vue'
const size = ref([
  { id: 'a', size: 50 },
  { id: 'b', size: 50 },
])
</script>
<template>
  <Splitter.Root :size="size">
    <Splitter.Context v-slot="splitter">
      <Splitter.Panel id="a">
        <button @click="splitter.setSize('a', 10)">Set A to 10%</button>
      </Splitter.Panel>
      <Splitter.ResizeTrigger id="a:b" />
      <Splitter.Panel id="b">
        <button @click="splitter.setSize('b', 10)">Set B to 10%</button>
      </Splitter.Panel>
    </Splitter.Context>
  </Splitter.Root>
</template>
Handling Events
Splitter also provides onSizeChangeStart and onSizeChangeEnd events which can be useful to
perform some actions during the start and end of the resizing process:
import { Splitter } from '@ark-ui/react'
export const Events = () => (
  <Splitter.Root
    defaultSize={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
    onSizeChange={(details) => console.log('onSizeChange', details)}
    onSizeChangeEnd={(details) => console.log('onSizeChangeEnd', details)}
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
)
import { Splitter } from '@ark-ui/solid'
export const Events = () => (
  <Splitter.Root
    size={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
    onSizeChange={(details) => console.log('onSizeChange', details)}
    onSizeChangeEnd={(details) => console.log('onSizeChangeEnd', details)}
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
)
<script setup lang="ts">
import { ref } from 'vue'
import { Splitter } from '@ark-ui/vue'
const size = ref([
  { id: 'a', size: 50 },
  { id: 'b', size: 50 },
])
</script>
<template>
  <Splitter.Root
    :size="size"
    @size-change="(details) => console.log('onSizeChange', details)"
    @size-change-end="(details) => console.log('onSizeChangeEnd', details)"
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <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:
import { Splitter } from '@ark-ui/react'
export const Vertical = () => (
  <Splitter.Root
    orientation="vertical"
    defaultSize={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
)
import { Splitter } from '@ark-ui/solid'
export const Vertical = () => (
  <Splitter.Root
    orientation="vertical"
    size={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
)
<script setup lang="ts">
import { ref } from 'vue'
import { Splitter } from '@ark-ui/vue'
const size = ref([
  { id: 'a', size: 50 },
  { id: 'b', size: 50 },
])
</script>
<template>
  <Splitter.Root :size="size" orientation="vertical">
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
</template>
API Reference
Root
| Prop | Default | Type | 
|---|---|---|
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | |
| defaultSize | PanelSizeData[]The initial size of the panels when it is first rendered. Use this when you do not need to control the state of the carousel. | |
| 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. | |
| onSizeChange | (details: SizeChangeDetails) => voidFunction called when the splitter is resized. | |
| onSizeChangeEnd | (details: SizeChangeDetails) => voidFunction called when the splitter resize ends. | |
| orientation | 'horizontal' | 'vertical'The orientation of the splitter. Can be `horizontal` or `vertical` | |
| size | PanelSizeData[]The size data of the panels | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | splitter | 
| [data-part] | root | 
| [data-orientation] | The orientation of the splitter | 
Panel
| Prop | Default | Type | 
|---|---|---|
| id | PanelId | |
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | |
| snapSize | number | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | splitter | 
| [data-part] | panel | 
| [data-orientation] | The orientation of the panel | 
ResizeTrigger
| Prop | Default | Type | 
|---|---|---|
| id | type ONLY_FOR_FORMAT =
  | `${string}:${string}`
  | `${string}:${number}`
  | `${number}:${string}`
  | `${number}:${number}` | |
| asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior.For more details, read our Composition guide. | |
| disabled | boolean | |
| step | number | 
| Data Attribute | Value | 
|---|---|
| [data-scope] | splitter | 
| [data-part] | resize-trigger | 
| [data-orientation] | The orientation of the resizetrigger | 
| [data-focus] | Present when focused | 
| [data-disabled] | Present when disabled | 
RootProvider
| Prop | Default | Type | 
|---|---|---|
| value | UseSplitterReturn | |
| asChild | booleanUse 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.