Resizable
Accessible resizable panel groups and layouts with keyboard support.
Installation
Add the component to your project:
rails generate shadcn:component resizable
Usage
<%= render Shadcn::ResizablePanelGroupComponent.new(direction: :horizontal) do |group| %>
<% group.with_panel(default_size: 50) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">One</span>
</div>
<% end %>
<% group.with_handle(with_handle: true) %>
<% group.with_panel(default_size: 50) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Two</span>
</div>
<% end %>
<% end %>
Examples
Vertical
Use the direction: :vertical option for vertical resizing.
<%= render Shadcn::ResizablePanelGroupComponent.new(direction: :vertical, class_name: "h-[200px]") do |group| %>
<% group.with_panel(default_size: 25) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Header</span>
</div>
<% end %>
<% group.with_handle %>
<% group.with_panel(default_size: 75) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Content</span>
</div>
<% end %>
<% end %>
With Handle
Add a visible grip handle with with_handle: true.
<%= render Shadcn::ResizablePanelGroupComponent.new(direction: :horizontal) do |group| %>
<% group.with_panel(default_size: 30) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Sidebar</span>
</div>
<% end %>
<% group.with_handle(with_handle: true) %>
<% group.with_panel(default_size: 70) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Content</span>
</div>
<% end %>
<% end %>
Three Panels
Create layouts with multiple panels by adding more panels and handles.
<%= render Shadcn::ResizablePanelGroupComponent.new(direction: :horizontal) do |group| %>
<% group.with_panel(default_size: 25) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">One</span>
</div>
<% end %>
<% group.with_handle(with_handle: true) %>
<% group.with_panel(default_size: 50) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Two</span>
</div>
<% end %>
<% group.with_handle(with_handle: true) %>
<% group.with_panel(default_size: 25) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Three</span>
</div>
<% end %>
<% end %>
Min/Max Constraints
Use min_size and max_size to constrain panel sizes.
<%= render Shadcn::ResizablePanelGroupComponent.new(direction: :horizontal) do |group| %>
<% group.with_panel(default_size: 30, min_size: 20, max_size: 40) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">20-40%</span>
</div>
<% end %>
<% group.with_handle(with_handle: true) %>
<% group.with_panel(default_size: 70, min_size: 60, max_size: 80) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">60-80%</span>
</div>
<% end %>
<% end %>
Nested Layout
Create complex layouts by nesting panel groups.
<%= render Shadcn::ResizablePanelGroupComponent.new(direction: :horizontal, class_name: "h-[300px]") do |group| %>
<% group.with_panel(default_size: 25) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Sidebar</span>
</div>
<% end %>
<% group.with_handle %>
<% group.with_panel(default_size: 75) do %>
<%= render Shadcn::ResizablePanelGroupComponent.new(direction: :vertical) do |inner| %>
<% inner.with_panel(default_size: 30) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Header</span>
</div>
<% end %>
<% inner.with_handle %>
<% inner.with_panel(default_size: 70) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Content</span>
</div>
<% end %>
<% end %>
<% end %>
<% end %>
Persistent Layout
Use auto_save_id to persist panel sizes in localStorage.
Resize the panels above, then refresh the page. Your layout will be restored.
<%= render Shadcn::ResizablePanelGroupComponent.new(
direction: :horizontal,
auto_save_id: "my-layout"
) do |group| %>
<% group.with_panel(default_size: 50) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Panel One</span>
</div>
<% end %>
<% group.with_handle(with_handle: true) %>
<% group.with_panel(default_size: 50) do %>
<div class="flex h-full items-center justify-center p-6">
<span class="font-semibold">Panel Two</span>
</div>
<% end %>
<% end %>
API Reference
ResizablePanelGroupComponent
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| direction |
Symbol
|
:horizontal
|
Direction of panels (:horizontal or :vertical) |
| auto_save_id |
String
|
nil
|
ID for persisting sizes to localStorage |
Slots
| Slot | Props | Description |
|---|---|---|
| with_panel |
default_size:,
min_size:,
max_size:
|
Resizable panel with optional size constraints (percentages 0-100) |
| with_handle | with_handle: |
Draggable separator between panels |
Stimulus Controller
This component requires JavaScript. The Stimulus controller shadcn--resizable provides interactivity.
Handles panel resizing with mouse, touch, and keyboard support.
Installation
Add to your config/importmap.rb:
pin "shadcn-rails", to: "shadcn/index.js"
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
yarn add shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails"
const application = Application.start()
registerShadcnControllers(application)
Or import just this controller:
import ResizableController from "shadcn-rails/controllers/resizable_controller"
application.register("shadcn--resizable", ResizableController)
Targets
| Name | Description |
|---|---|
| panel | Resizable panel elements |
| handle | Draggable resize handles |
Values
| Name | Type | Default | Description |
|---|---|---|---|
| direction | String |
"horizontal" |
Panel direction (horizontal or vertical) |
| autoSaveId | String |
null |
ID for localStorage persistence |
Actions
| Action | Description |
|---|---|
| startResize | Begin resize operation (mouse/touch) |
TypeScript
Type definitions are included. Import types as needed:
import type { ResizableController } from "shadcn-rails"
Accessibility
- Handle uses
role="separator"for semantics - Sets appropriate
aria-orientation - Handle is keyboard focusable with
tabindex="0" - Keyboard navigation:
- Arrow Left/Arrow Right to resize horizontal panels
- Arrow Up/Arrow Down to resize vertical panels
- Shift + Arrow for larger adjustments (10%)
- Home to collapse previous panel to minimum
- End to collapse next panel to minimum
- Touch support for mobile devices
On This Page