Skip to main content

resizable

Accessible resizable panel groups and layouts with keyboard support.

About

The Resizable component is built on top of react-resizable-panels by bvaughn.

Philosophy

Resizable panels let users allocate screen real estate to match their workflow. We wrap react-resizable-panels because the math of proportional resizing, minimum sizes, and persistent layouts is deceptively complex. The PanelGroup/Panel/Handle model keeps the API simple while supporting arbitrarily complex layouts.

How It's Built

Loading diagram...

Installation


npx @gentleduck/cli add resizable

npx @gentleduck/cli add resizable

Usage

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
<ResizablePanelGroup orientation="horizontal">
  <ResizablePanel>One</ResizablePanel>
  <ResizableHandle />
  <ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>
<ResizablePanelGroup orientation="horizontal">
  <ResizablePanel>One</ResizablePanel>
  <ResizableHandle />
  <ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>

Examples

Vertical

Use the orientation prop to set the direction of the resizable panels.

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
 
export default function Example() {
  return (
    <ResizablePanelGroup orientation="vertical">
      <ResizablePanel>One</ResizablePanel>
      <ResizableHandle />
      <ResizablePanel>Two</ResizablePanel>
    </ResizablePanelGroup>
  )
}
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
 
export default function Example() {
  return (
    <ResizablePanelGroup orientation="vertical">
      <ResizablePanel>One</ResizablePanel>
      <ResizableHandle />
      <ResizablePanel>Two</ResizablePanel>
    </ResizablePanelGroup>
  )
}

Handle

You can set or hide the handle by using the withHandle prop on the ResizableHandle component.

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
 
export default function Example() {
  return (
    <ResizablePanelGroup orientation="horizontal">
      <ResizablePanel>One</ResizablePanel>
      <ResizableHandle withHandle />
      <ResizablePanel>Two</ResizablePanel>
    </ResizablePanelGroup>
  )
}
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
 
export default function Example() {
  return (
    <ResizablePanelGroup orientation="horizontal">
      <ResizablePanel>One</ResizablePanel>
      <ResizableHandle withHandle />
      <ResizablePanel>Two</ResizablePanel>
    </ResizablePanelGroup>
  )
}

Component Composition

Loading diagram...

API Reference

ResizablePanelGroup

PropTypeDefaultDescription
orientation"horizontal" | "vertical"(required)Layout orientation of the panels
classNamestring--Additional CSS classes for the panel group
dir"ltr" | "rtl"--Text direction override for RTL support
childrenReact.ReactNode--ResizablePanel and ResizableHandle elements
...propsReact.ComponentPropsWithoutRef<typeof Group>--Additional props inherited from Group.

ResizablePanel

Re-exports Panel from react-resizable-panels directly.

PropTypeDefaultDescription
defaultSizenumber--Default size of the panel as a percentage (0-100)
minSizenumber--Minimum size of the panel as a percentage
maxSizenumber--Maximum size of the panel as a percentage
collapsiblebooleanfalseWhether the panel can be collapsed
classNamestring--Additional CSS classes for the panel
childrenReact.ReactNode--Panel content
...propsReact.ComponentPropsWithoutRef<typeof Panel>--Additional props inherited from Panel.

ResizableHandle

PropTypeDefaultDescription
withHandleboolean--Whether to render the visible grip icon handle
classNamestring--Additional CSS classes for the resize handle
...propsReact.ComponentPropsWithoutRef<typeof Separator>--Additional props inherited from Separator.

RTL Support

Direction is resolved through the shared primitives direction module. Use a local dir="rtl" override when the component exposes it, or set DirectionProvider at app/root level for global RTL/LTR behavior.