@hobui/viui-cli 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +136 -0
  2. package/dist/assets/cursor/.design-system-version +1 -0
  3. package/dist/assets/cursor/commands/audit-accessibility.md +25 -0
  4. package/dist/assets/cursor/commands/audit-ui.md +35 -0
  5. package/dist/assets/cursor/commands/component.md +18 -0
  6. package/dist/assets/cursor/commands/fix-storybook.md +24 -0
  7. package/dist/assets/cursor/commands/generate-component-from-figma.md +26 -0
  8. package/dist/assets/cursor/commands/generate-page-from-figma.md +26 -0
  9. package/dist/assets/cursor/plans/DESIGN_SYSTEM_PLAN.md +177 -0
  10. package/dist/assets/cursor/plans/PLANS_INDEX.md +35 -0
  11. package/dist/assets/cursor/rules/accessibility-contrast.mdc +38 -0
  12. package/dist/assets/cursor/rules/bem-class-style.mdc +107 -0
  13. package/dist/assets/cursor/rules/component-naming.mdc +57 -0
  14. package/dist/assets/cursor/rules/design-system-component-library.mdc +59 -0
  15. package/dist/assets/cursor/rules/design-system-workflow.mdc +48 -0
  16. package/dist/assets/cursor/rules/figma-mapping.mdc +37 -0
  17. package/dist/assets/cursor/rules/icons.mdc +42 -0
  18. package/dist/assets/cursor/rules/project-structure.mdc +137 -0
  19. package/dist/assets/cursor/rules/storybook-component-template.mdc +103 -0
  20. package/dist/assets/cursor/rules/storybook.mdc +68 -0
  21. package/dist/assets/cursor/rules/tokens.mdc +32 -0
  22. package/dist/assets/cursor/rules/viui-themes.mdc +53 -0
  23. package/dist/assets/cursor/rules/vuetify-layout.mdc +52 -0
  24. package/dist/assets/cursor/skills/accessibility.md +75 -0
  25. package/dist/assets/cursor/skills/design-system-thinking.md +40 -0
  26. package/dist/assets/cursor/skills/figma-interpretation.md +38 -0
  27. package/dist/assets/cursor/skills/vue-vuetify-design-system-architect.md +60 -0
  28. package/dist/assets/cursor/sync-manifest.json +6 -0
  29. package/dist/assets/plugins/viui-conf/defaults/README.md +27 -0
  30. package/dist/assets/plugins/viui-conf/defaults/alerts.ts +13 -0
  31. package/dist/assets/plugins/viui-conf/defaults/app-bar.ts +14 -0
  32. package/dist/assets/plugins/viui-conf/defaults/avatars.ts +14 -0
  33. package/dist/assets/plugins/viui-conf/defaults/buttons.ts +15 -0
  34. package/dist/assets/plugins/viui-conf/defaults/by-theme/index.ts +30 -0
  35. package/dist/assets/plugins/viui-conf/defaults/by-theme/material.ts +15 -0
  36. package/dist/assets/plugins/viui-conf/defaults/by-theme/minimalist-2.ts +15 -0
  37. package/dist/assets/plugins/viui-conf/defaults/by-theme/neo-brutalism.ts +15 -0
  38. package/dist/assets/plugins/viui-conf/defaults/cards.ts +12 -0
  39. package/dist/assets/plugins/viui-conf/defaults/chips.ts +15 -0
  40. package/dist/assets/plugins/viui-conf/defaults/data-tables.ts +11 -0
  41. package/dist/assets/plugins/viui-conf/defaults/dialogs.ts +13 -0
  42. package/dist/assets/plugins/viui-conf/defaults/global.ts +12 -0
  43. package/dist/assets/plugins/viui-conf/defaults/index.ts +93 -0
  44. package/dist/assets/plugins/viui-conf/defaults/inputs.ts +42 -0
  45. package/dist/assets/plugins/viui-conf/defaults/lists.ts +17 -0
  46. package/dist/assets/plugins/viui-conf/defaults/main.ts +12 -0
  47. package/dist/assets/plugins/viui-conf/defaults/menus.ts +14 -0
  48. package/dist/assets/plugins/viui-conf/defaults/navigation-drawer.ts +14 -0
  49. package/dist/assets/plugins/viui-conf/defaults/pagination.ts +13 -0
  50. package/dist/assets/plugins/viui-conf/defaults/snackbars.ts +13 -0
  51. package/dist/assets/plugins/viui-conf/theme-base.ts +34 -0
  52. package/dist/assets/plugins/viui-conf/v-dark.ts +38 -0
  53. package/dist/assets/plugins/viui-conf/v-light.ts +41 -0
  54. package/dist/assets/plugins/vuetifies/defaults/buttons.ts +15 -0
  55. package/dist/assets/plugins/vuetifies/defaults/cards.ts +12 -0
  56. package/dist/assets/plugins/vuetifies/defaults/global.ts +12 -0
  57. package/dist/assets/plugins/vuetifies/defaults/index.ts +45 -0
  58. package/dist/assets/plugins/vuetifies/defaults/inputs.ts +42 -0
  59. package/dist/assets/plugins/vuetifies/defaults/lists.ts +17 -0
  60. package/dist/assets/plugins/vuetifies/theme-base.ts +34 -0
  61. package/dist/assets/plugins/vuetifies/v-dark.ts +38 -0
  62. package/dist/assets/plugins/vuetifies/v-light.ts +41 -0
  63. package/dist/assets/plugins/vuetify-defaults/buttons.ts +15 -0
  64. package/dist/assets/plugins/vuetify-defaults/cards.ts +12 -0
  65. package/dist/assets/plugins/vuetify-defaults/global.ts +12 -0
  66. package/dist/assets/plugins/vuetify-defaults/index.ts +45 -0
  67. package/dist/assets/plugins/vuetify-defaults/inputs.ts +42 -0
  68. package/dist/assets/plugins/vuetify-defaults/lists.ts +17 -0
  69. package/dist/cli.d.ts +3 -0
  70. package/dist/cli.d.ts.map +1 -0
  71. package/dist/cli.js +402 -0
  72. package/package.json +27 -0
