Skip to main content

Overview

Sidebar
Main Content
Drag the handle to resize the panels.
Resizable provides a split-pane layout where the user can drag a handle to resize adjacent panels. Supports horizontal and vertical splits, with configurable min/max sizes and collapsible panels.

Installation

npm install @araf-ds/core

Usage

import {
  ResizablePanelGroup,
  ResizablePanel,
  ResizableHandle,
} from "@araf-ds/core"

export default function Example() {
  return (
    <ResizablePanelGroup direction="horizontal" className="rounded-lg border">
      <ResizablePanel defaultSize={35} minSize={20}>
        <div className="p-4">
          <p className="text-sm font-semibold text-muted-foreground">Sidebar</p>
        </div>
      </ResizablePanel>
      <ResizableHandle withHandle />
      <ResizablePanel defaultSize={65}>
        <div className="p-4">
          <p className="text-sm">Main Content</p>
        </div>
      </ResizablePanel>
    </ResizablePanelGroup>
  )
}

Variants

Horizontal Split (Sidebar + Main)

<ResizablePanelGroup direction="horizontal" className="min-h-screen rounded-lg border">
  <ResizablePanel defaultSize={20} minSize={15} maxSize={40} collapsible>
    <SidebarNavigation />
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={80}>
    <main className="p-6">{children}</main>
  </ResizablePanel>
</ResizablePanelGroup>

Vertical Split (Editor + Preview)

<ResizablePanelGroup direction="vertical" className="h-[500px] rounded-lg border">
  <ResizablePanel defaultSize={50}>
    <div className="p-4 font-mono text-sm">
      {/* Code editor */}
    </div>
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={50}>
    <div className="p-4">
      {/* Live preview */}
    </div>
  </ResizablePanel>
</ResizablePanelGroup>

Three-Panel Layout

<ResizablePanelGroup direction="horizontal" className="rounded-lg border">
  <ResizablePanel defaultSize={20} minSize={15}>
    <FileTree />
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={55}>
    <CodeEditor />
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={25} minSize={15}>
    <PropertiesPanel />
  </ResizablePanel>
</ResizablePanelGroup>

API Reference

ResizablePanelGroup

direction
string
required
Split direction. Values: horizontal · vertical
onLayout
(sizes: number[]) => void
Callback fired when panel sizes change. Receives an array of percentage sizes.
className
string
Additional class names. Set min-h-* or h-* here to constrain the group height.

ResizablePanel

defaultSize
number
Initial size as a percentage of the group (0–100).
minSize
number
Minimum size as a percentage.
maxSize
number
Maximum size as a percentage.
collapsible
boolean
default:"false"
Allows the panel to collapse to zero when dragged past its minimum size.
collapsedSize
number
default:"0"
Size in percentage when collapsed.

ResizableHandle

withHandle
boolean
default:"false"
Shows a visible grip icon on the divider for discoverability.

Accessibility

  • ResizableHandle is keyboard accessible — focus it and use Arrow keys to resize
  • The handle has role="separator" with aria-valuenow, aria-valuemin, aria-valuemax
  • aria-label is automatically set based on the adjacent panel names
  • On touch devices, the handle responds to touch drag events

Do’s & Don’ts

Do

  • Always set minSize to prevent panels from collapsing unexpectedly
  • Use withHandle to make the drag target visually obvious
  • Persist panel sizes to localStorage via onLayout for a better UX
  • Use collapsible for sidebar panels that users may want to hide entirely

Don't

  • Don’t use Resizable on mobile — touch drag on small screens is error-prone
  • Don’t set defaultSize values that don’t add up to 100
  • Don’t put critical content in a panel that can collapse to zero without warning
  • Don’t nest ResizablePanelGroups unless necessary — it complicates layout logic