Live Preview
This is an informational alert — check it out!
Success! Your changes have been saved.
Warning — this action cannot be undone easily.
Error! Something went wrong. Please try again.
Alert Component Generation Skill
Skill này hướng dẫn bạn (AI Agent) tạo component Alert / Banner — thông báo inline hiển thị trên page cho user biết trạng thái, cảnh báo, hoặc thông tin quan trọng.
1. Mục tiêu (Objective)
Tạo component Alert với 4 severity levels, có thể dismissible, chứa action buttons, và tích hợp 100% semantic color tokens.
2. AI Context & Intent (Ngữ cảnh cho AI)
Khi nào dùng Alert?
- Thông báo inline trên page: Luôn hiển thị, user cần đọc
- Contextual feedback: Kết quả action, trạng thái hệ thống
- Cảnh báo quan trọng: Breaking changes, maintenance notice
⚠️ Phân biệt Alert vs Toast vs Modal (QUAN TRỌNG)
| Tiêu chí | Alert | Toast | Modal |
|---|---|---|---|
| Vị trí | Inline trong page | Fixed corner (top/bottom) | Overlay center |
| Thời gian | Persistent (luôn hiện) | Auto-dismiss (3–5s) | User phải close |
| Blocking | ❌ Không chặn | ❌ Không chặn | ✅ Chặn interaction |
| Khi nào | Info quan trọng, cần đọc lại | Success/error tạm thời | Cần confirm/input |
| Ví dụ | "Account chưa verify" | "Đã copy link" | "Xác nhận xoá?" |
Decision Tree cho AI
text
Cần thông báo cho user?
├─ Inline, persistent, user cần đọc → Alert
├─ Tạm thời, auto-dismiss → Toast
├─ Cần user action/confirm → Modal (alert dialog)
├─ System-wide notice → Banner (full-width Alert)
└─ Contextual hint nhỏ → Tooltip
3. Ngữ nghĩa & Phân loại (Semantics)
3.1. Severity Variants
| Variant | Mục đích | Icon (Lucide) | Tokens |
|---|---|---|---|
info |
Thông tin trung lập, hướng dẫn | info (info.svg) |
base.info-muted / base.info-muted-foreground |
success |
Xác nhận hành động thành công | circle-check (circle-check.svg) |
base.success-muted / base.success-muted-foreground |
warning |
Cảnh báo, cần chú ý | triangle-alert (triangle-alert.svg) |
base.warning-muted / base.warning-muted-foreground |
destructive |
Lỗi, hành động thất bại | circle-x (circle-x.svg) |
base.destructive-muted / base.destructive-muted-foreground |
3.2. Display Modes
| Mode | Mô tả |
|---|---|
| Inline | Trong content flow, width theo container |
| Banner | Full-width, fixed-top, persistent — cho system-wide notices (offline, maintenance) |
3.3. Banner Variant (Extended)
Reference: Fluent UI
MessageBar(persistent), MD3 persistent top snackbar, Ant Design Alertbannerprop
| Aspect | Spec |
|---|---|
| Position | position: fixed; top: 0; left: 0; right: 0; |
| z-index | --z-index-fixed |
| Radius | 0 (full-width, no rounding) |
| Dismissible | ❌ Non-dismissible for offline/error — ✅ Dismissible for info/maintenance |
| Auto-show/hide | Triggered by system event (e.g., navigator.onLine change) |
| Color | Uses same severity variants (warning, destructive, info) |
| Body push | When active, add padding-top to <body> equal to banner height |
| Icon | Lucide wifi-off (offline), alert-triangle (maintenance), info (notice) |
| Content | Single line: icon + message + optional action link |
| Height | Auto, min --spacing-11 (44px) |
| Animation | Slide down: --duration-normal-2 + --easing-emphasized-decelerate |
CSS Skeleton:
css
.alert--banner {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: var(--z-index-fixed);
border-radius: 0;
border: none;
border-bottom: 1px solid var(--border);
padding: var(--spacing-3) var(--spacing-5);
display: flex;
align-items: center;
gap: var(--spacing-3);
min-height: var(--spacing-11);
animation: banner-slide-down var(--duration-normal-2) var(--easing-emphasized-decelerate);
}
/* Offline banner specifically */
.alert--banner[data-variant="warning"] {
background: var(--warning-muted);
color: var(--warning-muted-foreground);
}
@keyframes banner-slide-down {
from { transform: translateY(-100%); }
to { transform: translateY(0); }
}
/* Push body content */
body.has-banner {
padding-top: var(--spacing-11);
}
@media (prefers-reduced-motion: reduce) {
.alert--banner { animation: none; }
}
3.6. Slot Map (Figma ↔ Code)
📎 Source:
slot-manifest.json→alert· Layer: card
| Figma Slot | data-slot |
CSS Class | Required | Accepts |
|---|---|---|---|---|
| Root | alert |
.alert |
✅ | — |
| Icon | alert-icon |
— | ❌ | severity-icon |
| Content | alert-content |
— | ✅ | text |
| Title | alert-title |
— | ✅ | text |
| Description | alert-description |
— | ❌ | text |
| Action | alert-action |
— | ❌ | button, close-button, link |
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 |
number | {item.padding-default} |
Internal padding |
radius |
number | {item.radius} |
Corner radius |
gap-icon |
number | {spacing.3} |
Gap between icon and content |
gap-title-body |
number | {spacing.1} |
Gap between title and description |
icon-size |
number | {min-width.5} |
Alert icon size |
title-font-size |
number | {font.size.sm} |
Alert title font size |
title-font-weight |
number | {font.weight.semibold} |
Alert title font weight |
body-font-size |
number | {font.size.sm} |
Alert body text size |
close-button-size |
number | {min-width.5} |
Dismiss close button size |
color.info-bg |
color | {base.info-muted} |
Info variant background |
color.info-fg |
color | {base.info-muted-foreground} |
Info variant text + icon |
color.success-bg |
color | {base.success-muted} |
Success variant background |
color.success-fg |
color | {base.success-muted-foreground} |
Success variant text + icon |
color.warning-bg |
color | {base.warning-muted} |
Warning variant background |
color.warning-fg |
color | {base.warning-muted-foreground} |
Warning variant text + icon |
color.destructive-bg |
color | {base.destructive-muted} |
Destructive variant background |
color.destructive-fg |
color | {base.destructive-muted-foreground} |
Destructive variant text + icon |
color.close-button |
color | {base.muted-foreground} |
Close button color |
color.close-hover |
color | {state-layer.hover} |
Close button hover |
color.focus-ring |
color | {focus.ring-color} |
Focus ring color — ref shared/focus |
color.disabled-bg |
color | {base.muted} |
Disabled state background |
color.disabled-fg |
color | {base.muted-foreground} |
Disabled state foreground |
border-width |
number | {border-width.1} |
Optional border width |
transition |
string | {duration.fast-2} {easing.standard} |
Default interaction transition |
5. Props & API
typescript
interface AlertProps {
/** Severity variant */
variant?: 'info' | 'success' | 'warning' | 'destructive';
/** Title text (optional, bold) */
title?: string;
/** Description/body */
children: ReactNode;
/** Custom icon override */
icon?: ReactNode;
/** Có thể dismiss (hiện close button) */
dismissible?: boolean;
/** Callback khi dismiss */
onDismiss?: () => void;
/** Action buttons/links */
action?: ReactNode;
/** Display mode */
mode?: 'inline' | 'banner';
}
6. Accessibility (a11y)
- Role:
role="alert"cho thông báo quan trọng (sẽ announce ngay bởi screen reader). - Role (info):
role="status"cho thông tin không khẩn cấp. - Live region:
aria-live="assertive"(error/warning) hoặcaria-live="polite"(info/success). - Close button:
aria-label="Dismiss alert". - Icon: Icon decorative thêm
aria-hidden="true"(meaning đã có trong text). - Focus: Nếu alert xuất hiện dynamic, focus vẫn ở vị trí hiện tại (không tự steal focus).
- Banner mode: Banner KHÔNG steal focus khi xuất hiện. Screen reader announce qua
aria-live.
7. Best Practices & Rules
- Không dùng Alert cho Toast: Alert là persistent, Toast là transient.
- Icon phù hợp: LUÔN có icon matching severity — giúp color-blind users. CHỈ dùng Lucide icon từ
assets/icons/(xemicon.mdmục 10). CẤM dùng text emoji. - Không spam: Tránh hiển thị quá nhiều alerts cùng lúc — gộp lại nếu có thể.
- Dismissible logic: Info/success có thể dismiss. Warning/error NÊN persistent (quan trọng).
- Không Hardcode: Mọi giá trị từ Token.
- Banner mode: Chỉ dùng cho system-wide notice — offline, maintenance, critical update. KHÔNG dùng cho per-form validation.
8. Example Usage
jsx
{/* Info alert */}
<Alert variant="info" title="Gợi ý">
Bạn có thể liên kết thêm thẻ ngân hàng để thanh toán nhanh hơn.
</Alert>
{/* Error alert with action */}
<Alert
variant="destructive"
title="Xác thực thất bại"
action={<Button variant="outline" size="sm">Thử lại</Button>}
>
Không thể kết nối đến máy chủ. Vui lòng kiểm tra kết nối mạng.
</Alert>
{/* Dismissible success */}
<Alert variant="success" dismissible onDismiss={handleDismiss}>
Giao dịch thành công! Mã giao dịch: #VNP12345.
</Alert>
{/* Banner mode — maintenance */}
<Alert variant="warning" mode="banner">
Hệ thống bảo trì từ 00:00 — 04:00 ngày 27/02/2026.
</Alert>
{/* Banner mode — offline detection */}
<Alert variant="warning" mode="banner" icon={<WifiOffIcon />}>
Không có kết nối mạng. Dữ liệu sẽ đồng bộ khi online.
</Alert>