Prisma
Live Preview

Skeleton Component Generation Skill

Skill này hướng dẫn bạn (AI Agent) tạo component Skeleton — placeholder loading hiển thị trước khi nội dung thật tải xong.

1. Mục tiêu (Objective)

Tạo component Skeleton với shimmer animation, hỗ trợ nhiều hình dạng (text, circle, rectangle), có thể compose thành loading layout. Tích hợp 100% Design Tokens.

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

Khi nào dùng Skeleton?

  • Content đang tải: Thay thế text, image, card khi fetch data
  • Perceived performance: Giảm cảm giác chờ đợi (tốt hơn spinner)
  • Layout preservation: Giữ layout ổn định, tránh content shift

Phân biệt với component khác

Tình huống Component đúng Lý do
Nội dung đang tải, biết layout Skeleton Giữ đúng layout shape
Đang tải, không biết layout Spinner / Loading Không giả lập layout
Action đang xử lý (submit) Spinner trong Button User triggered action
Page transition Progress Bar Navigation loading
Empty state (không có data) Empty State component Không phải loading

Decision Tree cho AI

text
Content đang tải?
├─ Biết layout sẽ như nào → Skeleton (mimic layout)
│   ├─ Text line → Skeleton variant="text"
│   ├─ Avatar circle → Skeleton variant="circle"
│   ├─ Image rect → Skeleton variant="rectangle"
│   └─ Card phức tạp → Compose nhiều Skeleton
├─ Không biết layout → Spinner / Loading indicator
├─ User vừa submit → Button loading state
└─ Không có data → Empty State

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

3.1. Variants

Variant Hình dạng Use case
text Rectangle, height = line-height Text placeholder
circle Circle Avatar, icon placeholder
rectangle Rectangle, custom w×h Image, card, banner
rounded Rectangle + border-radius Button, input placeholder

3.2. Animation

  • Shimmer/Pulse: Gradient animation di chuyển từ trái → phải (shimmer) hoặc fade in/out (pulse).
  • Mặc định: shimmer. Cho phải disable animation (accessibility: prefers-reduced-motion).

3.4. Slot Map (Figma ↔ Code)

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

Figma Slot data-slot CSS Class Required Accepts
Root skeleton .skeleton
Line skeleton-line ❌ (n×)
Circle skeleton-circle
Rect skeleton-rect

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ả
radius-text number {border-radius.default} Text lines radius
radius-rounded number {item.radius} Button/input placeholder radius
radius-circle number {border-radius.full} Avatar placeholder radius
text-height.sm number {font.leading.4} Small text line height
text-height.md number {font.leading.5} Default text line height
text-height.lg number {font.leading.7} Heading placeholder height
gap number {spacing.2} Gap between skeleton lines
color.background color {base.muted} Skeleton base color
color.highlight color {base.background} Shimmer bright point
animation-duration number 1500 Shimmer cycle duration (ms)
transition string {duration.fast-2} {easing.standard} Default interaction transition
padding number {item.padding-default} Internal padding

5. Props & API

typescript
interface SkeletonProps {
  /** Shape variant */
  variant?: 'text' | 'circle' | 'rectangle' | 'rounded';
  /** Width — number (px) hoặc string ("100%") */
  width?: number | string;
  /** Height — number (px) hoặc string */
  height?: number | string;
  /** Animation type */
  animation?: 'shimmer' | 'pulse' | 'none';
  /** Number of lines (variant="text") */
  lines?: number;
  /** Last line width (variant="text", lines > 1) */
  lastLineWidth?: string; // vd: "60%" — dòng cuối ngắn hơn
}

6. Accessibility (a11y)

  • ARIA: role="status" + aria-label="Loading" hoặc aria-busy="true" trên container.
  • Reduced motion: Respect prefers-reduced-motion: reduce — tắt shimmer animation, chỉ hiện static background.
  • Screen reader: Announce "Loading" khi skeleton visible, "Loaded" khi content replace skeleton.

7. Best Practices & Rules

  • Mimic real layout: Skeleton phải giống layout thật nhất có thể — đúng số dòng, đúng kích thước.
  • Không quá chi tiết: Không cần skeleton cho mỗi icon nhỏ — focus vào khối chính (text, image, card).
  • Transition: Khi content load xong, fade in content — không snap.
  • Không Hardcode: Mọi giá trị từ Token.

8. Example Usage

jsx
{/* Text placeholder */}
<Skeleton variant="text" lines={3} lastLineWidth="60%" />

{/* Avatar + text */}
<div style={{ display: 'flex', gap: 12 }}>
  <Skeleton variant="circle" width={40} height={40} />
  <div>
    <Skeleton variant="text" width={120} />
    <Skeleton variant="text" width={200} />
  </div>
</div>

{/* Card skeleton */}
<Skeleton variant="rectangle" width="100%" height={200} />
<Skeleton variant="text" lines={2} />
<Skeleton variant="rounded" width={100} height={36} />