Resizable
Splittable panel container — a flex layout with drag handles auto-injected between adjacent panels. Pointer events cover mouse, trackpad, and touch; arrow keys nudge the boundary in 5% steps with PageUp/Down for 10% and Home/End to drive it to the panel's floor (5% unless data-lb-min says otherwise). Each handle is a role="separator" with proper aria-orientation and value attributes.
a11y (built in): each injected handle is a focusable window splitter — role="separator", tabindex="0", aria-orientation (flipped against the container axis), an aria-label, and aria-valuenow/aria-valuemin/aria-valuemax rewritten on every drag, key press and setSizes() call. Keyboard alone does the whole job: ←/→ (or ↑/↓ when vertical) move 5%, PageUp/PageDown 10%, Home/End run the boundary to the floor. Per-panel data-lb-min (default 5%) keeps a pane from collapsing out of reach, and the handle takes the standard :focus-visible outline.
Usage: Add data-lb-resizable to a wrapper div. Direct children become panels — handles are inserted between them. Set data-lb-direction="vertical" for stacked layout, per-panel data-lb-size (%) for initial sizing, data-lb-min for a floor.
Two-pane horizontal — sidebar + main
The default direction. Drag the divider between the two panels with the mouse, or focus it with Tab and press ← / →.
Two-pane vertical — data-lb-direction="vertical"
Same component, stacked axis. Useful for editor + preview, or list + detail.
Three-pane — IDE layout
Two handles, one for each adjacent boundary. Each panel can have its own initial size and minimum.
Nested splits
Resizables compose — one panel can itself be a vertical Resizable, giving the IDE-style left rail + center stack + right rail layout.
Min sizes — data-lb-min
Each panel can declare a percentage floor. Try dragging the divider all the way left — the sidebar bottoms out at 20% instead of collapsing.
Event listener and programmatic API
The component dispatches lb-resizable-change with {sizes} after every drag and key adjustment. el._lbResizable.setSizes([…]) moves the boundaries from JS — useful for "reset" buttons or saved layouts.