Broadcast Bar System
可堆疊多則公告的頂部廣播列系統,依優先級佇列輪播,支援倒數計時、CTA 與關閉記憶,高度變化以 spring 平滑推擠內容。
載入預覽⋯
Playground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
5000
<BroadcastBarSystem />
安裝
npx shadcn@latest add https://webberui.com/r/broadcast-bar-system.json或在 components.json 設定 registries 後,改用 @webberui/broadcast-bar-system 安裝。
安裝依賴後,從 registry JSON(/r/broadcast-bar-system.json 的 files[0].content)複製 broadcast-bar-system.tsx 原始碼到你的 components/ui/ 目錄:
npm install motion clsx tailwind-merge lucide-react使用
import { BroadcastBarSystem } from "@/components/ui/broadcast-bar-system";
<BroadcastBarSystem
messages={[
{
id: "sale",
variant: "promo",
priority: 3,
content: "夏季特賣最後倒數",
countdownTo: Date.now() + 1000 * 60 * 60 * 2,
cta: { label: "去逛逛", href: "/sale" },
},
{
id: "maintenance",
variant: "warning",
priority: 1,
content: "系統將於本週日 02:00 進行維護",
},
]}
/>公告依 priority 由高到低排入佇列並自動輪播;使用者關閉的公告會記憶在 localStorage,重新整理後不再出現。廣播列本身是常規流佈局,高度改變時以 spring 過渡,自然平滑地推擠下方頁面內容。
Props
BroadcastBarSystem
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
messages | BroadcastMessage[] | — | 公告陣列,依 priority 由高到低輪播 |
rotateInterval | number | 5000 | 自動輪播間隔(毫秒),設 0 停用 |
storageKey | string | null | "wb-broadcast-dismissed" | 記憶已關閉公告的 localStorage 鍵名;null 停用持久化 |
sticky | boolean | false | 是否黏附於容器頂部 |
onDismiss | (id: string) => void | — | 關閉單則公告時觸發 |
onEmpty | () => void | — | 所有公告皆關閉、廣播列收合為零高度時觸發一次 |
BroadcastMessage
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
id | string | — | 唯一識別,用於輪播定位與關閉記憶 |
content | React.ReactNode | — | 主要文字內容 |
priority | number | 0 | 數字越大越先輪播 |
variant | "info" | "success" | "warning" | "critical" | "promo" | "info" | 強調色與預設圖示 |
icon | React.ReactNode | — | 自訂前綴圖示,覆蓋變體預設 |
cta | BroadcastCTA | — | 行動呼籲;帶 href 渲染連結,否則渲染按鈕 |
countdownTo | number | Date | — | 倒數目標,顯示即時 HH:MM:SS 倒數 |
onCountdownEnd | () => void | — | 倒數歸零時觸發一次 |
dismissible | boolean | true | 是否顯示關閉按鈕 |
細節
- 優先級佇列:
messages會依priority穩定排序,僅顯示未被關閉的公告;同時只呈現一則,並以固定間隔輪播。 - 倒數計時:
countdownTo支援毫秒 timestamp 或Date,每 250ms 更新,超過一天時顯示D天 HH:MM:SS。倒數歸零觸發onCountdownEnd一次。 - 關閉記憶:關閉的公告 id 會寫入
localStorage(可用storageKey自訂或以null關閉);localStorage不可用時靜默降級為僅記憶當前工作階段。 - 平滑推擠:廣播列量測內容高度並以 spring 過渡自身高度,切換不同高度的公告或全部關閉時,下方內容會被平滑地推擠或回填。
可及性
- 廣播列以
role="region"搭配aria-label標示,方便輔助科技定位。 - 多則公告時提供可鍵盤操作的導覽點(
role="tab"),每點帶「第 N 則,共 M 則」標籤;關閉按鈕帶aria-label。 - 指標懸停或鍵盤焦點進入時自動暫停輪播,避免使用者閱讀時內容跳動。
- 尊重系統「減少動態效果」:停用自動輪播與位移動畫,高度改為即時切換,公告改以淡入淡出呈現。
- 倒數計時在掛載後才渲染,避免依賴
Date.now()造成 hydration 不一致。