codefast/ui

Command Palette

Search for a command to run...

Source
Layout

Resizable

Drag-to-resize panel groups. Supports horizontal, vertical, and nested layouts.

Examples

Vertical split

Stack panels and resize along the vertical axis.

Header
Content
19 lines
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";

export function ResizableVertical() {
  return (
    <ResizableGroup orientation="vertical" className="min-h-50 max-w-sm rounded-lg border">
      <ResizablePanel defaultSize="25%">
        <div className="flex h-full items-center justify-center p-6">
          <span className="font-semibold">Header</span>
        </div>
      </ResizablePanel>
      <ResizableSeparator />
      <ResizablePanel defaultSize="75%">
        <div className="flex h-full items-center justify-center p-6">
          <span className="font-semibold">Content</span>
        </div>
      </ResizablePanel>
    </ResizableGroup>
  );
}

Handle

Use the withHandle prop on ResizableSeparator to show a visible handle.

Sidebar
Content
19 lines
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";

export function ResizableSeparatorDemo() {
  return (
    <ResizableGroup orientation="horizontal" className="min-h-50 max-w-md rounded-lg border md:min-w-112.5">
      <ResizablePanel defaultSize="25%">
        <div className="flex h-full items-center justify-center p-6">
          <span className="font-semibold">Sidebar</span>
        </div>
      </ResizablePanel>
      <ResizableSeparator withHandle />
      <ResizablePanel defaultSize="75%">
        <div className="flex h-full items-center justify-center p-6">
          <span className="font-semibold">Content</span>
        </div>
      </ResizablePanel>
    </ResizableGroup>
  );
}

RTL

Right-to-left layout support for languages such as Arabic and Hebrew.

Translations are AI-generated for demonstration and may be imperfect.

واحد
اثنان
ثلاثة
61 lines
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";

import type { Translations } from "#/features/components-catalog/components/detail/language";
import { useTranslation } from "#/features/components-catalog/components/detail/language-context";

const translations: Translations = {
  en: {
    dir: "ltr",
    values: {
      one: "One",
      two: "Two",
      three: "Three",
    },
  },
  ar: {
    dir: "rtl",
    values: {
      one: "واحد",
      two: "اثنان",
      three: "ثلاثة",
    },
  },
  he: {
    dir: "rtl",
    values: {
      one: "אחד",
      two: "שניים",
      three: "שלושה",
    },
  },
};

export function ResizableRtl() {
  const { dir, t } = useTranslation(translations, "ar");

  return (
    <ResizableGroup orientation="horizontal" className="max-w-sm rounded-lg border" dir={dir}>
      <ResizablePanel defaultSize="50%">
        <div className="flex h-50 items-center justify-center p-6">
          <span className="font-semibold">{t.one}</span>
        </div>
      </ResizablePanel>
      <ResizableSeparator withHandle />
      <ResizablePanel defaultSize="50%">
        <ResizableGroup orientation="vertical" dir={dir}>
          <ResizablePanel defaultSize="25%">
            <div className="flex h-full items-center justify-center p-6">
              <span className="font-semibold">{t.two}</span>
            </div>
          </ResizablePanel>
          <ResizableSeparator withHandle />
          <ResizablePanel defaultSize="75%">
            <div className="flex h-full items-center justify-center p-6">
              <span className="font-semibold">{t.three}</span>
            </div>
          </ResizablePanel>
        </ResizableGroup>
      </ResizablePanel>
    </ResizableGroup>
  );
}

Usage

The minimal import and composition — see Examples below for styled, real-world variants.

15 lines
import { ResizableGroup, ResizablePanel, ResizableSeparator } from "@codefast/ui/resizable";

export function ResizableUsage() {
  return (
    <ResizableGroup className="max-w-md rounded-lg border">
      <ResizablePanel defaultSize={50}>
        <div className="flex h-32 items-center justify-center p-6">One</div>
      </ResizablePanel>
      <ResizableSeparator />
      <ResizablePanel defaultSize={50}>
        <div className="flex h-32 items-center justify-center p-6">Two</div>
      </ResizablePanel>
    </ResizableGroup>
  );
}

Anatomy

How the parts nest — every slot the component exposes, in composition order.

ResizableGroup
├── ResizablePanel
├── ResizableSeparator
└── ResizablePanel

Features

  • Built on react-resizable-panels — defaultSize/minSize/maxSize are percentages of the group, not pixels.
  • withHandle on ResizableSeparator adds a small visible grip in the middle of the drag handle.
  • Nest a ResizableGroup inside a ResizablePanel to combine horizontal and vertical splits in one layout.

API reference

Props for each part of the component. All native element props are also forwarded.

ResizableGroup

A row or column of resizable panels.

orientation"horizontal" | "vertical"

Axis the panels are laid along.

Default"horizontal"

ResizablePanel

defaultSizenumber (percent)

The panel's initial size.

minSizenumber (percent)

The panel's minimum size.

Default0

maxSizenumber (percent)

The panel's maximum size.

Default100

ResizableSeparator

The draggable handle placed between two panels.

withHandleboolean

Shows a small visible grip in the middle of the drag handle.

Defaultfalse

Accessibility

Built to be keyboard-navigable and screen-reader friendly out of the box.

KeyFunction
TabMoves focus to a separator handle.
Arrow+LeftResizes the panels by a step.
Arrow+RightResizes the panels by a step.
  • Each handle is a focusable separator with aria-valuenow for its position.
  • Set sensible minSize so panels can’t collapse to nothing by accident.
  • Provide a non-drag fallback layout on touch where resizing is awkward.

Guidelines

Conventions that keep usage consistent across an app.

Do

  • Use for app shells — sidebars, editors, split views.
  • Set min/max sizes to keep panels usable.

Don’t

  • Don’t use for simple content that doesn’t need resizing.
  • Don’t allow a panel to shrink below a readable size.

Explore further

Ready to integrate?

Follow the Getting Started guide to install @codefast/ui, or browse the full component gallery.