Skip to content

Documentation

neelam-ui

Search documentation

Getting Started
Forms
Overlays
Navigation
Data Display
Layout
AI & Chat
Blocks
GitHub repository

Resizable

A row or column of panels resized by dragging the handles between them — or, just as fully, with the arrow keys.

Sidebar

Content

Drag the divider, or focus it and press ← / →.

Usage#

import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from "neelam-ui";
 
<ResizablePanelGroup className="h-64">
  <ResizablePanel defaultSize={30} minSize={15}>Sidebar</ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel>Content</ResizablePanel>
</ResizablePanelGroup>

Compose them alternating: panel, handle, panel, handle, panel. A handle resizes only its immediate previous and next sibling.

Sizing#

defaultSize, minSize, and maxSize are percentages of the group's main axis. Omit defaultSize and a panel fills whatever is left over, split evenly with any other unsized panels.

A vertical group needs an explicit height

Panels resolve their percentage sizes against the group's main-axis size, and a flex container with no definite height cannot give them one. Set h-80, h-screen, or similar on a direction="vertical" group. Width is not the same problem — the group defaults to w-full, which is almost always what is wanted.

Adjacency, not registration#

A handle reads minSize and maxSize straight back off its neighbours' own data-* attributes rather than through context. A handle only ever needs to know about its two immediate siblings, never the whole group — the same approach Carousel takes reading its slides from the DOM instead of an id-registration system.

Resizing by keyboard#

This is not a mouse-only control. ResizableHandle is a WAI-ARIA window splitter: focusable, with role="separator", and fully operable from the keyboard. Dragging is one input method, not the only one.

Try it above

Tab to the divider in the demo and press the arrow keys. If a resizable layout in your own app cannot do this, it is not finished.

Keyboard#

Keyboard shortcuts
KeyBehaviour
TabMoves focus to the handle. Each handle is its own tab stop.
Shrinks or grows the previous panel, in a horizontal group.
The same, in a vertical group.
HomeCollapses the previous panel to its minimum.
EndExpands the previous panel to its maximum.

Accessibility#

  • The handle is role="separator" with aria-orientation, the WAI-ARIA window splitter pattern.
  • aria-valuenow is required the moment a separator becomes focusable, and is kept current as the panel resizes — along with aria-valuemin and aria-valuemax, which reflect the neighbours' real bounds rather than a fixed 0–100.
  • The handle is a genuine tab stop (tabIndex={0}), which is what makes the keyboard path work at all.
  • The grip icon (withHandle) is decorative; the handle's own role and values carry the meaning.

API reference#

ResizablePanelGroup#

Props for ResizablePanelGroup
PropTypeDefault
direction

`"horizontal"` (panels side by side, the default) or `"vertical"` (stacked).

enumhorizontal

ResizablePanel#

Props for ResizablePanel
PropTypeDefault
defaultSize

Initial size, as a percentage of the group's main axis. Omit to fill the space left over by sized siblings, split evenly with any other unsized panels.

number
maxSize

Maximum size, as a percentage. Defaults to `100`.

number100
minSize

Minimum size, as a percentage. Defaults to `0`.

number0

ResizableHandle#

Props for ResizableHandle
PropTypeDefault
withHandle

Shows a small grip icon centered on the handle. Defaults to `false`.

booleanfalse