---
type: doc
title: Resizable
description: Accessible panel groups with pointer and keyboard resizing.
---

> Fulldev UI for Astro. The `@fulldev` registry in `components.json` points at `https://ui.full.dev/r/styles/{style}/{name}.json`; see [installation](/astro/docs/installation.md).

```astro title="src/components/examples/resizable/resizable-demo.astro"
---
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
---

<ResizablePanelGroup direction="horizontal" class="max-w-sm rounded-lg border">
  <ResizablePanel defaultSize={50}>
    <div class="flex h-[200px] items-center justify-center p-6">
      <span class="font-semibold">One</span>
    </div>
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={50}>
    <ResizablePanelGroup direction="vertical">
      <ResizablePanel defaultSize={25}>
        <div class="flex h-full items-center justify-center p-6">
          <span class="font-semibold">Two</span>
        </div>
      </ResizablePanel>
      <ResizableHandle withHandle />
      <ResizablePanel defaultSize={75}>
        <div class="flex h-full items-center justify-center p-6">
          <span class="font-semibold">Three</span>
        </div>
      </ResizablePanel>
    </ResizablePanelGroup>
  </ResizablePanel>
</ResizablePanelGroup>
```

## Installation

```bash
npx shadcn@latest add @fulldev/resizable
```

## Usage

```ts
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
```

```astro
<ResizablePanelGroup direction="horizontal">
  <ResizablePanel>One</ResizablePanel>
  <ResizableHandle />
  <ResizablePanel>Two</ResizablePanel>
</ResizablePanelGroup>
```

A group needs one handle between each pair of panels. Sizes are percentages,
such as `defaultSize={50}`. Each group owns only its direct panels and handles,
so a panel can contain another group.

## Composition

```text
ResizablePanelGroup
├── ResizablePanel
├── ResizableHandle
└── ResizablePanel
```

## Vertical

Use `direction="vertical"` for vertical resizing.

```astro title="src/components/examples/resizable/resizable-vertical.astro"
---
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
---

<ResizablePanelGroup
  direction="vertical"
  class="min-h-[200px] max-w-sm rounded-lg border"
>
  <ResizablePanel defaultSize={25}>
    <div class="flex h-full items-center justify-center p-6">
      <span class="font-semibold">Header</span>
    </div>
  </ResizablePanel>
  <ResizableHandle />
  <ResizablePanel defaultSize={75}>
    <div class="flex h-full items-center justify-center p-6">
      <span class="font-semibold">Content</span>
    </div>
  </ResizablePanel>
</ResizablePanelGroup>
```

## Handle

Use the `withHandle` prop on `ResizableHandle` to show a visible handle.

```astro title="src/components/examples/resizable/resizable-handle.astro"
---
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
---

<ResizablePanelGroup
  direction="horizontal"
  class="min-h-[200px] max-w-sm rounded-lg border"
>
  <ResizablePanel defaultSize={25}>
    <div class="flex h-full items-center justify-center p-6">
      <span class="font-semibold">Sidebar</span>
    </div>
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={75}>
    <div class="flex h-full items-center justify-center p-6">
      <span class="font-semibold">Content</span>
    </div>
  </ResizablePanel>
</ResizablePanelGroup>
```

## RTL

```astro title="src/components/examples/resizable/resizable-rtl.astro"
---
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"

const 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: "שלושה",
    },
  },
}

const { dir, values: t } = translations.ar
---

<ResizablePanelGroup
  direction="horizontal"
  class="max-w-sm rounded-lg border"
  dir={dir}
>
  <ResizablePanel defaultSize={50}>
    <div class="flex h-[200px] items-center justify-center p-6">
      <span class="font-semibold">{t.one}</span>
    </div>
  </ResizablePanel>
  <ResizableHandle withHandle />
  <ResizablePanel defaultSize={50}>
    <ResizablePanelGroup direction="vertical" dir={dir}>
      <ResizablePanel defaultSize={25}>
        <div class="flex h-full items-center justify-center p-6">
          <span class="font-semibold">{t.two}</span>
        </div>
      </ResizablePanel>
      <ResizableHandle withHandle />
      <ResizablePanel defaultSize={75}>
        <div class="flex h-full items-center justify-center p-6">
          <span class="font-semibold">{t.three}</span>
        </div>
      </ResizablePanel>
    </ResizablePanelGroup>
  </ResizablePanel>
</ResizablePanelGroup>
```

