Prisma
Live Preview
Assist
Filter
Input JD John Doe JS Jane Smith
Suggestion
Fill Styles

--- description: Hướng dẫn Agent tự động tạo UI Component chip (M3 Chip) — 4 variants (Assist, Filter, Input, Suggestion), tích hợp 100% design tokens

chip Component Generation Skill

Skill này hướng dẫn bạn (AI Agent) tạo component chip — tương đương Material Design 3 Chip. chip giúp người dùng nhập thông tin, lựa chọn, lọc nội dung, hoặc kích hoạt hành động.

1. Mục tiêu (Objective)

Tạo component chip đa năng với 4 variants chính theo M3: Assist, Filter, Input, Suggestion. Hỗ trợ thêm 2 fill-styles: Tonal (filled muted) và Primary (filled primary). Tích hợp 100% semantic color tokens.

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

Khi nào dùng chip?

  • Assist: Hành động thông minh/tự động — "Add to calendar", "Share location"
  • Filter: Lọc nội dung theo tag — "Frontend", "Backend", "In Progress"
  • Input: Dữ liệu người dùng nhập — contacts, tags, email addresses
  • Suggestion: Gợi ý contextual — suggested replies, search suggestions

Phân biệt chip vs Badge

Component Mục đích Interactive? Kích thước
Badge Status label, counter, dot ❌ Read-only Nhỏ, compact
chip Action, filter, input, suggestion ✅ Clickable / selectable / removable Lớn hơn, touch-friendly

Decision Tree cho AI

text
Cần element tương tác dạng chip?
├─ Action shortcut (smart action) → chip type="assist"
├─ Filter/toggle selection → chip type="filter"
├─ User-entered data (contact, tag) → chip type="input"
├─ Contextual suggestion → chip type="suggestion"
├─ Filled muted background → chip fill="tonal"
└─ Primary accent fill → chip fill="primary"

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

3.1. Variant Types (M3 Chip Mapping)

Variant M3 Name Mục đích Icon Closable Selectable
assist Assist Chip Smart/automated actions ✅ Leading optional
filter Filter Chip Filter content by tag ✅ Checkmark when selected
input Input Chip User-entered data ✅ Avatar/icon optional ✅ Required
suggestion Suggestion Chip Dynamic suggestions

3.2. Fill Styles

Fill Mô tả Khi nào dùng
outlined Border only, transparent BG (default) Tất cả variants mặc định
tonal Filled muted BG Emphasis nhẹ, secondary context
primary Filled primary BG Strong emphasis, CTA-like

3.3. States

State Mô tả Visual Change
Default Trạng thái bình thường Outlined hoặc filled
Hover Mouse hover State layer overlay 8%
Focus Keyboard focus Focus ring
Selected Filter chip active (checked) Tonal BG + checkmark icon
Disabled Không tương tác Reduced opacity per M3

3.4. Size

  • sm: height: 28px, font.size.xs (12px) — compact contexts
  • md: height: 32px, font.size.sm (14px) — standard M3 chip

3.5. Slot Map (Figma ↔ Code)

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

