Frontend Lab
← 回到所有模式
PF03💬 Feedback · 反饋徽章

Badge

徽章

難度 ★★★★標籤 badge · count · status3 min read

模式簡述

Badge:小型狀態或計數指示。bell icon 旁的數字、狀態 dot、NEW 標記都是。視覺重量很小但很有用。

3
● 上線● 等待中● 離線NEW
預設|數字 3 + 狀態 dot

Claude Code Prompt

💬 Claude Code Prompt
參考:PF03 badge
組件:Badge.tsx

Badge:小型狀態或計數指示。bell icon 旁的數字、狀態 dot、NEW 標記都是。視覺重量很小但很有用。

限制:
- 99+ 沒寫
- 位置貼版上限
- 顏色亂用

完整程式碼

Badge.tsx
"use client";
import { Bell, Mail, Heart } from "lucide-react";
import { cn } from "@/lib/utils";

type State = "default" | "count" | "dot" | "max";

export function Badge({ state = "default" }: { state?: State }) {
return (
  <div className="w-full max-w-md">
    <div className="flex items-center justify-around rounded-lg border border-border bg-background/30 p-6">
      <div className="relative">
        <button className="grid h-10 w-10 place-items-center rounded-full bg-muted">
          <Bell className="h-4 w-4" />
        </button>
        {(state === "dot") && (
          <span className="absolute -right-0.5 -top-0.5 h-2.5 w-2.5 rounded-full bg-red-500 ring-2 ring-background" />
        )}
        {(state === "count" || state === "default") && (
          <span className="absolute -right-1 -top-1 grid h-4 min-w-[16px] place-items-center rounded-full bg-red-500 px-1 font-mono text-[9px] text-white ring-2 ring-background">
            {state === "default" ? 3 : 12}
          </span>
        )}
        {state === "max" && (
          <span className="absolute -right-1.5 -top-1 grid h-4 min-w-[24px] place-items-center rounded-full bg-red-500 px-1 font-mono text-[9px] text-white ring-2 ring-background">
            99+
          </span>
        )}
      </div>

      <div className="relative">
        <button className="grid h-10 w-10 place-items-center rounded-full bg-muted">
          <Mail className="h-4 w-4" />
        </button>
      </div>

      <div className="relative">
        <button className="grid h-10 w-10 place-items-center rounded-full bg-muted">
          <Heart className="h-4 w-4" />
        </button>
      </div>
    </div>

    <div className="mt-4 flex flex-wrap gap-2">
      <span className={cn("rounded-full bg-emerald-500/15 px-2 py-0.5 font-mono text-[10px] text-emerald-500")}>
        ● 上線
      </span>
      <span className="rounded-full bg-amber-500/15 px-2 py-0.5 font-mono text-[10px] text-amber-500">
        ● 等待中
      </span>
      <span className="rounded-full bg-red-500/15 px-2 py-0.5 font-mono text-[10px] text-red-500">
        ● 離線
      </span>
      <span className="rounded-full border border-border px-2 py-0.5 font-mono text-[10px] text-muted-foreground">
        NEW
      </span>
    </div>
  </div>
);
}

何時用

  • ✅ 通知未讀數
  • ✅ 狀態指示(在線、離線、忙碌)
  • ✅ NEW、BETA、PRO 標籤

何時別用

  • ❌ 承載互動(用 button)
  • ❌ 資訊量大(用 banner 或 toast)
  • ❌ 需要解釋(badge 太小,加 tooltip)

我踩過的坑

  1. 99+ 沒寫:999 個未讀整個 badge 撐爆。> 99 顯示 ‘99+’。

  2. 位置貼版上限:絕對定位 -top-1 -right-1 + ring-2 ring-background。

  3. 顏色亂用:紅色不該用在「success」。emerald=on、amber=warn、red=alert、gray=disabled。

相關模式

  • PB10
  • PF01

搜尋

按 ⌘K 隨時開啟