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>
Anatomy
Section titled “Anatomy”<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>Examples
Section titled “Examples”<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>
Events
Section titled “Events”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>
Vertical
Section titled “Vertical”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>
Render Prop
Section titled “Render Prop”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>
Root Provider
Section titled “Root Provider”<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>
API Reference
Section titled “API Reference”Root
| Prop | Default | Type |
|---|---|---|
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
defaultSize | — | splitter.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. |
id | — | stringThe 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. |
orientation | — | "horizontal" | "vertical"The orientation of the splitter. Can be `horizontal` or `vertical` |
size | — | splitter.PanelSizeData[]The size data of the panels |
| Emit | Event |
|---|---|
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
| Prop | Default | Type |
|---|---|---|
id* | — | PanelId |
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
snapSize | — | number |
ResizeTrigger
| Prop | Default | Type |
|---|---|---|
id* | — | `${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}` |
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
disabled | — | false | true |
step | — | number |
RootProvider
| Prop | Default | Type |
|---|---|---|
value* | — | MachineApi<PropTypes> |
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
Root
| Prop | Default | Type |
|---|---|---|
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
defaultSize | — | splitter.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 | — | splitter.PanelSizeData[]The size data of the panels |
Context
| Prop | Default | Type |
|---|---|---|
children* | — | (context: UseSplitterContext) => ReactNode |
Panel
| Prop | Default | Type |
|---|---|---|
id* | — | PanelId |
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
snapSize | — | number |
ResizeTrigger
| Prop | Default | Type |
|---|---|---|
id* | — | `${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}` |
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
disabled | — | false | true |
step | — | number |
RootProvider
| Prop | Default | Type |
|---|---|---|
value* | — | UseSplitterReturn |
asChild | — | false | trueUse the provided child element as the default rendered element, combining their props and behavior. |
Root
| Prop | Default | Type |
|---|---|---|
asChild | — | (props: (userProps?: solid_js205.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.ElementUse the provided child element as the default rendered element, combining their props and behavior. |
defaultSize | — | splitter.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 | — | splitter.PanelSizeData[]The size data of the panels |
Context
| Prop | Default | Type |
|---|---|---|
children* | — | (context: UseSplitterContext) => Element |
Panel
| Prop | Default | Type |
|---|---|---|
id* | — | PanelId |
asChild | — | (props: (userProps?: solid_js205.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.ElementUse the provided child element as the default rendered element, combining their props and behavior. |
snapSize | — | number |
ResizeTrigger
| Prop | Default | Type |
|---|---|---|
id* | — | `${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}` |
asChild | — | (props: (userProps?: solid_js205.JSX.ButtonHTMLAttributes<HTMLButtonElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.ElementUse the provided child element as the default rendered element, combining their props and behavior. |
disabled | — | false | true |
step | — | number |
RootProvider
| Prop | Default | Type |
|---|---|---|
value* | — | UseSplitterReturn |
asChild | — | (props: (userProps?: solid_js205.JSX.HTMLAttributes<HTMLDivElement> | undefined) => JSX.HTMLAttributes<any>) => JSX.ElementUse the provided child element as the default rendered element, combining their props and behavior. |
Root
| Prop | Default | Type |
|---|---|---|
asChild | — | import("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]> |
children | — | Snippet<[]> | undefined |
defaultSize | — | import("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterPanelSizeData[] |
id | — | stringA 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. |
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: import("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterSizeChangeDetails) => voidFunction called when the splitter is resized. |
onSizeChangeEnd | — | (details: import("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterSizeChangeDetails) => voidFunction called when the splitter resize ends. |
orientation | — | "horizontal" | "vertical"The orientation of the splitter. Can be `horizontal` or `vertical` |
size | — | import("/home/runner/work/ui/ui/packages/svelte/dist/index").SplitterPanelSizeData[]The size data of the panels |
Context
| Prop | Default | Type |
|---|---|---|
render* | — | Snippet<[UseSplitterContext]> |
Panel
| Prop | Default | Type |
|---|---|---|
id* | — | PanelId |
asChild | — | import("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]> |
children | — | Snippet<[]> | undefined |
snapSize | — | number |
ResizeTrigger
| Prop | Default | Type |
|---|---|---|
id* | — | `${string}:${string}` | `${string}:${number}` | `${number}:${string}` | `${number}:${number}` |
asChild | — | import("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"button">]> |
children | — | Snippet<[]> | undefined |
disabled | — | false | true |
step | — | number |
RootProvider
| Prop | Default | Type |
|---|---|---|
value* | — | UseSplitterReturn |
asChild | — | import("svelte").Snippet<[import("/home/runner/work/ui/ui/packages/svelte/dist/types").PropsFn<"div">]> |
children | — | Snippet<[]> | undefined |