Prisma
Live Preview
A
BN
CD
EF
GH
JK
LM
NP
+3

Avatar Component Generation Skill

Skill này hướng dẫn bạn (AI Agent) tạo component Avatar — hiển thị ảnh đại diện user hoặc entity, có fallback initials/icon.

1. Mục tiêu (Objective)

Tạo component Avatar hỗ trợ image, initials fallback, icon fallback, multiple sizes, status indicator, và group stacking. Tích hợp 100% Design Tokens.

2. AI Context & Intent (Ngữ cảnh cho AI)

Khi nào dùng Avatar?

  • Đại diện user: profile picture, comment author, chat participant
  • Đại diện entity: team, organization, workspace
  • Danh sách user: member list, participant list (Avatar Group)

Phân biệt với component khác

Tình huống Component đúng Lý do
Ảnh đại diện user/entity Avatar Circular crop + fallback
Ảnh sản phẩm / thumbnail Image / Thumbnail Rectangular, ratio khác
Icon đại diện tính năng Icon Không phải user
Logo brand Image / Logo Sizing/ratio khác

Decision Tree cho AI

text
Cần hiển thị đại diện?
├─ User / person → Avatar (image hoặc initials)
├─ Team / organization → Avatar (icon hoặc initials)
├─ Nhóm users → Avatar Group (stacked)
├─ Ảnh sản phẩm → Image component
└─ Brand logo → Image/Logo component

3. Ngữ nghĩa & Phân loại (Semantics)

3.1. Content Priority (Fallback chain)

text
1. Image (src provided + loads successfully)
   ↓ Image load fails
2. Initials (từ name: "Ngọc Lê" → "NL")
   ↓ Không có name
3. Icon fallback (user icon mặc định)

3.2. Sizes

Size Dimension Font size Use case
xs 24px font.size.xs Dense lists, inline mentions
sm 32px font.size.sm Compact lists, comments
md 40px font.size.base Default, navigation
lg 48px font.size.lg Profile headers
xl 56px font.size.xl Profile pages
2xl 80px font.size.2xl Hero profile

3.3. Shape

  • Circle (mặc định): Dùng cho user avatars.
  • Rounded square: Dùng cho workspace/organization/bot.

3.4. Status Indicator

Badge nhỏ góc dưới-phải hiển thị trạng thái:

Status Color Mô tả
online base.success User đang online
offline base.muted-foreground Offline / ẩn
busy base.destructive Đang bận
away base.warning Vắng mặt

3.5. Slot Map (Figma ↔ Code)

📎 Source: slot-manifest.jsonavatar · Layer: item

Figma Slot data-slot CSS Class Required Accepts
Root avatar .avatar
Image avatar-image image
Fallback avatar-fallback initials, icon
Badge avatar-badge status-dot, count-badge

4. Token Mapping

📦 Token values: Xem ATOMIC-MAPPING.md — single source of truth cho tất cả actual token values.

Token Type Value Mô tả
size.xs number {min-width.6} Dense lists, inline mentions
size.sm number {min-width.8} Compact lists, comments
size.md number {min-width.10} Default, navigation
size.lg number {min-width.12} Profile headers
size.xl number {min-width.14} Profile pages
size.2xl number {min-width.20} Hero profile
font-size.xs number {font.size.xs}
font-size.sm number {font.size.sm}
font-size.md number {font.size.base}
font-size.lg number {font.size.lg}
font-size.xl number {font.size.xl}
font-size.2xl number {font.size.2xl}
radius-circle number {border-radius.full} Circle shape for user avatars
radius-square number {border-radius.lg} Rounded square for org/workspace
ring-width number {border-width.2} Border ring for group stacking
ring-color color {base.background} White ring when group stacking
group-overlap number -8 Negative margin for stacked avatars
status-dot-size.sm number {spacing.2} Status dot for small avatars
status-dot-size.md number {spacing.3} Status dot for default+ avatars
status-dot-ring number {border-width.2} White ring around status dot
color.initials-bg color {base.primary-muted} Background when showing initials
color.initials-fg color {base.primary-muted-foreground} Initials text color
color.fallback-bg color {base.muted} Background when showing icon fallback
color.fallback-fg color {base.muted-foreground} Fallback icon color
color.status-online color {base.success} Online dot color
color.status-offline color {base.muted-foreground} Offline dot color
color.status-busy color {base.destructive} Busy dot color
color.status-away color {base.warning} Away dot color
transition string {duration.fast-2} {easing.standard} Default interaction transition
padding number {item.padding-default} Internal padding
font-weight number {font.weight.medium} Default font weight

5. Props & API

typescript
interface AvatarProps {
  /** Image source URL */
  src?: string;
  /** Alt text (accessibility) */
  alt?: string;
  /** User/entity name — dùng cho initials fallback */
  name?: string;
  /** Size preset */
  size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
  /** Shape */
  shape?: 'circle' | 'square';
  /** Online status indicator */
  status?: 'online' | 'offline' | 'busy' | 'away';
  /** Custom fallback icon */
  fallbackIcon?: ReactNode;
}

interface AvatarGroupProps {
  /** Max avatars visible — vượt quá hiện "+N" */
  max?: number;
  /** Size applied to all children */
  size?: AvatarProps['size'];
  /** Children = Avatar components */
  children: ReactNode;
}

6. Accessibility (a11y)

  • Alt text: <img> phải có alt mô tả (vd: alt="Ngọc Lê's avatar").
  • Initials: Container cần role="img" + aria-label="[Name]".
  • Status: Status dot cần aria-label (vd: aria-label="Online").
  • Group: Avatar Group cần role="group" + aria-label="Team members".
  • "+N" counter: Cần aria-label="and N more members".

7. Best Practices & Rules

  • Initials algorithm: Lấy ký tự đầu của 2 từ đầu tiên, uppercase. "Ngọc Lê" → "NL", "Admin" → "A".
  • Image loading: Hiện initials/icon TRƯỚC, khi image load xong mới swap — tránh layout shift.
  • Group stacking: Dùng negative margin + z-index tăng dần + border ring trắng.
  • Không Hardcode: Mọi giá trị từ Token.
  • Responsive: Size có thể thay đổi theo breakpoint.

8. Example Usage

jsx
{/* With image */}
<Avatar src="/avatar.jpg" name="Ngọc Lê" size="lg" status="online" />

{/* Initials fallback */}
<Avatar name="Ngọc Lê" size="md" />
{/* → Hiển thị "NL" */}

{/* Icon fallback */}
<Avatar size="md" />
{/* → Hiển thị user icon mặc định */}

{/* Avatar group */}
<AvatarGroup max={3} size="sm">
  <Avatar src="/a.jpg" name="User A" />
  <Avatar src="/b.jpg" name="User B" />
  <Avatar name="User C" />
  <Avatar name="User D" />
  <Avatar name="User E" />
</AvatarGroup>
{/* → Hiển thị 3 avatars + "+2" */}