use-splitter | Mantine

Create resizable split pane layouts with keyboard support, collapsible panels and constraints

use-splitter hook provides resizable split-pane functionality. It handles pointer drag on resize handles, keyboard navigation following the WAI-ARIA Window Splitter pattern, collapsible panels and min/max constraints. Sizes can be percentages (flexible panes) or px / rem (fixed panes).

defaultSize , min and max accept CSS units. A plain number or % string is a flexible size that shares the leftover space, while a px or rem string is a fixed size that stays constant when the container is resized. Sizes are reported back in the unit they were declared in, so a '240px' pane stays '240px' in sizes and onSizeChange . When at least one pane uses a fixed unit, the hook resolves the layout in pixels using the measured container size:

Set orientation="vertical" to create a vertical split layout. Keyboard navigation uses ArrowUp/ArrowDown instead of ArrowLeft/ArrowRight:

Set collapsible: true on a panel to allow it to collapse to zero size. When dragged below the collapseThreshold (defaults to min ), the panel snaps to 0%. Use collapse() , expand() and toggleCollapse() for programmatic control. Press Enter on a handle to toggle the smaller adjacent collapsible panel:

The hook supports any number of panels. Each handle controls the boundary between its two adjacent panels:

By default, each handle only affects its two adjacent panels. When a neighbor panel is at its minimum, the handle stops. Use the redistribute prop to allow borrowing space from panels further away when the immediate neighbor cannot shrink any more.

redistribute="nearest" takes space from the nearest panel in the drag direction first, then moves to the next one if more space is needed. Try dragging the first handle to the right — when the second panel hits its minimum (20%), space is taken from the third and fourth panels:

redistribute="equal" distributes the needed space equally among all panels in the drag direction, respecting each panel's minimum. Panels that hit their minimum are excluded and the remaining deficit is re-distributed among the rest:

Pass a function to redistribute for full control over how space is borrowed. The function receives { sizes, panels, handleIndex, delta } and must return a new sizes array. This example always borrows from the last panel when growing and from the first panel when shrinking:

You can make the drag handle a small floating grip button instead of a full-height bar. In this example, only the grip icon is draggable — the thin line between panels is not interactive:

Compose multiple useSplitter instances to create complex layouts with both horizontal and vertical splits. Here the right side of a horizontal split contains a vertical split:

A real-world example combining a collapsible file explorer sidebar, a code editor panel and a terminal — similar to VS Code:

Pass sizes and onSizeChange to control the sizes externally. Use setSizes() for programmatic updates:

Current sizes: [ 50, 50 ]

Handles follow the WAI-ARIA Window Splitter pattern:

| Key | Action | |-----|--------| | ArrowLeft/ArrowRight | Resize by step (horizontal) | | ArrowUp/ArrowDown | Resize by step (vertical) | | Shift + Arrow | Resize by shiftStep | | Home | Shrink panel before handle to its min | | End | Grow panel before handle to its max | | Enter | Toggle collapse of the smaller adjacent collapsible panel |

The hook uses the Pointer Events API which handles both mouse and touch automatically. Set touch-action: none on the handle element to prevent the browser from interpreting touch drag as scroll:

UseSplitterPanel , UseSplitterOptions , UseSplitterReturnValue , UseSplitterRedistributeInput , UseSplitterRedistributeFn , UseSplitterResolvedPanel , SplitterPaneSize and SplitterStep types are exported from the @mantine/hooks package:

Recommended articles