Expose Overview
一鍵讓整頁各區塊以 FLIP 同時縮小飛入縮圖總覽,點選縮圖即放大回位,形成頁面級空間導航地圖。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
3
12
240
<ExposeOverview />
安裝
npx shadcn@latest add https://webberui.com/r/expose-overview.json或在 components.json 設定 registries 後,改用 @webberui/expose-overview 安裝。
安裝依賴後,從 registry JSON(/r/expose-overview.json 的 files[0].content)複製 expose-overview.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion lucide-react clsx tailwind-merge使用
以 ExposeOverview 包住多個 ExposeSection,每個 section 是一個整頁區塊。工具列上的「總覽」鈕會把所有區塊縮成縮圖網格,點任一縮圖即放大回到該區塊。
import { ExposeOverview, ExposeSection } from "@/components/ui/expose-overview";
<ExposeOverview height={320} columns={3} defaultActiveId="cover">
<ExposeSection id="cover" label="封面">
<div className="flex h-full w-full items-center justify-center bg-violet-500 text-white">
封面
</div>
</ExposeSection>
<ExposeSection id="features" label="功能">
<div className="flex h-full w-full items-center justify-center bg-sky-500 text-white">
功能
</div>
</ExposeSection>
<ExposeSection id="pricing" label="定價">
<div className="flex h-full w-full items-center justify-center bg-emerald-500 text-white">
定價
</div>
</ExposeSection>
</ExposeOverview>受控總覽
open / onOpenChange 與 activeId / onActiveChange 皆可受控,方便與外部按鈕或路由狀態同步。
const [open, setOpen] = React.useState(false);
const [active, setActive] = React.useState("cover");
<ExposeOverview
open={open}
onOpenChange={setOpen}
activeId={active}
onActiveChange={setActive}
>
{/* ExposeSection ... */}
</ExposeOverview>Props
ExposeOverview
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
open | boolean | — | 受控:是否展開縮圖總覽 |
defaultOpen | boolean | false | 非受控初始展開狀態 |
onOpenChange | (open: boolean) => void | — | 展開狀態變更時觸發 |
activeId | string | — | 受控:目前聚焦的區塊 id |
defaultActiveId | string | 第一個區塊 | 非受控初始聚焦區塊 id |
onActiveChange | (id: string) => void | — | 聚焦區塊變更時觸發 |
columns | number | 3 | 總覽網格欄數(2–6),同時決定縮圖縮放比 |
gap | number | 12 | 總覽縮圖間距(px) |
height | number | 420 | 每個區塊(一個視窗畫面)高度(px) |
toolbar | boolean | true | 是否顯示內建工具列(區塊名稱+總覽切換鈕) |
ExposeSection
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 唯一識別 key,聚焦、縮圖配對與導覽用 |
label | string | id | 顯示名稱,用於工具列、縮圖標籤與 aria-label |
children | React.ReactNode | — | 區塊內容,會在放大與縮圖兩種尺寸間等比縮放 |
細節
- 等比縮圖:內容固定以「視窗寬 × 視窗高」渲染,總覽時整塊套用
transform: scale(1 / columns),因此縮圖是真實內容的等比縮小,不會變形或重排。 - FLIP 同步飛入:閱讀模式下所有區塊絕對疊放於同一視窗位置,開啟總覽時各自以
layout動畫飛向自己的縮圖格位;選定縮圖則反向放大回填視窗。 - 導覽點:兩個以上區塊時,工具列下方顯示導覽點,可在閱讀模式直接切換聚焦區塊;總覽開啟時自動淡出。
可及性
- 工具列切換鈕帶
aria-pressed;縮圖為原生button語意,可用 Tab 聚焦、Enter / Space 選定放大。 - 閱讀模式下方向鍵(← → ↑ ↓)切換聚焦區塊,
Esc關閉總覽。 - 未聚焦且未展開的區塊標記
aria-hidden並停用指標事件,朗讀時只讀出當前畫面。 - 使用者系統開啟「減少動態效果」時,縮放與位移改為瞬間切換,不播放 FLIP 動畫。