Figma Slot data-slot CSS Class Required Accepts
Root chip .chip
Icon chip-icon icon
Label chip-label text
Remove chip-remove close-icon

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ả
height.sm number {min-width.7} Small chip height — 28px
height.md number {min-width.8} Default chip height — 32px per M3
padding-x.sm number {spacing.2} Horizontal padding small — 8px
padding-x.md number {spacing.3} Horizontal padding default — 12px
padding-x.with-icon number {spacing.2} Left padding with leading icon
padding-y number {spacing.1} Vertical padding — 4px
gap number {spacing.1} Gap between elements — 4px
radius number {border-radius.md} Corner radius — 8px per M3
border-width number {border-width.1} Outline border — 1px
font-size.sm number {font.size.xs} Small label
font-size.md number {font.size.sm} Default label
font-weight number {font.weight.medium} Label weight — 500
icon-size.sm number {min-width.4} Icon size small — 16px
icon-size.md number {min-width.5} Icon size default — 20px
avatar-size number {min-width.6} Avatar for input chip — 24px
close-size number {min-width.4} Close icon — 16px
checkmark-size number {min-width.5} Checkmark for filter — 20px
color.assist-bg color transparent Assist chip BG
color.assist-fg color {base.foreground} Assist chip text
color.assist-border color {base.input-border} Assist chip border
color.filter-bg color transparent Filter chip unselected BG
color.filter-fg color {base.foreground} Filter chip unselected text
color.filter-border color {base.input-border} Filter chip unselected border
color.filter-selected-bg color {base.primary-muted} Filter chip selected BG
color.filter-selected-fg color {base.primary-muted-foreground} Filter chip selected text
color.input-bg color transparent Input chip BG
color.input-fg color {base.foreground} Input chip text
color.input-border color {base.input-border} Input chip border
color.suggestion-bg color transparent Suggestion chip BG
color.suggestion-fg color {base.foreground} Suggestion chip text
color.suggestion-border color {base.input-border} Suggestion chip border
color.tonal-bg color {base.muted} Tonal fill BG
color.tonal-fg color {base.foreground} Tonal fill text
color.primary-bg color {base.primary} Primary fill BG
color.primary-fg color {base.primary-foreground} Primary fill text
color.hover color {state-layer.hover} Hover overlay
color.colored-hover color {state-layer.colored-hover} Hover for primary fills
color.close-fg color {base.muted-foreground} Close icon default
color.close-hover color {base.foreground} Close icon hover
color.disabled-bg color {base.muted} Disabled BG
color.disabled-fg color {base.muted-foreground} Disabled text
color.disabled-border color {base.muted} Disabled border
color.focus-ring color {focus.ring-color} Focus ring
transition string {duration.fast-2} {easing.standard} Transition timing

5. Props & API

typescript
interface chipProps {
  /** Chip type — maps to M3 chip variants */
  type?: 'assist' | 'filter' | 'input' | 'suggestion';
  /** Fill style */
  fill?: 'outlined' | 'tonal' | 'primary';
  /** Size */
  size?: 'sm' | 'md';
  /** Label text */
  children: ReactNode;
  /** Leading icon (Lucide icon) */
  icon?: ReactNode;
  /** Avatar (for input chip) — URL or ReactNode */
  avatar?: string | ReactNode;
  /** Selected state (filter chip) */
  selected?: boolean;
  /** On select toggle (filter chip) */
  onSelect?: (selected: boolean) => void;
  /** On click (assist, suggestion) */
  onClick?: () => void;
  /** Removable — shows close icon (input chip) */
  removable?: boolean;
  /** On remove callback */
  onRemove?: () => void;
  /** Disabled state */
  disabled?: boolean;
}

6. HTML Structure

6.1. Assist Chip

html
<button class="chip chip-assist chip-md" type="button">
    <svg class="chip-icon"><!-- Lucide icon --></svg>
    <span class="chip-label">Add to calendar</span>
</button>

6.2. Filter Chip

html
<button class="chip chip-filter chip-md" 
        type="button" 
        role="checkbox" 
        aria-checked="false">
    <span class="chip-checkmark" aria-hidden="true">
        <svg><!-- check icon --></svg>
    </span>
    <span class="chip-label">Frontend</span>
</button>

<!-- Selected state -->
<button class="chip chip-filter chip-md chip-selected" 
        type="button" 
        role="checkbox" 
        aria-checked="true">
    <span class="chip-checkmark" aria-hidden="true">
        <svg><!-- check icon, visible --></svg>
    </span>
    <span class="chip-label">Frontend</span>
</button>

6.3. Input Chip

html
<span class="chip chip-input chip-md">
    <img class="chip-avatar" src="avatar.jpg" alt="John" />
    <span class="chip-label">John Doe</span>
    <button class="chip-close" type="button" aria-label="Remove John Doe">
        <svg><!-- x icon --></svg>
    </button>
</span>

6.4. Suggestion Chip

