Lineup Poster Section
音樂祭海報式的演出陣容版面:名字依 tier 分行、字級逐層遞減,滑過或點擊即以共享布局動畫升格到更大的行,其餘名字重新齊行撐滿。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
<LineupPosterSection />
安裝
npx shadcn@latest add https://webberui.com/r/lineup-poster-section.json或在 components.json 設定 registries 後,改用 @webberui/lineup-poster-section 安裝。
安裝依賴後,從 registry JSON(/r/lineup-poster-section.json 的 files[0].content)複製 lineup-poster-section.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge使用
import { LineupPosterSection } from "@/components/ui/lineup-poster-section";
const lineup = ["Aurora Halo", "Neon Tide", "Velvet Static", "Glass Meridian"];
<LineupPosterSection
names={lineup}
title="Sunrise Festival 2026"
footer="Jul 12–14 · Green Valley"
/>;置頂的 featured 行永遠顯示目前升格的名字(預設為第一位)。滑鼠滑過任一名字會即時預覽升格,移出海報後回復;點擊則固定該名字。你也可以用受控模式接管升格狀態:
const [promoted, setPromoted] = React.useState("Neon Tide-1");
<LineupPosterSection
names={lineup}
promotedId={promoted}
onPromotedChange={setPromoted}
trigger="click"
/>;名字也可傳入完整物件以自訂穩定 id:
<LineupPosterSection
names={[
{ id: "aurora", name: "Aurora Halo" },
{ id: "neon", name: "Neon Tide" },
]}
defaultPromotedId="neon"
/>;Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
names | (string | { id, name })[] | — | 演出名單,依陣列順序排列;字串會以 名稱-索引 生成 id |
promotedId | string | — | 受控:目前升格到 featured 行的名字 id |
defaultPromotedId | string | 第一個名字 | 非受控初始升格名字 id |
onPromotedChange | (id: string) => void | — | 升格改變時的回呼 |
trigger | "hover" | "click" | "both" | "both" | 觸發升格的方式 |
revertOnLeave | boolean | true | 滑鼠移出海報時是否回復到已點擊固定的名字 |
tierCounts | number[] | 自動金字塔分佈 | 各 tier(不含 featured 行)的容量 |
separator | React.ReactNode | "•" | 名字之間的分隔符 |
title | React.ReactNode | — | 海報上方標題 |
footer | React.ReactNode | — | 海報下方附註 |
aria-label | string | "演出陣容" | 無障礙區域標籤 |
細節
- 共享布局動畫:每個名字都帶有
layoutId,升格時 Motion 會把它從原本的 tier 行連續補間到 featured 行。刻意採用layout="position"(只補間位置、字級即時切換),避免大字級文字在放大過程中被拉伸模糊。 - 自動分層:未指定
tierCounts時,剩餘名字會依2, 3, 4, …的遞增容量切成金字塔式的數行,落單的尾數併入最後一行,字級逐層遞減。 - 齊行撐滿:多名字的行採
justify-between左右對齊撐滿整行、以分隔符分隔;featured 行只有一個名字時置中。 - hover 防抖:升格造成重排的瞬間會短暫鎖住
mouseenter,避免游標靜止不動卻因元素位移而連鎖切換。
可及性
- 每個名字都是原生
<button>,可用 Tab 聚焦、Enter/Space 升格;aria-pressed反映目前固定的名字。 - 額外支援方向鍵(←→↑↓)在原始名單順序中移動焦點;移動焦點本身不觸發升格,因此重排時焦點不會被打斷。
- 以鍵盤或點擊升格後,若名字因換行重新掛載而失焦,元件會自動把焦點補回升格後的名字。
- 使用者系統開啟「減少動態效果」時停用共享布局動畫,升格改為即時切換,版面結構完全不變。