Resizable

A component for building resizable panel groups with draggable separators.

Overview

Resizable creates panel layouts with draggable separators. It does not own a panel background, border, radius, or shadow; wrap it in Card, Surface, or an app-owned container when you need a framed area. The examples below use consumer-painted frame classes with SurfaceProvider so the resize handle reads the matching surface context.

Usage

import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@tilt-legal/cubitt-components/resizable";
import { SurfaceProvider } from "@tilt-legal/cubitt-components/utilities";
<SurfaceProvider level={3}>
  <ResizablePanelGroup
    className="h-full min-h-80 w-full overflow-hidden rounded-xl border border-border-3 bg-surface-3"
    orientation="horizontal"
  >
    <ResizablePanel>One</ResizablePanel>
    <ResizableHandle />
    <ResizablePanel>Two</ResizablePanel>
  </ResizablePanelGroup>
</SurfaceProvider>

Examples

Vertical

Use orientation="vertical" to stack panels vertically.

With Handle

Add withHandle to display a visible grip on the resize separator.

Pixel-Based Sizing

Use numeric values for pixel-based constraints. The second panel fills the remaining space.

API Reference

ResizablePanelGroup

Container component that manages the resizable panel layout.

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"The panel layout direction.
onLayoutChange(layout: Layout) => void-Callback when panel sizes change.
classNamestring-Additional classes for layout sizing and app-owned framing.

ResizablePanel

Panel size props accept percentages, pixels, relative font units, and viewport units. Numeric values are treated as pixels, while strings without units are treated as percentages.

PropTypeDefaultDescription
defaultSizenumber | string-Initial size.
minSizenumber | string-Minimum size constraint.
maxSizenumber | string-Maximum size constraint.
collapsiblebooleanfalseWhether the panel can collapse.
collapsedSizenumber | string-Size when collapsed.
onResize(size) => void-Callback when the panel is resized.
classNamestring-Additional classes for panel content layout.

ResizableHandle

Draggable separator between panels.

PropTypeDefaultDescription
withHandleboolean | React.ReactNodefalseShows the default grip when true, or renders a custom grip element.
disabledbooleanfalseDisables resizing through this handle.
classNamestring-Additional classes for the separator.

Hooks

useResizablePanelRef

Get a ref to imperatively control a panel.

import { useResizablePanelRef } from "@tilt-legal/cubitt-components/resizable";

function Component() {
  const panelRef = useResizablePanelRef();

  return (
    <ResizablePanelGroup orientation="horizontal">
      <ResizablePanel collapsible panelRef={panelRef}>
        Sidebar
      </ResizablePanel>
      <ResizableHandle />
      <ResizablePanel>Content</ResizablePanel>
    </ResizablePanelGroup>
  );
}

useResizableGroupRef

Get a ref to imperatively control the entire group layout.

import { useResizableGroupRef } from "@tilt-legal/cubitt-components/resizable";

function Component() {
  const groupRef = useResizableGroupRef();

  return (
    <ResizablePanelGroup groupRef={groupRef} orientation="horizontal">
      <ResizablePanel id="left">Left</ResizablePanel>
      <ResizableHandle />
      <ResizablePanel id="right">Right</ResizablePanel>
    </ResizablePanelGroup>
  );
}

useResizableDefaultLayout

Persist and restore layouts to storage.

import { useResizableDefaultLayout } from "@tilt-legal/cubitt-components/resizable";

function Component() {
  const { defaultLayout } = useResizableDefaultLayout({
    panelIds: ["sidebar", "content"],
    storage: localStorage,
  });

  return (
    <ResizablePanelGroup defaultLayout={defaultLayout} orientation="horizontal">
      <ResizablePanel defaultSize={280} id="sidebar">
        Sidebar
      </ResizablePanel>
      <ResizableHandle />
      <ResizablePanel id="content">Content</ResizablePanel>
    </ResizablePanelGroup>
  );
}

Types

import type {
  ResizableLayout,
  ResizablePanelGroupHandle,
  ResizablePanelHandle,
  ResizablePanelSize,
} from "@tilt-legal/cubitt-components/resizable";

Credits

Built with react-resizable-panels.

On this page