---
title: Resizable
description: Accessible resizable panel groups and layouts with keyboard support.
---

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/resizable"

templ ResizableDemo() {
	@resizable.PanelGroup(resizable.PanelGroupProps{
		Orientation: resizable.OrientationHorizontal,
		Class:       "max-w-sm rounded-lg border",
	}) {
		@resizable.Panel(resizable.PanelProps{DefaultSize: "50%"}) {
			<div class="flex h-[200px] items-center justify-center p-6">
				<span class="font-semibold">One</span>
			</div>
		}
		@resizable.Handle(resizable.HandleProps{WithHandle: true})
		@resizable.Panel(resizable.PanelProps{DefaultSize: "50%"}) {
			@resizable.PanelGroup(resizable.PanelGroupProps{Orientation: resizable.OrientationVertical}) {
				@resizable.Panel(resizable.PanelProps{DefaultSize: "25%"}) {
					<div class="flex h-full items-center justify-center p-6">
						<span class="font-semibold">Two</span>
					</div>
				}
				@resizable.Handle(resizable.HandleProps{WithHandle: true})
				@resizable.Panel(resizable.PanelProps{DefaultSize: "75%"}) {
					<div class="flex h-full items-center justify-center p-6">
						<span class="font-semibold">Three</span>
					</div>
				}
			}
		}
	}
}
```

## About

The `Resizable` component is a Templ pendant of [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels), the same primitive used by shadcn's Base UI variant. Its UI behavior targets `react-resizable-panels` `4.5.8`, the version currently resolved by shadcn/ui.

## Installation

<CodeTabs>

<TabsList>
  <TabsTrigger value="cli">Command</TabsTrigger>
  <TabsTrigger value="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent value="cli">

```bash
shadcn-templ add resizable
```

</TabsContent>

<TabsContent value="manual">

<Steps className="mb-0 pt-2">

<Step>Copy and paste the following code into your project.</Step>

<ComponentSource name="resizable" title="components/resizable/resizable.templ" />

<ComponentSource name="resizable" title="components/resizable/resizable.js" />

Component scripts are loaded through the shared script bundle, see [JavaScript](/docs/installation#javascript).

<Step>Update the import paths to match your project setup.</Step>

</Steps>

</TabsContent>

</CodeTabs>

## Usage

```go showLineNumbers
import "github.com/axadrn/shadcn-templ/v2/components/resizable"
```

```templ showLineNumbers
@resizable.PanelGroup() {
  @resizable.Panel() {
    One
  }
  @resizable.Handle()
  @resizable.Panel() {
    Two
  }
}
```

## Composition

`Panel` and `Handle` components must be direct children of `PanelGroup`.

```text
PanelGroup
├── Panel
├── Handle
└── Panel
```

## Vertical

Use `Orientation: resizable.OrientationVertical` for vertical resizing.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/resizable"

templ ResizableVertical() {
	@resizable.PanelGroup(resizable.PanelGroupProps{
		Orientation: resizable.OrientationVertical,
		Class:       "min-h-[200px] max-w-sm rounded-lg border",
	}) {
		@resizable.Panel(resizable.PanelProps{DefaultSize: "25%"}) {
			<div class="flex h-full items-center justify-center p-6">
				<span class="font-semibold">Header</span>
			</div>
		}
		@resizable.Handle()
		@resizable.Panel(resizable.PanelProps{DefaultSize: "75%"}) {
			<div class="flex h-full items-center justify-center p-6">
				<span class="font-semibold">Content</span>
			</div>
		}
	}
}
```

## Handle

Use `WithHandle: true` to show a visible grip.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/resizable"

