gladvn 0.2.35 → 0.2.37

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 (134) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -1
  3. package/scripts/strip-comments.ts +79 -0
  4. package/src/blocks/auth-form.tsx +34 -30
  5. package/src/blocks/auth-recovery.tsx +9 -13
  6. package/src/blocks/auth-split.tsx +46 -36
  7. package/src/blocks/settings.tsx +84 -117
  8. package/src/components/macro/alert-preset.tsx +3 -1
  9. package/src/components/macro/carousel-preset.tsx +0 -1
  10. package/src/components/macro/checkbox-preset.test.tsx +2 -2
  11. package/src/components/macro/checkbox-preset.tsx +1 -2
  12. package/src/components/macro/command-preset.tsx +1 -1
  13. package/src/components/macro/date-picker.tsx +5 -18
  14. package/src/components/macro/dialog-preset.tsx +5 -3
  15. package/src/components/macro/input-preset.tsx +0 -1
  16. package/src/components/macro/select-preset.tsx +1 -1
  17. package/src/components/macro/switch-preset.test.tsx +1 -1
  18. package/src/components/micro/accordion.test.tsx +6 -12
  19. package/src/components/micro/alert-dialog.tsx +0 -2
  20. package/src/components/micro/alert.test.tsx +5 -8
  21. package/src/components/micro/alert.tsx +0 -2
  22. package/src/components/micro/badge.test.tsx +5 -7
  23. package/src/components/micro/badge.tsx +1 -3
  24. package/src/components/micro/button.test.tsx +19 -26
  25. package/src/components/micro/button.tsx +3 -11
  26. package/src/components/micro/calendar.tsx +12 -13
  27. package/src/components/micro/card.test.tsx +3 -5
  28. package/src/components/micro/carousel.tsx +0 -1
  29. package/src/components/micro/chart.tsx +3 -2
  30. package/src/components/micro/checkbox.test.tsx +9 -18
  31. package/src/components/micro/combobox.tsx +1 -3
  32. package/src/components/micro/command.tsx +23 -11
  33. package/src/components/micro/context-menu.tsx +0 -2
  34. package/src/components/micro/dialog.test.tsx +6 -14
  35. package/src/components/micro/dialog.tsx +0 -2
  36. package/src/components/micro/drawer.tsx +0 -3
  37. package/src/components/micro/dropdown-menu.test.tsx +8 -14
  38. package/src/components/micro/dropdown-menu.tsx +0 -2
  39. package/src/components/micro/field.tsx +3 -3
  40. package/src/components/micro/hover-card.tsx +0 -2
  41. package/src/components/micro/input-group.tsx +9 -42
  42. package/src/components/micro/input.test.tsx +15 -24
  43. package/src/components/micro/navigation-menu.tsx +0 -2
  44. package/src/components/micro/popover.test.tsx +5 -9
  45. package/src/components/micro/progress.tsx +5 -1
  46. package/src/components/micro/select.test.tsx +5 -18
  47. package/src/components/micro/select.tsx +3 -5
  48. package/src/components/micro/separator.tsx +1 -1
  49. package/src/components/micro/sheet.test.tsx +6 -14
  50. package/src/components/micro/sheet.tsx +0 -2
  51. package/src/components/micro/sidebar.tsx +5 -6
  52. package/src/components/micro/sonner.tsx +0 -1
  53. package/src/components/micro/switch.test.tsx +9 -18
  54. package/src/components/micro/switch.tsx +1 -1
  55. package/src/components/micro/tabs.test.tsx +5 -11
  56. package/src/components/micro/theme-provider.tsx +0 -12
  57. package/src/components/micro/toggle-group.tsx +1 -12
  58. package/src/components/micro/tooltip.test.tsx +7 -12
  59. package/src/dev/App.tsx +6 -6
  60. package/src/dev/components/BlockViewer.tsx +15 -4
  61. package/src/dev/components/Container.tsx +20 -0
  62. package/src/dev/components/GladvnLogo.tsx +3 -9
  63. package/src/dev/components/code-highlighter.tsx +5 -3
  64. package/src/dev/components/showcase.tsx +116 -168
  65. package/src/dev/sections/buttons.tsx +4 -9
  66. package/src/dev/sections/display.tsx +68 -72
  67. package/src/dev/sections/feedback.tsx +304 -314
  68. package/src/dev/sections/forms.tsx +10 -14
  69. package/src/dev/sections/interactive.tsx +32 -32
  70. package/src/dev/sections/overview.tsx +2 -10
  71. package/src/dev/showcase/accordion.tsx +512 -554
  72. package/src/dev/showcase/alert-dialog.tsx +525 -565
  73. package/src/dev/showcase/alert.tsx +352 -402
  74. package/src/dev/showcase/aspect-ratio.tsx +167 -193
  75. package/src/dev/showcase/avatar.tsx +231 -269
  76. package/src/dev/showcase/badge.tsx +92 -140
  77. package/src/dev/showcase/breadcrumb.tsx +113 -135
  78. package/src/dev/showcase/button.tsx +140 -173
  79. package/src/dev/showcase/calendar.tsx +187 -237
  80. package/src/dev/showcase/card.tsx +229 -261
  81. package/src/dev/showcase/carousel.tsx +288 -315
  82. package/src/dev/showcase/chart.tsx +44 -50
  83. package/src/dev/showcase/checkbox.tsx +286 -330
  84. package/src/dev/showcase/collapsible.tsx +143 -160
  85. package/src/dev/showcase/combobox.tsx +327 -369
  86. package/src/dev/showcase/command.tsx +106 -120
  87. package/src/dev/showcase/context-menu.tsx +93 -107
  88. package/src/dev/showcase/dialog.tsx +585 -630
  89. package/src/dev/showcase/drawer.tsx +176 -196
  90. package/src/dev/showcase/dropdown-menu.tsx +183 -201
  91. package/src/dev/showcase/empty.tsx +232 -274
  92. package/src/dev/showcase/hover-card.tsx +153 -180
  93. package/src/dev/showcase/input-group.tsx +221 -253
  94. package/src/dev/showcase/input-otp.tsx +204 -250
  95. package/src/dev/showcase/input.tsx +246 -325
  96. package/src/dev/showcase/item.tsx +134 -152
  97. package/src/dev/showcase/kbd.tsx +149 -172
  98. package/src/dev/showcase/label.tsx +50 -68
  99. package/src/dev/showcase/menubar.tsx +194 -213
  100. package/src/dev/showcase/navigation-menu.tsx +119 -133
  101. package/src/dev/showcase/overview-components/ArchitectureSection.tsx +126 -0
  102. package/src/dev/showcase/overview-components/CodeBlock.tsx +50 -0
  103. package/src/dev/showcase/overview-components/ColorPaletteSection.tsx +44 -0
  104. package/src/dev/showcase/overview-components/DashboardPreview.tsx +159 -0
  105. package/src/dev/showcase/overview-components/FeatureGridSection.tsx +535 -0
  106. package/src/dev/showcase/overview-components/FooterCTA.tsx +137 -0
  107. package/src/dev/showcase/overview-components/HeroSection.tsx +65 -0
  108. package/src/dev/showcase/overview-components/PrinciplesSection.tsx +128 -0
  109. package/src/dev/showcase/overview.tsx +21 -1163
  110. package/src/dev/showcase/pagination.tsx +144 -190
  111. package/src/dev/showcase/popover.tsx +181 -196
  112. package/src/dev/showcase/progress.tsx +141 -189
  113. package/src/dev/showcase/radio-group.tsx +272 -332
  114. package/src/dev/showcase/resizable.tsx +119 -141
  115. package/src/dev/showcase/scroll-area.tsx +21 -36
  116. package/src/dev/showcase/select.tsx +262 -322
  117. package/src/dev/showcase/separator.tsx +75 -73
  118. package/src/dev/showcase/sheet.tsx +333 -361
  119. package/src/dev/showcase/sidebar.tsx +53 -59
  120. package/src/dev/showcase/skeleton.tsx +93 -112
  121. package/src/dev/showcase/slider.tsx +244 -296
  122. package/src/dev/showcase/sonner.tsx +251 -258
  123. package/src/dev/showcase/spinner.tsx +46 -67
  124. package/src/dev/showcase/switch.tsx +298 -362
  125. package/src/dev/showcase/table.tsx +76 -80
  126. package/src/dev/showcase/tabs.tsx +302 -355
  127. package/src/dev/showcase/textarea.tsx +240 -293
  128. package/src/dev/showcase/toast.tsx +48 -54
  129. package/src/dev/showcase/toggle-group.tsx +104 -129
  130. package/src/dev/showcase/toggle.tsx +82 -102
  131. package/src/dev/showcase/tooltip.tsx +173 -192
  132. package/src/dev/showcase/why.tsx +6 -12
  133. package/src/hooks/use-mobile.test.ts +3 -2
  134. package/src/lib/utils.test.ts +5 -4
