Live Preview
--- description: Hướng dẫn Agent tự động tạo UI Component Sidebar / Navigation Rail dựa trên Design Tokens, có ngữ nghĩa chuẩn Material 3 & iOS HIG
Sidebar Component Generation Skill
Skill này hướng dẫn bạn (AI Agent) tạo component Sidebar / Navigation Rail — thanh điều hướng dọc bên trái cho dashboard, admin, và complex apps.
1. Mục tiêu (Objective)
Tạo component Sidebar collapsible, hỗ trợ nested navigation, badges, và tích hợp 100% Design Tokens. Phải responsive: collapse thành Rail (icon-only) hoặc ẩn hoàn toàn trên mobile.
2. AI Context & Intent (Ngữ cảnh cho AI)
Khi nào dùng Sidebar?
- Dashboard / Admin panel: Navigation chính cho complex apps
- Multi-section apps: Email, project management, CRM
- Khi có > 7 navigation items: navigation-menu không đủ chỗ
Phân biệt với component khác
| Tình huống | Component đúng | Lý do |
|---|---|---|
| Navigation dọc, persistent | Sidebar | Luôn hiện, nhiều items |
| Navigation ngang, top | navigation-menu | Ít items, compact |
| Slide-in tạm thời | Drawer | Temporary, overlay |
| Settings categories | Sidebar hoặc Tabs | Tuỳ complexity |
Decision Tree cho AI
text
Cần navigation panel?
├─ Permanent, vertical, nhiều items → Sidebar
│ ├─ Dashboard/admin → Sidebar (default)
│ ├─ Cần tiết kiệm space → Sidebar (collapsible)
│ └─ Mobile → Sidebar → Drawer (temporary overlay)
├─ Temporary overlay panel → Drawer
├─ Horizontal top → navigation-menu
└─ Content switching cùng page → Tabs
3. Ngữ nghĩa & Phân loại (Semantics)
3.1. States
| State | Width | Mô tả |
|---|---|---|
expanded |
256px (default) | Full sidebar: icon + text + badges |
collapsed |
64px | Icon-only rail: hover tooltip cho labels |
hidden |
0px | Ẩn hoàn toàn (mobile default) |
3.2. Anatomy
text
┌──────────────────────┐
│ [Logo / Brand] │
│ │
│ SECTION LABEL │
│ ● Dashboard │ ← active (highlight bg + left indicator)
│ ○ Transactions │
│ ○ Cards │
│ ○ Reports [5] │ ← badge counter
│ │
│ SETTINGS │
│ ○ Account │
│ ○ Security │
│ ├─ Password │ ← nested sub-item
│ └─ 2FA │
│ │
│ ────────────────── │ ← divider
│ ○ Help & Support │
│ ○ Logout │
└──────────────────────┘
3.3. Navigation Item Types
| Type | Mô tả |
|---|---|
| Link | Điều hướng đến page |
| Parent | Có sub-items, click → expand/collapse children |
| External | Link external với icon ↗ |
| Action | Trigger action (logout, settings) |
3.4. Slot Map (Figma ↔ Code)
📎 Source:
slot-manifest.json→sidebar· Layer: surface
| Figma Slot | data-slot |
CSS Class | Required | Accepts |
|---|---|---|---|---|
| Root | sidebar |
.surface-sidebar |
✅ | — |
| Header | sidebar-header |
.slot-header |
❌ | brand-logo, user-profile |
| Content | sidebar-content |
.slot-body |
✅ | nav-group, list |
| Footer | sidebar-footer |
.slot-footer |
❌ | user-profile, settings-link, collapse-button |
4. Token Mapping
?? Atomic Mapping: Xem
ATOMIC-MAPPING.md? m?c sidebar. Component token JSON files d� deprecated.Semantic color tokens (qua Mode layer) và state-specific colors được define đầy đủ trong file
.tokens.json.
5. Props & API
typescript
interface SidebarProps {
/** Current state */
state?: 'expanded' | 'collapsed' | 'hidden';
/** Width preset */
width?: 'compact' | 'default' | 'wide';
/** Header/logo element */
header?: ReactNode;
/** Footer element (user info, logout) */
footer?: ReactNode;
/** On state change (collapse/expand) */
onStateChange?: (state: 'expanded' | 'collapsed' | 'hidden') => void;
/** Overlay mode on mobile (renders as Drawer) */
mobileOverlay?: boolean;
children: ReactNode;
}
interface SidebarSectionProps {
/** Section label (uppercase) */
label?: string;
children: ReactNode;
}
interface SidebarItemProps {
/** Label text */
label: string;
/** Icon (required for collapsed state) */
icon: ReactNode;
/** Navigation target */
href?: string;
onClick?: () => void;
/** Active state */
active?: boolean;
/** Badge counter */
badge?: string | number;
/** Disabled */
disabled?: boolean;
/** Nested sub-items */
children?: ReactNode;
}
6. Accessibility (a11y)
- Semantic HTML:
<nav>+aria-label="Sidebar navigation". - Collapse button:
aria-label="Collapse sidebar"/"Expand sidebar",aria-expanded. - Active item:
aria-current="page". - Nested: Parent item có
aria-expanded, sub-items trong<ul>. - Keyboard:
Tabqua items,Enter/Spacenavigate hoặc expand/collapse parent,Arrow Up/Downtrong submenu. - Badge:
aria-labeldescriptive ("Transactions, 5 new"). - Collapsed tooltip: Tooltip cho icon-only items phải có
role="tooltip". - Mobile: Khi render as overlay, cần focus trap +
Escapeclose.
7. Best Practices & Rules
- Collapse persistent: Lưu trạng thái expand/collapse vào localStorage.
- Mobile: Auto-hide → render as Drawer overlay.
- Active indicator: Dùng left border bar + background highlight — 2 cues rõ ràng.
- Section labels: UPPERCASE, smaller font, muted color — visual separator.
- Nested max depth: Tối đa 2 levels (parent → children). Sâu hơn → redesign IA.
- Không Hardcode: Mọi giá trị từ Token.
- Icon: Sidebar items BẮT BUỘC dùng Lucide icon từ
assets/icons/. CẤM dùng text emoji hoặc icon từ library khác. Xemicon.mdmục 10. - Scroll: Sidebar content nên scroll independently.
- Transition: Collapse animation smooth, text fade out trước khi width shrinks.
8. Example Usage
jsx
{/* Dashboard sidebar */}
<Sidebar
state={sidebarState}
onStateChange={setSidebarState}
header={<Logo collapsed={sidebarState === 'collapsed'} />}
footer={
<SidebarItem icon={<LogoutIcon />} label="Đăng xuất" onClick={logout} />
}
>
<SidebarSection label="Menu chính">
<SidebarItem icon={<DashboardIcon />} label="Tổng quan" href="/" active />
<SidebarItem icon={<WalletIcon />} label="Giao dịch" href="/transactions" badge={5} />
<SidebarItem icon={<CardIcon />} label="Thẻ" href="/cards" />
<SidebarItem icon={<ChartIcon />} label="Báo cáo" href="/reports" />
</SidebarSection>
<SidebarSection label="Cài đặt">
<SidebarItem icon={<UserIcon />} label="Tài khoản" href="/account" />
<SidebarItem icon={<ShieldIcon />} label="Bảo mật">
<SidebarItem label="Mật khẩu" href="/security/password" />
<SidebarItem label="Xác thực 2 bước" href="/security/2fa" />
</SidebarItem>
</SidebarSection>
</Sidebar>