Splitter
A component that divides your interface into resizable sections
A component that divides your interface into resizable sections
Please note, the API of this component is currently in a preview phase and is subject to change.
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.
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'
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'
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>
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'
const RenderProp = () => (
  <Splitter.Root
    defaultSize={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    {(api) => (
      <>
        <Splitter.Panel id="a">
          <button onClick={() => api.setSize('a', 10)}>Set to 10%</button>
        </Splitter.Panel>
        <Splitter.ResizeTrigger id="a:b" />
        <Splitter.Panel id="b">
          <button onClick={() => api.setSize('b', 10)}>Set to 10%</button>
        </Splitter.Panel>
      </>
    )}
  </Splitter.Root>
)
import { Splitter } from '@ark-ui/solid'
const RenderProp = () => (
  <Splitter.Root
    size={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
  >
    {(api) => (
      <>
        <Splitter.Panel id="a">
          <button onClick={() => api().setSize('a', 10)}>Set to 10%</button>
        </Splitter.Panel>
        <Splitter.ResizeTrigger id="a:b" />
        <Splitter.Panel id="b">
          <button onClick={() => api().setSize('b', 10)}>Set to 10%</button>
        </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" v-slot="api">
    <Splitter.Panel id="a">
      <button @click="api.setSize('a', 10)">Set A to 10%</button>
    </Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">
      <button @click="api.setSize('b', 10)">Set B to 10%</button>
    </Splitter.Panel>
  </Splitter.Root>
</template>
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'
const Events = () => (
  <Splitter.Root
    defaultSize={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
    onSizeChangeStart={(details) => console.log('onSizeChangeStart', 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'
const Events = () => (
  <Splitter.Root
    size={[
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ]}
    onSizeChangeStart={(details) => console.log('onSizeChangeStart', 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-start="(details) => console.log('onSizeChangeStart', 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>
By default, the Splitter component is horizontal. If you need a vertical
splitter, use the orientation prop:
import { Splitter } from '@ark-ui/react'
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'
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>
| Prop | Type | Default | 
|---|---|---|
| asChildRender as a different element type. | boolean | |
| defaultSizeThe initial size of the splitter. | PanelSizeData[] | |
| dirThe document's text/writing direction. | 'ltr' | 'rtl' | "ltr" | 
| getRootNodeA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron. | () => Node | ShadowRoot | Document | |
| idThe unique identifier of the machine. | string | |
| idsThe ids of the elements in the splitter. Useful for composition. | Partial<{
  root: string
  resizeTrigger(id: string): string
  label(id: string): string
  panel(id: string | number): string
}> | |
| onSizeChangeFunction called when the splitter is resized. | (details: SizeChangeDetails) => void | |
| onSizeChangeEndFunction called when the splitter resize ends. | (details: SizeChangeDetails) => void | |
| onSizeChangeStartFunction called when the splitter resize starts. | (details: SizeChangeDetails) => void | |
| orientationThe orientation of the splitter. Can be `horizontal` or `vertical` | 'horizontal' | 'vertical' | |
| sizeThe size data of the panels | PanelSizeData[] | 
| Prop | Type | Default | 
|---|---|---|
| id | PanelId | |
| asChildRender as a different element type. | boolean | |
| snapSize | number | 
| Prop | Type | Default | 
|---|---|---|
| id | type ONLY_FOR_FORMAT =
  | `${string}:${string}`
  | `${string}:${number}`
  | `${number}:${string}`
  | `${number}:${number}` | |
| asChildRender as a different element type. | boolean | |
| disabled | boolean | |
| step | number |