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