App Shells & Panels

Elastic Split Workspace

A multi-column drag-to-split panel workspace whose dividers have spring feedback; panels collapse to a thin strip in one click and the neighbouring panels reflow elastically.

This is a WebberUI Pro component

The install command below needs a licence to run; without one it returns 401.

How to install Pro components →See the plans →

Bring this into your project

Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.

npx webberui@latest add "https://webberui.com/r/elastic-split-workspace.en.json?t=<install token>"

New project or installation trouble? Start here →

Playground

Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.

10
48
Active edited usageDefault props
<ElasticSplitWorkspace/>

The complete example includes the preview layout and data. Install the component first, then paste this file into your project.

Installation

npx webberui@latest add "https://webberui.com/r/elastic-split-workspace.en.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/elastic-split-workspace.

Usage

Declare each column with SplitPanel; the workspace inserts a draggable divider between adjacent panels automatically:

import {
  ElasticSplitWorkspace,
  SplitPanel,
} from "@/components/ui/elastic-split-workspace";

<ElasticSplitWorkspace className="h-[320px]">
  <SplitPanel id="nav" title="Navigation" defaultSize={22} minSize={14} collapsible>
    {/* sidebar content */}
  </SplitPanel>
  <SplitPanel id="main" title="Main" defaultSize={56}>
    {/* main content */}
  </SplitPanel>
  <SplitPanel id="aside" title="Properties" defaultSize={22} collapsible>
    {/* inspector content */}
  </SplitPanel>
</ElasticSplitWorkspace>;
  • Drag a divider to adjust the ratio of the adjacent panels; dragging past the minimum meets rubber-band resistance and springs back on release.
  • A collapsible panel gets a collapse button in its title row; once collapsed it becomes a clickable thin strip to expand, and the neighbouring panels reflow immediately with an elastic width animation.
  • Pass direction="vertical" to split into rows (top and bottom) instead.

Props

ElasticSplitWorkspace

PropTypeDefaultDescription
childrenReactNode—The set of panels; children must be SplitPanel elements
direction"horizontal" | "vertical""horizontal"Split direction: horizontal columns or vertical rows
onPanelCollapse(id: string, collapsed: boolean) => void—Fires when a panel collapses or expands
aria-labelstring"Divide Workspace"Accessible label for the workspace
classNamestring—Appended to the frame's className

SplitPanel

PropTypeDefaultDescription
idstring—Unique identifier for the panel
defaultSizenumber1Initial ratio (a relative weight; panels divide the remaining space in proportion)
minSizenumber10Minimum size (as a percentage of the workspace, 0–100)
collapsiblebooleanfalseWhether it can collapse to a thin strip in one click
collapsedSizenumber48Pixel width (horizontal) or height (vertical) of the collapsed strip
defaultCollapsedbooleanfalseWhether it starts collapsed
titleReactNode—Title, shown in the panel header and on the collapsed strip
iconReactNode—Small icon next to the title
classNamestring—Appended to the panel container's className

How it works

  • Spring physics: panel widths track the pointer instantly while dragging a divider; past a panel's minSize boundary a rubber-band damping applies, and on release a spring brings it back to a legal boundary.
  • Elastic reflow: panels transition flex-grow and flex-basis with springs, so when one panel collapses to a strip the adjacent expanded panels continuously take up the released space, producing a live reflow.
  • Ratios are preserved: expanding a panel after collapsing it returns to the ratio it had before, rather than resetting.
  • Measurement: dragging measures the actual pixel sizes of the two adjacent panels and converts them into weights, so only that pair is adjusted and the other panels are untouched.

Accessibility

  • Each divider is a role="separator" with aria-orientation and aria-valuenow / valuemin / valuemax, focusable with Tab.
  • With a divider focused, ← → resize step by step in the horizontal direction and ↑ ↓ in the vertical.
  • The collapse / expand buttons are native <button>s with aria-label and full keyboard support.
  • The panels on either side of a collapsed strip are clickable buttons — the whole strip expands it.
  • With "reduce motion" enabled, the spring transitions become instant changes; functionality and structure are entirely unchanged.