Resizable
Anatomy
Draggable panel dividers that enable horizontal or vertical resizing of adjacent content panels. Uses flex layout with draggable handles.
maud_ui::primitives::resizable
Props
Generated from public Rust fields. Defaults are evaluated from the implementation.
| Prop | Type | Default | Description |
|---|---|---|---|
id | String | "resizable" | No description |
panels | Vec<Panel> | [] | No description |
direction | Direction | Horizontal | No description |
Examples
Sidebar + Content
Three-column Layout
Explorer
Editor
Select a file from the explorer to view its contents here. This center panel occupies the majority of the available space.
Inspector
Properties and metadata for the selected item will appear in this panel.
Usage and composition
Import
use maud_ui::primitives::resizable::{self, Props, Panel, Direction};
Example
use maud::html;
use maud_ui::primitives::resizable;
html! {
(resizable::render(resizable::Props {
id: "demo-resize".to_string(),
direction: resizable::Direction::Horizontal,
panels: vec![
resizable::Panel {
content: html! { div { "Sidebar" } },
default_size: 30.0,
min_size: Some(15.0),
},
resizable::Panel {
content: html! { div { "Main content" } },
default_size: 70.0,
min_size: Some(30.0),
},
],
}))
}
Panel Struct
| Field | Type | Description |
|---|---|---|
| content | Markup | Panel content markup. |
| default_size | f64 | Initial flex proportion (typically 0–100 for percentages). |
| min_size | Option | Minimum percentage of the whole group (default: 10.0), independent of the initial flex proportions. |
Direction Enum
| Value | Description |
|---|---|
| Horizontal | Panels side-by-side; handles are vertical dividers. |
| Vertical | Panels stacked; handles are horizontal dividers. |
Usage Patterns
Two-panel horizontal layout (sidebar + content)
html! {
(resizable::render(resizable::Props {
id: "sidebar-layout".to_string(),
direction: resizable::Direction::Horizontal,
panels: vec![
resizable::Panel {
content: html! { div { h3 { "Navigation" } } },
default_size: 30.0,
min_size: Some(15.0),
},
resizable::Panel {
content: html! { div { p { "Main dashboard" } } },
default_size: 70.0,
min_size: Some(30.0),
},
],
}))
}
Three-panel horizontal (file explorer layout)
html! {
(resizable::render(resizable::Props {
id: "editor-layout".to_string(),
direction: resizable::Direction::Horizontal,
panels: vec![
resizable::Panel {
content: html! { div { "Explorer" } },
default_size: 20.0,
min_size: Some(10.0),
},
resizable::Panel {
content: html! { div { "Editor" } },
default_size: 55.0,
min_size: Some(20.0),
},
resizable::Panel {
content: html! { div { "Inspector" } },
default_size: 25.0,
min_size: Some(10.0),
},
],
}))
}
Vertical split (top + bottom)
html! {
(resizable::render(resizable::Props {
id: "vertical-split".to_string(),
direction: resizable::Direction::Vertical,
panels: vec![
resizable::Panel {
content: html! { div { "Preview" } },
default_size: 60.0,
min_size: Some(30.0),
},
resizable::Panel {
content: html! { div { "Console" } },
default_size: 40.0,
min_size: Some(20.0),
},
],
}))
}
Data Attributes
data-mui="resizable"— root element marker.data-direction— "horizontal" or "vertical" for client JS routing.data-index— handle index (separates panels N and N+1).data-min-size— minimum panel size as a percentage (e.g., "15.0").
Related
Drawer, Card (fixed layouts), Sheet (modal overlay).
Shadcn reference
https://ui.shadcn.com/docs/components/resizable
Accessibility
- Each handle is a
<div role="separator">witharia-orientation(horizontal/vertical). - With JavaScript initialized, handles are keyboard-focusable (
tabindex="0"), andaria-valuenowreflects their current position. - Drag and keyboard resizing are client-JavaScript controlled. Without the controller, panels remain readable and each divider is marked disabled and removed from the tab order.
- If the panel minima exceed the available group size, the controller scales them proportionally. Reported ARIA positions continue to reflect the rendered sizes. This invalid-constraint fallback can differ from the pinned reference's reported position.