templ ResizableHandle() {
	@resizable.PanelGroup(resizable.PanelGroupProps{
		Orientation: resizable.OrientationHorizontal,
		Class:       "min-h-[200px] max-w-sm rounded-lg border",
	}) {
		@resizable.Panel(resizable.PanelProps{DefaultSize: "25%"}) {
			<div class="flex h-full items-center justify-center p-6">
				<span class="font-semibold">Sidebar</span>
			</div>
		}
		@resizable.Handle(resizable.HandleProps{WithHandle: true})
		@resizable.Panel(resizable.PanelProps{DefaultSize: "75%"}) {
			<div class="flex h-full items-center justify-center p-6">
				<span class="font-semibold">Content</span>
			</div>
		}
	}
}
```

## RTL

Resizable panel groups follow the document direction.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/resizable"

templ ResizableRTL() {
	@resizable.PanelGroup(resizable.PanelGroupProps{
		Orientation: resizable.OrientationHorizontal,
		Class:       "max-w-sm rounded-lg border",
		Attributes:  templ.Attributes{"dir": "rtl"},
	}) {
		@resizable.Panel(resizable.PanelProps{DefaultSize: "50%"}) {
			<div class="flex h-[200px] items-center justify-center p-6">
				<span class="font-semibold">واحد</span>
			</div>
		}
		@resizable.Handle(resizable.HandleProps{WithHandle: true})
		@resizable.Panel(resizable.PanelProps{DefaultSize: "50%"}) {
			@resizable.PanelGroup(resizable.PanelGroupProps{
				Orientation: resizable.OrientationVertical,
				Attributes:  templ.Attributes{"dir": "rtl"},
			}) {
				@resizable.Panel(resizable.PanelProps{DefaultSize: "25%"}) {
					<div class="flex h-full items-center justify-center p-6">
						<span class="font-semibold">اثنان</span>
					</div>
				}
				@resizable.Handle(resizable.HandleProps{WithHandle: true})
				@resizable.Panel(resizable.PanelProps{DefaultSize: "75%"}) {
					<div class="flex h-full items-center justify-center p-6">
						<span class="font-semibold">ثلاثة</span>
					</div>
				}
			}
		}
	}
}
```

## Imperative API

The browser API mirrors the panel and group imperative handles used by shadcn's primitive.

```js
window.tui.resizable.resize("panel-id", "40%")
window.tui.resizable.collapse("panel-id")
window.tui.resizable.expand("panel-id")
window.tui.resizable.getSize("panel-id")
window.tui.resizable.getLayout("group-id")
window.tui.resizable.setLayout("group-id", {
  "left-panel": 40,
  "right-panel": 60,
})
```

`getSize` returns `{ asPercentage, inPixels }`. Group layouts are objects keyed by panel ID, matching `react-resizable-panels` v4. `PanelGroup` dispatches `resizable-layout-change` while resizing and `resizable-layout-changed` when the interaction is committed. Both events expose `{ layout }` in `event.detail`; the completed event also includes `isUserInteraction`.

## API Reference

### PanelGroup

| Prop                      | Type                                             | Default                 |
| ------------------------- | ------------------------------------------------ | ----------------------- |
| `Orientation`             | `OrientationHorizontal \| OrientationVertical` | `OrientationHorizontal` |
| `DefaultLayout`           | `map[string]float64`                             | -                       |
| `Disabled`                | `bool`                                           | `false`                 |
| `DisableCursor`           | `bool`                                           | `false`                 |
| `ResizeTargetMinimumSize` | `ResizeTargetMinimumSize`                        | `{Coarse: 20, Fine: 10}`|
| `ID`                      | `string`                                         | generated               |
| `Class`                   | `string`                                         | -                       |
| `Style`                   | `string`                                         | -                       |
| `Attributes`              | `templ.Attributes`                               | -                       |

### Panel

Sizes accept percentages, pixels, unitless percentage strings, and CSS length units. Numeric values passed to the JavaScript API are pixels, matching `react-resizable-panels` v4.

| Prop            | Type               | Default |
| --------------- | ------------------ | ------- |
| `DefaultSize`   | `string`           | auto    |
| `MinSize`       | `string`           | `0%`    |
| `MaxSize`       | `string`           | `100%`  |
| `Collapsible`   | `bool`             | `false` |
| `CollapsedSize` | `string`           | `0%`    |
| `Disabled`      | `bool`             | `false` |
| `GroupResizeBehavior` | `GroupResizeBehavior` | `PreserveRelativeSize` |
| `ID`            | `string`           | generated |
| `Class`         | `string`           | -       |
| `Style`         | `string`           | -       |
| `Attributes`    | `templ.Attributes` | -       |

### Handle

| Prop                 | Type               | Default |
| -------------------- | ------------------ | ------- |
| `WithHandle`         | `bool`             | `false` |
| `Disabled`           | `bool`             | `false` |
| `DisableDoubleClick` | `bool`             | `false` |
| `ID`                 | `string`           | generated |
| `Class`              | `string`           | -       |
| `Style`              | `string`           | -       |
| `Attributes`         | `templ.Attributes` | -       |

## Changelog

### `react-resizable-panels` 4.5.8

This pendant follows the concrete v4 version currently resolved by shadcn/ui rather than an unspecified moving `v4` target. Panel sizes use CSS-aware values such as `"50%"`, layouts are keyed by panel ID, `PanelGroup` maps to `Group`, and `Handle` maps to `Separator`.