@@ -15,75 +15,65 @@ import { useDevContext } from "../../dev/components/dev-context";
15
15
  import {
16
16
  DocsP,
17
17
  ExampleGrid,
18
- ExampleSection,
18
+ ShowcaseExample,
19
19
  Showcase,
20
20
  ShowcaseDocs
21
21
  } from "../../dev/components/showcase";
22
22
  import { type Size } from "../../lib/types";
23
23
 
24
- // ──────────────────────────────────────────────────────────
25
- // SECTION 1: Macro Content
26
- // ──────────────────────────────────────────────────────────
27
24
  function CardMacroShowcase({ globalSize }: { globalSize: Size }) {
28
25
  return (
29
- <div className="space-y-10 mt-6">
26
+ <div className="space-y-10">
30
27
  <ExampleGrid>
31
- <ExampleSection
32
- label="Tiêu chuẩn (Standard)"
33
- description="Card cài sẵn với đầy đủ tiêu đề, nội dung và chân trang."
34
- codeString={`<CardPreset
35
- title="Account Settings"
28
+ <ShowcaseExample title="Tiêu chuẩn (Standard)" description="Card cài sẵn với đầy đủ tiêu đề, nội dung và chân trang." code={`<CardPreset
29
+ title="Cài đặt tài khoản"
36
30
  description="Quản lý các cài đặt và tùy chọn cho tài khoản của bạn."
37
- footer={<Button>Save Changes</Button>}
31
+ footer={<Button>Lưu thay đổi</Button>}
38
32
  className="w-full"
39
33
  >
40
34
  <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50">
41
35
  Settings form content goes here.
42
36
  </div>
43
- </CardPreset>`}
44
- >
45
- <CardPreset
46
- size={globalSize}
47
- title="Account Settings"
48
- description="Quản lý các cài đặt và tùy chọn cho tài khoản của bạn."
49
- footer={<Button size={globalSize}>Save Changes</Button>}
50
- className="w-full"
51
- >
52
- <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50">
53
- Settings form content goes here.
54
- </div>
55
- </CardPreset>
56
- </ExampleSection>
37
+ </CardPreset>`} preview={
38
+ <>
39
+ <CardPreset
40
+ size={globalSize}
41
+ title="Cài đặt tài khoản"
42
+ description="Quản lý các cài đặt và tùy chọn cho tài khoản của bạn."
43
+ footer={<Button size={globalSize}>Lưu thay đổi</Button>}
44
+ className="w-full"
45
+ >
46
+ <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50">
47
+ Settings form content goes here.
48
+ </div>
49
+ </CardPreset>
50
+ </>
51
+ } />
57
52
 
58
- <ExampleSection
59
- label="Không Footer"
60
- description="Bỏ qua prop footer để ẩn hoàn toàn phần chân trang."
61
- codeString={`<CardPreset
62
- title="Notification Preferences"
53
+ <ShowcaseExample title="Không có Footer" description="Bỏ qua prop footer để ẩn hoàn toàn phần chân trang." code={`<CardPreset
54
+ title="Tùy chọn thông báo"
63
55
  description="Chọn những thông tin mà bạn muốn nhận thông báo."
64
56
  className="w-full"
65
57
  >
66
58
  <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50">
67
59
  Switches and toggles go here.
68
60
  </div>
69
- </CardPreset>`}
70
- >
71
- <CardPreset
72
- size={globalSize}
73
- title="Notification Preferences"
74
- description="Chọn những thông tin mà bạn muốn nhận thông báo."
75
- className="w-full"
76
- >
77
- <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50">
78
- Switches and toggles go here.
79
- </div>
80
- </CardPreset>
81
- </ExampleSection>
61
+ </CardPreset>`} preview={
62
+ <>
63
+ <CardPreset
64
+ size={globalSize}
65
+ title="Tùy chọn thông báo"
66
+ description="Chọn những thông tin mà bạn muốn nhận thông báo."
67
+ className="w-full"
68
+ >
69
+ <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50">
70
+ Switches and toggles go here.
71
+ </div>
72
+ </CardPreset>
73
+ </>
74
+ } />
82
75
 
83
- <ExampleSection
84
- label="Custom Title Node"
85
- description="Tiêu đề hỗ trợ nhận ReactNode thay vì string."
86
- codeString={`<CardPreset
76
+ <ShowcaseExample title="Custom Title Node" description="Tiêu đề hỗ trợ nhận ReactNode thay vì string." code={`<CardPreset
87
77
  title={
88
78
  <div className="flex items-center gap-2">
89
79
  <span>API Keys</span>
@@ -99,37 +89,35 @@ function CardMacroShowcase({ globalSize }: { globalSize: Size }) {
99
89
  Copy
100
90
  </Button>
101
91
  </div>
102
- </CardPreset>`}
103
- >
104
- <CardPreset
105
- size={globalSize}
106
- title={
107
- <div className="flex items-center gap-2">
108
- <span>API Keys</span>
109
- <Badge color="warning">Experimental</Badge>
110
- </div>
111
- }
112
- description="Quản lý các khóa API bí mật của bạn."
113
- className="w-full"
114
- >
115
- <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50 flex items-center justify-between">
116
- <span className="font-mono">sk_live_123...</span>
117
- <Button size="sm" variant="outline">
118
- Copy
119
- </Button>
120
- </div>
121
- </CardPreset>
122
- </ExampleSection>
92
+ </CardPreset>`} preview={
93
+ <>
94
+ <CardPreset
95
+ size={globalSize}
96
+ title={
97
+ <div className="flex items-center gap-2">
98
+ <span>API Keys</span>
99
+ <Badge color="warning">Experimental</Badge>
100
+ </div>
101
+ }
102
+ description="Quản lý các khóa API bí mật của bạn."
103
+ className="w-full"
104
+ >
105
+ <div className="text-sm text-muted-foreground bg-muted/30 p-4 rounded-lg border border-dashed border-border/50 flex items-center justify-between">
106
+ <span className="font-mono">sk_live_123...</span>
107
+ <Button size="sm" variant="outline">
108
+ Copy
109
+ </Button>
110
+ </div>
111
+ </CardPreset>
112
+ </>
113
+ } />
123
114
 
124
- <ExampleSection
125
- label="Với Form Controls"
126
- description="Sử dụng children để đặt input form bên trong nội dung."
127
- codeString={`<CardPreset
128
- title="Update Profile"
115
+ <ShowcaseExample title="Với Form Controls" description="Sử dụng children để đặt input form bên trong nội dung." code={`<CardPreset
116
+ title="Cập nhật hồ sơ"
129
117
  description="Thay đổi tên hiển thị và email của bạn."
130
118
  footer={
131
119
  <div className="flex justify-between w-full">
132
- <Button variant="ghost">Cancel</Button>
120
+ <Button variant="ghost">Huỷ</Button>
133
121
  <Button>Save</Button>
134
122
  </div>
135
123
  }
@@ -152,53 +140,48 @@ function CardMacroShowcase({ globalSize }: { globalSize: Size }) {
152
140
  />
153
141
  </div>
154
142
  </div>
155
- </CardPreset>`}
156
- >
157
- <CardPreset
158
- size={globalSize}
159
- title="Update Profile"
160
- description="Thay đổi tên hiển thị và email của bạn."
161
- footer={
162
- <div className="flex justify-between w-full">
163
- <Button variant="ghost" size={globalSize}>
164
- Cancel
165
- </Button>
166
- <Button size={globalSize}>Save</Button>
167
- </div>
168
- }
169
- className="w-full"
170
- >
171
- <div className="grid gap-4">
172
- <div className="flex flex-col space-y-1.5">
173
- <Label htmlFor="macro-name">Name</Label>
174
- <Input id="macro-name" placeholder="Enter your name" />
175
- </div>
176
- <div className="flex flex-col space-y-1.5">
177
- <Label htmlFor="macro-email">Email</Label>
178
- <Input
179
- id="macro-email"
180
- type="email"
181
- placeholder="hello@example.com"
182
- />
183
- </div>
184
- </div>
185
- </CardPreset>
186
- </ExampleSection>
143
+ </CardPreset>`} preview={
144
+ <>
145
+ <CardPreset
146
+ size={globalSize}
147
+ title="Cập nhật hồ sơ"
148
+ description="Thay đổi tên hiển thị và email của bạn."
149
+ footer={
150
+ <div className="flex justify-between w-full">
151
+ <Button variant="ghost" size={globalSize}>
152
+ Cancel
153
+ </Button>
154
+ <Button size={globalSize}>Save</Button>
155
+ </div>
156
+ }
157
+ className="w-full"
158
+ >
159
+ <div className="grid gap-4">
160
+ <div className="flex flex-col space-y-1.5">
161
+ <Label htmlFor="macro-name">Name</Label>
162
+ <Input id="macro-name" placeholder="Enter your name" />
163
+ </div>
164
+ <div className="flex flex-col space-y-1.5">
165
+ <Label htmlFor="macro-email">Email</Label>
166
+ <Input
167
+ id="macro-email"
168
+ type="email"
169
+ placeholder="hello@example.com"
170
+ />
171
+ </div>
172
+ </div>
173
+ </CardPreset>
174
+ </>
175
+ } />
187
176
  </ExampleGrid>
188
177
  </div>
189
178
  );
190
179
  }
191
180
 
192
- // ──────────────────────────────────────────────────────────
193
- // SECTION 2: Micro Content
194
- // ──────────────────────────────────────────────────────────
195
181
  function CardMicroShowcase({ globalSize }: { globalSize: Size }) {
196
182
  return (
197
- <div className="space-y-10 mt-6">
198
- <ExampleSection
199
- label="Cơ bản (Standard)"
200
- description="Lắp ráp thủ công từ CardHeader, CardTitle, CardContent, CardFooter."
201
- codeString={`<Card className="w-full max-w-sm">
183
+ <div className="space-y-10">
184
+ <ShowcaseExample title="Cơ bản (Standard)" description="Lắp ráp thủ công từ CardHeader, CardTitle, CardContent, CardFooter." code={`<Card className="w-full max-w-sm">
202
185
  <CardHeader>
203
186
  <CardTitle>Create project</CardTitle>
204
187
  <CardDescription>
@@ -219,42 +202,40 @@ function CardMicroShowcase({ globalSize }: { globalSize: Size }) {
219
202
  </form>
220
203
  </CardContent>
221
204
  <CardFooter className="flex justify-between">
222
- <Button variant="outline">Cancel</Button>
223
- <Button>Deploy</Button>
205
+ <Button variant="outline">Huỷ</Button>
206
+ <Button>Triển khai</Button>
224
207
  </CardFooter>
225
- </Card>`}
226
- >
227
- <Card size={globalSize} className="w-full max-w-sm">
228
- <CardHeader>
229
- <CardTitle>Create project</CardTitle>
230
- <CardDescription>
231
- Deploy your new project in one-click.
232
- </CardDescription>
233
- </CardHeader>
234
- <CardContent>
235
- <form>
236
- <div className="grid w-full items-center gap-4">
237
- <div className="flex flex-col space-y-1.5">
238
- <Label htmlFor="name">Name</Label>
239
- <Input id="name" placeholder="Name of your project" />
240
- </div>
241
- </div>
242
- </form>
243
- </CardContent>
244
- <CardFooter className="flex justify-between">
245
- <Button variant="outline" size={globalSize}>
246
- Cancel
247
- </Button>
248
- <Button size={globalSize}>Deploy</Button>
249
- </CardFooter>
250
- </Card>
251
- </ExampleSection>
208
+ </Card>`} preview={
209
+ <>
210
+ <Card size={globalSize} className="w-full max-w-sm">
211
+ <CardHeader>
212
+ <CardTitle>Create project</CardTitle>
213
+ <CardDescription>
214
+ Deploy your new project in one-click.
215
+ </CardDescription>
216
+ </CardHeader>
217
+ <CardContent>
218
+ <form>
219
+ <div className="grid w-full items-center gap-4">
220
+ <div className="flex flex-col space-y-1.5">
221
+ <Label htmlFor="name">Name</Label>
222
+ <Input id="name" placeholder="Name of your project" />
223
+ </div>
224
+ </div>
225
+ </form>
226
+ </CardContent>
227
+ <CardFooter className="flex justify-between">
228
+ <Button variant="outline" size={globalSize}>
229
+ Cancel
230
+ </Button>
231
+ <Button size={globalSize}>Triển khai</Button>
232
+ </CardFooter>
233
+ </Card>
234
+ </>
235
+ } />
252
236
 
253
237
  <ExampleGrid>
254
- <ExampleSection
255
- label="Chỉ có nội dung (Content Only)"
256
- description="Dùng Card như một container bọc ngoài đơn giản."
257
- codeString={`<Card className="w-full">
238
+ <ShowcaseExample title="Chỉ có nội dung (Content Only)" description="Dùng Card như một container bọc ngoài đơn giản." code={`<Card className="w-full">
258
239
  <CardContent>
259
240
  <p className="text-sm text-muted-foreground pt-4 md:pt-6">
260
241
  This is a simple content-only card without a header
@@ -262,31 +243,29 @@ function CardMicroShowcase({ globalSize }: { globalSize: Size }) {
262
243
  container.
263
244
  </p>
264
245
  </CardContent>
265
- </Card>`}
266
- >
267
- <Card size={globalSize} className="w-full">
268
- <CardContent>
269
- <p className="text-sm text-muted-foreground pt-4 md:pt-6">
270
- This is a simple content-only card without a header or footer.
271
- Useful for wrapping any content in a card container.
272
- </p>
273
- </CardContent>
274
- </Card>
275
- </ExampleSection>
246
+ </Card>`} preview={
247
+ <>
248
+ <Card size={globalSize} className="w-full">
249
+ <CardContent>
250
+ <p className="text-sm text-muted-foreground pt-4 md:pt-6">
251
+ This is a simple content-only card without a header or footer.
252
+ Useful for wrapping any content in a card container.
253
+ </p>
254
+ </CardContent>
255
+ </Card>
256
+ </>
257
+ } />
276
258
 
277
- <ExampleSection
278
- label="Header đặc chế"
279
- description="Tích hợp menu góc phải mà Preset khó thực hiện."
280
- codeString={`<Card className="w-full">
259
+ <ShowcaseExample title="Header đặc chế" description="Tích hợp menu góc phải mà Preset khó thực hiện." code={`<Card className="w-full">
281
260
  <CardHeader>
282
261
  <div className="flex items-center justify-between">
283
262
  <div className="flex flex-col gap-1.5">
284
263
  <div className="flex items-center gap-2">
285
- <CardTitle>Notifications</CardTitle>
264
+ <CardTitle>Thông báo</CardTitle>
286
265
  <Badge color="secondary">3 new</Badge>
287
266
  </div>
288
267
  <CardDescription>
289
- You have 3 unread messages.
268
+ Bạn 3 tin nhắn chưa đọc.
290
269
  </CardDescription>
291
270
  </div>
292
271
  <Button
@@ -314,55 +293,52 @@ function CardMicroShowcase({ globalSize }: { globalSize: Size }) {
314
293
  </Button>
315
294
  </div>
316
295
  </CardHeader>
317
- </Card>`}
318
- >
319
- <Card size={globalSize} className="w-full">
320
- <CardHeader>
321
- <div className="flex items-center justify-between">
322
- <div className="flex flex-col gap-1.5">
323
- <div className="flex items-center gap-2">
324
- <CardTitle>Notifications</CardTitle>
325
- <Badge color="secondary">3 new</Badge>
326
- </div>
327
- <CardDescription>You have 3 unread messages.</CardDescription>
328
- </div>
329
- <Button
330
- variant="ghost"
331
- size="sm"
332
- iconOnly
333
- className="h-8 w-8 rounded-full"
334
- >
335
- <span className="sr-only">Open menu</span>
336
- <svg
337
- width="15"
338
- height="15"
339
- viewBox="0 0 15 15"
340
- fill="none"
341
- xmlns="http://www.w3.org/2000/svg"
342
- className="h-4 w-4"
343
- >
344
- <path
345
- d="M3.625 7.5C3.625 8.12132 3.12132 8.625 2.5 8.625C1.87868 8.625 1.375 8.12132 1.375 7.5C1.375 6.87868 1.87868 6.375 2.5 6.375C3.12132 6.375 3.625 6.87868 3.625 7.5ZM8.625 7.5C8.625 8.12132 8.12132 8.625 7.5 8.625C6.87868 8.625 6.375 8.12132 6.375 7.5C6.375 6.87868 6.87868 6.375 7.5 6.375C8.12132 6.375 8.625 6.87868 8.625 7.5ZM13.625 7.5C13.625 8.12132 13.1213 8.625 12.5 8.625C11.8787 8.625 11.375 8.12132 11.375 7.5C11.375 6.87868 11.8787 6.375 12.5 6.375C13.1213 6.375 13.625 6.87868 13.625 7.5Z"
346
- fill="currentColor"
347
- fillRule="evenodd"
348
- clipRule="evenodd"
349
- ></path>
350
- </svg>
351
- </Button>
352
- </div>
353
- </CardHeader>
354
- </Card>
355
- </ExampleSection>
296
+ </Card>`} preview={
297
+ <>
298
+ <Card size={globalSize} className="w-full">
299
+ <CardHeader>
300
+ <div className="flex items-center justify-between">
301
+ <div className="flex flex-col gap-1.5">
302
+ <div className="flex items-center gap-2">
303
+ <CardTitle>Thông báo</CardTitle>
304
+ <Badge color="secondary">3 new</Badge>
305
+ </div>
306
+ <CardDescription>Bạn 3 tin nhắn chưa đọc.</CardDescription>
307
+ </div>
308
+ <Button
309
+ variant="ghost"
310
+ size="sm"
311
+ iconOnly
312
+ className="h-8 w-8 rounded-full"
313
+ >
314
+ <span className="sr-only">Open menu</span>
315
+ <svg
316
+ width="15"
317
+ height="15"
318
+ viewBox="0 0 15 15"
319
+ fill="none"
320
+ xmlns="http://www.w3.org/2000/svg"
321
+ className="h-4 w-4"
322
+ >
323
+ <path
324
+ d="M3.625 7.5C3.625 8.12132 3.12132 8.625 2.5 8.625C1.87868 8.625 1.375 8.12132 1.375 7.5C1.375 6.87868 1.87868 6.375 2.5 6.375C3.12132 6.375 3.625 6.87868 3.625 7.5ZM8.625 7.5C8.625 8.12132 8.12132 8.625 7.5 8.625C6.87868 8.625 6.375 8.12132 6.375 7.5C6.375 6.87868 6.87868 6.375 7.5 6.375C8.12132 6.375 8.625 6.87868 8.625 7.5ZM13.625 7.5C13.625 8.12132 13.1213 8.625 12.5 8.625C11.8787 8.625 11.375 8.12132 11.375 7.5C11.375 6.87868 11.8787 6.375 12.5 6.375C13.1213 6.375 13.625 6.87868 13.625 7.5Z"
325
+ fill="currentColor"
326
+ fillRule="evenodd"
327
+ clipRule="evenodd"
328
+ ></path>
329
+ </svg>
330
+ </Button>
331
+ </div>
332
+ </CardHeader>
333
+ </Card>
334
+ </>
335
+ } />
356
336
  </ExampleGrid>
357
337
 
358
- <ExampleSection
359
- label="Thẻ chỉ số KPI (Stats Cards)"
360
- description="Thiết kế thẻ dashboard thông dụng trong thực tế."
361
- fullWidth
362
- codeString={`<div className="grid grid-cols-1 md:grid-cols-3 gap-6 w-full">
338
+ <ShowcaseExample title="Thẻ chỉ số KPI (Stats Cards)" description="Thiết kế thẻ dashboard thông dụng trong thực tế." code={`<div className="grid grid-cols-1 md:grid-cols-3 gap-6 w-full">
363
339
  <Card>
364
340
  <CardHeader className="pb-2">
365
- <CardDescription>Total Revenue</CardDescription>
341
+ <CardDescription>Tổng doanh thu</CardDescription>
366
342
  <CardTitle className="text-3xl">
367
343
  $45,231.89
368
344
  </CardTitle>
@@ -375,7 +351,7 @@ function CardMicroShowcase({ globalSize }: { globalSize: Size }) {
375
351
  </Card>
376
352
  <Card>
377
353
  <CardHeader className="pb-2">
378
- <CardDescription>Subscriptions</CardDescription>
354
+ <CardDescription>Lượt đăng ký</CardDescription>
379
355
  <CardTitle className="text-3xl">+2,350</CardTitle>
380
356
  </CardHeader>
381
357
  <CardContent>
@@ -386,7 +362,7 @@ function CardMicroShowcase({ globalSize }: { globalSize: Size }) {
386
362
  </Card>
387
363
  <Card>
388
364
  <CardHeader className="pb-2">
389
- <CardDescription>Active Now</CardDescription>
365
+ <CardDescription>Đang hoạt động</CardDescription>
390
366
  <CardTitle className="text-3xl">+573</CardTitle>
391
367
  </CardHeader>
392
368
  <CardContent>
@@ -395,58 +371,56 @@ function CardMicroShowcase({ globalSize }: { globalSize: Size }) {
395
371
  </p>
396
372
  </CardContent>
397
373
  </Card>
398
- </div>`}
399
- >
400
- <div className="grid grid-cols-1 md:grid-cols-3 gap-6 w-full">
401
- <Card size={globalSize}>
402
- <CardHeader className="pb-2">
403
- <CardDescription>Total Revenue</CardDescription>
404
- <CardTitle className="text-3xl">$45,231.89</CardTitle>
405
- </CardHeader>
406
- <CardContent>
407
- <p className="text-xs text-muted-foreground">
408
- +20.1% from last month
409
- </p>
410
- </CardContent>
411
- </Card>
412
- <Card size={globalSize}>
413
- <CardHeader className="pb-2">
414
- <CardDescription>Subscriptions</CardDescription>
415
- <CardTitle className="text-3xl">+2,350</CardTitle>
416
- </CardHeader>
417
- <CardContent>
418
- <p className="text-xs text-muted-foreground">
419
- +180.1% from last month
420
- </p>
421
- </CardContent>
422
- </Card>
423
- <Card size={globalSize}>
424
- <CardHeader className="pb-2">
425
- <CardDescription>Active Now</CardDescription>
426
- <CardTitle className="text-3xl">+573</CardTitle>
427
- </CardHeader>
428
- <CardContent>
429
- <p className="text-xs text-muted-foreground">
430
- +201 since last hour
431
- </p>
432
- </CardContent>
433
- </Card>
434
- </div>
435
- </ExampleSection>
374
+ </div>`} preview={
375
+ <>
376
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-6 w-full">
377
+ <Card size={globalSize}>
378
+ <CardHeader className="pb-2">
379
+ <CardDescription>Tổng doanh thu</CardDescription>
380
+ <CardTitle className="text-3xl">$45,231.89</CardTitle>
381
+ </CardHeader>
382
+ <CardContent>
383
+ <p className="text-xs text-muted-foreground">
384
+ +20.1% from last month
385
+ </p>
386
+ </CardContent>
387
+ </Card>
388
+ <Card size={globalSize}>
389
+ <CardHeader className="pb-2">
390
+ <CardDescription>Lượt đăng ký</CardDescription>
391
+ <CardTitle className="text-3xl">+2,350</CardTitle>
392
+ </CardHeader>
393
+ <CardContent>
394
+ <p className="text-xs text-muted-foreground">
395
+ +180.1% from last month
396
+ </p>
397
+ </CardContent>
398
+ </Card>
399
+ <Card size={globalSize}>
400
+ <CardHeader className="pb-2">
401
+ <CardDescription>Đang hoạt động</CardDescription>
402
+ <CardTitle className="text-3xl">+573</CardTitle>
403
+ </CardHeader>
404
+ <CardContent>
405
+ <p className="text-xs text-muted-foreground">
406
+ +201 since last hour
407
+ </p>
408
+ </CardContent>
409
+ </Card>
410
+ </div>
411
+ </>
412
+ } />
436
413
  </div>
437
414
  );
438
415
  }
439
416
 
440
- // ──────────────────────────────────────────────────────────
441
- // SECTION 3: Entry point
442
- // ──────────────────────────────────────────────────────────
443
417
  export default function CardShowcase() {
444
418
  const { size: globalSize } = useDevContext();
445
419
  return (
446
420
  <Showcase
447
421
  title="Card"
448
422
  description="Thẻ hiển thị thông tin đóng gói có cấu trúc (tiêu đề, nội dung, footer)."
449
- generalConcept={
423
+ guideline={
450
424
  <ShowcaseDocs>
451
425
  <DocsP>
452
426
  Dùng để nhóm các thông tin liên quan lại với nhau trong một
@@ -455,14 +429,8 @@ export default function CardShowcase() {
455
429
  </DocsP>
456
430
  </ShowcaseDocs>
457
431
  }
458
- tabs={[
459
- {
460
- label: "Micro (Primitive)",
461
- content: <CardMicroShowcase globalSize={globalSize} /> },
462
- {
463
- label: "Macro (Preset)",
464
- content: <CardMacroShowcase globalSize={globalSize} /> },
465
- ]}
432
+ micro={{ content: <CardMicroShowcase globalSize={globalSize} /> }}
433
+ macro={{ content: <CardMacroShowcase globalSize={globalSize} /> }}
466
434
  />
467
435
  );
468
436
  }