Prisma
Live Preview
Primary Success Warning Error Info Outline

--- description: Hướng dẫn Agent tự động tạo UI Component Badge/Tag/Chip dựa trên Design Tokens, có ngữ nghĩa chuẩn Material 3 & iOS HIG

Badge Component Generation Skill

Skill này hướng dẫn bạn (AI Agent) tạo component Badge / Tag / Chip — nhãn nhỏ hiển thị trạng thái, danh mục, hoặc số đếm.

1. Mục tiêu (Objective)

Tạo component Badge đa năng: hiển thị status label, counter (notification count), tag cho categorization, chip có thể xoá. Tích hợp 100% semantic color tokens.

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

Khi nào dùng Badge?

  • Hiển thị trạng thái: "Active", "Pending", "Expired"
  • Counter / Notification dot: Số unread messages, notification count
  • Category tag: Nhãn phân loại ("Frontend", "Backend", "Design")
  • Selectable chip: Tag có thể thêm/xoá (vd: filter tags)

Phân biệt Badge / Tag / Chip

Tên Mục đích Interactive?
Badge Status label, counter ❌ Read-only
Tag Category, taxonomy ❌ Read-only hoặc ✅ removable
Chip Filter, selection ✅ Selectable / removable

Decision Tree cho AI

text
Cần hiển thị label nhỏ?
├─ Status / trạng thái → Badge (variant theo severity)
├─ Notification count → Badge (counter mode)
├─ Notification dot (không số) → Badge (dot mode)
├─ Category / phân loại → Tag
├─ Filter có thể xoá → Chip (removable)
└─ Selection toggle → Chip (selectable)

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

3.1. Variant theo Severity / Semantic

Variant Mục đích Token BG Token Text
default Neutral info base.muted base.foreground
primary Brand accent base.primary-muted base.primary-muted-foreground
secondary Secondary brand base.secondary-muted base.secondary-muted-foreground
success Positive status base.success-muted base.success-muted-foreground
warning Caution base.warning-muted base.warning-muted-foreground
destructive Error / danger base.destructive-muted base.destructive-muted-foreground
info Informational base.info-muted base.info-muted-foreground
outline Subtle, bordered transparent base.foreground + base.border

3.2. Mode

Mode Mô tả
Label Text badge (mặc định) — "Active", "New"
Counter Số đếm — "3", "99+" (compact oval)
Dot Chấm tròn nhỏ, không text — notification indicator

3.3. Size

  • sm: font.size.xs (12px), padding minimal
  • md: font.size.sm (14px), padding cân đối

3.4. Slot Map (Figma ↔ Code)

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

Figma Slot data-slot CSS Class Required Accepts
Root badge .badge
Icon badge-icon icon
Label badge-label text, number

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ả
padding-x.sm number {spacing.1-5} Horizontal padding for small badge
padding-x.md number {spacing.2-5} Horizontal padding for medium badge
padding-y.sm number {spacing.0-5} Vertical padding for small badge
padding-y.md number {spacing.1} Vertical padding for medium badge
font-size.sm number {font.size.xs} Small badge text
font-size.md number {font.size.sm} Medium badge text
font-weight number {font.weight.medium} Badge label weight
radius number {border-radius.full} chip shape
dot-size number {spacing.2} Notification dot diameter
close-icon-size number {spacing.3} Remove button size for chip mode
gap number {spacing.1} Gap between icon and text
color.default-bg color {base.muted}
color.default-fg color {base.foreground}
color.primary-bg color {base.primary-muted}
color.primary-fg color {base.primary-muted-foreground}
color.secondary-bg color {base.secondary-muted}
color.secondary-fg color {base.secondary-muted-foreground}
color.success-bg color {base.success-muted}
color.success-fg color {base.success-muted-foreground}
color.warning-bg color {base.warning-muted}
color.warning-fg color {base.warning-muted-foreground}
color.destructive-bg color {base.destructive-muted}
color.destructive-fg color {base.destructive-muted-foreground}
color.info-bg color {base.info-muted}
color.info-fg color {base.info-muted-foreground}
color.outline-border color {base.border}
color.close-hover color {state-layer.hover}
transition string {duration.fast-2} {easing.standard} Default interaction transition

5. Props & API

typescript
interface BadgeProps {
  /** Semantic variant */
  variant?: 'default' | 'primary' | 'secondary' | 'success' | 'warning' | 'destructive' | 'info' | 'outline';
  /** Display mode */
  mode?: 'label' | 'counter' | 'dot';
  /** Size */
  size?: 'sm' | 'md';
  /** Content — text hoặc number */
  children?: ReactNode;
  /** Max count (counter mode) — vượt quá hiển thị "99+" */
  maxCount?: number;
  /** Left icon */
  icon?: ReactNode;
  /** Removable — hiện nút close (chip mode) */
  removable?: boolean;
  /** On remove callback */
  onRemove?: () => void;
}

6. Accessibility (a11y)

  • Role: Badge read-only là <span>, không cần role đặc biệt.
  • Counter: Dùng aria-label mô tả context (vd: aria-label="3 unread messages").
  • Removable (chip): Nút close phải có aria-label="Remove [tag name]".
  • Dot: Badge dot BẮT BUỘC có aria-label vì không có text visible.
  • Color không đủ: Không chỉ dùng màu sắc để truyền tải thông tin — kết hợp icon hoặc text.

7. Best Practices & Rules

  • Không interactive (Badge/Tag): Không có hover/click effect, chỉ hiển thị thông tin.
  • Counter max: Khi giá trị > maxCount (mặc định 99), hiển thị "99+".
  • Dot position: Khi dùng như notification dot overlapping element khác, dùng absolute positioning.
  • Không Hardcode: Mọi giá trị từ Token.
  • Semantic color: LUÔN chọn variant phù hợp ngữ nghĩa — success cho trạng thái tốt, destructive cho lỗi...
  • Icon: Close/remove icon (x) và leading icon CHỈ dùng Lucide icon từ assets/icons/. CẤM dùng text emoji. Xem icon.md mục 10.

8. Example Usage

jsx
{/* Status badges */}
<Badge variant="success">Active</Badge>
<Badge variant="warning">Pending</Badge>
<Badge variant="destructive">Expired</Badge>

{/* Counter */}
<Badge variant="destructive" mode="counter" maxCount={99}>150</Badge>
{/* → Hiển thị "99+" */}

{/* Dot notification */}
<Badge mode="dot" variant="destructive" />

{/* Removable tag/chip */}
<Badge variant="primary" removable onRemove={handleRemove}>
  Frontend
</Badge>