solid-tom-ui 1.0.10 → 1.0.14

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 (120) hide show
  1. package/README.md +246 -246
  2. package/dist/README.md +246 -246
  3. package/dist/components/avatar/avatar.js.map +1 -1
  4. package/dist/components/badge/badge.js.map +1 -1
  5. package/dist/components/breadcrumb/breadcrumb.js.map +1 -1
  6. package/dist/components/button/button.js.map +1 -1
  7. package/dist/components/carousel/carousel.js.map +1 -1
  8. package/dist/components/chat-bubble/chatBubble.js.map +1 -1
  9. package/dist/components/checkbox/checkbox.js.map +1 -1
  10. package/dist/components/collapse/collapse.js.map +1 -1
  11. package/dist/components/context-menu/context-menu.js.map +1 -1
  12. package/dist/components/context-menu/context-menu.store.js.map +1 -1
  13. package/dist/components/divider/divider.js.map +1 -1
  14. package/dist/components/dropdown/dropdown.js.map +1 -1
  15. package/dist/components/dropdown/dropdown.store.js.map +1 -1
  16. package/dist/components/float-button/float-button.js.map +1 -1
  17. package/dist/components/hover-3d-image/hover-3d-image.js.map +1 -1
  18. package/dist/components/image-preview/image-preview.js.map +1 -1
  19. package/dist/components/input/input.js.map +1 -1
  20. package/dist/components/input/input.utils.js.map +1 -1
  21. package/dist/components/input/variants/input-color.js.map +1 -1
  22. package/dist/components/input/variants/input-date.js.map +1 -1
  23. package/dist/components/input/variants/input-number.d.ts.map +1 -1
  24. package/dist/components/input/variants/input-number.js +1 -1
  25. package/dist/components/input/variants/input-number.js.map +1 -1
  26. package/dist/components/input/variants/input-otp.js.map +1 -1
  27. package/dist/components/input/variants/input-password.js.map +1 -1
  28. package/dist/components/input/variants/input-radio.js.map +1 -1
  29. package/dist/components/input/variants/input-range.js.map +1 -1
  30. package/dist/components/input/variants/input-text.d.ts.map +1 -1
  31. package/dist/components/input/variants/input-text.js +1 -1
  32. package/dist/components/input/variants/input-text.js.map +1 -1
  33. package/dist/components/input/variants/input-textarea.js.map +1 -1
  34. package/dist/components/loading/loading.js.map +1 -1
  35. package/dist/components/mansory/mansory.js.map +1 -1
  36. package/dist/components/menu/menu.js.map +1 -1
  37. package/dist/components/menu/menu.types.d.ts +2 -3
  38. package/dist/components/menu/menu.types.d.ts.map +1 -1
  39. package/dist/components/modal/modal.js.map +1 -1
  40. package/dist/components/modal/modalContext.js.map +1 -1
  41. package/dist/components/pagination/pagination.js.map +1 -1
  42. package/dist/components/progress-bar/progress-bar.js.map +1 -1
  43. package/dist/components/qr-code/qr-code.js.map +1 -1
  44. package/dist/components/select/select.js.map +1 -1
  45. package/dist/components/select-zone/select-zone.js.map +1 -1
  46. package/dist/components/skeleton/skeleton.js.map +1 -1
  47. package/dist/components/slider/slider.js.map +1 -1
  48. package/dist/components/splitter/splitter.js.map +1 -1
  49. package/dist/components/steps/steps.js.map +1 -1
  50. package/dist/components/swap/swap.js.map +1 -1
  51. package/dist/components/switch/switch.js.map +1 -1
  52. package/dist/components/tab/tab.js.map +1 -1
  53. package/dist/components/table/table.js.map +1 -1
  54. package/dist/components/timeline/timeline.js.map +1 -1
  55. package/dist/components/toast/icons/ErrorIcon.js.map +1 -1
  56. package/dist/components/toast/icons/IconCircle.js.map +1 -1
  57. package/dist/components/toast/icons/InfoIcon.js.map +1 -1
  58. package/dist/components/toast/icons/LoaderIcon.js.map +1 -1
  59. package/dist/components/toast/icons/SuccessIcon.js.map +1 -1
  60. package/dist/components/toast/icons/WarningIcon.js.map +1 -1
  61. package/dist/components/toast/toast.js.map +1 -1
  62. package/dist/components/toast/toast.store.js.map +1 -1
  63. package/dist/components/tooltip/tooltip.js.map +1 -1
  64. package/dist/components/tour/tour.js.map +1 -1
  65. package/dist/components/upload/upload.js.map +1 -1
  66. package/dist/components/z-index/z-index.context.js.map +1 -1
  67. package/dist/components/z-index/z-index.js.map +1 -1
  68. package/dist/components/z-index/z-index.store.js.map +1 -1
  69. package/dist/components/z-index/z-index.types.js.map +1 -1
  70. package/dist/package.json +1 -1
  71. package/dist/skill/avatar.skill.md.txt +255 -255
  72. package/dist/skill/badge.skill.md.txt +223 -223
  73. package/dist/skill/breadcrumb.skill.md.txt +177 -177
  74. package/dist/skill/button.skill.md.txt +198 -198
  75. package/dist/skill/carousel.skill.md.txt +406 -406
  76. package/dist/skill/chat-bubble.skill.md.txt +342 -342
  77. package/dist/skill/checkbox.skill.md.txt +326 -326
  78. package/dist/skill/code-preview.skill.md.txt +240 -240
  79. package/dist/skill/collapse.skill.md.txt +329 -329
  80. package/dist/skill/context-menu.skill.md.txt +233 -233
  81. package/dist/skill/diff.skill.md.txt +244 -244
  82. package/dist/skill/divider.skill.md.txt +151 -151
  83. package/dist/skill/doc.skill.md.txt +191 -191
  84. package/dist/skill/drawer.skill.md.txt +157 -157
  85. package/dist/skill/dropdown.skill.md.txt +198 -198
  86. package/dist/skill/float-button.skill.md.txt +315 -315
  87. package/dist/skill/hover-3d-image.skill.md.txt +120 -120
  88. package/dist/skill/iframe.skill.md.txt +114 -114
  89. package/dist/skill/image-preview.skill.md.txt +162 -162
  90. package/dist/skill/indicator.skill.md.txt +60 -60
  91. package/dist/skill/input.skill.md.txt +489 -489
  92. package/dist/skill/loading.skill.md.txt +127 -127
  93. package/dist/skill/menu.skill.md.txt +476 -476
  94. package/dist/skill/modal.skill.md.txt +359 -359
  95. package/dist/skill/pagination.skill.md.txt +405 -405
  96. package/dist/skill/progress-bar.skill.md.txt +207 -207
  97. package/dist/skill/qr-code.skill.md.txt +136 -136
  98. package/dist/skill/rating.skill.md.txt +167 -167
  99. package/dist/skill/select-zone.skill.md.txt +93 -93
  100. package/dist/skill/select.skill.md.txt +663 -663
  101. package/dist/skill/skeleton.skill.md.txt +192 -192
  102. package/dist/skill/slider.skill.md.txt +404 -404
  103. package/dist/skill/splitter.skill.md.txt +411 -411
  104. package/dist/skill/steps.skill.md.txt +264 -264
  105. package/dist/skill/swap.skill.md.txt +139 -139
  106. package/dist/skill/switch.skill.md.txt +191 -191
  107. package/dist/skill/tab.skill.md.txt +484 -484
  108. package/dist/skill/table.example.header.md.txt +666 -666
  109. package/dist/skill/table.skill.md.txt +1407 -1407
  110. package/dist/skill/text-rotate.skill.md.txt +186 -186
  111. package/dist/skill/timeline.skill.md.txt +247 -247
  112. package/dist/skill/toast.skill.md.txt +531 -531
  113. package/dist/skill/tooltip.skill.md.txt +222 -222
  114. package/dist/skill/tour.skill.md.txt +156 -156
  115. package/dist/skill/upload.skill.md.txt +358 -358
  116. package/dist/utils/cn.js.map +1 -1
  117. package/dist/utils/element-tracker.js.map +1 -1
  118. package/dist/utils/helper.js.map +1 -1
  119. package/dist/utils/hoc.js.map +1 -1
  120. package/package.json +132 -133
