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.json→chip· 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 havearia-label="Remove [label]". - Disabled:
disabledattribute on<button>,aria-disabled="true"on non-button elements. - Touch target: Minimum 48×32dp per M3 — ensure
min-heightmeets 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. Xemicon.mdmục 10. - Chip set: Khi có nhiều chips, wrap trong
<div class="chip-group">vớigap: var(--spacing-2)và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
-foregroundtoken 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>