@magic-spells / split-panel

Split the view.

Draggable, keyboard-accessible resizable panels — horizontal or vertical, nested to any depth, with min/max constraints and layouts that remember themselves.

Install npm i @magic-spells/split-panel
Size 3.2 kB min+gzip · 0 deps

Basic split

Two panels with authored starting sizes. size takes a percent (30 or 30%) or a pixel value (250px). The divider between them is generated automatically. Drag it, or focus it and use the arrow keys (Shift for bigger steps, Enter or double-click to reset).

Panel 1 · size="30%"

Thirty percent to start.

Panel 2 · size="70%"

Seventy percent to start.

Vertical stack

direction="vertical" stacks panels into rows — the divider becomes horizontal and drags up and down. Panels without a size split the space equally.

Top

Bottom

Nested layouts

A panel can contain another group. Here the right column holds a direction="vertical" group — each group only manages its own direct children, so the dividers never interfere with each other.

Sidebar

One column on the left.

Editor

The right column is its own vertical group.

Console

Min & max limits

Constraints accept pixels or percentages. The sidebar is clamped between min="200px" and max="50%", and the inspector never shrinks below min="15%" — dividers hard-stop at the limits, and the pixel minimum holds even when the window shrinks.

Sidebar · 200px–50%

Main

Inspector · min 15%

Fade to hidden

The left panel starts at size="250px" (its max) and exposes --split-panel-visible — a 10 readout of where it sits in its min="0px" max="250px" range, driving the scale/blur/fade. With snap="0 100" and an eased transition, releasing the drag settles it to fully hidden or fully open — whichever is nearer.

Fading

Drag, then release.

Cover

Saved positions

Give a group an id and it persists its sizes to localStorage on every committed change. Drag a divider, reload the page — the layout comes back.

Remembered

Stored under split-panel:demo-layout.

Also remembered

Events & API

Dragging fires a light split-panel:resize stream and a single split-panel:resize-end per gesture. The group also exposes setSizes(), resetSizes(), and a disabled lock. This group has an eased transition, so the setSizes() buttons glide.

A

B