apps/www/content/docs/components/splitter.mdx
import { Splitter } from "@chakra-ui/react"
<Splitter.Root>
<Splitter.Panel />
<Splitter.ResizeTrigger>
<Splitter.ResizeTriggerSeparator />
<Splitter.ResizeTriggerIndicator />
</Splitter.ResizeTrigger>
<Splitter.Panel />
</Splitter.Root>
The Splitter component provides shortcuts for common use cases.
The Splitter.ResizeTrigger renders the Splitter.ResizeTriggerSeparator and
Splitter.ResizeTriggerIndicator within it by default.
Explicitly writing this:
<Splitter.ResizeTrigger id="a:b" />
is shorthand for the following if you don't need to customize the separator or indicator:
<Splitter.ResizeTrigger id="a:b">
<Splitter.ResizeTriggerSeparator />
<Splitter.ResizeTriggerIndicator />
</Splitter.ResizeTrigger>
Use onResize and size props to manage panel sizes programmatically.
<Splitter.Root
panels={[{ id: "a" }, { id: "b" }]}
size={sizes}
onResize={(details) => setSizes(details.size)}
>
</Splitter.Root>
An alternative way to control the splitter is to use the RootProvider
component and the useSplitter store hook.
This way you can access the splitter state and methods from outside the splitter.
<ExampleTabs name="splitter-with-store" />Pass the orientation="vertical" prop to the Splitter.Root component for
stacked panels that resize vertically.
Use the useBreakpointValue hook to change the splitter orientation based on
screen size. This example shows a vertical splitter on mobile devices and a
horizontal splitter on larger screens.
Create layouts with more than two resizable panels by passing an array of panels
to the panels prop of the Splitter.Root component.
Make the panels collapsible and snapped to a specific size by setting the
collapsible and collapsedSize properties on a panel in the panels array.
This allows users to snap panels to a defined minimum size.
<Splitter.Root
defaultSize={[40, 60]}
panels={[
{ id: "a", collapsible: true, collapsedSize: 5, minSize: 25 },
{ id: "b", minSize: 50 },
]}
>
</Splitter.Root>
Set minSize and maxSize on panels to constrain their resizable range and
prevent resizing beyond these boundaries.
Here's an example of how to nest splitters inside panels to create more complex layouts. Each nested splitter can have its own orientation, sizes, and behaviors independent of the parent splitter.
<ExampleTabs name="splitter-nested" />Set a defaultSize and pair it with a storage solution, such as
useLocalStorage, to save users’ panel size preferences. This ensures that
panel layouts persist across sessions. Alternatively, you can use cookies or
other storage mechanisms depending on your needs.
Pass the disabled prop to the Splitter.ResizeTrigger to disable resize on a
panel. This is useful if you want certain panels to remain fixed while allowing
others to resize.
<Splitter.ResizeTrigger disabled id="a:b" />
Customize the resize trigger to show only the separator without the indicator. This creates a minimal, clean appearance while maintaining full resize functionality.
<Splitter.ResizeTrigger id="a:b">
<Splitter.ResizeTriggerSeparator />
</Splitter.ResizeTrigger>
Use Splitter.Context to access the splitter context and add a double-click
handler to the resize trigger. This example resets panel sizes to their default
values when the resize handle is double-clicked.
Track resize events using onResizeStart, onResize, and onResizeEnd props.
This example logs all resize events with timestamps and panel sizes, useful for
debugging or implementing custom resize behavior.
The Splitter supports keyboard-based resizing for accessibility and precise
control:
keyboardResizeBy prop.This example shows a horizontal splitter where panels can be shown or hidden dynamically. Use the buttons above the splitter to toggle the left and right panels - perfect for layouts where certain sections may not always be needed.
The splitter automatically adjusts the remaining panels when one is hidden,
keeping everything responsive. Initial panel sizes are set with defaultSize,
and minSize ensures panels never shrink too small.
Add or remove panels dynamically while maintaining relative proportions. This example demonstrates how to manage panel state and redistribute sizes when panels are added or removed.
<ExampleTabs name="splitter-dynamic-panel" />A real-world VS Code-like layout demonstrating nested splitters with different orientations, collapsible panels, and integrated code editing.
<ExampleTabs name="splitter-ide-layout" />When you need to programmatically control the splitter, you can access the splitter context and its methods in two ways:
Splitter.Context render propuseSplitterContext hookUse Splitter.Context as a render prop to access the context within the
component tree:
<Splitter.Root defaultSize={[50, 50]} panels={[{ id: "a" }, { id: "b" }]}>
<Splitter.Panel id="a">Panel A</Splitter.Panel>
<Splitter.Context>
{(context) => (
<Splitter.ResizeTrigger
id="a:b"
onDoubleClick={() => {
context.resetSizes()
}}
/>
)}
</Splitter.Context>
<Splitter.Panel id="b">Panel B</Splitter.Panel>
</Splitter.Root>
Alternatively, use the useSplitterContext hook in a child component:
import { useSplitterContext } from "@chakra-ui/react"
const ResetButton = () => {
const splitter = useSplitterContext()
return <button onClick={() => splitter.resetSizes()}>Reset Sizes</button>
}
const Demo = () => (
<Splitter.Root defaultSize={[50, 50]} panels={[{ id: "a" }, { id: "b" }]}>
<Splitter.Panel id="a">Panel A</Splitter.Panel>
<Splitter.ResizeTrigger id="a:b" />
<Splitter.Panel id="b">
<ResetButton />
</Splitter.Panel>
</Splitter.Root>
)
The context object (from either method) includes:
resetSizes(): Reset all panels to their default sizessetSize(sizes): Set panel sizes programmaticallycollapsePanel(id): Collapse a specific panelexpandPanel(id): Expand a collapsed panelisPanelCollapsed(id): Check if a panel is collapsedgetItems(): Get the current items (panels and handles)size: Current panel sizes arrayExplore the Splitter component parts interactively. Click on parts in the
sidebar to highlight them in the preview.