Frontend Lab
← 回到所有模式
PD10📊 Data Display · 資料展示頭像

Avatar Stack

頭像堆疊

難度 ★★★★標籤 avatar · stack · +N3 min read

模式簡述

Avatar Stack:多個頭像疊著顯示,後面接 +N。Linear、Figma 的成員列表都這樣。

E
A
B

3 位成員

3 個|全部顯示

Claude Code Prompt

💬 Claude Code Prompt
參考:PD10 avatar-stack
組件:AvatarStack.tsx

Avatar Stack:多個頭像疊著顯示,後面接 +N。Linear、Figma 的成員列表都這樣。

限制:
- 沒上限
- 沒 ring 區隔
- hover 不展開

完整程式碼

AvatarStack.tsx
"use client";
import { cn } from "@/lib/utils";

type State = "few" | "many" | "empty";

const AVATARS = [
{ char: "E", color: "bg-lab-accent/30 text-lab-accent" },
{ char: "A", color: "bg-blue-500/30 text-blue-400" },
{ char: "B", color: "bg-emerald-500/30 text-emerald-400" },
{ char: "C", color: "bg-purple-500/30 text-purple-400" },
{ char: "D", color: "bg-pink-500/30 text-pink-400" },
{ char: "F", color: "bg-orange-500/30 text-orange-400" },
{ char: "G", color: "bg-yellow-500/30 text-yellow-400" },
{ char: "H", color: "bg-cyan-500/30 text-cyan-400" },
];

export function AvatarStack({ state = "few" }: { state?: State }) {
if (state === "empty") {
  return (
    <div className="grid w-full max-w-md place-items-center rounded-lg border border-dashed border-border/60 py-10">
      <p className="font-mono text-xs text-muted-foreground">尚無成員</p>
    </div>
  );
}

const list = state === "many" ? AVATARS : AVATARS.slice(0, 3);
const display = list.slice(0, 5);
const extra = list.length - display.length;

return (
  <div className="w-full max-w-md">
    <div className="flex -space-x-2">
      {display.map((a, i) => (
        <div
          key={i}
          className={cn(
            "grid h-9 w-9 place-items-center rounded-full ring-2 ring-background font-mono text-xs",
            a.color,
          )}
        >
          {a.char}
        </div>
      ))}
      {extra > 0 && (
        <div className="grid h-9 w-9 place-items-center rounded-full bg-muted text-muted-foreground ring-2 ring-background font-mono text-xs">
          +{extra}
        </div>
      )}
    </div>
    <p className="mt-2 font-mono text-[11px] text-muted-foreground">
      {list.length} 位成員
    </p>
  </div>
);
}

何時用

  • ✅ 參與者列表(commit、PR、issue)
  • ✅ 團隊成員預覽
  • ✅ 誰在線上的縮圖

何時別用

  • ❌ 要看清楚每個成員(直接列出)
  • ❌ 需要互動每個頭像(堆疊難點擊)
  • ❌ 成員只有 1 個(直接顯示)

我踩過的坑

  1. 沒上限:12 個頭像疊著看不清。最多 5 個 + N。

  2. 沒 ring 區隔:頭像顏色相近時邊界看不出。用 ring-2 ring-background。

  3. hover 不展開:使用者想看誰沒辦法。hover 後 reveal 全名 tooltip。

相關模式

  • PA03

搜尋

按 ⌘K 隨時開啟