@@ -0,0 +1,107 @@
1
+ ---
2
+ description: BEM class naming và style theo class — dễ tìm DOM, cập nhật quy mô lớn, tránh phình file do inline style
3
+ globs: src/design-system/**/*, src/components/**/*, src/storybook/**/*, **/*.stories.ts, **/*.vue, src/assets/styles/**/*
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # BEM Class & Style theo class (Rule bắt buộc khi tạo/cập nhật design-system, components, stories)
8
+
9
+ Khi tạo mới hoặc cập nhật component, foundation story hoặc bất kỳ file thuộc design system, **luôn dùng cấu hình class theo BEM** và **ưu tiên style qua class (CSS/SCSS)** thay vì attribute `style` inline. Rule này bổ sung `component-naming.mdc` và `storybook.mdc`.
10
+
11
+ ## Mục đích
12
+
13
+ | Mục tiêu | Cách đạt |
14
+ |----------|----------|
15
+ | **Dễ tìm kiếm theo DOM** | Root và section có class BEM cố định; querySelector / test / DevTools tìm theo class. |
16
+ | **Dễ cập nhật, chỉnh sửa style quy mô lớn** | Một class nhiều chỗ dùng; sửa một định nghĩa trong CSS/SCSS là đủ. |
17
+ | **Không bị scale dung lượng file vì attribute style** | Tránh object `style: { ... }` lặp lại hàng chục/dòng; đưa vào class trong CSS/SCSS. |
18
+
19
+ ## Quy ước BEM
20
+
21
+ - **Block**: thành phần độc lập; tên **kebab-case**, một từ hoặc cụm (vd: `spacing-layout-stories`, `vi-button`, `colors-stories`).
22
+ - **Element**: phần con thuộc block; nối bằng `__` (hai gạch dưới): `block__element` (vd: `spacing-layout-stories__overview`, `spacing-layout-stories__card`).
23
+ - **Modifier**: biến thể của block hoặc element; nối bằng `--`: `block--modifier` hoặc `block__element--modifier` (vd: `vi-button--primary`, `spacing-layout-stories__card--highlight`).
24
+
25
+ Tên class: **chỉ lowercase, số và dấu gạch nối**; không dùng camelCase hay PascalCase trong class.
26
+
27
+ ## Áp dụng theo loại file
28
+
29
+ ### 1. Foundation stories (`src/storybook/Foundations/*.stories.ts`)
30
+
31
+ - **Root element** (div/vue wrapper của toàn bộ story): luôn có **một block class** tương ứng tên story, ví dụ:
32
+ - `SpacingLayout.stories.ts` → `class: 'spacing-layout-stories'`
33
+ - `Colors.stories.ts` → `class: 'colors-stories'`
34
+ - `Typography.stories.ts` → `class: 'typography-stories'`
35
+ - **Section / nhóm nội dung**: dùng element class, ví dụ `spacing-layout-stories__overview`, `spacing-layout-stories__grid`, `spacing-layout-stories__card`.
36
+ - **Style**: Ưu tiên đưa vào file SCSS/CSS (cùng thư mục hoặc `src/assets/styles/`) và gắn class; **inline `style`** chỉ dùng khi giá trị **động** (theme CSS variable, token runtime, prop). Ví dụ nền/ chữ theo theme có thể giữ `style` với `var(--v-theme-*)` hoặc chuyển sang class + CSS variable trong SCSS.
37
+
38
+ ### 2. Component Vue (`*.vue` trong `src/design-system/`, `src/components/`)
39
+
40
+ - **Root element** của component: có **block class** trùng với tên component dạng kebab-case (vd: `vi-button` → class `vi-button`, `BaseAlert` → `base-alert`).
41
+ - **Phần con**: dùng `__element` (vd: `vi-button__icon`, `base-alert__title`). Biến thể dùng `--modifier` (vd: `vi-button--primary`).
42
+ - **Style**: Trong `<style scoped>` hoặc file `.css`/`.scss` cùng thư mục; tránh style inline trừ khi dynamic.
43
+
44
+ ### 3. Stories của component (`*.stories.ts` cạnh component)
45
+
46
+ - **Root wrapper** (nếu có) hoặc **canvas container**: nên có block class, ví dụ `vi-button-stories` hoặc dùng trực tiếp component (component đã có block class).
47
+ - **Style** cho layout story: dùng class + CSS/SCSS thay vì inline.
48
+
49
+ ## Vị trí đặt CSS/SCSS — Tổng thể dự án
50
+
51
+ Toàn bộ SCSS/CSS dùng chung (BEM, layout, foundations, component blocks) nằm dưới **một điểm vào**: `src/assets/styles/`. Không tách riêng SCSS chỉ cho Storybook Foundations; mọi phần (foundations, design-system, components, app) đều tham chiếu hoặc import từ đây.
52
+
53
+ ### Cấu trúc gợi ý `src/assets/styles/`
54
+
55
+ | File / thư mục | Mục đích | Ai dùng |
56
+ |----------------|----------|---------|
57
+ | `main.scss` | Entry: import tokens + các partial; được load bởi app/Storybook. | Toàn app, Storybook (qua plugin Vite/Vuetify). |
58
+ | `inet-tokens.scss` | Biến CSS từ design tokens (đã có). | Mọi SCSS khác qua `@use`. |
59
+ | `_variables.scss` | Biến/mixin dùng chung (nếu cần). | Các partial. |
60
+ | `foundations/` | Partial theo từng foundation story (BEM block). | Story import hoặc `main.scss` import. |
61
+ | `foundations/_spacing-layout-stories.scss` | Class `.spacing-layout-stories`, `.spacing-layout-stories__*`. | `SpacingLayout.stories.ts` (import trong story hoặc qua main). |
62
+ | `foundations/_colors-stories.scss` | Class `.colors-stories`, `.colors-stories__*`. | `Colors.stories.ts`. |
63
+ | `foundations/_typography-stories.scss` | Class `.typography-stories`, `.typography-stories__*`. | `Typography.stories.ts`. |
64
+ | `foundations/_index.scss` | `@forward` các partial foundations. | `main.scss` import một lần. |
65
+ | `components/` hoặc `design-system/` | Partial cho Vi* / brands / errors (block BEM component). | Component Vue import file rời hoặc dùng `<style scoped>`; có thể forward từ đây nếu cần dùng chung. |
66
+
67
+ - **Foundation stories**: Style theo class BEM đặt trong `src/assets/styles/foundations/`; story file có thể import trực tiếp `@/assets/styles/foundations/spacing-layout-stories.scss` hoặc dùng chung qua `main.scss` (đã load toàn app).
68
+ - **Component Vue (vi-ui, brands, errors)**: Có thể (1) `<style scoped>` trong `.vue`, hoặc (2) file SCSS cùng thư mục component và import trong component, hoặc (3) partial trong `src/assets/styles/components/` và import từ `main.scss` nếu style dùng nhiều nơi.
69
+ - **Chung toàn app**: Reset, layout, utility — trong `main.scss` hoặc partial `_base.scss` / `_utilities.scss` trong `src/assets/styles/`.
70
+
71
+ ### Nguyên tắc
72
+
73
+ - **Một nguồn sự thật**: Tokens → `inet-tokens.scss`; class BEM cho story/component → partial trong `src/assets/styles/` (foundations, components), không rải file SCSS riêng lẻ ngoài cấu trúc này (trừ `<style scoped>` trong Vue).
74
+ - **Foundations** là một phần của tổng thể: không tạo thư mục SCSS riêng cho `src/storybook/Foundations/`; dùng `src/assets/styles/foundations/` và import từ entry chung hoặc từ story.
75
+
76
+ ## Ví dụ (theo SpacingLayout.stories.ts)
77
+
78
+ - Root:
79
+ ```ts
80
+ h('div', { class: 'spacing-layout-stories', style: { padding: '24px', ... } }, [...])
81
+ ```
82
+ Chuẩn hóa: root giữ `class: 'spacing-layout-stories'`; các thuộc tính tĩnh (padding, borderRadius, minHeight) nên chuyển vào `.spacing-layout-stories { ... }` trong file SCSS; chỉ giữ inline khi dùng biến theme (vd `backgroundColor: themeColors.surfaceBackground` hoặc `var(--v-theme-background)`).
83
+
84
+ - Section/ card:
85
+ ```ts
86
+ h('div', { class: 'spacing-layout-stories__card', ... }, [...])
87
+ ```
88
+
89
+ ## Ngoại lệ (inline style chấp nhận được)
90
+
91
+ - Giá trị **phụ thuộc runtime**: theme (CSS variable), token đọc từ composable, prop (vd width/height từ args).
92
+ - **Một lần**, ít lặp: một vài thuộc tính đơn lẻ không đáng kể dung lượng.
93
+
94
+ ## Checklist khi tạo/cập nhật
95
+
96
+ - [ ] Root element có **block class** BEM (kebab-case) chưa?
97
+ - [ ] Section/ element con có **element class** (`block__element`) hoặc modifier khi cần?
98
+ - [ ] Style **tĩnh** đã đưa vào class (CSS/SCSS) chưa, tránh lặp object `style` lớn?
99
+ - [ ] Có thể **tìm nhanh trong DOM** bằng class (DevTools, test, script) không?
100
+
101
+ ## Tham chiếu
102
+
103
+ - Naming component/file: `component-naming.mdc`
104
+ - Cấu trúc Storybook: `storybook.mdc`
105
+ - Design system & tokens: `design-system-component-library.mdc`, `tokens.mdc`
106
+
107
+ Khi được kích hoạt (file khớp glob), **chủ động gợi ý hoặc áp dụng** class BEM và chuyển style sang class/CSS để đạt ba mục đích trên.
@@ -0,0 +1,57 @@
1
+ ---
2
+ description: Component naming (bắt buộc) — quy ước tên component, file, props, thư mục
3
+ globs: src/design-system/**/*, src/components/**/*, src/storybook/**/*, **/*.stories.ts
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Component Naming (Rule bắt buộc)
8
+
9
+ Khi tạo hoặc đổi tên component, story, thư mục trong design system, tuân theo quy ước dưới đây. Chi tiết vị trí file: `project-structure.mdc`; workflow NHÓM: `design-system-workflow.mdc`.
10
+
11
+ ## Quy tắc đặt tên tổng quát (dự án)
12
+
13
+ | Đối tượng | Quy ước | Ví dụ |
14
+ |-----------|---------|--------|
15
+ | Tên Component (.vue) | PascalCase | `ProductCard.vue` |
16
+ | Thư mục chứa Component | PascalCase | `src/components/ProductCard/` |
17
+ | Interfaces / Types | PascalCase | `ProductInfo` |
18
+ | Composables (.ts) | camelCase | `useAuth.ts`, `useLocalStorage.ts` |
19
+ | Biến (props, refs) | camelCase | `const isLoading = ref(false)` |
20
+ | Sự kiện (emit) | kebab-case | `emit('close-modal')` |
21
+
22
+ **Ngoại lệ:** Trong `src/design-system/vi-ui/` thư mục component dùng **kebab-case** `vi-<tên>` (vd. `vi-button/`, `vi-input/`) theo quy ước vi-ui; tên file và component vẫn PascalCase (`ViButton.vue`).
23
+
24
+ **src/storybook:** Thư mục con PascalCase (`Introduction/`, `Foundations/`, `Themes/`); file `.vue`, `.stories.ts`, `.mdx` PascalCase (vd. `NeoBrutalism.vue`, `Colors.stories.ts`). Chi tiết: `storybook.mdc`.
25
+
26
+ ## Quy ước chính (chi tiết)
27
+
28
+ | Loại | Quy ước | Ví dụ |
29
+ |------|---------|--------|
30
+ | **Component Vue** | PascalCase; BaseX nếu là base/primitive | `Button.vue`, `BaseAlert.vue`, `ErrorPage.vue`, `ViButton.vue` |
31
+ | **Component vi-ui** | Tiền tố `Vi` + PascalCase; thư mục `vi-<tên>` | `ViButton.vue` trong `vi-button/`, `ViInput.vue` trong `vi-input/` |
32
+ | **Stories** | `ComponentName.stories.ts`, cùng thư mục với component | `ViButton.stories.ts`, `BaseAlert.stories.ts` |
33
+ | **Props / events** | kebab-case trong template; camelCase trong script; emit: kebab-case | `variant="primary"`, `defineProps<{ variant: string }>()`, `emit('close-modal')` |
34
+ | **Thư mục component** | PascalCase (xem bảng trên); vi-ui: kebab `vi-<tên>` | `ProductCard/`, `vi-button/`, `brands/` (nhóm) |
35
+ | **Composables** | camelCase, tiền tố `use` | `useAuth.ts`, `useLocalStorage.ts` |
36
+ | **Token / types** | Token file: lowercase hoặc camelCase; types: PascalCase, file `*-types.ts` hoặc `*.d.ts` | `inet-design-tokens.ts`, `inet-tokens-types.ts` |
37
+ | **CSS/SCSS** | lowercase, gạch nối nếu cần | `main.scss`, `_error-page.css` |
38
+ | **Class (BEM)** | block__element--modifier; kebab-case | `spacing-layout-stories`, `spacing-layout-stories__card` — chi tiết: `bem-class-style.mdc` |
39
+
40
+ ## Vi-ui (design-system)
41
+
42
+ - **Tên component:** `Vi` + tên (PascalCase), vd: `ViButton`, `ViCard`, `ViAlert`.
43
+ - **Thư mục:** `vi-<tên>` (kebab-case), vd: `src/design-system/vi-ui/vi-button/`.
44
+ - **File:** `ViName.vue` và `ViName.stories.ts` trong cùng thư mục.
45
+ - **Export:** Re-export qua `src/design-system/vi-ui/index.ts` nếu có.
46
+ - **Story Vue (khi component có slot):** Nếu component dùng nhiều slot (activator + default, list + items) và story dùng `render()` dễ khiến preview trống, tạo thêm `ViNameStory.vue` chứa template đầy đủ + dữ liệu demo; trong `ViName.stories.ts` dùng `component: ViNameStory` và chỉ truyền `args`. Chi tiết: `storybook.mdc` § "Vi-ui: Component có slot → dùng Story Vue".
47
+
48
+ ## Components (brands, errors, icons)
49
+
50
+ - **Tên component:** PascalCase, không bắt buộc tiền tố Vi (vd: `BrandLogo`, `ErrorPage`, `ArrowLeftRight`).
51
+ - **Thư mục:** Một thư mục per component, tên lowercase (vd: `src/components/brands/`, `src/components/errors/`).
52
+
53
+ ## Story title (sidebar)
54
+
55
+ - Theo cấu trúc trong `storybook.mdc`: `{Nhóm}/{Tên}`, vd: `vi-ui/Button`, `Brands/Logo`, `Errors/ErrorPage`, `Foundations/Colors`.
56
+
57
+ Khi được kích hoạt (file khớp glob), áp dụng quy ước naming trên và gợi ý chỉnh nếu lệch.
@@ -0,0 +1,59 @@
1
+ ---
2
+ description: Design system & component architecture — Vue 3 + Vuetify, tokens, API, NHÓM; naming PascalCase, vi-*, *.stories.ts. Cùng dùng: component-naming.mdc, design-system-workflow.mdc. Skill: .cursor/skills/vue-vuetify-design-system-architect.md
3
+ globs: src/components/**/*, src/design-system/**/*, src/tokens/**/*, src/storybook/**/*, src/assets/styles/**/*, docs/**/*
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Design System & Component Library (Subagent)
8
+
9
+ **Bạn là design system và component library trong dự án này.**
10
+
11
+ ## Vai trò
12
+
13
+ - **Nguồn chân lý** cho tokens, components và quy ước giao diện của dự án.
14
+ - **Hướng dẫn** khi tạo/sửa component, tokens, stories hoặc tài liệu design system.
15
+ - **Đảm bảo** mọi output dùng Vue 3 + Vuetify và design tokens từ `src/tokens/`.
16
+
17
+ ## Nguyên tắc khi áp dụng rule này
18
+
19
+ 1. **Tokens trước** — Màu, spacing, typography lấy từ design system; không hard-code giá trị theme/layout.
20
+ 2. **Vue 3 + Vuetify** — Composition API, `<script lang="ts" setup>`, component/theme Vuetify 3; theme bắt nguồn từ tokens.
21
+ 3. **Accessibility** — ARIA, bàn phím, focus, HTML ngữ nghĩa; kiểm tra tương phản và vùng chạm.
22
+ 4. **API rõ ràng** — Props, slots, events nhất quán; tùy biến qua props/theme thay vì override từng chỗ.
23
+ 5. **Tuân AGENTS.md** — Không tự chạy lệnh shell khi chưa có đồng ý; giải thích rủi ro với thao tác hạ tầng.
24
+ 6. **Class BEM & style theo class** — Root component/story có block class BEM; style qua CSS/SCSS, tránh inline style trừ giá trị động. Chi tiết: `bem-class-style.mdc`.
25
+ 7. **Vi-ui & Icons khi gen code** — Khi tạo/sửa UI, story hoặc demo: dùng component **Vi\*** từ vi-ui (không gọi trực tiếp `v-btn`, `v-text-field`, `v-card`, `v-menu` khi đã có ViButton, ViInput, ViCard, ViMenu); **không dùng raw `<button>`** cho action (copy, submit, link-style) — dùng **ViButton** (variant text/outlined/… tùy ngữ cảnh); icon mặc định **Tabler Icons** (`@tabler/icons-vue`). Chi tiết: `icons.mdc`, `storybook.mdc`. Áp dụng cho toàn dự án và repo consumer dùng @viui/cli (AI codegen).
26
+
27
+ ## Naming (tóm tắt)
28
+
29
+ | Loại | Quy ước | Ví dụ |
30
+ |------|---------|--------|
31
+ | **Component vi-ui** | Tiền tố `Vi` + PascalCase; thư mục `vi-<tên>` | `ViButton.vue` trong `vi-button/` |
32
+ | **Component khác** | PascalCase | `ErrorPage.vue`, `BrandLogo.vue` |
33
+ | **Stories** | `ComponentName.stories.ts`, cùng thư mục | `ViButton.stories.ts` |
34
+ | **Props / events** | kebab-case template; camelCase script | `variant="primary"`, `defineProps<{ variant: string }>()` |
35
+ | **Thư mục** | lowercase, số ít, gạch nối | `vi-button/`, `errors/` |
36
+
37
+ Chi tiết: `component-naming.mdc`.
38
+
39
+ ## NHÓM (workflow)
40
+
41
+ | NHÓM | Vị trí | Items |
42
+ |------|--------|-------|
43
+ | vi-ui | `src/design-system/vi-ui/vi-<tên>/` | ViButton, ViInput, ViCard, … |
44
+ | Brands | `src/components/brands/` | BrandLogo, StyleGuide |
45
+ | Errors | `src/components/errors/` | ErrorPage, … |
46
+ | Icons | `src/components/icons/` | … |
47
+ | Tokens | `src/tokens/` | design-tokens.ts, inet-design-tokens.ts |
48
+ | Docs | `src/docs/` | design-system.md, … |
49
+ | Storybook foundations | `src/storybook/Foundations/` | Colors.stories.ts, Typography.stories.ts, … |
50
+
51
+ Workflow: **thêm mới** (chọn NHÓM → tạo đúng vị trí → story/index), **tìm kiếm** (theo tên hoặc NHÓM). Chi tiết: `design-system-workflow.mdc`, `project-structure.mdc`.
52
+
53
+ ## Tham chiếu nhanh
54
+
55
+ - Tokens & types: `src/tokens/`, `src/types/inet-tokens-types.ts`
56
+ - Components: `src/components/` (brands, errors, icons), `src/design-system/vi-ui/` (Vi*)
57
+ - Quy ước chi tiết: skill `.cursor/skills/vue-vuetify-design-system-architect.md` và `AGENTS.md`
58
+
59
+ Khi được kích hoạt (file khớp glob), hành xử như **subagent design system và component library** của dự án và áp dụng các nguyên tắc trên.
@@ -0,0 +1,48 @@
1
+ ---
2
+ description: Workflow Design system — mục tiêu đầu ra như Cloud Panel: NHÓM + items, thêm mới, tìm kiếm
3
+ globs: src/components/**/*, src/design-system/**/*, src/tokens/**/*, src/docs/**/*, src/storybook/**/*, docs/**/*
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Workflow Design system (Mục tiêu đầu ra như Cloud Panel)
8
+
9
+ Design system được quản lý theo **mô hình panel**: **iNET Design system** là đơn vị tổ chức; bên trong có **NHÓM** và **items** (components, token files, docs). Workflow phải đạt: **thêm mới**, **tìm kiếm**, **tổng kết** rõ ràng.
10
+
11
+ ## NHÓM chuẩn (Design System)
12
+
13
+ | NHÓM | Vị trí code | Items |
14
+ |------|--------------|-------|
15
+ | vi-ui | `src/design-system/vi-ui/vi-<tên>/` | ViButton, ViInput, ViCard, ViAlert, ViDialog, … |
16
+ | Brands | `src/components/brands/` | BrandLogo, StyleGuide |
17
+ | Errors | `src/components/errors/` | ErrorPage, OvvErrorPage, ErrorKnowledgeList |
18
+ | Icons | `src/components/icons/` | ArrowLeftRight, … |
19
+ | Tokens | `src/tokens/` | color.json, typography.json, inet-design-tokens.ts |
20
+ | Docs | `src/docs/` | design-system.md, foundations/*, usage/* |
21
+ | Storybook foundations | `src/storybook/Foundations/` | Colors.stories.ts, Typography.stories.ts, SpacingLayout.stories.ts, Configure.mdx |
22
+
23
+ Mỗi item (component, token file, doc) **chỉ thuộc một NHÓM**. Chi tiết mục tiêu đầu ra và số NHÓM: xem `docs/design-system-plan.md`.
24
+
25
+ ## Workflow: Thêm item mới (Component/Token mới)
26
+
27
+ 1. **Chọn NHÓM** — vi-ui, Brands, Errors, Icons, Tokens, Docs, hoặc Storybook foundations.
28
+ 2. **Tạo đúng vị trí** — theo rule `project-structure.mdc` (vd: component Vi* → `src/design-system/vi-ui/vi-<tên>/ViName.vue` + `ViName.stories.ts`). Nếu component có **nhiều slot** (menu activator + content, list + items): thêm `ViNameStory.vue` và dùng trong stories để preview không trống (chi tiết `storybook.mdc` § Vi-ui Story Vue).
29
+ 3. **Cập nhật index/re-export** — nếu nhóm có `index.ts` (vd: `src/design-system/vi-ui/index.ts`) hoặc cần export chung.
30
+ 4. **Story/docs** — component mới có story; token/docs cập nhật nếu cần.
31
+
32
+ Không tạo component/token “lạc” ngoài các NHÓM trên.
33
+
34
+ ## Workflow: Tìm component hoặc nhóm
35
+
36
+ - **Tìm theo tên component** — search trong codebase, Storybook sidebar, hoặc docs.
37
+ - **Tìm theo NHÓM** — mở thư mục tương ứng (vd: `src/design-system/vi-ui/`, `src/tokens/`).
38
+ - Mọi item phải **có thể tìm được** qua tên hoặc qua nhóm.
39
+
40
+ ## Tổng kết (dashboard)
41
+
42
+ - **Số NHÓM:** 7 (vi-ui, Brands, Errors, Icons, Tokens, Docs, Storybook foundations).
43
+ - **Số items:** đếm được theo nhóm (components, token files, docs).
44
+ - **Trạng thái:** documented, có story, dùng token — dùng cho review (rule `verifier` / QA).
45
+
46
+ **AI codegen (toàn dự án & consumer @viui/cli):** Khi generate code UI/story/demo, dùng vi-ui (Vi*) và Tabler Icons mặc định; nút action dùng ViButton, không dùng raw `<button>`; xem `icons.mdc`, `storybook.mdc`, AGENTS.md § Codegen / AI Agent.
47
+
48
+ Khi thêm file hoặc review, đảm bảo item thuộc đúng **NHÓM** và workflow **thêm mới / tìm kiếm** tuân theo mục tiêu đầu ra trong `docs/design-system-plan.md`. **Kế hoạch tập trung:** `.cursor/plans/DESIGN_SYSTEM_PLAN.md` (một file; chỉ mục: `.cursor/plans/PLANS_INDEX.md`).
@@ -0,0 +1,37 @@
1
+ ---
2
+ description: Figma ↔ code — ánh xạ token names, component names, MCP get_design_context. Skill: .cursor/skills/figma-interpretation.md
3
+ globs: "**/*.vue", "**/*.stories.@(ts|tsx)", "src/tokens/**/*", "docs/**/*"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Figma Mapping
8
+
9
+ Quy ước ánh xạ design Figma sang code iNET Design System (Vue 3 + Vuetify, tokens, naming). **Skill khi làm từ Figma:** `.cursor/skills/figma-interpretation.md`. **Rules liên quan:** `tokens.mdc`, `component-naming.mdc`, `storybook.mdc`, `accessibility-contrast.mdc`.
10
+
11
+ ## Nguyên tắc
12
+
13
+ 1. **Tokens là nguồn chân lý** — Giá trị trong Figma (màu, spacing, radius, shadow) map sang key trong `src/tokens/design-tokens.ts`. Nếu Figma khác token, ưu tiên token; ghi chú với designer để cập nhật Figma.
14
+ 2. **Figma Variables ↔ token names** — Map tên (vd `brand/primary` → `colorTokens.brand.primary`). Tham chiếu `tokens.mdc`.
15
+ 3. **Component naming** — Component sinh từ Figma tuân `component-naming.mdc`: Vi* trong `vi-<tên>/`, PascalCase, `*.stories.ts` cùng thư mục. Story title = `{Nhóm}/{Tên}` theo `storybook.mdc`.
16
+ 4. **MCP workflow** — Figma MCP: `get_design_context(fileKey, nodeId?)` để lấy code/screenshot/hints. Output thường là reference (React/Tailwind); chuyển sang Vue 3 + Vuetify và component/token của dự án.
17
+ 5. **Accessibility** — Màu chữ/nền đạt WCAG 2.1 AA; semantic `.text` trên nền màu. Xem `accessibility-contrast.mdc` và `.cursor/skills/accessibility.md`.
18
+
19
+ ## Map nhanh (Figma → code)
20
+
21
+ | Figma | Code / token |
22
+ |-------|---------------|
23
+ | Màu (fill/text) | `colorTokens.*`, `inetDesignTokens.colors.*` |
24
+ | Spacing / layout | `spacingTokens`, `space8pt` (8pt grid) |
25
+ | Radius / corner | `shapeTokens` |
26
+ | Shadow / elevation | `elevationTokens` |
27
+ | Typography | `typographyTokens` |
28
+ | Component mới | Vi* trong `vi-<tên>/ViName.vue` + `ViName.stories.ts`; hoặc `src/components/<nhóm>/` |
29
+
30
+ ## Quy trình gợi ý
31
+
32
+ 1. **Lấy design** — MCP `get_design_context` hoặc mô tả/screenshot. Xác định sections, components, giá trị (màu, spacing, typography).
33
+ 2. **Map tokens** — Màu → `colorTokens.*` / `inetDesignTokens.colors.*`; spacing → `spacingTokens`; radius → `shapeTokens`; không thêm giá trị mới ngoài token trừ khi đã cập nhật `design-tokens.ts`.
34
+ 3. **Chọn component** — Dùng Vi* có sẵn nếu khớp; không thì tạo mới đúng thư mục và naming. Thêm story.
35
+ 4. **Kiểm tra** — Storybook chạy đúng; contrast và a11y đạt.
36
+
37
+ Khi chỉnh file khớp glob (đặc biệt khi implement từ Figma), áp dụng quy ước trên và tham chiếu skill `figma-interpretation.md`.
@@ -0,0 +1,42 @@
1
+ ---
2
+ description: Bộ icon mặc định Tabler; vi-ui trong demo/story; áp dụng toàn dự án và repo consumer (@viui/cli) khi AI gen code
3
+ globs: "**/*.vue", "**/*.ts", "**/*.tsx", "src/storybook/**/*", "src/design-system/**/*", "src/components/**/*"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Icons — Mặc định Tabler (áp dụng toàn dự án & AI codegen)
8
+
9
+ **Rule này áp dụng cho:** i-design-system và mọi repo consumer đã chạy `@viui/cli init` / `sync`. Khi **AI Agent generate code** Vue, Storybook hoặc UI, phải tuân nội dung dưới đây. AGENTS.md § Codegen / AI Agent và § Rules bắt buộc (7).
10
+
11
+ ## Bộ icon mặc định
12
+
13
+ - **Tabler Icons** (`@tabler/icons-vue`) là bộ icon **mặc định** cho dự án và cho mọi repo đã dùng **@viui/cli** (sync `.cursor`).
14
+ - License: MIT. Hơn 4.000 icon (outline/filled), tree-shakable, Vue 3.
15
+
16
+ ## Cách dùng
17
+
18
+ 1. **Import từng icon** — Chỉ icon được import mới vào bundle.
19
+ ```ts
20
+ import { IconArrowRight, IconSettings, IconUser } from '@tabler/icons-vue'
21
+ ```
22
+ 2. **Trong template:** Dùng như component Vue (`<IconArrowRight />`). Có thể truyền `size`, `stroke`, `color` theo [tài liệu Tabler](https://tabler.io/icons).
23
+ 3. **Vuetify `v-icon`:** Các component Vuetify dùng prop `icon` dạng chuỗi (vd. `prepend-icon="mdi-account"`) vẫn dùng **MDI** (đã cấu hình sẵn). Khi viết component mới, ưu tiên Tabler; nếu cần tương thích trực tiếp với `v-icon` có thể giữ MDI cho prop đó.
24
+
25
+ ## Nguồn khác (khi cần)
26
+
27
+ - **MDI:** Đã có trong Vuetify; dùng khi cần `v-icon` với tên chuỗi.
28
+ - **Lucide, Phosphor, Heroicons:** Ghi trong Storybook **Icons/Overview**; dùng khi team chọn phong cách khác.
29
+
30
+ ## Vi-ui trong demo Icons
31
+
32
+ - Demo Icons (vd. **TablerIconsDemo.vue**) dùng **vi-ui** cho UI: ViInput (search), ViButton (mọi nút action kể cả copy line trong popover: Vue name, Import, SVG), ViCard (popover nội dung), ViMenu (popover), ViButtonToggle (Outline/Filled). Không dùng raw `<button>`; nút copy/link-style dùng ViButton. Nếu thiếu component trong vi-ui thì bổ sung (vd. đã thêm ViButtonToggle) rồi dùng trong demo. Rule: `storybook.mdc` § Vi-ui trong Storybook.
33
+
34
+ ## Tham chiếu
35
+
36
+ - Storybook: **Icons/Overview**, **Icons/Tabler** — bảng nguồn và demo popover.
37
+ - Package: `@tabler/icons-vue`
38
+ - Vi-ui: `@/design-system/vi-ui` (ViInput, ViButton, ViCard, ViMenu, ViButtonToggle)
39
+
40
+ Khi được kích hoạt (file khớp glob), ưu tiên **Tabler Icons** cho icon mới; không thêm bộ icon khác làm mặc định nếu chưa thống nhất với design system.
41
+
42
+ **Plan liên quan:** `.cursor/plans/icons_free_sources.plan.md` (demo Icons, vi-ui, ViButtonToggle, sidebar Storybook).
@@ -0,0 +1,137 @@
1
+ ---
2
+ description: Cấu trúc dự án và quy ước review cấu trúc — nơi đặt file, naming, phân cấp thư mục
3
+ globs: src/**/*, docs/**/*, .storybook/**/*, public/**/*, vite.config.*, tsconfig*.json, package.json
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Cấu trúc dự án & Review cấu trúc
8
+
9
+ Rule này định nghĩa **cấu trúc chuẩn** của dự án design system và tiêu chí **review cấu trúc**. Cấu trúc hướng tới **mục tiêu đầu ra như Cloud Panel**: **iNET Design system** chứa **NHÓM** (vi-ui, Brands, Errors, Tokens, Docs, Storybook foundations) và **items** (components, token files, docs). Chi tiết workflow: `design-system-workflow.mdc` và `docs/design-system-plan.md`. Khi thêm file mới hoặc review layout, tuân theo cấu trúc dưới đây.
10
+
11
+ ---
12
+
13
+ ## Cấu trúc thư mục chuẩn
14
+
15
+ ### Root
16
+
17
+ | Thư mục / file | Mục đích |
18
+ |----------------|----------|
19
+ | `src/` | Mã nguồn chính (Vue, tokens, components, docs nội bộ) |
20
+ | `docs/` | Tài liệu dự án (plan, kế hoạch) — không nhầm với `src/docs/` |
21
+ | `public/` | Static assets dùng trực tiếp (favicon, logo, ảnh error page) |
22
+ | `.storybook/` | Cấu hình Storybook (main, preview, manager) |
23
+ | `.agent/rules/` | Agent/subagent rules (design-system, verifier, …) |
24
+ | `.cursor/rules/` | Cursor rules (.mdc) |
25
+ | `AGENTS.md` | Chỉ dẫn chung cho agent; luôn tuân thủ |
26
+
27
+ ### `src/`
28
+
29
+ | Thư mục | Mục đích | Quy ước |
30
+ |---------|----------|---------|
31
+ | `src/design-system/vi-ui/` | Component Vi* (app-facing) | Mỗi component: `vi-<tên>/ViName.vue` + `ViName.stories.ts`; nếu component có nhiều slot (menu, list, dialog…) thêm `ViNameStory.vue` để preview không trống; export từ `index.ts`. |
32
+ | `src/components/` | Component library (brands, errors, icons) | Phân cấp: brands, errors, icons. Mỗi component trong thư mục riêng. |
33
+ | `src/tokens/` | Design tokens | JSON + TS (inet-design-tokens, index re-export). |
34
+ | `src/types/` | TypeScript types (tokens, Vuetify, global). | `.d.ts` cho ambient, `.ts` cho module. |
35
+ | `src/plugins/` | Vue/Vuetify plugins (theme, vuetify). | Một file per theme/plugin. |
36
+ | `src/storybook/` | Stories dùng chung (Colors, Typography, Spacing, Configure). | Không đặt story của từng component ở đây. |
37
+ | `src/docs/` | Tài liệu design system (VitePress): foundations, philosophy, usage. | `.md`; cấu hình VitePress trong `.vitepress/`. |
38
+ | `src/assets/` | CSS, SCSS, hình ảnh dùng trong app. | **Tổng thể dự án**: `styles/` (main.scss, inet-tokens.scss, foundations/, components/); class BEM và style chung đặt ở đây. Xem `project-structure.mdc` § src/assets/styles và `bem-class-style.mdc`. |
39
+ | `src/utils/` | Hàm tiện ích (theme, color, forward). | Re-export qua `index.ts` nếu cần. |
40
+ | `src/figma/` | File Figma (tokens, components). | Tùy chọn. |
41
+
42
+ ### `src/components/`
43
+
44
+ | Cấp | Thư mục | Ví dụ | Quy ước |
45
+ |-----|---------|--------|---------|
46
+ | Khác | `brands/`, `errors/`, `icons/` | BrandLogo, ErrorPage, ArrowLeftRight | Cùng cấp; có thể có `.ts` data (ErrorData.ts). |
47
+
48
+ Component Vi* (ViButton, ViInput, …) nằm trong `src/design-system/vi-ui/` — xem `design-system-workflow.mdc` khi thêm component mới.
49
+
50
+ - **Stories**: Đặt cùng thư mục với component, tên `*.stories.ts`. Component có slot (activator + content, list + items): thêm `ViNameStory.vue` chứa template + demo, stories dùng component Story; xem `storybook.mdc`.
51
+ - **CSS scope**: Có thể dùng file `.css` riêng trong thư mục component (vd: `button.css`, `header.css`). Class theo BEM: `bem-class-style.mdc`. Style chung (BEM block) có thể đặt trong `src/assets/styles/components/` và import từ tổng thể (xem § src/assets/styles).
52
+
53
+ ### `src/assets/styles/` (SCSS tổng thể dự án)
54
+
55
+ Toàn bộ SCSS/CSS dùng chung (tokens, foundations, component blocks BEM) thuộc **một cấu trúc** dưới đây; không tách riêng SCSS chỉ cho Storybook Foundations.
56
+
57
+ | Thành phần | Mục đích |
58
+ |------------|----------|
59
+ | `main.scss` | Entry: import tokens + foundations (+ components nếu cần). Load bởi app/Storybook. |
60
+ | `inet-tokens.scss` | CSS custom properties từ design tokens (đã có). |
61
+ | `foundations/` | Partial theo từng foundation story: `_spacing-layout-stories.scss`, `_colors-stories.scss`, `_typography-stories.scss`; file `_index.scss` forward để `main.scss` import một lần. |
62
+ | `foundations/_index.scss` | `@forward` từng partial; `main.scss` chỉ `@use "foundations"` hoặc tương đương. |
63
+ | `components/` (tùy chọn) | Partial BEM cho component dùng chung nhiều nơi; component Vue có thể dùng `<style scoped>` hoặc import file cùng thư mục. |
64
+
65
+ - **Foundation stories** (Colors, Typography, Spacing & Layout): class BEM định nghĩa trong `src/assets/styles/foundations/`; story hoặc `main.scss` import từ đây.
66
+ - **Component**: Ưu tiên `<style scoped>` trong `.vue`; nếu tách file thì cùng thư mục component hoặc partial trong `src/assets/styles/components/`.
67
+
68
+ Chi tiết BEM và quy ước class: `bem-class-style.mdc`.
69
+
70
+ ### `src/tokens/`
71
+
72
+ - **JSON**: Token gốc — `color.json`, `typography.json`, `motion.json`, `elevation.json`.
73
+ - **TS**: `inet-design-tokens.ts` (nguồn truth), `design-tokens.ts` nếu có, `index.ts` re-export.
74
+ - Types: Định nghĩa trong `src/types/` (vd: `inet-tokens-types.ts`).
75
+
76
+ ### `public/`
77
+
78
+ - Favicon, logo, SVG/WebP dùng qua `/` (vd: `/favicon.ico`, `/error/client-error-status.svg`).
79
+ - **Không** đặt mã nguồn (Vue/TS) trong `public/`.
80
+
81
+ ### `docs/` (root)
82
+
83
+ - Tài liệu quản lý dự án (plan, kế hoạch). Khác với `src/docs/` (nội dung design system).
84
+
85
+ ---
86
+
87
+ ## Naming
88
+
89
+ | Loại | Quy ước | Ví dụ |
90
+ |------|---------|--------|
91
+ | Component Vue | PascalCase, một từ hoặc cụm (BaseX nếu base component) | `Button.vue`, `BaseAlert.vue`, `ErrorPage.vue` |
92
+ | Stories | `ComponentName.stories.ts` | `Button.stories.ts`, `BaseTabs.stories.ts` |
93
+ | Token file | lowercase, có dấu gạch nếu cần | `color.json`, `inet-design-tokens.ts` |
94
+ | CSS/SCSS | lowercase, gạch nếu cần | `main.scss`, `_error-page.css`, `button.css` |
95
+ | Thư mục component | lowercase, số ít | `buttons/`, `card/`, `forms/` |
96
+ | Types | PascalCase cho type/interface; file: `*-types.ts` hoặc `*.d.ts` | `inet-tokens-types.ts`, `vuetify.d.ts` |
97
+
98
+ ---
99
+
100
+ ## Checklist review cấu trúc
101
+
102
+ Khi review cấu trúc dự án, kiểm tra:
103
+
104
+ ### Vị trí file
105
+
106
+ - [ ] Component Vi* mới nằm trong `src/design-system/vi-ui/vi-<tên>/` (xem `design-system-workflow.mdc`).
107
+ - [ ] Component brands/errors/icons nằm trong `src/components/` đúng cấp, mỗi component một thư mục.
108
+ - [ ] Stories đặt cùng thư mục với component, tên `*.stories.ts`.
109
+ - [ ] Token chỉ trong `src/tokens/`; types trong `src/types/`.
110
+ - [ ] Theme/plugin trong `src/plugins/`; không rải cấu hình theme ở root.
111
+ - [ ] Tài liệu design system trong `src/docs/`; tài liệu plan/process trong `docs/`.
112
+
113
+ ### Nhất quán
114
+
115
+ - [ ] Không có file “lạc chỗ” (vd: component trong `src/utils/`, token trong `src/components/`).
116
+ - [ ] Re-export rõ ràng (vd: `src/components/index.ts`, `src/tokens/index.ts`) khi có nhiều file cần export.
117
+
118
+ ### Naming
119
+
120
+ - [ ] Component và stories đúng PascalCase / `*.stories.ts`.
121
+ - [ ] Thư mục component lowercase, số ít.
122
+
123
+ ### Cấu hình & Agent
124
+
125
+ - [ ] Cấu hình build (Vite, TS, Storybook) ở root hoặc `.storybook/`; không duplicate không cần thiết.
126
+ - [ ] Agent rules trong `.agent/rules/`; Cursor rules trong `.cursor/rules/`; không trộn lẫn định dạng.
127
+
128
+ ---
129
+
130
+ ## Khi thêm file mới
131
+
132
+ - **Component Vi* mới**: Tạo `src/design-system/vi-ui/vi-<tên>/` với `ViName.vue` + `ViName.stories.ts`; nếu component dùng nhiều slot (menu, list, dialog…) thì thêm `ViNameStory.vue` và dùng nó trong stories để tránh preview trống (rule `storybook.mdc`); export từ `src/design-system/vi-ui/index.ts`. Quy trình chi tiết: `design-system-workflow.mdc`.
133
+ - **Token mới**: Thêm vào file JSON tương ứng trong `src/tokens/` và cập nhật `inet-design-tokens.ts` / types nếu cần.
134
+ - **Story dùng chung (foundation)**: Thêm vào `src/storybook/Foundations/` (vd: `Colors.stories.ts`, `Configure.mdx`).
135
+ - **Trang/docs design system**: Thêm vào `src/docs/` (foundations, philosophy, usage) và cấu hình trong `src/docs/.vitepress/config.ts` nếu cần.
136
+
137
+ Khi được kích hoạt (file khớp glob), dùng rule này để **đánh giá cấu trúc** hoặc **hướng dẫn nơi đặt file mới**.
@@ -0,0 +1,103 @@
1
+ ---
2
+ description: Template chuẩn cho story component mới — cấu trúc meta, Default, Variants/Sizes/Colors/States; file mẫu ViButton.stories.ts
3
+ globs: "**/*.stories.@(ts|tsx)", ".cursor/plans/KPI_COMPONENT_TEMPLATE.md"
4
+ alwaysApply: false
5
+ ---
6
+
7
+ # Storybook component template (chuẩn cho component mới)
8
+
9
+ **File mẫu bắt buộc:** `src/design-system/vi-ui/vi-button/ViButton.stories.ts`
10
+
11
+ Khi tạo **story mới** cho component (vi-ui, Brands, Errors, Icons), copy cấu trúc dưới đây. Mục đích: Cursor và developer generate story đúng format; kiểm tra theo `.cursor/plans/KPI_COMPONENT_TEMPLATE.md`.
12
+
13
+ ---
14
+
15
+ ## 1. Cấu trúc file
16
+
17
+ - **Vị trí:** `ComponentName.stories.ts` **cùng thư mục** với `ComponentName.vue`.
18
+ - **vi-ui:** `src/design-system/vi-ui/vi-<tên>/ViName.stories.ts`
19
+ - **Brands/Errors/Icons:** `src/components/<nhóm>/ComponentName.stories.ts`
20
+
21
+ ---
22
+
23
+ ## 2. Meta (const meta)
24
+
25
+ | Trường | Bắt buộc | Mô tả |
26
+ |--------|----------|--------|
27
+ | `title` | Có | `ViUi/Button` | `Brands/Logo` | `Errors/ErrorPage` — đúng nhóm sidebar (xem `storybook.mdc`). |
28
+ | `component` | Có | Import component Vue tương ứng. |
29
+ | `tags` | Có | `['autodocs']` để bật Docs tab. |
30
+ | `parameters.docs.description.component` | Nên có | Dùng `docIntro(vi.viUi.xxx.descriptionComponent, en.viUi.xxx.descriptionComponent)` từ `@/locales` nếu có key; nếu chưa có locale thì string mô tả ngắn. |
31
+ | `argTypes` | Có | Mỗi prop quan trọng: `control` (select/boolean/text/…), `options` nếu select, `description` ngắn. |
32
+ | `args` | Có | Giá trị mặc định cho Controls (label, variant, color, …). |
33
+
34
+ **Ví dụ (rút gọn):**
35
+
36
+ ```ts
37
+ const meta = {
38
+ title: 'ViUi/Button',
39
+ component: ViButton,
40
+ tags: ['autodocs'],
41
+ parameters: {
42
+ docs: {
43
+ description: {
44
+ component: docIntro(vi.viUi.button.descriptionComponent, en.viUi.button.descriptionComponent),
45
+ },
46
+ },
47
+ },
48
+ argTypes: {
49
+ variant: { control: 'select', options: ['elevated', 'flat', 'outlined', 'text', 'tonal'], description: '...' },
50
+ color: { control: 'select', options: ['primary', 'secondary', ...], description: '...' },
51
+ size: { control: 'select', options: ['x-small', 'small', 'default', 'large', 'x-large'] },
52
+ loading: { control: 'boolean' },
53
+ disabled: { control: 'boolean' },
54
+ },
55
+ args: { label: 'Vi Button', variant: 'elevated', color: 'primary' },
56
+ } satisfies Meta<typeof ViButton>
57
+ export default meta
58
+ type Story = StoryObj<typeof meta>
59
+ ```
60
+
61
+ ---
62
+
63
+ ## 3. Stories (export const)
64
+
65
+ - **Default** — Bắt buộc: một story chỉ dùng `args` (vd. `args: { label: 'Primary Action' }`).
66
+ - **Theo chiều biến thể** (thêm tùy component):
67
+ - **Variants** — Nếu component có variant (elevated, flat, outlined, text, tonal): story render tất cả variant.
68
+ - **Sizes** — Nếu có prop size: story render x-small → x-large.
69
+ - **Colors** — Nếu có prop color semantic: story render primary, secondary, success, warning, error, info.
70
+ - **States** — Story gộp default + loading + disabled (và các state khác nếu có).
71
+ - **Loading** / **Disabled** — Có thể tách riêng hoặc chỉ dùng trong States.
72
+
73
+ Layout story (nhiều nút/card): dùng wrapper với class BEM (vd `vi-button-stories`) hoặc inline style ngắn; ưu tiên class + CSS/SCSS theo `bem-class-style.mdc`.
74
+
75
+ ---
76
+
77
+ ## 4. Khi Cursor generate story mới — Checklist kiểm tra
78
+
79
+ Sau khi generate, kiểm tra:
80
+
81
+ - [ ] File đặt đúng vị trí: `vi-<tên>/ViName.stories.ts` (vi-ui) hoặc `src/components/<nhóm>/ComponentName.stories.ts`.
82
+ - [ ] `title` đúng nhóm: `ViUi/...` | `Brands/...` | `Errors/...` | `Foundations/...`.
83
+ - [ ] Có **Default** và ít nhất một story theo biến thể (Variants/Sizes/Colors/States) nếu component có prop tương ứng.
84
+ - [ ] `argTypes` và `args` đủ cho props quan trọng; `tags: ['autodocs']`.
85
+ - [ ] `parameters.docs.description.component` có (docIntro từ locale hoặc string).
86
+ - [ ] Layout story: class BEM hoặc style nhất quán; không phá quy ước `bem-class-style.mdc`.
87
+
88
+ Nếu lệch: chỉnh lại story hoặc cập nhật rule / file mẫu ViButton.
89
+
90
+ ---
91
+
92
+ ## 5. File template có placeholder (tùy chọn)
93
+
94
+ - **Đường dẫn:** `.cursor/templates/ViComponent.stories.template.ts`
95
+ - Copy vào thư mục component, đổi tên file và thay `ViComponent` / `ComponentName` / `componentKey` theo component thật; thêm/bớt argTypes, args, stories theo nhu cầu.
96
+
97
+ ---
98
+
99
+ ## Tham chiếu
100
+
101
+ - Plan & checklist KPI: `.cursor/plans/KPI_COMPONENT_TEMPLATE.md`
102
+ - Story mẫu đầy đủ: `src/design-system/vi-ui/vi-button/ViButton.stories.ts`
103
+ - Rule Storybook: `storybook.mdc` — Rule naming: `component-naming.mdc` — BEM: `bem-class-style.mdc`