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.json→avatar· 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óaltmô 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" */}