Bloom Logo

Resizable

Accessible resizable panel layout groups with horizontal and vertical drag handles built on react-resizable-panels.

importimport { Resizable } from "@/components/ui/resizable/resizable";
$npx @bloomui-react/cli add resizable
resizable.tsx
"use client";

import { Icon } from "@iconify/react";
import type * as React from "react";
import { Group, Panel, Separator } from "react-resizable-panels";
import { cn } from "@/lib/utils";

export interface ResizablePanelGroupProps
  extends Omit<React.ComponentProps<typeof Group>, "orientation"> {
  direction?: "horizontal" | "vertical";
}

const ResizablePanelGroup = ({
  className,
  direction = "horizontal",
  ...props
}: ResizablePanelGroupProps) => (
  <Group
    orientation={direction}
    className={cn(
      "flex size-full data-[panel-group-direction=vertical]:flex-col",
      className,
    )}
    {...props}
  />
);

const ResizablePanel = Panel;

const ResizableHandle = ({
  withHandle,
  className,
  ...props
}: React.ComponentProps<typeof Separator> & {
  withHandle?: boolean;
}) => (
  <Separator
    className={cn(
      "relative flex w-px items-center justify-center bg-zinc-200 dark:bg-zinc-800 after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-500/20 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90",
      className,
    )}
    {...props}
  >
    {withHandle && (
      <div className="z-10 flex h-4 w-3 items-center justify-center rounded-sm border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-900 shadow-xs">
        <Icon
          icon="hugeicons:drag-drop-vertical"
          className="size-2.5 text-zinc-400 dark:text-zinc-500"
        />
      </div>
    )}
  </Separator>
);

export { ResizableHandle, ResizablePanel, ResizablePanelGroup };

Default

Horizontal resizable panels with drag handle grip.

Sidebar (30%)
Main Content (70%)

Vertical Layout

Vertical layout direction using direction=vertical.

direction: horizontal | vertical
Top Viewport (40%)
Bottom Terminal / Console (60%)
API Reference

Props — Resizable Components

Supported properties for Resizable subcomponents.

ComponentPropTypeDescription
ResizablePanelGroupdirection'horizontal' | 'vertical'Split direction layout for panels.
ResizablePaneldefaultSizenumberInitial percentage size of the panel.
ResizableHandlewithHandlebooleanRenders drag grip handle icon badge.