資料展示
動態徽章
帶計數的徽章:數字變化逐位滾動,可關閉並縮小退場、鄰居平順補位,另有直播用的脈衝變體。
標籤、狀態與未讀數都用得上的徽章。count 變化時每一位數字以 spring 滾動到新值,位數增加時新位從左側長出、減少時收攏,超過 maxCount 顯示「99+」;計數從無到有時整顆計數泡彈入。開啟 removable 後右側出現 ×,點擊時徽章縮小、淡出並收攏寬度,動畫結束才呼叫 onRemove;放進 StatusBadge.Group 時,鄰居會以 FLIP 平順補位。pulse 會在左側加上一顆向外擴散的圓點,適合「LIVE」等即時狀態。
把這個效果裝進你的專案
在專案資料夾執行指令,CLI 會加入原始碼與依賴套件,再依下方使用範例引用元件。
npx webberui@latest add status-badgePlayground
即時調整 props、程式碼片段同步更新——直接試出你要的樣子再複製。
12
300
編輯中的呼叫預設屬性
<StatusBadge/>
完整範例包含預覽的排版與資料。先安裝元件,再把範例檔貼入你的專案。
安裝
npx webberui@latest add https://webberui.com/r/status-badge.json或在 components.json 設定 registries 後,改用 @webberui/status-badge 安裝。
使用
import { StatusBadge } from "@/components/ui/status-badge";
<StatusBadge count={12} countLabel={(n) => `未讀 ${n} 則`}>
收件匣
</StatusBadge>
<StatusBadge variant="destructive" pulse>
LIVE
</StatusBadge>可移除的標籤列:把多個徽章放進 StatusBadge.Group(內含 AnimatePresence + flex 容器),由父層管理清單,onRemove 時把該項移除即可。
const [tags, setTags] = React.useState(["設計系統", "無障礙", "效能"]);
<StatusBadge.Group label="文章標籤">
{tags.map((tag) => (
<StatusBadge
key={tag}
variant="outline"
removable
onRemove={() => setTags((prev) => prev.filter((t) => t !== tag))}
>
{tag}
</StatusBadge>
))}
</StatusBadge.Group>Props
| Prop | 型別 | 預設值 | 說明 |
|---|---|---|---|
variant | "default" | "secondary" | "outline" | "destructive" | "success" | "default" | 外觀變體 |
children | ReactNode | — | 徽章文字 |
count | number | — | 計數;顯示在文字右側(無文字時單獨顯示),數字變化時逐位滾動 |
maxCount | number | 99 | 計數上限,超過時顯示「上限+」(例如 99+) |
showZero | boolean | false | count 為 0 時是否仍顯示計數 |
icon | ReactNode | — | 左側圖示 |
pulse | boolean | false | 左側顯示無限擴散的脈衝圓點(直播、連線中等狀態) |
removable | boolean | false | 顯示關閉按鈕,點擊後縮小退場再呼叫 onRemove |
onRemove | () => void | — | 退場動畫結束後回呼;由父層把這個徽章從清單移除 |
removeLabel | string | "移除 " + 文字 | 關閉按鈕的 aria-label |
size | "sm" | "md" | "md" | 尺寸 |
stiffness | number | 300 | 數字滾動 spring 的剛性 |
damping | number | 30 | 數字滾動 spring 的阻尼 |
countLabel | (count: number) => string | String(count) | 計數變化時給螢幕閱讀器的宣告文字 |
ref | Ref<HTMLSpanElement> | — | 轉給根元素的 ref |
className | string | — | 透傳到根元素 |
StatusBadge.Group
| 欄位 | 型別 | 預設值 | 說明 |
|---|---|---|---|
children | ReactNode | — | 一組 StatusBadge;每個都要有穩定的 key,清單由父層管理 |
label | string | — | 群組的 aria-label;有提供時容器帶 role="group" |
className | string | — | 透傳到群組容器(預設 flex flex-wrap gap-2) |
細節
- 逐位滾動:每一位數字是一個
overflow-hidden欄,內放 0–9 直列,以 spring 把y滾到目標;個位先滾、高位依序跟上。數字一律tabular-nums,寬度不會跳動。 - 移除流程:點 × 時徽章以
scale→0、opacity→0、寬度收攏退場,結束後才呼叫onRemove;徽章本身帶layout="position",在 flex 容器裡新增或移除時鄰居以 FLIP 補位(只動位置、不縮放文字)。 - 自己組容器也可以:把徽章放進
<AnimatePresence mode="popLayout">+ 一個relative flex容器,父層管理清單即可;StatusBadge.Group就是這個組合。 - 節奏變數:退場時長預設 150ms,可用
--wb-status-badge-duration覆寫(例如200ms);脈衝圓點顏色預設跟隨文字色,可用--wb-status-badge-pulse-color覆寫。
可及性
- 計數動畫對輔助科技隱藏,另以
aria-live="polite"的 sr-only 文字宣告,內容由countLabel產生(例如「未讀 12 則」) - 脈衝圓點與圖示皆為
aria-hidden - × 是
type="button",aria-label預設為「移除」加上徽章文字;聚焦時按 Enter、Space、Delete 或 Backspace 都能移除,並有 focus-visible 外框 StatusBadge.Group提供label時為role="group"並帶aria-label- 使用者系統開啟「減少動態效果」時,數字直接替換、脈衝停止擴散只留靜態圓點、移除時只淡出不縮放,鄰居直接到位