WebberUI

Stage Manager Scenes

A stage-managed layout — the main scene sits center stage while the rest stack as tilted thumbnails in a sidebar, swapping places with shared-element FLIP and a depth-of-field blur when selected.

This is a WebberUI Pro component

Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.

How to install Pro components →See the plans →

Loading preview…
npx shadcn@latest add "https://webberui.com/r/stage-manager-scenes.json?t=<install token>"

Playground

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

<StageManagerScenes />

Installation

npx shadcn@latest add "https://webberui.com/r/stage-manager-scenes.json?t=<install token>"

Or, once registries are configured in components.json, install it as @webberui/stage-manager-scenes.

Usage

Declare each scene with StageManagerScene, and StageManagerScenes puts the currently selected one center stage while shrinking the rest into sidebar thumbnails. Clicking a thumbnail swaps positions with a shared-element FLIP animation.

import {
  StageManagerScene,
  StageManagerScenes,
} from "@/components/ui/stage-manager-scenes";

<div className="h-[300px] w-full max-w-md">
  <StageManagerScenes defaultActiveId="mail">
    <StageManagerScene id="mail" label="Inbox">
      <div className="flex h-full items-center justify-center bg-sky-600 text-white">
        Inbox
      </div>
    </StageManagerScene>
    <StageManagerScene id="calendar" label="Calendar">
      <div className="flex h-full items-center justify-center bg-rose-500 text-white">
        Calendar
      </div>
    </StageManagerScene>
  </StageManagerScenes>
</div>

Controlled mode: hold activeId yourself and update it in onActiveChange.

const [active, setActive] = React.useState("mail");

<StageManagerScenes activeId={active} onActiveChange={setActive}>
  {/* ...scenes */}
</StageManagerScenes>

Props

StageManagerScenes

PropTypeDefaultDescription
activeIdstringControlled: the id of the scene currently center stage
defaultActiveIdstringfirst sceneInitial stage scene id in uncontrolled mode
onActiveChange(id: string) => voidFires when the stage scene changes (called in both controlled and uncontrolled modes)
side"left" | "right""left"Which side the thumbnail sidebar sits on
labelstring"舞台調度"Accessible label for the whole stage-managed region
childrenReactNodeSeveral StageManagerScene children

StageManagerScene

PropTypeDefaultDescription
idstringUnique scene identifier, used as the controlled value and the FLIP pairing key
labelstringScene title, used for the accessible label and the thumbnail corner label
childrenReactNodeScene content — shown at full size on stage and scaled down as a thumbnail in the sidebar

How it works

  • Each scene binds the same shared element through layoutId; on a switch, the stage scene shrinks back into the sidebar while the selected thumbnail grows onto the stage, the two swapping in a synchronized FLIP.
  • The scene taking the stage focuses through a blur(14px) → blur(0) depth-of-field focus pull, while the sidebar thumbnails keep a slight blur and tilt to reinforce the depth.
  • Sidebar thumbnails scale the entire scene down with transform: scale(), giving a proportional "mini stage" preview rather than maintaining a separate set of thumbnail content.
  • When several StageManagerScenes coexist on one page, each one's LayoutGroup isolates its layoutIds, so scene ids never interfere with each other.

Accessibility

  • Sidebar thumbnails are native buttons, focusable with Tab and activated with Enter / Space; the / arrow keys (plus Home / End) rove focus among the thumbnails.
  • The stage is a role="region" carrying the current scene title as its aria-label; a separate aria-live="polite" region announces the current scene on a switch.
  • The mini preview inside a thumbnail is marked aria-hidden and is not interactive, so assistive technology only reads the button semantics "switch to scene: {label}".
  • When the user has "reduce motion" enabled at the system level, the movement, scaling, and blur all complete instantly and the switch result is shown directly.

On this page