Skip to content
UI

Splitter

A component that divides the layout into resizable panels.

<script setup lang="ts">
import { ref } from 'vue'
import { Splitter } from '@destyler-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">
      <div className="bar"></div>
    </Splitter.ResizeTrigger>
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
</template>
import { useState } from 'react'
import { Splitter } from '@destyler-ui/react'

export function Basic() {
  const [size] = useState([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])

  return (
    <Splitter.Root size={size}>
      <Splitter.Panel id="a">A</Splitter.Panel>
      <Splitter.ResizeTrigger id="a:b">
        <div className="bar"></div>
      </Splitter.ResizeTrigger>
      <Splitter.Panel id="b">B</Splitter.Panel>
    </Splitter.Root>
  )
}
import { Splitter } from '@destyler-ui/solid/splitter'

export function Basic() {
  return (
    <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 lang="ts">
  import type { SplitterRootProps } from '@destyler-ui/svelte'
  import { Splitter } from '@destyler-ui/svelte'

  let { size = $bindable([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ]), ...props }: SplitterRootProps = $props()
</script>

<Splitter.Root bind:size {...props}>
  <Splitter.Panel id="a">A</Splitter.Panel>
  <Splitter.ResizeTrigger id="a:b"><div class="bar"></div></Splitter.ResizeTrigger>
  <Splitter.Panel id="b">B</Splitter.Panel>
</Splitter.Root>
<script setup lang="ts">
import { Splitter } from '@destyler-ui/vue'
</script>
<template>
<Splitter.Root>
<Splitter.Panel />
<Splitter.ResizeTrigger />
<Splitter.Panel />
</Splitter.Root>
</template>
import { Splitter } from '@destyler-ui/react'
export default function Basic() {
return (
<Splitter.Root>
<Splitter.Panel />
<Splitter.ResizeTrigger />
<Splitter.Panel />
</Splitter.Root>
)
}
import { Splitter } from '@destyler-ui/solid'
export default function Basic() {
return (
<Splitter.Root
size={[
{ id: 'left', size: 50 },
{ id: 'right', size: 50 },
]}
>
<Splitter.Panel id="left" />
<Splitter.ResizeTrigger id="left:right" />
<Splitter.Panel id="right" />
</Splitter.Root>
)
}
<script lang="ts">
import { Splitter } from '@destyler-ui/svelte'
let size = $state([
{ id: 'a', size: 50 },
{ id: 'b', size: 50 },
])
</script>
<Splitter.Root bind:size>
<Splitter.Panel id="a">Panel A</Splitter.Panel>
<Splitter.ResizeTrigger id="a:b">
<div class="bar"></div>
</Splitter.ResizeTrigger>
<Splitter.Panel id="b">Panel B</Splitter.Panel>
</Splitter.Root>
<script setup lang="ts">
import { ref } from 'vue'
import { Splitter } from '@destyler-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">
      <div className="bar"></div>
    </Splitter.ResizeTrigger>
    <Splitter.Panel id="b">B</Splitter.Panel>
  </Splitter.Root>
</template>
import { useState } from 'react'
import { Splitter } from '@destyler-ui/react'

export function Basic() {
  const [size] = useState([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])

  return (
    <Splitter.Root size={size}>
      <Splitter.Panel id="a">A</Splitter.Panel>
      <Splitter.ResizeTrigger id="a:b">
        <div className="bar"></div>
      </Splitter.ResizeTrigger>
      <Splitter.Panel id="b">B</Splitter.Panel>
    </Splitter.Root>
  )
}
import { Splitter } from '@destyler-ui/solid/splitter'

export function Basic() {
  return (
    <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 lang="ts">
  import type { SplitterRootProps } from '@destyler-ui/svelte'
  import { Splitter } from '@destyler-ui/svelte'

  let { size = $bindable([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ]), ...props }: SplitterRootProps = $props()
</script>

<Splitter.Root bind:size {...props}>
  <Splitter.Panel id="a">A</Splitter.Panel>
  <Splitter.ResizeTrigger id="a:b"><div class="bar"></div></Splitter.ResizeTrigger>
  <Splitter.Panel id="b">B</Splitter.Panel>
</Splitter.Root>

Listen for resize events.

<script setup lang="ts">
import { Splitter } from '@destyler-ui/vue'
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>
import { useState } from 'react'
import { Splitter } from '@destyler-ui/react'

export function Events() {
  const [size] = useState([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])

  return (
    <Splitter.Root
      size={size}
      // eslint-disable-next-line no-console
      onSizeChange={details => console.log('onSizeChange', details)}
      // eslint-disable-next-line no-console
      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 '@destyler-ui/solid/splitter'

export function Events() {
  return (
    <Splitter.Root
      size={[
        { id: 'a', size: 50 },
        { id: 'b', size: 50 },
      ]}
      onSizeChange={details => console.warn('onSizeChange', details)}
      onSizeChangeEnd={details => console.warn('onSizeChangeEnd', details)}
    >
      <Splitter.Panel id="a">A</Splitter.Panel>
      <Splitter.ResizeTrigger id="a:b" />
      <Splitter.Panel id="b">B</Splitter.Panel>
    </Splitter.Root>
  )
}
<script lang="ts">
  import { Splitter } from '@destyler-ui/svelte'

  let size = $state([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])
</script>

<Splitter.Root
  bind:size
  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>

Display a vertical splitter layout.

<script setup lang="ts">
import { Splitter } from '@destyler-ui/vue'
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>
import { useState } from 'react'
import { Splitter } from '@destyler-ui/react'

export function Vertical() {
  const [size] = useState([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])

  return (
    <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>
  )
}
import { Splitter } from '@destyler-ui/solid/splitter'

export function Vertical() {
  return (
    <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 lang="ts">
  import { Splitter } from '@destyler-ui/svelte'

  let size = $state([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])
</script>

<Splitter.Root bind:size orientation="vertical">
  <Splitter.Panel id="a">A</Splitter.Panel>
  <Splitter.ResizeTrigger id="a:b" />
  <Splitter.Panel id="b">B</Splitter.Panel>
</Splitter.Root>

Use render prop for custom splitter rendering.

<script setup lang="ts">
import { Splitter } from '@destyler-ui/vue'
import { ref } from '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>
import { useState } from 'react'
import { Splitter } from '@destyler-ui/react'

export function RenderProp() {
  const [size] = useState([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])

  return (
    <Splitter.Root size={size}>
      <Splitter.Context>
        {splitter => (
          <>
            <Splitter.Panel id="a">
              <button onClick={() => splitter.setSize('a', 10)}>
                Set A to 10%
              </button>
            </Splitter.Panel>
            <Splitter.ResizeTrigger id="a:b" />
            <Splitter.Panel id="b">
              <button onClick={() => splitter.setSize('b', 10)}>
                Set B to 10%
              </button>
            </Splitter.Panel>
          </>
        )}
      </Splitter.Context>
    </Splitter.Root>
  )
}
import { Splitter } from '@destyler-ui/solid/splitter'

export function RenderProp() {
  return (
    <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 lang="ts">
  import { Splitter } from '@destyler-ui/svelte'

  let size = $state([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])
</script>

<Splitter.Root bind:size>
  <Splitter.Context>
    {#snippet render(splitter)}
      <Splitter.Panel id="a">
        <button onclick={() => splitter().setSize('a', 10)}>Set A to 10%</button>
      </Splitter.Panel>
      <Splitter.ResizeTrigger id="a:b" />
      <Splitter.Panel id="b">
        <button onclick={() => splitter().setSize('b', 10)}>Set B to 10%</button>
      </Splitter.Panel>
    {/snippet}
  </Splitter.Context>
</Splitter.Root>
<script setup lang="ts">
import { Splitter, useSplitter } from '@destyler-ui/vue'
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>
import { useState } from 'react'
import { Splitter, useSplitter } from '@destyler-ui/react'

export function RootProvider() {
  const [size] = useState([
    { id: 'a', size: 50 },
    { id: 'b', size: 50 },
  ])

  const splitter = useSplitter({ size })

  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 '@destyler-ui/solid/splitter'

export function 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 lang="ts">
  import { Splitter, useSplitter } from '@destyler-ui/svelte'

  const id = $props.id()
  const splitter = useSplitter({
    id,
    size: [
      { id: 'a', size: 50 },
      { id: 'b', size: 50 },
    ],
  })
</script>

<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>

Root

PropDefaultType
asChildfalse | true

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

defaultSizesplitter.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.

idstring

The unique identifier of the machine.

idsPartial<{ 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.

orientation"horizontal" | "vertical"

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

sizesplitter.PanelSizeData[]

The size data of the panels

EmitEvent
sizeChange[details: SizeChangeDetails]

Function called when the splitter is resized.

sizeChangeEnd[details: SizeChangeDetails]

Function called when the splitter resize ends.

Context

No serializable props or emits are declared for this part.

Panel

PropDefaultType
id*PanelId
asChildfalse | true

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

snapSizenumber

ResizeTrigger

PropDefaultType
id*`${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}`
asChildfalse | true

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

disabledfalse | true
stepnumber

RootProvider

PropDefaultType
value*MachineApi<PropTypes>
asChildfalse | true

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

Root

PropDefaultType
asChildfalse | true

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

defaultSizesplitter.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.

idsPartial<{ 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) => void

Function called when the splitter is resized.

onSizeChangeEnd(details: SizeChangeDetails) => void

Function called when the splitter resize ends.

orientation"horizontal" | "vertical"

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

sizesplitter.PanelSizeData[]

The size data of the panels

Context

PropDefaultType
children*(context: UseSplitterContext) => ReactNode

Panel

PropDefaultType
id*PanelId
asChildfalse | true

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

snapSizenumber

ResizeTrigger

PropDefaultType
id*`${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}`
asChildfalse | true

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

disabledfalse | true
stepnumber

RootProvider

PropDefaultType
value*UseSplitterReturn
asChildfalse | true

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

Root

PropDefaultType
asChild(props: (userProps?: solid_js205.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

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

defaultSizesplitter.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.

idsPartial<{ 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) => void

Function called when the splitter is resized.

onSizeChangeEnd(details: SizeChangeDetails) => void

Function called when the splitter resize ends.

orientation"horizontal" | "vertical"

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

sizesplitter.PanelSizeData[]

The size data of the panels

Context

PropDefaultType
children*(context: UseSplitterContext) => Element

Panel

PropDefaultType
id*PanelId
asChild(props: (userProps?: solid_js205.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

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

snapSizenumber

ResizeTrigger

PropDefaultType
id*`${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}`
asChild(props: (userProps?: solid_js205.JSX.ButtonHTMLAttributes<HTMLButtonElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

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

disabledfalse | true
stepnumber

RootProvider

PropDefaultType
value*UseSplitterReturn
asChild(props: (userProps?: solid_js205.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.Element

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

Root

PropDefaultType
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]>
childrenSnippet<[]> | undefined
defaultSizeimport("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterPanelSizeData[]
idstring

A stable id for the splitter. Svelte hooks cannot call `$props.id()`. Components should pass the id generated at the component's top level; `Splitter.Root` does this automatically.

idsPartial<{ 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: import("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterSizeChangeDetails) => void

Function called when the splitter is resized.

onSizeChangeEnd(details: import("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterSizeChangeDetails) => void

Function called when the splitter resize ends.

orientation"horizontal" | "vertical"

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

sizeimport("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterPanelSizeData[]

The size data of the panels

Context

PropDefaultType
render*Snippet<[UseSplitterContext]>

Panel

PropDefaultType
id*PanelId
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]>
childrenSnippet<[]> | undefined
snapSizenumber

ResizeTrigger

PropDefaultType
id*`${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}`
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"button">]>
childrenSnippet<[]> | undefined
disabledfalse | true
stepnumber

RootProvider

PropDefaultType
value*UseSplitterReturn
asChildimport("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]>
childrenSnippet<[]> | undefined