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/splitter'
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/splitter'
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 { Splitter } from '@ark-ui/vue/splitter'
import { ref } from '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:
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/splitter'
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/splitter'
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 { Splitter } from '@ark-ui/vue/splitter'
import { ref } from '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/splitter'
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/splitter'
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 { Splitter } from '@ark-ui/vue/splitter'
import { ref } from '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>
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.
import { Splitter, useSplitter } from '@ark-ui/react/splitter'
export const RootProvider = () => {
  const splitter = useSplitter({ defaultSize: [{ id: 'a', size: 50 }] })
  return (
    <>
      <button onClick={() => splitter.setToMaxSize('a')}>Maximize a</button>
      <Splitter.RootProvider value={splitter}>
        <Splitter.Panel id="a">A</Splitter.Panel>
        <Splitter.ResizeTrigger id="a:b" />
        <Splitter.Panel id="b">B</Splitter.Panel>
      </Splitter.RootProvider>
    </>
  )
}
import { Splitter, useSplitter } from '@ark-ui/solid/splitter'
export const RootProvider = () => {
  const splitter = useSplitter({ size: [{ id: 'a', size: 50 }] })
  return (
    <>
      <button onClick={() => splitter().setToMaxSize('a')}>Maximize a</button>
      <Splitter.RootProvider value={splitter}>
        <Splitter.Panel id="a">A</Splitter.Panel>
        <Splitter.ResizeTrigger id="a:b" />
        <Splitter.Panel id="b">B</Splitter.Panel>
      </Splitter.RootProvider>
    </>
  )
}
<script setup lang="ts">
import { Splitter, useSplitter } from '@ark-ui/vue/splitter'
import { ref } from 'vue'
const size = ref([
  { id: 'a', size: 50 },
  { id: 'b', size: 50 },
])
const splitter = useSplitter({ size: size.value })
</script>
<template>
  <button @click="splitter.setToMaxSize('a')">Maximize a</button>
  <Splitter.RootProvider :value="splitter">
    <Splitter.Panel id="a">A</Splitter.Panel>
    <Splitter.ResizeTrigger id="a:b" />
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.RootProvider>
</template>
If you're using the
RootProvidercomponent, you don't need to use theRootcomponent.
API Reference
Accessibility
Complies with the Window Splitter WAI-ARIA design pattern.