@@ -1,240 +1,240 @@
1
- ## COMPONENT IDENTITY
2
- - **Import**: `import { CodePreview } from '@/components/doc/CodePreview';`
3
- - **Export**: `CodePreview` (named), `CODE_PREVIEW_THEMES`, `CodePreviewTheme` (type export)
4
- - **Framework**: SolidJS
5
- - **Purpose**: Internal documentation component — renders a tabbed panel with a live component preview and syntax-highlighted source code; used in Storybook stories and docs pages; NOT exported from `solid-tom-ui`
6
- - **Dependencies**: Shiki (syntax highlighting) · Prettier standalone (auto-format)
7
-
8
- ---
9
-
10
- ## TYPE SIGNATURE
11
-
12
- ```ts
13
- interface CodePreviewProps {
14
- code: string; // Source code string hiển thị trong tab Code
15
- preview: Component<any>; // SolidJS component render trong tab Preview
16
- title?: string; // Tiêu đề (hiện chưa render, dành cho tương lai)
17
- language?: string; // Ngôn ngữ highlight; default: 'tsx'
18
- theme?: CodePreviewTheme; // Shiki theme; default: 'dracula'
19
- classNames?: {
20
- previewBlock?: string; // Class bổ sung cho vùng preview
21
- };
22
- }
23
- ```
24
-
25
- ---
26
-
27
- ## BASIC USAGE
28
-
29
- ```tsx
30
- const myCode = `<Button variant="solid" color="primary">Click me</Button>`;
31
-
32
- <CodePreview
33
- code={myCode}
34
- preview={() => <Button variant="solid" color="primary">Click me</Button>}
35
- />
36
- ```
37
-
38
- ---
39
-
40
- ## USAGE WITH THEME
41
-
42
- ```tsx
43
- <CodePreview
44
- code={myCode}
45
- preview={() => <MyComponent />}
46
- theme="tokyo-night"
47
- />
48
- ```
49
-
50
- ---
51
-
52
- ## USAGE WITH CUSTOM LANGUAGE
53
-
54
- ```tsx
55
- <CodePreview
56
- code={`const x: number = 42;`}
57
- preview={() => <div>42</div>}
58
- language="typescript"
59
- />
60
- ```
61
-
62
- Các giá trị `language` được hỗ trợ: `'tsx'` · `'typescript'` · `'jsx'` · `'javascript'`
63
-
64
- ---
65
-
66
- ## USAGE WITH PREVIEW CLASSNAMES
67
-
68
- ```tsx
69
- <CodePreview
70
- code={myCode}
71
- preview={() => <MyComponent />}
72
- classNames={{ previewBlock: 'bg-base-200 min-h-[300px]' }}
73
- />
74
- ```
75
-
76
- ---
77
-
78
- ## CODE FORMATTING
79
-
80
- Code truyền vào `code` prop **không cần format thủ công** — Prettier tự động:
81
- - Căn chỉnh indentation (2 spaces)
82
- - Thêm trailing comma
83
- - Wrap dòng dài (printWidth: 80)
84
- - Semi-colon ở cuối statement
85
-
86
- **Lưu ý**: Prettier dùng `babel` parser, nhận JSX fragment bare (không cần wrapper function):
87
-
88
- ```tsx
89
- // ✅ Đúng — JSX fragment bare
90
- const code = `<Button color="primary">Click</Button>`;
91
-
92
- // ✅ Đúng — JSX multi-line
93
- const code = `
94
- <FloatButton
95
- type="flower"
96
- color="orange"
97
- actions={[<Button />, <Button />]}
98
- />
99
- `;
100
-
101
- // ✅ Đúng — TypeScript expression
102
- const code = `const x: Record<string, number> = { a: 1 };`;
103
- ```
104
-
105
- ---
106
-
107
- ## AVAILABLE THEMES
108
-
109
- Export `CODE_PREVIEW_THEMES` chứa toàn bộ danh sách, dùng để build UI chọn theme:
110
-
111
- ```tsx
112
- import { CODE_PREVIEW_THEMES } from '@/components/doc/CodePreview';
113
-
114
- // Render dropdown chọn theme
115
- <select>
116
- {CODE_PREVIEW_THEMES.map(t => <option value={t}>{t}</option>)}
117
- </select>
118
- ```
119
-
120
- ### Danh sách themes
121
-
122
- | Theme | Phong cách |
123
- |---|---|
124
- | `dracula` *(default)* | Dark purple — Dracula official |
125
- | `dracula-soft` | Dracula nhạt màu hơn |
126
- | `github-dark` | GitHub dark |
127
- | `github-dark-default` | GitHub dark default |
128
- | `github-dark-dimmed` | GitHub dark dimmed |
129
- | `github-dark-high-contrast` | GitHub dark high contrast |
130
- | `github-light` | GitHub light |
131
- | `github-light-default` | GitHub light default |
132
- | `github-light-high-contrast` | GitHub light high contrast |
133
- | `tokyo-night` | Tokyo Night (blue/purple) |
134
- | `one-dark-pro` | Atom One Dark Pro |
135
- | `nord` | Nord (arctic blue tones) |
136
- | `monokai` | Monokai classic |
137
- | `night-owl` | Night Owl (Sarah Drasner) |
138
- | `catppuccin-mocha` | Catppuccin Mocha (warm dark) |
139
- | `catppuccin-macchiato` | Catppuccin Macchiato |
140
- | `catppuccin-frappe` | Catppuccin Frappé |
141
- | `catppuccin-latte` | Catppuccin Latte (light) |
142
- | `rose-pine` | Rosé Pine (dark) |
143
- | `rose-pine-dawn` | Rosé Pine Dawn (light) |
144
- | `rose-pine-moon` | Rosé Pine Moon |
145
- | `material-theme` | Material Theme |
146
- | `material-theme-darker` | Material Theme Darker |
147
- | `material-theme-ocean` | Material Theme Ocean |
148
- | `material-theme-palenight` | Material Theme Palenight |
149
- | `material-theme-lighter` | Material Theme Lighter |
150
- | `vitesse-dark` | Vitesse Dark (Anthony Fu) |
151
- | `vitesse-light` | Vitesse Light |
152
- | `vitesse-black` | Vitesse Black |
153
- | `solarized-dark` | Solarized Dark |
154
- | `solarized-light` | Solarized Light |
155
- | `everforest-dark` | Everforest Dark |
156
- | `everforest-light` | Everforest Light |
157
- | `synthwave-84` | SynthWave '84 (neon) |
158
- | `poimandres` | Poimandres (deep space) |
159
- | `ayu-dark` | Ayu Dark |
160
- | `aurora-x` | Aurora X |
161
- | `andromeeda` | Andromeeda |
162
- | `dark-plus` | Dark+ (VS Code default dark) |
163
- | `light-plus` | Light+ (VS Code default light) |
164
- | `min-dark` | Min Dark (minimal) |
165
- | `min-light` | Min Light (minimal) |
166
- | `plastic` | Plastic |
167
- | `red` | Red |
168
- | `slack-dark` | Slack Dark |
169
- | `slack-ochin` | Slack Ochin |
170
- | `snazzy-light` | Snazzy Light |
171
- | `vesper` | Vesper |
172
-
173
- ---
174
-
175
- ## PATTERN: DÙNG TRONG STORYBOOK STORY
176
-
177
- ```tsx
178
- import { CodePreview } from '@/components/doc/CodePreview';
179
- import type { Meta, StoryObj } from 'storybook-solidjs-vite';
180
-
181
- const myCode = `<MyComponent
182
- prop="value"
183
- onAction={() => {}}
184
- />`;
185
-
186
- export const Example: StoryObj = {
187
- render: () => (
188
- <CodePreview
189
- code={myCode}
190
- preview={() => (
191
- <MyComponent
192
- prop="value"
193
- onAction={() => {}}
194
- />
195
- )}
196
- />
197
- ),
198
- };
199
- ```
200
-
201
- ---
202
-
203
- ## PATTERN: DÙNG TRONG IFRAME (component cần isolated CSS)
204
-
205
- ```tsx
206
- import { CodePreview } from '@/components/doc/CodePreview';
207
- import { Iframe } from '@/components/iframe';
208
-
209
- <CodePreview
210
- code={myCode}
211
- preview={() => (
212
- <Iframe
213
- element={() => <MyComponent />}
214
- />
215
- )}
216
- />
217
- ```
218
-
219
- Dùng `<Iframe>` khi component có CSS toàn cục (animation, fixed position, z-index cao) có thể xung đột với trang docs.
220
-
221
- ---
222
-
223
- ## INTERNALS (cho maintainer)
224
-
225
- | Layer | Implementation |
226
- |---|---|
227
- | **Formatter** | Prettier 3.x standalone, parser `babel` |
228
- | **Highlighter** | Shiki 4.x, `createHighlighter` singleton |
229
- | **Theme loading** | Lazy per theme, cache qua `Set<string>` |
230
- | **Async state** | SolidJS `createResource` + `Suspense` |
231
- | **Default theme** | `dracula` (load khi init) |
232
- | **Default language** | `tsx` |
233
- | **Supported langs** | `tsx`, `typescript`, `jsx`, `javascript` |
234
- ---
235
-
236
- ## Component Conventions
237
-
238
- > **CSS encoding**: internal CSS classes use short encoded names (e.g. `cp01`, `cp02`) per project convention.
239
-
240
- > **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.
1
+ ## COMPONENT IDENTITY
2
+ - **Import**: `import { CodePreview } from '@/components/doc/CodePreview';`
3
+ - **Export**: `CodePreview` (named), `CODE_PREVIEW_THEMES`, `CodePreviewTheme` (type export)
4
+ - **Framework**: SolidJS
5
+ - **Purpose**: Internal documentation component — renders a tabbed panel with a live component preview and syntax-highlighted source code; used in Storybook stories and docs pages; NOT exported from `solid-tom-ui`
6
+ - **Dependencies**: Shiki (syntax highlighting) · Prettier standalone (auto-format)
7
+
8
+ ---
9
+
10
+ ## TYPE SIGNATURE
11
+
12
+ ```ts
13
+ interface CodePreviewProps {
14
+ code: string; // Source code string hiển thị trong tab Code
15
+ preview: Component<any>; // SolidJS component render trong tab Preview
16
+ title?: string; // Tiêu đề (hiện chưa render, dành cho tương lai)
17
+ language?: string; // Ngôn ngữ highlight; default: 'tsx'
18
+ theme?: CodePreviewTheme; // Shiki theme; default: 'dracula'
19
+ classNames?: {
20
+ previewBlock?: string; // Class bổ sung cho vùng preview
21
+ };
22
+ }
23
+ ```
24
+
25
+ ---
26
+
27
+ ## BASIC USAGE
28
+
29
+ ```tsx
30
+ const myCode = `<Button variant="solid" color="primary">Click me</Button>`;
31
+
32
+ <CodePreview
33
+ code={myCode}
34
+ preview={() => <Button variant="solid" color="primary">Click me</Button>}
35
+ />
36
+ ```
37
+
38
+ ---
39
+
40
+ ## USAGE WITH THEME
41
+
42
+ ```tsx
43
+ <CodePreview
44
+ code={myCode}
45
+ preview={() => <MyComponent />}
46
+ theme="tokyo-night"
47
+ />
48
+ ```
49
+
50
+ ---
51
+
52
+ ## USAGE WITH CUSTOM LANGUAGE
53
+
54
+ ```tsx
55
+ <CodePreview
56
+ code={`const x: number = 42;`}
57
+ preview={() => <div>42</div>}
58
+ language="typescript"
59
+ />
60
+ ```
61
+
62
+ Các giá trị `language` được hỗ trợ: `'tsx'` · `'typescript'` · `'jsx'` · `'javascript'`
63
+
64
+ ---
65
+
66
+ ## USAGE WITH PREVIEW CLASSNAMES
67
+
68
+ ```tsx
69
+ <CodePreview
70
+ code={myCode}
71
+ preview={() => <MyComponent />}
72
+ classNames={{ previewBlock: 'bg-base-200 min-h-[300px]' }}
73
+ />
74
+ ```
75
+
76
+ ---
77
+
78
+ ## CODE FORMATTING
79
+
80
+ Code truyền vào `code` prop **không cần format thủ công** — Prettier tự động:
81
+ - Căn chỉnh indentation (2 spaces)
82
+ - Thêm trailing comma
83
+ - Wrap dòng dài (printWidth: 80)
84
+ - Semi-colon ở cuối statement
85
+
86
+ **Lưu ý**: Prettier dùng `babel` parser, nhận JSX fragment bare (không cần wrapper function):
87
+
88
+ ```tsx
89
+ // ✅ Đúng — JSX fragment bare
90
+ const code = `<Button color="primary">Click</Button>`;
91
+
92
+ // ✅ Đúng — JSX multi-line
93
+ const code = `
94
+ <FloatButton
95
+ type="flower"
96
+ color="orange"
97
+ actions={[<Button />, <Button />]}
98
+ />
99
+ `;
100
+
101
+ // ✅ Đúng — TypeScript expression
102
+ const code = `const x: Record<string, number> = { a: 1 };`;
103
+ ```
104
+
105
+ ---
106
+
107
+ ## AVAILABLE THEMES
108
+
109
+ Export `CODE_PREVIEW_THEMES` chứa toàn bộ danh sách, dùng để build UI chọn theme:
110
+
111
+ ```tsx
112
+ import { CODE_PREVIEW_THEMES } from '@/components/doc/CodePreview';
113
+
114
+ // Render dropdown chọn theme
115
+ <select>
116
+ {CODE_PREVIEW_THEMES.map(t => <option value={t}>{t}</option>)}
117
+ </select>
118
+ ```
119
+
120
+ ### Danh sách themes
121
+
122
+ | Theme | Phong cách |
123
+ |---|---|
124
+ | `dracula` *(default)* | Dark purple — Dracula official |
125
+ | `dracula-soft` | Dracula nhạt màu hơn |
126
+ | `github-dark` | GitHub dark |
127
+ | `github-dark-default` | GitHub dark default |
128
+ | `github-dark-dimmed` | GitHub dark dimmed |
129
+ | `github-dark-high-contrast` | GitHub dark high contrast |
130
+ | `github-light` | GitHub light |
131
+ | `github-light-default` | GitHub light default |
132
+ | `github-light-high-contrast` | GitHub light high contrast |
133
+ | `tokyo-night` | Tokyo Night (blue/purple) |
134
+ | `one-dark-pro` | Atom One Dark Pro |
135
+ | `nord` | Nord (arctic blue tones) |
136
+ | `monokai` | Monokai classic |
137
+ | `night-owl` | Night Owl (Sarah Drasner) |
138
+ | `catppuccin-mocha` | Catppuccin Mocha (warm dark) |
139
+ | `catppuccin-macchiato` | Catppuccin Macchiato |
140
+ | `catppuccin-frappe` | Catppuccin Frappé |
141
+ | `catppuccin-latte` | Catppuccin Latte (light) |
142
+ | `rose-pine` | Rosé Pine (dark) |
143
+ | `rose-pine-dawn` | Rosé Pine Dawn (light) |
144
+ | `rose-pine-moon` | Rosé Pine Moon |
145
+ | `material-theme` | Material Theme |
146
+ | `material-theme-darker` | Material Theme Darker |
147
+ | `material-theme-ocean` | Material Theme Ocean |
148
+ | `material-theme-palenight` | Material Theme Palenight |
149
+ | `material-theme-lighter` | Material Theme Lighter |
150
+ | `vitesse-dark` | Vitesse Dark (Anthony Fu) |
151
+ | `vitesse-light` | Vitesse Light |
152
+ | `vitesse-black` | Vitesse Black |
153
+ | `solarized-dark` | Solarized Dark |
154
+ | `solarized-light` | Solarized Light |
155
+ | `everforest-dark` | Everforest Dark |
156
+ | `everforest-light` | Everforest Light |
157
+ | `synthwave-84` | SynthWave '84 (neon) |
158
+ | `poimandres` | Poimandres (deep space) |
159
+ | `ayu-dark` | Ayu Dark |
160
+ | `aurora-x` | Aurora X |
161
+ | `andromeeda` | Andromeeda |
162
+ | `dark-plus` | Dark+ (VS Code default dark) |
163
+ | `light-plus` | Light+ (VS Code default light) |
164
+ | `min-dark` | Min Dark (minimal) |
165
+ | `min-light` | Min Light (minimal) |
166
+ | `plastic` | Plastic |
167
+ | `red` | Red |
168
+ | `slack-dark` | Slack Dark |
169
+ | `slack-ochin` | Slack Ochin |
170
+ | `snazzy-light` | Snazzy Light |
171
+ | `vesper` | Vesper |
172
+
173
+ ---
174
+
175
+ ## PATTERN: DÙNG TRONG STORYBOOK STORY
176
+
177
+ ```tsx
178
+ import { CodePreview } from '@/components/doc/CodePreview';
179
+ import type { Meta, StoryObj } from 'storybook-solidjs-vite';
180
+
181
+ const myCode = `<MyComponent
182
+ prop="value"
183
+ onAction={() => {}}
184
+ />`;
185
+
186
+ export const Example: StoryObj = {
187
+ render: () => (
188
+ <CodePreview
189
+ code={myCode}
190
+ preview={() => (
191
+ <MyComponent
192
+ prop="value"
193
+ onAction={() => {}}
194
+ />
195
+ )}
196
+ />
197
+ ),
198
+ };
199
+ ```
200
+
201
+ ---
202
+
203
+ ## PATTERN: DÙNG TRONG IFRAME (component cần isolated CSS)
204
+
205
+ ```tsx
206
+ import { CodePreview } from '@/components/doc/CodePreview';
207
+ import { Iframe } from '@/components/iframe';
208
+
209
+ <CodePreview
210
+ code={myCode}
211
+ preview={() => (
212
+ <Iframe
213
+ element={() => <MyComponent />}
214
+ />
215
+ )}
216
+ />
217
+ ```
218
+
219
+ Dùng `<Iframe>` khi component có CSS toàn cục (animation, fixed position, z-index cao) có thể xung đột với trang docs.
220
+
221
+ ---
222
+
223
+ ## INTERNALS (cho maintainer)
224
+
225
+ | Layer | Implementation |
226
+ |---|---|
227
+ | **Formatter** | Prettier 3.x standalone, parser `babel` |
228
+ | **Highlighter** | Shiki 4.x, `createHighlighter` singleton |
229
+ | **Theme loading** | Lazy per theme, cache qua `Set<string>` |
230
+ | **Async state** | SolidJS `createResource` + `Suspense` |
231
+ | **Default theme** | `dracula` (load khi init) |
232
+ | **Default language** | `tsx` |
233
+ | **Supported langs** | `tsx`, `typescript`, `jsx`, `javascript` |
234
+ ---
235
+
236
+ ## Component Conventions
237
+
238
+ > **CSS encoding**: internal CSS classes use short encoded names (e.g. `cp01`, `cp02`) per project convention.
239
+
240
+ > **Unique IDs**: if this component needs to generate HTML `id` attributes, always use `createUniqueId()` from `solid-js` — never `Math.random()` or `Date.now()`.