Stage Manager Scenes
舞台調度版面:主場景置中,其餘以傾斜縮圖疊列側欄,點選後共享元素 FLIP 對調並帶景深模糊。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<StageManagerScenes />
安裝
npx shadcn@latest add https://webberui.com/r/stage-manager-scenes.json或在 components.json 設定 registries 後,改用 @webberui/stage-manager-scenes 安裝。
安裝依賴後,從 registry JSON(/r/stage-manager-scenes.json 的 files[0].content)複製 stage-manager-scenes.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
以 StageManagerScene 宣告每個場景,StageManagerScenes 會把目前選中的放上中央舞台,其餘縮繪為側欄縮圖。點選縮圖即以共享元素 FLIP 對調位置。
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="收件匣">
<div className="flex h-full items-center justify-center bg-sky-600 text-white">
收件匣
</div>
</StageManagerScene>
<StageManagerScene id="calendar" label="行事曆">
<div className="flex h-full items-center justify-center bg-rose-500 text-white">
行事曆
</div>
</StageManagerScene>
</StageManagerScenes>
</div>受控模式:自行持有 activeId 並在 onActiveChange 更新。
const [active, setActive] = React.useState("mail");
<StageManagerScenes activeId={active} onActiveChange={setActive}>
{/* ...scenes */}
</StageManagerScenes>Props
StageManagerScenes
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
activeId | string | — | 受控:目前置於舞台中央的場景 id |
defaultActiveId | string | 第一個場景 | 非受控初始舞台場景 id |
onActiveChange | (id: string) => void | — | 舞台場景變更時觸發(受控與非受控皆呼叫) |
side | "left" | "right" | "left" | 側欄縮圖列的位置 |
label | string | "舞台調度" | 整個調度區的無障礙標籤 |
children | ReactNode | — | 若干 StageManagerScene 子元件 |
StageManagerScene
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 場景唯一識別碼,作為受控值與 FLIP 配對鍵 |
label | string | — | 場景標題,用於無障礙標籤與縮圖角落標籤 |
children | ReactNode | — | 場景內容,舞台顯示原尺寸、側欄縮繪為縮圖 |
細節
- 每個場景以
layoutId綁定同一個共享元素;切換時舞台場景縮回側欄、選中縮圖放大登台,兩者同步 FLIP 對調。 - 登台場景以
blur(14px) → blur(0)的景深模糊完成聚焦(focus pull),側欄縮圖則維持輕微模糊與傾斜以強化縱深。 - 側欄縮圖用
transform: scale()縮繪整個場景,等比呈現「迷你舞台」預覽,而非另外維護一份縮圖內容。 - 多個
StageManagerScenes同頁並存時,各自的LayoutGroup會隔離layoutId,場景 id 不會互相干擾。
可及性
- 側欄縮圖為原生
button,可 Tab 聚焦、Enter/空白鍵啟用;方向鍵↑/↓(含Home/End)在縮圖間漫遊焦點。 - 舞台為
role="region",並帶入目前場景標題作為aria-label;另有aria-live="polite"區塊於切換時播報目前場景。 - 縮圖的迷你預覽標記為
aria-hidden且不可互動,輔助科技只讀到「切換到場景:{label}」的按鈕語意。 - 使用者系統開啟「減少動態效果」時,位移、縮放與模糊皆即時完成,直接呈現切換結果。