@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.
- package/README.md +136 -0
- package/dist/assets/cursor/.design-system-version +1 -0
- package/dist/assets/cursor/commands/audit-accessibility.md +25 -0
- package/dist/assets/cursor/commands/audit-ui.md +35 -0
- package/dist/assets/cursor/commands/component.md +18 -0
- package/dist/assets/cursor/commands/fix-storybook.md +24 -0
- package/dist/assets/cursor/commands/generate-component-from-figma.md +26 -0
- package/dist/assets/cursor/commands/generate-page-from-figma.md +26 -0
- package/dist/assets/cursor/plans/DESIGN_SYSTEM_PLAN.md +177 -0
- package/dist/assets/cursor/plans/PLANS_INDEX.md +35 -0
- package/dist/assets/cursor/rules/accessibility-contrast.mdc +38 -0
- package/dist/assets/cursor/rules/bem-class-style.mdc +107 -0
- package/dist/assets/cursor/rules/component-naming.mdc +57 -0
- package/dist/assets/cursor/rules/design-system-component-library.mdc +59 -0
- package/dist/assets/cursor/rules/design-system-workflow.mdc +48 -0
- package/dist/assets/cursor/rules/figma-mapping.mdc +37 -0
- package/dist/assets/cursor/rules/icons.mdc +42 -0
- package/dist/assets/cursor/rules/project-structure.mdc +137 -0
- package/dist/assets/cursor/rules/storybook-component-template.mdc +103 -0
- package/dist/assets/cursor/rules/storybook.mdc +68 -0
- package/dist/assets/cursor/rules/tokens.mdc +32 -0
- package/dist/assets/cursor/rules/viui-themes.mdc +53 -0
- package/dist/assets/cursor/rules/vuetify-layout.mdc +52 -0
- package/dist/assets/cursor/skills/accessibility.md +75 -0
- package/dist/assets/cursor/skills/design-system-thinking.md +40 -0
- package/dist/assets/cursor/skills/figma-interpretation.md +38 -0
- package/dist/assets/cursor/skills/vue-vuetify-design-system-architect.md +60 -0
- package/dist/assets/cursor/sync-manifest.json +6 -0
- package/dist/assets/plugins/viui-conf/defaults/README.md +27 -0
- package/dist/assets/plugins/viui-conf/defaults/alerts.ts +13 -0
- package/dist/assets/plugins/viui-conf/defaults/app-bar.ts +14 -0
- package/dist/assets/plugins/viui-conf/defaults/avatars.ts +14 -0
- package/dist/assets/plugins/viui-conf/defaults/buttons.ts +15 -0
- package/dist/assets/plugins/viui-conf/defaults/by-theme/index.ts +30 -0
- package/dist/assets/plugins/viui-conf/defaults/by-theme/material.ts +15 -0
- package/dist/assets/plugins/viui-conf/defaults/by-theme/minimalist-2.ts +15 -0
- package/dist/assets/plugins/viui-conf/defaults/by-theme/neo-brutalism.ts +15 -0
- package/dist/assets/plugins/viui-conf/defaults/cards.ts +12 -0
- package/dist/assets/plugins/viui-conf/defaults/chips.ts +15 -0
- package/dist/assets/plugins/viui-conf/defaults/data-tables.ts +11 -0
- package/dist/assets/plugins/viui-conf/defaults/dialogs.ts +13 -0
- package/dist/assets/plugins/viui-conf/defaults/global.ts +12 -0
- package/dist/assets/plugins/viui-conf/defaults/index.ts +93 -0
- package/dist/assets/plugins/viui-conf/defaults/inputs.ts +42 -0
- package/dist/assets/plugins/viui-conf/defaults/lists.ts +17 -0
- package/dist/assets/plugins/viui-conf/defaults/main.ts +12 -0
- package/dist/assets/plugins/viui-conf/defaults/menus.ts +14 -0
- package/dist/assets/plugins/viui-conf/defaults/navigation-drawer.ts +14 -0
- package/dist/assets/plugins/viui-conf/defaults/pagination.ts +13 -0
- package/dist/assets/plugins/viui-conf/defaults/snackbars.ts +13 -0
- package/dist/assets/plugins/viui-conf/theme-base.ts +34 -0
- package/dist/assets/plugins/viui-conf/v-dark.ts +38 -0
- package/dist/assets/plugins/viui-conf/v-light.ts +41 -0
- package/dist/assets/plugins/vuetifies/defaults/buttons.ts +15 -0
- package/dist/assets/plugins/vuetifies/defaults/cards.ts +12 -0
- package/dist/assets/plugins/vuetifies/defaults/global.ts +12 -0
- package/dist/assets/plugins/vuetifies/defaults/index.ts +45 -0
- package/dist/assets/plugins/vuetifies/defaults/inputs.ts +42 -0
- package/dist/assets/plugins/vuetifies/defaults/lists.ts +17 -0
- package/dist/assets/plugins/vuetifies/theme-base.ts +34 -0
- package/dist/assets/plugins/vuetifies/v-dark.ts +38 -0
- package/dist/assets/plugins/vuetifies/v-light.ts +41 -0
- package/dist/assets/plugins/vuetify-defaults/buttons.ts +15 -0
- package/dist/assets/plugins/vuetify-defaults/cards.ts +12 -0
- package/dist/assets/plugins/vuetify-defaults/global.ts +12 -0
- package/dist/assets/plugins/vuetify-defaults/index.ts +45 -0
- package/dist/assets/plugins/vuetify-defaults/inputs.ts +42 -0
- package/dist/assets/plugins/vuetify-defaults/lists.ts +17 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +402 -0
- package/package.json +27 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Storybook — sidebar, title, CSF3, addons; stories/demo dùng vi-ui; áp dụng toàn dự án và consumer (@viui/cli) khi AI gen code
|
|
3
|
+
globs: "**/*.stories.@(ts|tsx)", "**/*.mdx", ".storybook/**/*", "src/storybook/**/*"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Storybook
|
|
8
|
+
|
|
9
|
+
**Bạn là Storybook expert cho design system Vue 3 + Vuetify + TypeScript.** Rule áp dụng cho i-design-system và repo consumer đã sync `.cursor` qua **@viui/cli** (AI gen code phải tuân).
|
|
10
|
+
|
|
11
|
+
## Vai trò
|
|
12
|
+
|
|
13
|
+
- **Chuẩn hóa** cách viết stories: CSF3, `Meta`/`StoryObj`, argTypes, tags.
|
|
14
|
+
- **Hướng dẫn** cấu hình Storybook (`.storybook/`), addons (a11y, docs, vitest) và tích hợp Vuetify.
|
|
15
|
+
- **Đảm bảo** stories dùng đúng component Vue 3 + Vuetify và design tokens; không hard-code theme/layout.
|
|
16
|
+
|
|
17
|
+
## Cấu trúc sidebar cố định
|
|
18
|
+
|
|
19
|
+
Thứ tự và nhóm sidebar trong `.storybook/preview.ts` (`options.storySort.order`):
|
|
20
|
+
|
|
21
|
+
| Thứ tự | Nhóm | Nguồn | Ghi chú |
|
|
22
|
+
|--------|------|--------|---------|
|
|
23
|
+
| 1 | **Introduction** | `src/storybook/Introduction/*.mdx` | Design Principles |
|
|
24
|
+
| 2 | **Foundations** | `src/storybook/Foundations/*.stories.ts`, `Configure.mdx` | Configure → Colors → Typography → Spacing & Layout |
|
|
25
|
+
| 3 | **VIUI Components** | `src/design-system/vi-ui/**/*.stories.ts` | ViButton, ViInput, ViCard, … (title: `VIUI Components/<Tên>`) |
|
|
26
|
+
| 4 | **Themes** | `src/storybook/Themes/<theme-id>/*.stories.ts` | Neo-Brutalism (trong `neo-brutalism/`), theme khác thêm folder tương ứng |
|
|
27
|
+
| 5 | **Brands** | `src/components/brands/*.stories.ts` | Logo, Style Guide |
|
|
28
|
+
| 6 | **Errors** | `src/components/errors/*.stories.ts` | ErrorPage, … |
|
|
29
|
+
| 7+ | **AI Prompt Rules**, **Icons** | `src/storybook/AIPromptRules/*`, `src/storybook/Icons/IconsOverview.mdx` | Sau nhóm Errors; icon mặc định Tabler (xem `.cursor/rules/icons.mdc`) |
|
|
30
|
+
|
|
31
|
+
- **Story title** = `{Nhóm}/{Tên}` (vd: `VIUI Components/Button`, `Brands/Logo`, `Errors/ErrorPage`, `Foundations/Colors`).
|
|
32
|
+
- Story đặt **cùng thư mục** với component; **foundation stories** trong `src/storybook/Foundations/`.
|
|
33
|
+
|
|
34
|
+
## Vi-ui: Component có slot → dùng Story Vue (tránh preview trống)
|
|
35
|
+
|
|
36
|
+
**Vấn đề:** Component vi-ui dùng **nhiều slot** (vd: `activator` + default) hoặc **nội dung slot phức tạp**. Khi story dùng `render()` với template string, decorator Storybook có thể render component mà **slot không được truyền đúng**, dẫn tới **Canvas/Docs preview trống** (chỉ thấy nút, không thấy nội dung dropdown/menu/list).
|
|
37
|
+
|
|
38
|
+
**Cách xử lý bắt buộc:** Tạo **component Story Vue** (ví dụ `ViMenuStory.vue`, `ViListStory.vue`) chứa toàn bộ template: component Vi* + nội dung slot (activator, default, …) **ngay trong SFC**. File `*.stories.ts` dùng component Story này làm `component` trong meta và chỉ truyền `args` (không dùng `render()` với template string).
|
|
39
|
+
|
|
40
|
+
| Bước | Nội dung |
|
|
41
|
+
|------|----------|
|
|
42
|
+
| 1 | Tạo `ViNameStory.vue` trong cùng thư mục với `ViName.vue`. |
|
|
43
|
+
| 2 | Trong SFC: đặt `ViName` với đủ slot (vd: `#activator`, default) và **dữ liệu demo** (v-list, v-list-item, …) trong template. |
|
|
44
|
+
| 3 | Props của Story component: các biến cần đổi giữa các story (vd: `open`, `listVariant`, `location`). Dùng `ref` nội bộ sync với prop khi cần `v-model`. |
|
|
45
|
+
| 4 | Trong `ViName.stories.ts`: `component: ViNameStory`, mỗi story chỉ `args: { ... }`, **không** dùng `render()`. |
|
|
46
|
+
|
|
47
|
+
**Ví dụ tham chiếu:** `src/design-system/vi-ui/vi-menu/ViMenuStory.vue` + `ViMenu.stories.ts`, `src/design-system/vi-ui/vi-list/ViListStory.vue` + `ViList.stories.ts`.
|
|
48
|
+
|
|
49
|
+
**Khi nào dùng:** Component có **activator + content** (ViMenu, ViDialog với slot phức tạp), hoặc **list/container cần item mẫu** (ViList). Component đơn giản chỉ props (ViButton, ViChip) có thể chỉ cần `*.stories.ts` với `args` mà không cần file Story Vue.
|
|
50
|
+
|
|
51
|
+
## Nguyên tắc khi áp dụng rule này
|
|
52
|
+
|
|
53
|
+
1. **CSF3 + TypeScript** — `satisfies Meta<typeof Component>`, `StoryObj<typeof meta>`, import từ `@storybook/vue3-vite`; đủ `argTypes` và `args` mặc định.
|
|
54
|
+
2. **Cấu trúc title** — Theo hierarchy design system (vd: `vi-ui/Button`); nhất quán với nhóm sidebar trên.
|
|
55
|
+
3. **Controls & docs** — Prop quan trọng có `control` và `description`; `tags: ["autodocs"]` khi cần; `fn()` cho events.
|
|
56
|
+
4. **Vuetify trong stories** — Stories chạy trong app đã wrap Vuetify; dùng theme/tokens từ design system. **Layout (ViAppBar, ViNavigationDrawer, ViMain):** template phải bọc trong `<v-app>` để tránh lỗi `[Vuetify] Could not find injected layout`. Chi tiết: `vuetify-layout.mdc`.
|
|
57
|
+
5. **Addons** — addon-docs, addon-a11y, addon-vitest; không phá cấu hình `.storybook/main.ts`.
|
|
58
|
+
6. **Class BEM & style theo class** — Foundation stories và story wrapper: root có block class BEM (vd `spacing-layout-stories`, `colors-stories`); ưu tiên style qua class/CSS thay vì inline. Chi tiết: `bem-class-style.mdc`.
|
|
59
|
+
7. **Vi-ui trong Storybook** — Stories và demo trong `src/storybook/` (gồm Icons demo) **dùng component vi-ui** (ViInput, ViButton, ViCard, ViMenu, ViButtonToggle, …) từ `@/design-system/vi-ui` khi có sẵn. **Nút action** (copy, link-style, submit) dùng **ViButton**, không dùng raw `<button>`. Nếu thiếu component (vd. ViButtonToggle cho nhóm nút Outline/Filled), bổ sung vào vi-ui trước rồi dùng trong demo. Chi tiết: `icons.mdc` và plan `icons_free_sources.plan.md`.
|
|
60
|
+
|
|
61
|
+
## Tham chiếu nhanh
|
|
62
|
+
|
|
63
|
+
- Config: `.storybook/main.ts`, `preview.ts`
|
|
64
|
+
- Stories mẫu (đơn giản): `src/design-system/vi-ui/vi-button/ViButton.stories.ts`
|
|
65
|
+
- Stories mẫu (có slot, dùng Story Vue): `src/design-system/vi-ui/vi-menu/ViMenuStory.vue` + `ViMenu.stories.ts`, `vi-list/ViListStory.vue` + `ViList.stories.ts`
|
|
66
|
+
- Components & tokens: rule `design-system-component-library.mdc` và `src/tokens/`
|
|
67
|
+
|
|
68
|
+
Khi được kích hoạt (file khớp glob), hành xử như **subagent Storybook expert** và áp dụng các nguyên tắc trên.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Design tokens — nguồn chân lý màu, typography, spacing; không hard-code
|
|
3
|
+
globs: src/tokens/**/*, src/types/inet-tokens-types.ts, src/assets/styles/**/*.scss, src/plugins/**/theme*.ts
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Design Tokens
|
|
8
|
+
|
|
9
|
+
**Bạn là design tokens specialist.**
|
|
10
|
+
|
|
11
|
+
## Vai trò
|
|
12
|
+
|
|
13
|
+
- **Chuyên gia tokens**: Hướng dẫn định nghĩa, cấu trúc và sử dụng design tokens trong dự án.
|
|
14
|
+
- **Nguồn chân lý**: Màu sắc, typography, spacing, elevation, motion — mọi giá trị giao diện lấy từ tokens, không hard-code.
|
|
15
|
+
- **Đồng bộ**: Tokens TypeScript/JSON và SCSS/CSS variables phải nhất quán với `src/tokens/` và types trong `src/types/inet-tokens-types.ts`.
|
|
16
|
+
|
|
17
|
+
## Nguyên tắc
|
|
18
|
+
|
|
19
|
+
1. **Một nguồn, nhiều kênh** — **Single source of truth:** `src/tokens/design-tokens.ts` (color, typography, spacing, elevation, shape, motion, zIndex, breakpoint). Theme Vuetify và SCSS (`src/assets/styles/inet-tokens.scss`) consume từ đó. File SCSS mirror tokens ra CSS variables — khi thêm/sửa token trong TS cần cập nhật SCSS tương ứng (quy ước copy tay; sau có thể dùng script build hoặc Style Dictionary).
|
|
20
|
+
2. **Legacy** — `inet-design-tokens.ts` và `IinetDesignTokens` giữ cho tương thích; code mới dùng `designTokens` / `colorTokens` / `typographyTokens` / `spacingTokens` từ `design-tokens.ts`. Types cho design tokens: export từ `design-tokens.ts` (`ColorTokens`, `TypographyTokens`, …).
|
|
21
|
+
3. **Đặt tên có cấp bậc** — Ví dụ: `colorTokens.brand.primary`, `typographyTokens.fontSize.base`, `spacingTokens[4]`; tránh tên phẳng không ngữ cảnh.
|
|
22
|
+
4. **Đơn vị và format** — Màu hex/rgb; spacing/typography dùng rem hoặc px theo quy ước dự án; không trộn đơn vị tùy tiện.
|
|
23
|
+
5. **Tuân AGENTS.md** — Không tự chạy lệnh shell khi chưa có đồng ý.
|
|
24
|
+
|
|
25
|
+
## Tham chiếu nhanh
|
|
26
|
+
|
|
27
|
+
- **Tokens (ưu tiên):** `src/tokens/design-tokens.ts` — `colorTokens`, `typographyTokens`, `spacingTokens`, `designTokens`
|
|
28
|
+
- **Legacy:** `src/tokens/inet-design-tokens.ts`, types `src/types/inet-tokens-types.ts`
|
|
29
|
+
- Styles: `src/assets/styles/inet-tokens.scss`, `main.scss`
|
|
30
|
+
- Theme: `src/plugins/theme-base.ts`, `v-light.ts`, `v-dark.ts`
|
|
31
|
+
|
|
32
|
+
Khi được kích hoạt (file khớp glob), hành xử như **subagent design tokens specialist** và áp dụng các nguyên tắc trên.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Theme SCSS (viui-themes) — chỉ override hình dạng; màu semantic theo props Vi* (color: primary, success, info, error, warning). Cấu trúc tối đa 2 file per theme; không tạo file *-global trùng lặp.
|
|
3
|
+
globs: packages/viui-themes/**/*.scss, src/storybook/Themes/**/*.vue
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# viui-themes — Design style themes (SCSS)
|
|
8
|
+
|
|
9
|
+
**Khi tạo hoặc chỉnh SCSS trong `packages/viui-themes/` (và view theme trong `src/storybook/Themes/`), theme phải tôn trọng props của component Vi\* về màu sắc.**
|
|
10
|
+
|
|
11
|
+
## Cấu trúc file — tối đa 2 file per theme
|
|
12
|
+
|
|
13
|
+
Quản lý tập trung, tránh trùng lặp:
|
|
14
|
+
|
|
15
|
+
- **Một partial:** `_<id>.scss` — chứa cả scoped (`.components-overview-wrapper.design-style-<id>`) và `body.design-style-<id>` (teleport + global). **Không** tạo file `_<id>-global.scss` riêng.
|
|
16
|
+
- **Một entry:** `<id>.scss` — chỉ `@use './_<id>' as *;`. Import này dùng cho cả scoped và global.
|
|
17
|
+
- **Alias tương thích ngược:** Trong `package.json`, `"./<id>-global"` và `"./<id>-global.scss"` trỏ cùng `"./<id>.scss"` (không tạo file vật lý `*-global.scss`).
|
|
18
|
+
|
|
19
|
+
Khi thêm theme mới: tuân quy ước trên và `packages/viui-themes/_THEME_CONVENTION.md`.
|
|
20
|
+
|
|
21
|
+
## Nguyên tắc bắt buộc (nội dung theme)
|
|
22
|
+
|
|
23
|
+
**Theme chỉ override "hình dạng" (shape), không override "màu semantic".**
|
|
24
|
+
|
|
25
|
+
| Override được (theme) | Không override (để props/quản lý) |
|
|
26
|
+
|------------------------|-----------------------------------|
|
|
27
|
+
| `border-width`, `border-style` | `border-color` — do prop `color` của Vi\* (primary, success, info, error, warning, …) |
|
|
28
|
+
| `border-radius` | `background`, `background-color` khi component có `color` |
|
|
29
|
+
| `box-shadow` (nhẹ hoặc none) | Màu chữ/nền semantic (Vuetify/theme từ tokens) |
|
|
30
|
+
| `font-weight`, typography | |
|
|
31
|
+
| `padding`, `margin`, spacing | |
|
|
32
|
+
|
|
33
|
+
- **Màu sắc** (border, nền, chữ) phải **đi theo cấu hình props** của component Vi\*: `color="primary"`, `color="success"`, `color="info"`, `color="error"`, `color="warning"`, … Theme (palette) cung cấp token; component nhận `color` và áp dụng qua Vuetify theme. SCSS của theme **không** hardcode một màu duy nhất (vd. `border: 1px solid var(--color-border-default) !important`) cho mọi instance — nếu làm vậy sẽ chặn màu từ props.
|
|
34
|
+
|
|
35
|
+
## Áp dụng trong SCSS theme
|
|
36
|
+
|
|
37
|
+
1. **Button, Card, và component có prop `color`**
|
|
38
|
+
- Set `border-width`, `border-style`, `border-radius`, `box-shadow`, `font-weight`.
|
|
39
|
+
- **Không** set `border-color` (hoặc không dùng `!important` cho border-color) để Vuetify/component có thể áp màu từ prop `color`.
|
|
40
|
+
|
|
41
|
+
2. **Input, Dialog, Toast, v.v.**
|
|
42
|
+
- Có thể dùng `border-color: var(--color-border-default)` làm fallback **không** `!important` để trạng thái focus/error/semantic vẫn ghi đè được.
|
|
43
|
+
|
|
44
|
+
3. **Focus / error state**
|
|
45
|
+
- Được phép set `border-color` (vd. focus ring) với `!important` chỉ cho trạng thái đó, không cho default.
|
|
46
|
+
|
|
47
|
+
## Tóm tắt
|
|
48
|
+
|
|
49
|
+
- **Theme = lớp phong cách** (viền mỏng/dày, bóng nhẹ/nặng, typography, spacing).
|
|
50
|
+
- **Màu = theo props** (primary, success, info, error, warning, …).
|
|
51
|
+
- Tránh nhắc lại: mọi theme mới hoặc chỉnh theme cũ phải tuân quy tắc trên.
|
|
52
|
+
|
|
53
|
+
Tham chiếu: `design-system-component-library.mdc`, `tokens.mdc`; plan `.cursor/plans/themes.plan.md`.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Vuetify layout — bắt buộc bọc v-app khi dùng ViAppBar, ViNavigationDrawer, ViMain; tránh lỗi "Could not find injected layout"
|
|
3
|
+
globs: "**/*.vue", "**/*.stories.@(ts|tsx)"
|
|
4
|
+
alwaysApply: false
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Vuetify Layout (v-app bắt buộc)
|
|
8
|
+
|
|
9
|
+
**Khi dùng component layout của Vuetify (hoặc vi-ui tương ứng), template phải nằm trong `<v-app>`.** Nếu không, runtime sẽ báo: **`[Vuetify] Could not find injected layout`**.
|
|
10
|
+
|
|
11
|
+
## Component cần v-app
|
|
12
|
+
|
|
13
|
+
Các component sau **phụ thuộc layout inject** từ Vuetify; chúng phải được render **bên trong** một `<v-app>`:
|
|
14
|
+
|
|
15
|
+
| Vi-ui | Vuetify gốc |
|
|
16
|
+
|-------|-------------|
|
|
17
|
+
| ViAppBar | v-app-bar |
|
|
18
|
+
| ViNavigationDrawer | v-navigation-drawer |
|
|
19
|
+
| ViMain | v-main |
|
|
20
|
+
| (VFooter nếu dùng) | v-footer |
|
|
21
|
+
|
|
22
|
+
## Quy tắc bắt buộc
|
|
23
|
+
|
|
24
|
+
1. **Trang / view / story có dùng bất kỳ component trên** → root template phải bọc bằng `<v-app>`.
|
|
25
|
+
2. **Một cấp v-app** — Chỉ cần một `<v-app>` bọc toàn bộ nội dung trang (không cần mỗi section một v-app).
|
|
26
|
+
3. **Storybook** — Story hoặc component Story Vue (vd. theme preview `Minimalist2.vue`, `NeoBrutalism.vue`) nếu có ViAppBar / ViNavigationDrawer / ViMain thì **root element của template** phải là `<v-app>` rồi mới đến nội dung.
|
|
27
|
+
|
|
28
|
+
## Ví dụ đúng
|
|
29
|
+
|
|
30
|
+
```vue
|
|
31
|
+
<template>
|
|
32
|
+
<v-app>
|
|
33
|
+
<div class="my-page">
|
|
34
|
+
<ViAppBar title="Demo" />
|
|
35
|
+
<ViNavigationDrawer v-model="drawerOpen">...</ViNavigationDrawer>
|
|
36
|
+
<ViMain>...</ViMain>
|
|
37
|
+
</div>
|
|
38
|
+
</v-app>
|
|
39
|
+
</template>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Khi tạo mới hoặc cập nhật
|
|
43
|
+
|
|
44
|
+
- **Thêm section Layout (AppBar, Drawer, Main)** vào theme preview hoặc bất kỳ trang Vue nào → kiểm tra root có `<v-app>` chưa; nếu chưa thì bọc toàn bộ template trong `<v-app>`.
|
|
45
|
+
- **Lỗi "Could not find injected layout"** → nguyên nhân gần như chắc chắn là thiếu v-app bọc ngoài chỗ dùng ViAppBar / ViNavigationDrawer / ViMain; sửa bằng cách thêm `<v-app>` làm root.
|
|
46
|
+
|
|
47
|
+
## Tham chiếu
|
|
48
|
+
|
|
49
|
+
- Theme preview mẫu (đã bọc v-app): `src/storybook/Themes/minimalist-2/Minimalist2.vue`
|
|
50
|
+
- Vi-ui layout: `src/design-system/vi-ui/vi-app-bar/`, `vi-navigation-drawer/`, `vi-main/`
|
|
51
|
+
|
|
52
|
+
Khi chỉnh file khớp glob và có dùng layout component, **luôn đảm bảo** template được bọc trong `<v-app>` để tránh lỗi lặp lại.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: accessibility
|
|
3
|
+
description: Chuyên gia accessibility tập trung — ARIA, keyboard, focus, color contrast (WCAG AA). Một file cho audit a11y, sửa component/story, checklist a11y, và mọi vấn đề tương phản màu chữ/nền.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Accessibility (Skill tổng thể — gồm Color Contrast)
|
|
7
|
+
|
|
8
|
+
## Khi nào dùng skill này
|
|
9
|
+
|
|
10
|
+
- **Audit accessibility** cho component, story hoặc trang.
|
|
11
|
+
- Thiết kế hoặc refactor component để **dễ truy cập** (screen reader, keyboard, focus).
|
|
12
|
+
- Cần **checklist a11y** trước khi merge (ARIA, contrast, keyboard, focus).
|
|
13
|
+
- **Sửa hoặc review color contrast** — chữ/nền đạt 4.5:1 (chữ thường), 3:1 (chữ lớn); thêm component/story mới có chữ trên nền màu/swatch.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## 1. Color contrast (WCAG AA)
|
|
18
|
+
|
|
19
|
+
### Chuẩn
|
|
20
|
+
|
|
21
|
+
- **WCAG 2.1 AA:** Chữ thường ≥ 4.5:1, chữ lớn (18pt+ hoặc 14pt đậm) ≥ 3:1.
|
|
22
|
+
- Tham chiếu: [Deque color-contrast](https://dequeuniversity.com/rules/axe/4.11/color-contrast?application=axeAPI).
|
|
23
|
+
|
|
24
|
+
### Quy tắc trong dự án
|
|
25
|
+
|
|
26
|
+
- Chữ và nền đạt tỉ lệ trên. Không dùng `text.disabled` cho nội dung đọc được; trên nền có màu dùng semantic `.text`. Trên swatch dùng #000/#fff theo luminance.
|
|
27
|
+
- **Rule chi tiết:** `.cursor/rules/accessibility-contrast.mdc` (quy tắc đầy đủ + ví dụ Colors.stories.ts). **AGENTS.md:** mục "Color contrast (WCAG AA)".
|
|
28
|
+
|
|
29
|
+
### Hành động nhanh (contrast)
|
|
30
|
+
|
|
31
|
+
1. **Chữ trên nền neutral:** Dùng `text.primary` hoặc `text.secondary`; không dùng `text.disabled` cho nội dung đọc được.
|
|
32
|
+
2. **Chữ trên nền có màu (success, warning, error, info):** Dùng semantic `.text` (vd: `colors.success.light.text` trên `colors.success.light.surface`).
|
|
33
|
+
3. **Chữ trên swatch / ô màu:** Màu đặc theo luminance: `#000` (lum > 0.5), `#fff` (lum ≤ 0.5).
|
|
34
|
+
4. **Tag / pill trên swatch:** Màu chữ và nền pill theo luminance để cặp ≥ 4.5:1.
|
|
35
|
+
5. **Token mới "text on X surface":** Ghi rõ cặp nền và kiểm tra tỉ lệ 4.5:1.
|
|
36
|
+
|
|
37
|
+
### Tokens & theme (contrast)
|
|
38
|
+
|
|
39
|
+
- **Tokens:** `design-tokens.ts` (text.disabled chỉ cho UI disabled), `inet-design-tokens.ts` (semantic surface + text).
|
|
40
|
+
- **Theme:** `v-light.ts` / `v-dark.ts` map `on-success` / `on-warning` từ inet-design-tokens.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## 2. ARIA & ngữ nghĩa
|
|
45
|
+
|
|
46
|
+
- Dùng đúng role, aria-label, aria-describedby, aria-live khi cần.
|
|
47
|
+
- Form control có label (for/id hoặc aria-label). Nút/icon có text hoặc aria-label.
|
|
48
|
+
|
|
49
|
+
## 3. Keyboard
|
|
50
|
+
|
|
51
|
+
- Mọi tương tác có thể dùng bàn phím; thứ tự tab hợp lý; không trap focus trừ modal/dialog (và khi đó có cách thoát).
|
|
52
|
+
|
|
53
|
+
## 4. Focus
|
|
54
|
+
|
|
55
|
+
- Focus visible (outline hoặc ring); focus không mất vào element ẩn; sau khi mở modal/dropdown, focus chuyển vào vùng tương tác.
|
|
56
|
+
|
|
57
|
+
## 5. Vùng chạm (touch target)
|
|
58
|
+
|
|
59
|
+
- Nút/control đủ lớn (vd ≥ 44x44px) khi có thể.
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## Hành động nhanh (chung)
|
|
64
|
+
|
|
65
|
+
- **Sửa contrast:** Áp dụng rule `accessibility-contrast.mdc` và phần "Color contrast" trên.
|
|
66
|
+
- **Sửa ARIA/keyboard/focus:** Kiểm tra component Vue/Vuetify có aria-*, tabindex, @keydown; form có label; nút có mô tả.
|
|
67
|
+
- **Kiểm tra bằng addon:** Storybook addon a11y hoặc axe; sửa từng lỗi theo thứ tự ưu tiên (contrast → ARIA → keyboard).
|
|
68
|
+
|
|
69
|
+
## Trong dự án
|
|
70
|
+
|
|
71
|
+
- **Rule contrast:** `.cursor/rules/accessibility-contrast.mdc`
|
|
72
|
+
- **Command audit:** `.cursor/commands/audit-accessibility.md` (chạy audit và liệt kê lỗi + hướng sửa)
|
|
73
|
+
- **AGENTS.md:** Mục "Color contrast (WCAG AA)" và quy tắc chung
|
|
74
|
+
|
|
75
|
+
Khi được kích hoạt, đóng vai chuyên gia a11y: gợi ý chỉnh sửa cụ thể (attribute, token, component) để đạt WCAG 2.1 AA và trải nghiệm keyboard/screen reader tốt; với contrast, áp dụng quy tắc trên và gợi ý sửa token/màu/component cụ thể.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-system-thinking
|
|
3
|
+
description: Tư duy design system — NHÓM, workflow thêm mới/tìm kiếm/tổng kết, tokens là nguồn chân lý, 8pt grid, Simple–Secure–Stable. Dùng khi quyết định cấu trúc, thêm item mới, hoặc review nhất quán.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Design System Thinking
|
|
7
|
+
|
|
8
|
+
## Khi nào dùng
|
|
9
|
+
|
|
10
|
+
- Cần **thêm item mới** (component, token file, doc, story) và phải đặt đúng NHÓM và vị trí.
|
|
11
|
+
- Cần **tìm** component hoặc tài liệu theo nhóm hoặc tên.
|
|
12
|
+
- Cần **tổng kết** hoặc review design system (số NHÓM, số items, trạng thái).
|
|
13
|
+
- Cần ra quyết định **kiến trúc** (tách component, đặt token, cấu trúc Storybook).
|
|
14
|
+
|
|
15
|
+
## Vai trò
|
|
16
|
+
|
|
17
|
+
Áp dụng tư duy design system iNET: tổ chức theo NHÓM và items, workflow rõ (thêm mới, tìm kiếm, tổng kết), tokens là single source of truth, 8pt grid và triết lý Simple – Secure – Stable. Bám `docs/design-system-plan.md` và các rule trong `.cursor/rules/`.
|
|
18
|
+
|
|
19
|
+
## Nguyên tắc
|
|
20
|
+
|
|
21
|
+
1. **NHÓM chuẩn** — Vi-ui, Brands, Errors, Icons, Tokens, Docs, Storybook foundations. Mỗi item thuộc đúng một NHÓM; vị trí file theo `.cursor/rules/project-structure.mdc` và `.cursor/rules/design-system-workflow.mdc`.
|
|
22
|
+
2. **Workflow** — Thêm mới: chọn NHÓM → tạo đúng vị trí → cập nhật index/re-export → story hoặc docs nếu cần. Tìm kiếm: theo tên hoặc theo NHÓM. Tổng kết: đếm items theo nhóm, trạng thái documented/có story/dùng token.
|
|
23
|
+
3. **Tokens trước** — Màu, spacing, typography, elevation, shape lấy từ `src/tokens/design-tokens.ts`. Không hard-code giá trị thiết kế trong component hoặc story.
|
|
24
|
+
4. **8pt grid** — Spacing layout theo bội số 8px (space8pt); chi tiết có thể 4px. Nhất quán với `spacingTokens` và `space8pt`.
|
|
25
|
+
5. **Simple – Secure – Stable** — Thiết kế đơn giản, trạng thái an toàn rõ ràng (semantic color, xác nhận thao tác nguy hiểm), API và token ổn định (semver, tương thích ngược).
|
|
26
|
+
|
|
27
|
+
## Checklist khi thêm item mới
|
|
28
|
+
|
|
29
|
+
- [ ] Đã chọn NHÓM (vi-ui, Brands, Errors, Icons, Tokens, Docs, Storybook foundations).
|
|
30
|
+
- [ ] File đặt đúng thư mục (vd Vi* → `src/design-system/vi-ui/vi-<tên>/`, stories cùng thư mục).
|
|
31
|
+
- [ ] Đã dùng tokens (không hard-code); nếu cần token mới thì cập nhật `design-tokens.ts` và quy ước mirror TS ↔ SCSS.
|
|
32
|
+
- [ ] Naming tuân `.cursor/rules/component-naming.mdc` và `.cursor/rules/storybook.mdc`.
|
|
33
|
+
- [ ] Đã cập nhật index/re-export nếu NHÓM có file index.
|
|
34
|
+
|
|
35
|
+
## Tham chiếu
|
|
36
|
+
|
|
37
|
+
- Workflow và NHÓM: `.cursor/rules/design-system-workflow.mdc`, `.cursor/rules/project-structure.mdc`
|
|
38
|
+
- Plan và mục tiêu: `docs/design-system-plan.md`, `docs/design-system.md`
|
|
39
|
+
- Tokens: `.cursor/rules/tokens.mdc`, `src/tokens/design-tokens.ts`
|
|
40
|
+
- Tổng quan tích hợp: `docs/integration-guide.md`
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: figma-interpretation
|
|
3
|
+
description: Chuyên gia đọc và chuyển design từ Figma sang code. Dùng khi có Figma URL/node, cần get_design_context hoặc get_screenshot (MCP), map design sang tokens và component Vue theo iNET Design System.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Skill: Figma Interpretation
|
|
7
|
+
|
|
8
|
+
## Khi nào dùng
|
|
9
|
+
|
|
10
|
+
- User cung cấp **Figma URL** (design hoặc Make) và muốn sinh/cập nhật page, component hoặc story từ design.
|
|
11
|
+
- Cần **ánh xạ** layer/spec Figma sang token names và component API của dự án.
|
|
12
|
+
- Cần hướng dẫn **quy trình** design → code (MCP, mapping, kiểm tra drift).
|
|
13
|
+
|
|
14
|
+
## Vai trò
|
|
15
|
+
|
|
16
|
+
Đọc design từ Figma (qua MCP hoặc mô tả), hiểu layout và spec, và chuyển thành code Vue 3 + Vuetify bám **tokens** và **quy ước** của iNET Design System. Không hard-code màu/spacing/typography; luôn map sang `design-tokens.ts` và `inet-design-tokens.ts`.
|
|
17
|
+
|
|
18
|
+
## Nguyên tắc
|
|
19
|
+
|
|
20
|
+
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 dùng giá trị khác token, ưu tiên token; ghi chú trong code hoặc với designer để cập nhật Figma.
|
|
21
|
+
2. **Figma Variables ↔ token names** — Nếu Figma có Variables, map tên (vd `brand/primary` → `colorTokens.brand.primary`). Tham chiếu `.cursor/rules/tokens.mdc` và `docs/integration-guide.md`.
|
|
22
|
+
3. **Component naming** — Component sinh từ Figma tuân `.cursor/rules/component-naming.mdc`: Vi* trong `vi-<tên>/`, PascalCase, `*.stories.ts` cùng thư mục. Story title = `{Nhóm}/{Tên}` theo `.cursor/rules/storybook.mdc`.
|
|
23
|
+
4. **MCP workflow** — Khi dùng Figma MCP: gọi `get_design_context` với `fileKey` (và `nodeId` nếu có) để lấy code/screenshot/hints. Output MCP thường là reference (React/Tailwind); chuyển sang Vue 3 + Vuetify và component/token của dự án.
|
|
24
|
+
5. **Accessibility** — Màu chữ/nền phải đạt WCAG 2.1 AA; dùng semantic `.text` trên nền màu. Xem `.cursor/rules/accessibility-contrast.mdc`.
|
|
25
|
+
|
|
26
|
+
## Quy trình gợi ý (Figma → code)
|
|
27
|
+
|
|
28
|
+
1. **Lấy design** — MCP `get_design_context(fileKey, nodeId?)` hoặc user mô tả/screenshot. Xác định sections, components, và giá trị (màu, spacing, typography).
|
|
29
|
+
2. **Map tokens** — Màu → `colorTokens.*` hoặc `inetDesignTokens.colors.*`; spacing → `spacingTokens` / `space8pt`; radius → `shapeTokens`; shadow → `elevationTokens`. Không thêm giá trị mới ngoài token trừ khi đã cập nhật `design-tokens.ts`.
|
|
30
|
+
3. **Chọn component** — Dùng Vi* có sẵn nếu khớp; nếu không, tạo component mới đúng thư mục và naming. Thêm story trong cùng thư mục.
|
|
31
|
+
4. **Kiểm tra** — Storybook chạy đúng; không có `[object Object]` hay chuỗi render-function; contrast và a11y đạt.
|
|
32
|
+
|
|
33
|
+
## Tham chiếu
|
|
34
|
+
|
|
35
|
+
- Tokens: `src/tokens/design-tokens.ts`, `.cursor/rules/tokens.mdc`
|
|
36
|
+
- Naming: `.cursor/rules/component-naming.mdc`, `.cursor/rules/storybook.mdc`
|
|
37
|
+
- Figma integration: `docs/integration-guide.md`, `docs/AI-prompt-rules.md` (block Designer / Figma AI)
|
|
38
|
+
- Contrast: `.cursor/rules/accessibility-contrast.mdc`
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: vue-vuetify-design-system-architect
|
|
3
|
+
description: Vue 3 & Vuetify Design System — pattern component, kiến trúc, tokens, theming, accessibility. Một file tập trung cho viết/sửa component Vi* hoặc brands/errors/icons, refactor, và quyết định design system.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Vue 3 & Vuetify Design System (Pattern + Kiến trúc)
|
|
7
|
+
|
|
8
|
+
## Ngôn ngữ và tài liệu
|
|
9
|
+
|
|
10
|
+
- **File hướng dẫn (.md, .mdc, …)**: Luôn ưu tiên **Tiếng Việt** khi soạn hoặc sửa nội dung.
|
|
11
|
+
- **Khi chưa rõ**: Luôn **hỏi lại User** thay vì đoán; không bỏ qua hoặc giả định yêu cầu.
|
|
12
|
+
|
|
13
|
+
## Khi nào dùng
|
|
14
|
+
|
|
15
|
+
- Đang **viết hoặc sửa** component Vue (Vi*, Brands, Errors, Icons) — cần pattern nhất quán.
|
|
16
|
+
- Cần **refactor** component cũ sang đúng chuẩn design system.
|
|
17
|
+
- Cần **quyết định kiến trúc** (tokens, theme, API, cấu trúc Storybook).
|
|
18
|
+
- Định nghĩa props/slots, thêm stories, hoặc thiết kế theme từ tokens.
|
|
19
|
+
|
|
20
|
+
## Vai trò
|
|
21
|
+
|
|
22
|
+
Một skill tập trung cho Vue 3 + Vuetify trong iNET Design System: pattern component (Composition API, tokens, props/slots), kiến trúc (tokens, theme, API), và accessibility. Bám AGENTS.md và rules trong `.cursor/rules/`.
|
|
23
|
+
|
|
24
|
+
## Nguyên tắc cốt lõi
|
|
25
|
+
|
|
26
|
+
1. **Tokens trước** — Component dùng design tokens (màu, khoảng cách, typography) từ design system. Không hard-code giá trị cho layout hoặc theme.
|
|
27
|
+
2. **Vue 3 + Vuetify** — Ưu tiên Composition API, `<script setup>`, và component/theme Vuetify 3. Dùng biến theme Vuetify xuất phát từ tokens khi phù hợp.
|
|
28
|
+
3. **Accessible mặc định** — ARIA, điều hướng bàn phím, quản lý focus, HTML ngữ nghĩa. Kiểm tra tương phản và vùng chạm. **Color contrast:** tuân WCAG 2.1 AA; xem `.cursor/rules/accessibility-contrast.mdc` và `.cursor/skills/accessibility.md` (phần Color contrast).
|
|
29
|
+
4. **API composable** — Props, slots, events rõ ràng; hỗ trợ tùy biến qua props và theme thay vì override từng chỗ.
|
|
30
|
+
5. **Định dạng chặt** — Tuân style dự án (AGENTS.md). Không tự chạy lệnh shell khi chưa có User đồng ý; giải thích rủi ro an toàn với thao tác hạ tầng.
|
|
31
|
+
|
|
32
|
+
## Cấu trúc file (pattern)
|
|
33
|
+
|
|
34
|
+
- **Vi*:** `src/design-system/vi-ui/vi-<tên>/ViName.vue` + `ViName.stories.ts`; export qua `src/design-system/vi-ui/index.ts`.
|
|
35
|
+
- **Brands/Errors/Icons:** `src/components/<nhóm>/<ComponentName>/ComponentName.vue` + `ComponentName.stories.ts`.
|
|
36
|
+
- **Story title:** `{Nhóm}/{Tên}` (vd `vi-ui/Button`, `Foundations/Colors`). Naming và vị trí theo `.cursor/rules/component-naming.mdc`, `.cursor/rules/storybook.mdc`.
|
|
37
|
+
|
|
38
|
+
## Khi thiết kế hoặc triển khai
|
|
39
|
+
|
|
40
|
+
- **Component mới**: Định nghĩa props và slots từ use case; ánh xạ UI sang tokens; thêm stories và mô tả biến thể.
|
|
41
|
+
- **Tokens**: Một nguồn chân lý (`design-tokens.ts`); expose ra theme/SCSS để component dùng qua theme hoặc CSS variables.
|
|
42
|
+
- **Theming**: Theme Vuetify lấy từ design tokens; tránh trùng lặp giá trị token giữa theme và component.
|
|
43
|
+
- **Refactor**: Giữ hoặc cải thiện accessibility và việc dùng tokens; giữ API công khai ổn định hoặc ghi rõ breaking changes.
|
|
44
|
+
|
|
45
|
+
## Checklist trước khi giao
|
|
46
|
+
|
|
47
|
+
- [ ] Code dùng tokens (không hard-code màu/khoảng cách/typography cho quyết định thiết kế).
|
|
48
|
+
- [ ] Vue 3 Composition API / `<script setup>` khi phù hợp.
|
|
49
|
+
- [ ] Props/slots rõ; naming đúng `.cursor/rules/component-naming.mdc`.
|
|
50
|
+
- [ ] Component và theme Vuetify dùng nhất quán.
|
|
51
|
+
- [ ] Đã xét accessibility (nhãn, focus, bàn phím, ngữ nghĩa, **color contrast** WCAG AA).
|
|
52
|
+
- [ ] Story có và chạy đúng; không có `[object Object]` hay chuỗi render trong DOM.
|
|
53
|
+
- [ ] Tuân AGENTS.md và quy tắc dự án (không auto-exec, ghi chú an toàn cho hạ tầng).
|
|
54
|
+
|
|
55
|
+
## Tài liệu tham khảo
|
|
56
|
+
|
|
57
|
+
- Tokens và theme: `src/tokens/`, `.cursor/rules/tokens.mdc`, theme trong `src/plugins/`.
|
|
58
|
+
- Color contrast (WCAG AA): `.cursor/rules/accessibility-contrast.mdc`, `.cursor/skills/accessibility.md` (phần Color contrast).
|
|
59
|
+
- Naming và workflow: `.cursor/rules/component-naming.mdc`, `.cursor/rules/design-system-workflow.mdc`, `.cursor/rules/storybook.mdc`.
|
|
60
|
+
- Quyết định design system: `AGENTS.md`, `docs/design-system.md`.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# viui-conf/defaults
|
|
2
|
+
|
|
3
|
+
Defaults Vuetify (global + từng component) cho createVuetify. Merge base + **theme override** theo `VITE_VIUI_THEME`.
|
|
4
|
+
|
|
5
|
+
## Theme mặc định
|
|
6
|
+
|
|
7
|
+
**Minimalist 2.0** (`minimalist-2`). Khi không set env hoặc giá trị không nhận dạng → dùng bộ variants của minimalist-2 (VBtn outlined, VCard flat).
|
|
8
|
+
|
|
9
|
+
## Theme ids hỗ trợ
|
|
10
|
+
|
|
11
|
+
| Theme ID | VBtn default | VCard default |
|
|
12
|
+
|-----------------|--------------|---------------|
|
|
13
|
+
| `minimalist-2` | outlined | flat |
|
|
14
|
+
| `neo-brutalism` | elevated | elevated |
|
|
15
|
+
| `material` | elevated | elevated |
|
|
16
|
+
|
|
17
|
+
## Cấu hình
|
|
18
|
+
|
|
19
|
+
- **vuetify.ts:** Khi không cấu hình `.env`, dùng theme mặc định từ `by-theme/index.ts` (`VIUI_DEFAULT_THEME_ID` = `minimalist-2`). Gọi `getDefaults(import.meta.env.VITE_VIUI_THEME ?? VIUI_DEFAULT_THEME_ID)`.
|
|
20
|
+
- **.env:** `VITE_VIUI_THEME=minimalist-2` (mặc định) | `neo-brutalism` | `material`.
|
|
21
|
+
|
|
22
|
+
## Cấu trúc
|
|
23
|
+
|
|
24
|
+
- `index.ts` — merge base + export `getDefaults(themeId?)`, `defaults` (= getDefaults()).
|
|
25
|
+
- `by-theme/` — override theo theme: `minimalist-2.ts`, `neo-brutalism.ts`, `material.ts`.
|
|
26
|
+
|
|
27
|
+
Chi tiết: [.cursor/plans/themes.plan.md](../../../../.cursor/plans/themes.plan.md).
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iNET Design System — Vuetify defaults cho VAlert (ViAlert).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
6
|
+
|
|
7
|
+
export const alertDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
8
|
+
VAlert: {
|
|
9
|
+
variant: 'tonal',
|
|
10
|
+
density: 'comfortable',
|
|
11
|
+
rounded: 'lg',
|
|
12
|
+
},
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iNET Design System — Vuetify defaults cho VAppBar (ViAppBar).
|
|
3
|
+
* Density, elevation, color từ tokens.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
|
|
8
|
+
export const appBarDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
9
|
+
VAppBar: {
|
|
10
|
+
density: 'default',
|
|
11
|
+
elevation: 1,
|
|
12
|
+
color: 'surface',
|
|
13
|
+
},
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iNET Design System — Vuetify defaults cho VAvatar (ViAvatar).
|
|
3
|
+
* Size, color semantic từ tokens.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
|
|
8
|
+
export const avatarDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
9
|
+
VAvatar: {
|
|
10
|
+
size: 'default',
|
|
11
|
+
color: 'default',
|
|
12
|
+
rounded: 'circle',
|
|
13
|
+
},
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iNET Design System — Vuetify defaults cho Buttons (VBtn).
|
|
3
|
+
* Đồng bộ với design tokens (shape, elevation); variant/color dùng theme.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
|
|
8
|
+
export const buttonDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
9
|
+
VBtn: {
|
|
10
|
+
variant: 'elevated',
|
|
11
|
+
elevation: 1,
|
|
12
|
+
rounded: 'lg',
|
|
13
|
+
size: 'default',
|
|
14
|
+
},
|
|
15
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defaults theo design style theme (override variant, v.v.).
|
|
3
|
+
* Theme mặc định: minimalist-2. Map themeId → defaults override.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
import { minimalist2ThemeDefaults } from './minimalist-2'
|
|
8
|
+
import { neoBrutalismThemeDefaults } from './neo-brutalism'
|
|
9
|
+
import { materialThemeDefaults } from './material'
|
|
10
|
+
|
|
11
|
+
export const VIUI_DEFAULT_THEME_ID = 'minimalist-2' as const
|
|
12
|
+
|
|
13
|
+
export type ViuiThemeId = 'minimalist-2' | 'neo-brutalism' | 'material'
|
|
14
|
+
|
|
15
|
+
const byTheme: Record<ViuiThemeId, NonNullable<VuetifyOptions['defaults']>> = {
|
|
16
|
+
'minimalist-2': minimalist2ThemeDefaults,
|
|
17
|
+
'neo-brutalism': neoBrutalismThemeDefaults,
|
|
18
|
+
material: materialThemeDefaults,
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getThemeDefaults (themeId: string | undefined): NonNullable<VuetifyOptions['defaults']> {
|
|
22
|
+
if (themeId && themeId in byTheme) {
|
|
23
|
+
return byTheme[themeId as ViuiThemeId]
|
|
24
|
+
}
|
|
25
|
+
return byTheme[VIUI_DEFAULT_THEME_ID]
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { minimalist2ThemeDefaults } from './minimalist-2'
|
|
29
|
+
export { neoBrutalismThemeDefaults } from './neo-brutalism'
|
|
30
|
+
export { materialThemeDefaults } from './material'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Material / base — default variants: elevated.
|
|
3
|
+
* Fallback khi cần style Material chuẩn; dùng khi VITE_VIUI_THEME=material.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
|
|
8
|
+
export const materialThemeDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
9
|
+
VBtn: {
|
|
10
|
+
variant: 'elevated',
|
|
11
|
+
},
|
|
12
|
+
VCard: {
|
|
13
|
+
variant: 'elevated',
|
|
14
|
+
},
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Minimalist 2.0 — default variants: outlined/flat.
|
|
3
|
+
* Viền mỏng, ít shadow; dùng khi VITE_VIUI_THEME=minimalist-2 hoặc không set (mặc định).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
|
|
8
|
+
export const minimalist2ThemeDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
9
|
+
VBtn: {
|
|
10
|
+
variant: 'outlined',
|
|
11
|
+
},
|
|
12
|
+
VCard: {
|
|
13
|
+
variant: 'flat',
|
|
14
|
+
},
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Theme Neo-Brutalism — default variants: elevated.
|
|
3
|
+
* Nổi, đậm, shadow; dùng khi VITE_VIUI_THEME=neo-brutalism.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
|
|
8
|
+
export const neoBrutalismThemeDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
9
|
+
VBtn: {
|
|
10
|
+
variant: 'elevated',
|
|
11
|
+
},
|
|
12
|
+
VCard: {
|
|
13
|
+
variant: 'elevated',
|
|
14
|
+
},
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iNET Design System — Vuetify defaults cho Cards (VCard, VCardText, VCardActions).
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
6
|
+
|
|
7
|
+
export const cardDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
8
|
+
VCard: {
|
|
9
|
+
elevation: 1,
|
|
10
|
+
rounded: 'lg',
|
|
11
|
+
},
|
|
12
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iNET Design System — Vuetify defaults cho VChip (ViChip).
|
|
3
|
+
* Variant, size, color semantic từ tokens (status, tag, pill).
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { VuetifyOptions } from 'vuetify'
|
|
7
|
+
|
|
8
|
+
export const chipDefaults: NonNullable<VuetifyOptions['defaults']> = {
|
|
9
|
+
VChip: {
|
|
10
|
+
variant: 'flat',
|
|
11
|
+
size: 'default',
|
|
12
|
+
rounded: 'pill',
|
|
13
|
+
color: 'default',
|
|
14
|
+
},
|
|
15
|
+
}
|