## Collapsible

Add `collapsible` and `collapsedSize` to a panel. Focus the handle and press
`Enter` to collapse or restore the panel before it. Dragging through `minSize`
also collapses it.

```astro live
---
import {
  ResizableHandle,
  ResizablePanel,
  ResizablePanelGroup,
} from "@/components/ui/resizable"
---

<ResizablePanelGroup class="h-48 max-w-2xl rounded-lg border">
  <ResizablePanel
    defaultSize={30}
    minSize={20}
    collapsible
    collapsedSize={0}
    class="flex items-center justify-center p-4"
  >
    Collapsible sidebar
  </ResizablePanel>
  <ResizableHandle withHandle aria-label="Resize or collapse sidebar" />
  <ResizablePanel
    defaultSize={70}
    minSize={30}
    class="flex items-center justify-center p-4"
  >
    Main content
  </ResizablePanel>
</ResizablePanelGroup>
```

## Keyboard Controls

| Key                   | Action                                                       |
| --------------------- | ------------------------------------------------------------ |
| Arrow keys            | Resize by `keyboardResizeBy` in the group direction.         |
| `Shift` + arrow       | Resize to the available limit.                               |
| `Home` / `End`        | Minimize or maximize the panel before the handle.            |
| `Enter`               | Collapse or restore the collapsible panel before the handle. |
| `F6` / `Shift` + `F6` | Focus the next or previous handle in the group.              |

## API Reference

Source: [`src/components/ui/resizable`](https://github.com/fulldotdev/ui/tree/main/src/components/ui/resizable)

### ResizablePanelGroup

`Resizable` is an alias for `ResizablePanelGroup`.

| Prop               | Type                         | Default        | Description                            |
| ------------------ | ---------------------------- | -------------- | -------------------------------------- |
| `direction`        | `"horizontal" \| "vertical"` | `"horizontal"` | Sets the layout and resize axis.       |
| `keyboardResizeBy` | `number`                     | `10`           | Percentage moved by an arrow keypress. |

### ResizablePanel

All sizes are percentages between 0 and 100.

| Prop            | Type      | Default    | Description                                 |
| --------------- | --------- | ---------- | ------------------------------------------- |
| `defaultSize`   | `number`  | even split | Initial panel size.                         |
| `minSize`       | `number`  | `0`        | Minimum expanded size.                      |
| `maxSize`       | `number`  | `100`      | Maximum size.                               |
| `collapsible`   | `boolean` | `false`    | Allows the panel to use its collapsed size. |
| `collapsedSize` | `number`  | `0`        | Size used while collapsed.                  |

### ResizableHandle

| Prop         | Type      | Default | Description                              |
| ------------ | --------- | ------- | ---------------------------------------- |
| `withHandle` | `boolean` | `false` | Shows a visible grip on the separator.   |
| `disabled`   | `boolean` | `false` | Blocks keyboard resizing on this handle. |

The root emits `resizable:change` with `{ layout: number[] }` and
`resizable:dragging` with `{ dragging: boolean }`. Dispatch `resizable:set` with
`{ layout: number[] }` to set a layout from client code. See the
[Data Slot docs](https://github.com/bejamas/data-slot/blob/main/packages/resizable/README.md)
for constraints and controller methods.

## Install what this page shows

```bash
npx shadcn@latest add @fulldev/resizable-examples
```
