useSplitter
Hook that manages resizable panel layout with keyboard navigation and pointer-based resizing.
Usage#
import { useSplitter } from '@primereact/headless/splitter';const { rootProps, getPanelProps, getGutterProps, handleProps } = useSplitter({
panels: [{ minSize: 10 }, { minSize: 10 }],
defaultSizes: [30, 70]
});
<div {...rootProps} style={{ display: 'flex' }}>
<div {...getPanelProps(0)} />
<div {...getGutterProps(0)}>
<div {...handleProps} />
</div>
<div {...getPanelProps(1)} />
</div>;useSplitter manages panel sizing, drag-to-resize, keyboard resizing, and collapse behavior — see Primitive for a component-based API.
Features#
- Declarative panel config — pass
panelswithminSize,maxSize,collapsible, andcollapsedSizeper pane instead of wiring constraints yourself - Pointer and keyboard resizing —
getGutterProps(index)returns an ARIA separator with drag, arrow key, Home/End, and Enter handlers already attached - Horizontal or vertical orientation — one flag switches axis, key mappings, and the data attributes you style against
- Controlled or uncontrolled sizes — feed
sizes+onResize/onResizeEndfor external state or let the hook manage it fromdefaultSizes - Collapsible panes — panels snap to
collapsedSizewhen dragged below their minimum, no extra logic required - Resize-in-progress signal —
state.resizingplusdata-resizinglets you switch cursors and disable selection during a drag
Working with callbacks#
Controlled sizes#
Feed sizes with onResizeEnd (fires after drag completes) or onResize (fires continuously) for external state.
const [sizes, setSizes] = React.useState([50, 50]);
const splitter = useSplitter({
panels: [{ minSize: 10 }, { minSize: 10 }],
sizes,
onResizeEnd: (e) => setSizes(e.sizes)
});Persisting layout across reloads#
Pair onResizeEnd with localStorage to restore the user's layout on next visit.
const [sizes, setSizes] = React.useState(() => JSON.parse(localStorage.getItem('layout') ?? '[30,70]'));
useSplitter({
panels: [{ minSize: 10 }, { minSize: 10 }],
sizes,
onResizeEnd: (e) => {
setSizes(e.sizes);
localStorage.setItem('layout', JSON.stringify(e.sizes));
}
});Collapsible side panel#
Mark a panel collapsible and give it a collapsedSize so dragging below minSize snaps it closed instead of getting stuck.
const splitter = useSplitter({
panels: [{ minSize: 15, collapsible: true, collapsedSize: 5 }, { minSize: 10 }],
defaultSizes: [30, 70]
});Fine-grained keyboard resizing#
Lower step when precise keyboard adjustments matter — the default of 5 moves the gutter 5% per arrow press.
const splitter = useSplitter({
panels: [{ minSize: 10 }, { minSize: 10 }],
step: 1
});Vertical orientation#
orientation: 'vertical' swaps the axis and rebinds arrow keys automatically.
const splitter = useSplitter({
panels: [{ minSize: 10 }, { minSize: 10 }],
orientation: 'vertical'
});Styling with data attributes#
The root exposes data-orientation, data-resizing, and data-disabled so cursor and selection rules can stay in CSS.
[data-orientation='horizontal'][data-resizing] {
cursor: col-resize;
user-select: none;
}
[data-orientation='vertical'][data-resizing] {
cursor: row-resize;
user-select: none;
}
[data-disabled] {
pointer-events: none;
opacity: 0.4;
}API#
useSplitter#
| Name | Type | Default |
|---|---|---|
panels | useSplitterPanelConfig[] | — |
| Declarative panel configuration array. When provided, the hook auto-registers panels from this config — no `registerPanel` calls needed. Each entry defines constraints for the panel at that index. | ||
sizes | number[] | — |
| Controlled panel sizes as percentages (must sum to ~100). When provided, the splitter operates in controlled mode — sizes are driven by this prop and should be updated via onResize or onResizeEnd callbacks. | ||
defaultSizes | number[] | — |
| Default initial panel sizes as percentages (must sum to ~100). Used for uncontrolled mode — sets the initial sizes on mount, after which internal state takes over. | ||
orientation | "horizontal" | "vertical" | horizontal |
| Orientation of the panels. | ||
disabled | boolean | false |
| When true, disables all resize interactions. | ||
step | number | 5 |
| Step factor to increment/decrement the size of the panels while pressing the arrow keys. | ||
onResizeStart | (event: useSplitterResizeEvent) => void | — |
| Callback invoked when resize starts. | ||
onResize | (event: useSplitterResizeEvent) => void | — |
| Callback invoked during resize with current panel sizes. | ||
onResizeEnd | (event: useSplitterResizeEvent) => void | — |
| Callback invoked when resize ends. | ||
onCollapse | (event: useSplitterCollapseEvent) => void | — |
| Callback invoked when a panel collapses or expands. | ||
Accessibility#
Arrow keys resize the panes, Home/End collapse to min/max, and Enter toggles between preset sizes. See Primitive for full WAI-ARIA compliance details.