html
<button class="chip chip-suggestion chip-md" type="button">
    <span class="chip-label">I agree</span>
</button>

6.5. Tonal & Primary Fill

html
<!-- Tonal fill -->
<button class="chip chip-assist chip-md chip-tonal" type="button">
    <span class="chip-label">Tonal action</span>
</button>

<!-- Primary fill -->
<button class="chip chip-filter chip-md chip-primary chip-selected" type="button">
    <span class="chip-label">Active filter</span>
</button>

7. CSS Classes

Class Mô tả
.chip Base class — shared layout & transitions
.chip-assist Assist chip colors & behavior
.chip-filter Filter chip colors & checkable behavior
.chip-input Input chip colors & removable behavior
.chip-suggestion Suggestion chip colors
.chip-sm Small size (28px)
.chip-md Default size (32px)
.chip-outlined Outlined style (default)
.chip-tonal Tonal/filled muted style
.chip-primary Primary filled style
.chip-selected Selected/checked state (filter)
.chip-disabled Disabled state
.chip-icon Leading icon element
.chip-avatar Avatar element (input chip)
.chip-label Label text element
.chip-checkmark Checkmark container (filter chip)
.chip-close Close/remove button (input chip)

8. Accessibility (a11y)

  • Assist/Suggestion: Use <button> — inherently focusable & clickable.
  • Filter: <button role="checkbox" aria-checked="true|false"> — communicates toggle state.
  • Input (removable): Use <span> container with <button> for close — close button MUST have aria-label="Remove [label]".
  • Disabled: disabled attribute on <button>, aria-disabled="true" on non-button elements.
  • Touch target: Minimum 48×32dp per M3 — ensure min-height meets touch target requirements.
  • Contrast: Label text must have ≥3:1 contrast ratio with chip background.
  • Keyboard: Enter/Space to activate, Tab to navigate between chips.

9. Best Practices & Rules

  • Không hardcode: Mọi giá trị từ Token — typography, spacing, color đều dùng var(--chip-*).
  • Icon: CHỈ dùng Lucide icon từ assets/icons/. CẤM dùng text emoji. Xem icon.md mục 10.
  • Chip set: Khi có nhiều chips, wrap trong <div class="chip-group"> với gap: var(--spacing-2)flex-wrap: wrap.
  • Horizontal scroll: Nếu chip-group overflow 1 hàng, cho phép horizontal scroll hoặc wrap.
  • Filter state management: Filter chips nên hoạt động trong group — khi select 1 chip, các chip khác vẫn giữ state.
  • Max label length: Suggestion chip nên ≤20 ký tự per M3 guideline.
  • Remove animation: Khi remove input chip, animate width → 0 rồi remove DOM node.
  • bg/fg pair rule: Khi set background bằng token, PHẢI set color bằng -foreground token tương ứng.

10. Example Usage

jsx
{/* Assist chips — smart actions */}
<div class="chip-group">
    <chip type="assist" icon={<Calendar />}>Add to calendar</chip>
    <chip type="assist" icon={<Share />}>Share location</chip>
    <chip type="assist" icon={<Map />}>Get directions</chip>
</div>

{/* Filter chips — selectable */}
<div class="chip-group">
    <chip type="filter" selected>Frontend</chip>
    <chip type="filter">Backend</chip>
    <chip type="filter">Design</chip>
    <chip type="filter" selected>In Progress</chip>
</div>

{/* Input chips — user data with remove */}
<div class="chip-group">
    <chip type="input" avatar="john.jpg" removable>John Doe</chip>
    <chip type="input" avatar="jane.jpg" removable>Jane Smith</chip>
</div>

{/* Suggestion chips — contextual */}
<div class="chip-group">
    <chip type="suggestion">I agree</chip>
    <chip type="suggestion">Thanks!</chip>
    <chip type="suggestion">Let me check</chip>
</div>

{/* Fill variants */}
<chip type="assist" fill="tonal" icon={<Star />}>Tonal assist</chip>
<chip type="filter" fill="primary" selected>Primary filter</chip>