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
@@ -18,46 +18,38 @@ import { useDevContext } from "../../dev/components/dev-context";
18
18
  import {
19
19
  DocsP,
20
20
  ExampleGrid,
21
- ExampleSection,
21
+ ShowcaseExample,
22
22
  Showcase,
23
23
  ShowcaseDocs
24
24
  } from "../../dev/components/showcase";
25
25
  import { type Size } from "../../lib/types";
26
26
 
27
- // ──────────────────────────────────────────────────────────
28
- // SECTION 1: Macro Content
29
- // ──────────────────────────────────────────────────────────
30
27
  function AvatarMacroShowcase({ globalSize }: { globalSize: Size }) {
31
28
  return (
32
- <div className="space-y-10 mt-6">
29
+ <div className="space-y-10">
33
30
  <ExampleGrid>
34
- <ExampleSection
35
- label="Tiêu chuẩn (Standard)"
36
- description="Avatar tự động fallback dựa vào tên truyền vào alt."
37
- codeString={`<div className="flex items-center gap-4">
31
+ <ShowcaseExample title="Tiêu chuẩn (Standard)" description="Avatar tự động fallback dựa vào tên truyền vào alt." code={`<div className="flex items-center gap-4">
38
32
  <AvatarPreset
39
33
  src="https://github.com/shadcn.png"
40
34
  alt="Shadcn"
41
35
  />
42
36
  <AvatarPreset alt="John Doe" />
43
37
  <AvatarPreset />
44
- </div>`}
45
- >
46
- <div className="flex items-center gap-4">
47
- <AvatarPreset
48
- size={globalSize}
49
- src="https://github.com/shadcn.png"
50
- alt="Shadcn"
51
- />
52
- <AvatarPreset size={globalSize} alt="John Doe" />
53
- <AvatarPreset size={globalSize} />
54
- </div>
55
- </ExampleSection>
38
+ </div>`} preview={
39
+ <>
40
+ <div className="flex items-center gap-4">
41
+ <AvatarPreset
42
+ size={globalSize}
43
+ src="https://github.com/shadcn.png"
44
+ alt="Shadcn"
45
+ />
46
+ <AvatarPreset size={globalSize} alt="John Doe" />
47
+ <AvatarPreset size={globalSize} />
48
+ </div>
49
+ </>
50
+ } />
56
51
 
57
- <ExampleSection
58
- label="Trạng thái (Status)"
59
- description="Hỗ trợ sẵn các trạng thái: online, offline, away."
60
- codeString={`<div className="flex items-center gap-4">
52
+ <ShowcaseExample title="Trạng thái (Status)" description="Hỗ trợ sẵn các trạng thái: online, offline, away." code={`<div className="flex items-center gap-4">
61
53
  <AvatarPreset
62
54
  src="https://github.com/shadcn.png"
63
55
  alt="Shadcn"
@@ -65,26 +57,23 @@ function AvatarMacroShowcase({ globalSize }: { globalSize: Size }) {
65
57
  />
66
58
  <AvatarPreset alt="Alice" status="away" />
67
59
  <AvatarPreset status="offline" />
68
- </div>`}
69
- >
70
- <div className="flex items-center gap-4">
71
- <AvatarPreset
72
- size={globalSize}
73
- src="https://github.com/shadcn.png"
74
- alt="Shadcn"
75
- status="online"
76
- />
77
- <AvatarPreset size={globalSize} alt="Alice" status="away" />
78
- <AvatarPreset size={globalSize} status="offline" />
79
- </div>
80
- </ExampleSection>
60
+ </div>`} preview={
61
+ <>
62
+ <div className="flex items-center gap-4">
63
+ <AvatarPreset
64
+ size={globalSize}
65
+ src="https://github.com/shadcn.png"
66
+ alt="Shadcn"
67
+ status="online"
68
+ />
69
+ <AvatarPreset size={globalSize} alt="Alice" status="away" />
70
+ <AvatarPreset size={globalSize} status="offline" />
71
+ </div>
72
+ </>
73
+ } />
81
74
  </ExampleGrid>
82
75
 
83
- <ExampleSection
84
- label="Nhóm Avatar (Avatar Group)"
85
- description="Kết hợp Preset với AvatarGroup để tiết kiệm code."
86
- fullWidth
87
- codeString={`<AvatarGroup>
76
+ <ShowcaseExample title="Nhóm Avatar (Avatar Group)" description="Kết hợp Preset với AvatarGroup để tiết kiệm code." code={`<AvatarGroup>
88
77
  <AvatarPreset
89
78
  src="https://github.com/shadcn.png"
90
79
  alt="Shadcn"
@@ -92,36 +81,31 @@ function AvatarMacroShowcase({ globalSize }: { globalSize: Size }) {
92
81
  <AvatarPreset alt="Alice Smith" />
93
82
  <AvatarPreset alt="Bob Jones" />
94
83
  <AvatarGroupCount>+3</AvatarGroupCount>
95
- </AvatarGroup>`}
96
- >
97
- <div className="flex flex-col gap-4">
98
- <AvatarGroup>
99
- <AvatarPreset
100
- size={globalSize}
101
- src="https://github.com/shadcn.png"
102
- alt="Shadcn"
103
- />
104
- <AvatarPreset size={globalSize} alt="Alice Smith" />
105
- <AvatarPreset size={globalSize} alt="Bob Jones" />
106
- <AvatarGroupCount size={globalSize}>+3</AvatarGroupCount>
107
- </AvatarGroup>
108
- </div>
109
- </ExampleSection>
84
+ </AvatarGroup>`} preview={
85
+ <>
86
+ <div className="flex flex-col gap-4">
87
+ <AvatarGroup>
88
+ <AvatarPreset
89
+ size={globalSize}
90
+ src="https://github.com/shadcn.png"
91
+ alt="Shadcn"
92
+ />
93
+ <AvatarPreset size={globalSize} alt="Alice Smith" />
94
+ <AvatarPreset size={globalSize} alt="Bob Jones" />
95
+ <AvatarGroupCount size={globalSize}>+3</AvatarGroupCount>
96
+ </AvatarGroup>
97
+ </div>
98
+ </>
99
+ } />
110
100
  </div>
111
101
  );
112
102
  }
113
103
 
114
- // ──────────────────────────────────────────────────────────
115
- // SECTION 2: Micro Content
116
- // ──────────────────────────────────────────────────────────
117
104
  function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
118
105
  return (
119
- <div className="space-y-10 mt-6">
106
+ <div className="space-y-10">
120
107
  <ExampleGrid>
121
- <ExampleSection
122
- label="Với Hình ảnh (With Image)"
123
- description="Hiển thị ảnh và sẽ fallback về chữ nếu ảnh lỗi."
124
- codeString={`<div className="flex items-center gap-4">
108
+ <ShowcaseExample title="Với Hình ảnh (With Image)" description="Hiển thị ảnh và sẽ fallback về chữ nếu ảnh lỗi." code={`<div className="flex items-center gap-4">
125
109
  <Avatar>
126
110
  <AvatarImage
127
111
  src="https://github.com/shadcn.png"
@@ -143,28 +127,26 @@ function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
143
127
  />
144
128
  <AvatarFallback>LR</AvatarFallback>
145
129
  </Avatar>
146
- </div>`}
147
- >
148
- <div className="flex items-center gap-4">
149
- <Avatar size={globalSize}>
150
- <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
151
- <AvatarFallback>CN</AvatarFallback>
152
- </Avatar>
153
- <Avatar size={globalSize}>
154
- <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
155
- <AvatarFallback>VC</AvatarFallback>
156
- </Avatar>
157
- <Avatar size={globalSize}>
158
- <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
159
- <AvatarFallback>LR</AvatarFallback>
160
- </Avatar>
161
- </div>
162
- </ExampleSection>
130
+ </div>`} preview={
131
+ <>
132
+ <div className="flex items-center gap-4">
133
+ <Avatar size={globalSize}>
134
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
135
+ <AvatarFallback>CN</AvatarFallback>
136
+ </Avatar>
137
+ <Avatar size={globalSize}>
138
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
139
+ <AvatarFallback>VC</AvatarFallback>
140
+ </Avatar>
141
+ <Avatar size={globalSize}>
142
+ <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
143
+ <AvatarFallback>LR</AvatarFallback>
144
+ </Avatar>
145
+ </div>
146
+ </>
147
+ } />
163
148
 
164
- <ExampleSection
165
- label="Lỗi Ảnh & Chỉ có Fallback"
166
- description="Khi không có ảnh hoặc ảnh lỗi, fallback sẽ hiển thị."
167
- codeString={`<div className="flex items-center gap-4">
149
+ <ShowcaseExample title="Lỗi Ảnh & Chỉ có Fallback" description="Khi không có ảnh hoặc ảnh lỗi, fallback sẽ hiển thị." code={`<div className="flex items-center gap-4">
168
150
  <Avatar>
169
151
  <AvatarImage
170
152
  src="https://broken-url.invalid/avatar.png"
@@ -194,46 +176,44 @@ function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
194
176
  </svg>
195
177
  </AvatarFallback>
196
178
  </Avatar>
197
- </div>`}
198
- >
199
- <div className="flex items-center gap-4">
200
- <Avatar size={globalSize}>
201
- <AvatarImage
202
- src="https://broken-url.invalid/avatar.png"
203
- alt="broken"
204
- />
205
- <AvatarFallback>BR</AvatarFallback>
206
- </Avatar>
207
- <Avatar size={globalSize}>
208
- <AvatarFallback>JD</AvatarFallback>
209
- </Avatar>
210
- <Avatar size={globalSize}>
211
- <AvatarFallback>
212
- <svg
213
- xmlns="http://www.w3.org/2000/svg"
214
- width="24"
215
- height="24"
216
- viewBox="0 0 24 24"
217
- fill="none"
218
- stroke="currentColor"
219
- strokeWidth="2"
220
- strokeLinecap="round"
221
- strokeLinejoin="round"
222
- className="size-4"
223
- >
224
- <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
225
- <circle cx="12" cy="7" r="4" />
226
- </svg>
227
- </AvatarFallback>
228
- </Avatar>
229
- </div>
230
- </ExampleSection>
179
+ </div>`} preview={
180
+ <>
181
+ <div className="flex items-center gap-4">
182
+ <Avatar size={globalSize}>
183
+ <AvatarImage
184
+ src="https://broken-url.invalid/avatar.png"
185
+ alt="broken"
186
+ />
187
+ <AvatarFallback>BR</AvatarFallback>
188
+ </Avatar>
189
+ <Avatar size={globalSize}>
190
+ <AvatarFallback>JD</AvatarFallback>
191
+ </Avatar>
192
+ <Avatar size={globalSize}>
193
+ <AvatarFallback>
194
+ <svg
195
+ xmlns="http://www.w3.org/2000/svg"
196
+ width="24"
197
+ height="24"
198
+ viewBox="0 0 24 24"
199
+ fill="none"
200
+ stroke="currentColor"
201
+ strokeWidth="2"
202
+ strokeLinecap="round"
203
+ strokeLinejoin="round"
204
+ className="size-4"
205
+ >
206
+ <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
207
+ <circle cx="12" cy="7" r="4" />
208
+ </svg>
209
+ </AvatarFallback>
210
+ </Avatar>
211
+ </div>
212
+ </>
213
+ } />
231
214
  </ExampleGrid>
232
215
 
233
- <ExampleSection
234
- label="Huy hiệu (With Badge)"
235
- description="Bạn có thể tự định vị Badge ở bất cứ đâu trên Avatar."
236
- codeString={`<div className="flex items-center gap-6">
216
+ <ShowcaseExample title="Huy hiệu (With Badge)" description="Bạn có thể tự định vị Badge ở bất cứ đâu trên Avatar." code={`<div className="flex items-center gap-6">
237
217
  <div className="flex flex-col items-center gap-2">
238
218
  <Avatar>
239
219
  <AvatarImage
@@ -260,33 +240,31 @@ function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
260
240
  Notification
261
241
  </span>
262
242
  </div>
263
- </div>`}
264
- >
265
- <div className="flex items-center gap-6">
266
- <div className="flex flex-col items-center gap-2">
267
- <Avatar size={globalSize}>
268
- <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
269
- <AvatarFallback>CN</AvatarFallback>
270
- <AvatarBadge className="absolute z-10 right-0 bottom-0 bg-green-500" />
271
- </Avatar>
272
- <span className="text-xs text-muted-foreground">Online</span>
273
- </div>
274
- <div className="flex flex-col items-center gap-2">
275
- <Avatar size={globalSize}>
276
- <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
277
- <AvatarFallback>VC</AvatarFallback>
278
- <AvatarBadge className="absolute z-10 right-0 top-0 bg-red-500" />
279
- </Avatar>
280
- <span className="text-xs text-muted-foreground">Notification</span>
281
- </div>
282
- </div>
283
- </ExampleSection>
243
+ </div>`} preview={
244
+ <>
245
+ <div className="flex items-center gap-6">
246
+ <div className="flex flex-col items-center gap-2">
247
+ <Avatar size={globalSize}>
248
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
249
+ <AvatarFallback>CN</AvatarFallback>
250
+ <AvatarBadge className="absolute z-10 right-0 bottom-0 bg-green-500" />
251
+ </Avatar>
252
+ <span className="text-xs text-muted-foreground">Online</span>
253
+ </div>
254
+ <div className="flex flex-col items-center gap-2">
255
+ <Avatar size={globalSize}>
256
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
257
+ <AvatarFallback>VC</AvatarFallback>
258
+ <AvatarBadge className="absolute z-10 right-0 top-0 bg-red-500" />
259
+ </Avatar>
260
+ <span className="text-xs text-muted-foreground">Notification</span>
261
+ </div>
262
+ </div>
263
+ </>
264
+ } />
284
265
 
285
266
  <ExampleGrid>
286
- <ExampleSection
287
- label="Nhóm cơ bản (Basic Group)"
288
- description="Xếp chồng nhiều avatar lên nhau."
289
- codeString={`<AvatarGroup>
267
+ <ShowcaseExample title="Nhóm cơ bản (Basic Group)" description="Xếp chồng nhiều avatar lên nhau." code={`<AvatarGroup>
290
268
  <Avatar>
291
269
  <AvatarImage
292
270
  src="https://github.com/shadcn.png"
@@ -308,28 +286,26 @@ function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
308
286
  />
309
287
  <AvatarFallback>LR</AvatarFallback>
310
288
  </Avatar>
311
- </AvatarGroup>`}
312
- >
313
- <AvatarGroup>
314
- <Avatar size={globalSize}>
315
- <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
316
- <AvatarFallback>CN</AvatarFallback>
317
- </Avatar>
318
- <Avatar size={globalSize}>
319
- <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
320
- <AvatarFallback>VC</AvatarFallback>
321
- </Avatar>
322
- <Avatar size={globalSize}>
323
- <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
324
- <AvatarFallback>LR</AvatarFallback>
325
- </Avatar>
326
- </AvatarGroup>
327
- </ExampleSection>
289
+ </AvatarGroup>`} preview={
290
+ <>
291
+ <AvatarGroup>
292
+ <Avatar size={globalSize}>
293
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
294
+ <AvatarFallback>CN</AvatarFallback>
295
+ </Avatar>
296
+ <Avatar size={globalSize}>
297
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
298
+ <AvatarFallback>VC</AvatarFallback>
299
+ </Avatar>
300
+ <Avatar size={globalSize}>
301
+ <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
302
+ <AvatarFallback>LR</AvatarFallback>
303
+ </Avatar>
304
+ </AvatarGroup>
305
+ </>
306
+ } />
328
307
 
329
- <ExampleSection
330
- label="Kèm bộ đếm (With Count)"
331
- description="Hiển thị những avatar còn lại bị ẩn."
332
- codeString={`<AvatarGroup>
308
+ <ShowcaseExample title="Kèm bộ đếm (With Count)" description="Hiển thị những avatar còn lại bị ẩn." code={`<AvatarGroup>
333
309
  <Avatar>
334
310
  <AvatarImage
335
311
  src="https://github.com/shadcn.png"
@@ -345,27 +321,23 @@ function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
345
321
  <AvatarFallback>VC</AvatarFallback>
346
322
  </Avatar>
347
323
  <AvatarGroupCount>+12</AvatarGroupCount>
348
- </AvatarGroup>`}
349
- >
350
- <AvatarGroup>
351
- <Avatar size={globalSize}>
352
- <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
353
- <AvatarFallback>CN</AvatarFallback>
354
- </Avatar>
355
- <Avatar size={globalSize}>
356
- <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
357
- <AvatarFallback>VC</AvatarFallback>
358
- </Avatar>
359
- <AvatarGroupCount size={globalSize}>+12</AvatarGroupCount>
360
- </AvatarGroup>
361
- </ExampleSection>
324
+ </AvatarGroup>`} preview={
325
+ <>
326
+ <AvatarGroup>
327
+ <Avatar size={globalSize}>
328
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
329
+ <AvatarFallback>CN</AvatarFallback>
330
+ </Avatar>
331
+ <Avatar size={globalSize}>
332
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
333
+ <AvatarFallback>VC</AvatarFallback>
334
+ </Avatar>
335
+ <AvatarGroupCount size={globalSize}>+12</AvatarGroupCount>
336
+ </AvatarGroup>
337
+ </>
338
+ } />
362
339
 
363
- {/* ── Use Case Comparison ─────────────────────── */}
364
- <ExampleSection
365
- label="🧭 Use Case Comparison"
366
- description="Các kịch bản thực tế giúp bạn quyết định nên dùng Micro hay Macro."
367
- fullWidth
368
- codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
340
+ <ShowcaseExample title="🧭 So sánh Use Case" description="Các kịch bản thực tế giúp bạn quyết định nên dùng Micro hay Macro." code={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
369
341
  {/* ── Story 1: Macro wins ── */}
370
342
  <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
371
343
  <div className="flex items-start gap-3">
@@ -436,88 +408,84 @@ function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
436
408
  </Avatar>
437
409
  </div>
438
410
  </div>
439
- </div>`}
440
- >
441
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
442
- {/* ── Story 1: Macro wins ── */}
443
- <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
444
- <div className="flex items-start gap-3">
445
- <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
446
- <CheckCircle2Icon className="size-4" aria-hidden="true" />
447
- </span>
448
- <div>
449
- <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
450
- Story 1 · Dùng Macro
451
- </p>
452
- <h3 className="mt-0.5 text-sm font-semibold text-foreground">
453
- Hiển thị Avatar chuẩn với URL và Fallback
454
- </h3>
455
- </div>
456
- </div>
457
- <p className="text-xs text-muted-foreground leading-relaxed">
458
- Hầu hết các trường hợp bạn chỉ một URL hình ảnh một cái
459
- tên. Macro tự động hiển thị ảnh, nếu ảnh lỗi thì tự sinh chữ
460
- viết tắt dựa trên tên cực kỳ tiện lợi mà không cần viết nhiều
461
- code.
462
- </p>
463
- <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
464
- <AvatarPreset
465
- size={globalSize === "sm" ? "md" : "lg"}
466
- src="https://github.com/shadcn.png"
467
- alt="Shadcn"
468
- />
469
- </div>
470
- </div>
411
+ </div>`} preview={
412
+ <>
413
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
414
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
415
+ <div className="flex items-start gap-3">
416
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
417
+ <CheckCircle2Icon className="size-4" aria-hidden="true" />
418
+ </span>
419
+ <div>
420
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
421
+ Story 1 · Dùng Macro
422
+ </p>
423
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
424
+ Hiển thị Avatar chuẩn với URL và Fallback
425
+ </h3>
426
+ </div>
427
+ </div>
428
+ <p className="text-xs text-muted-foreground leading-relaxed">
429
+ Hầu hết các trường hợp bạn chỉ có một URL hình ảnh và một cái
430
+ tên. Macro tự động hiển thị ảnh, nếu ảnh lỗi thì tự sinh chữ
431
+ viết tắt dựa trên tên cực kỳ tiện lợi không cần viết nhiều
432
+ code.
433
+ </p>
434
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
435
+ <AvatarPreset
436
+ size={globalSize === "sm" ? "md" : "lg"}
437
+ src="https://github.com/shadcn.png"
438
+ alt="Shadcn"
439
+ />
440
+ </div>
441
+ </div>
471
442
 
472
- {/* ── Story 2: Micro wins ── */}
473
- <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
474
- <div className="flex items-start gap-3">
475
- <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
476
- <LayersIcon className="size-4" aria-hidden="true" />
477
- </span>
478
- <div>
479
- <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
480
- Story 2 · Dùng Micro
481
- </p>
482
- <h3 className="mt-0.5 text-sm font-semibold text-foreground">
483
- Layout Fallback phức tạp hoặc tích hợp Badge đặc thù
484
- </h3>
485
- </div>
486
- </div>
487
- <p className="text-xs text-muted-foreground leading-relaxed">
488
- Khi bạn muốn Fallback một Icon thay Text, hoặc muốn đính
489
- kèm một Badge tùy chỉnh hoàn toàn tự do (như icon viền, thông
490
- báo tin nhắn), bạn phải dùng Primitive để lắp ghép.
491
- </p>
492
- <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
493
- <Avatar size={globalSize === "sm" ? "md" : "lg"}>
494
- <AvatarImage src="/broken.png" alt="Avatar" />
495
- <AvatarFallback>
496
- <UserIcon className="size-1/2 text-muted-foreground" />
497
- </AvatarFallback>
498
- <AvatarBadge className="bg-blue-500">
499
- <CheckIcon className="size-2 text-white" />
500
- </AvatarBadge>
501
- </Avatar>
502
- </div>
503
- </div>
504
- </div>
505
- </ExampleSection>
443
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
444
+ <div className="flex items-start gap-3">
445
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
446
+ <LayersIcon className="size-4" aria-hidden="true" />
447
+ </span>
448
+ <div>
449
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
450
+ Story 2 · Dùng Micro
451
+ </p>
452
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
453
+ Layout Fallback phức tạp hoặc tích hợp Badge đặc thù
454
+ </h3>
455
+ </div>
456
+ </div>
457
+ <p className="text-xs text-muted-foreground leading-relaxed">
458
+ Khi bạn muốn Fallback là một Icon thay vì Text, hoặc muốn đính
459
+ kèm một Badge tùy chỉnh hoàn toàn tự do (như icon viền, thông
460
+ báo tin nhắn), bạn phải dùng Primitive để lắp ghép.
461
+ </p>
462
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
463
+ <Avatar size={globalSize === "sm" ? "md" : "lg"}>
464
+ <AvatarImage src="/broken.png" alt="Avatar" />
465
+ <AvatarFallback>
466
+ <UserIcon className="size-1/2 text-muted-foreground" />
467
+ </AvatarFallback>
468
+ <AvatarBadge className="bg-blue-500">
469
+ <CheckIcon className="size-2 text-white" />
470
+ </AvatarBadge>
471
+ </Avatar>
472
+ </div>
473
+ </div>
474
+ </div>
475
+ </>
476
+ } />
506
477
  </ExampleGrid>
507
478
  </div>
508
479
  );
509
480
  }
510
481
 
511
- // ──────────────────────────────────────────────────────────
512
- // SECTION 3: Entry point
513
- // ──────────────────────────────────────────────────────────
514
482
  export default function AvatarShowcase() {
515
483
  const { size: globalSize } = useDevContext();
516
484
  return (
517
485
  <Showcase
518
486
  title="Avatar"
519
487
  description="Hiển thị hình ảnh đại diện của người dùng hoặc các thực thể khác."
520
- generalConcept={
488
+ guideline={
521
489
  <ShowcaseDocs>
522
490
  <DocsP>
523
491
  Dùng để hiển thị hình ảnh đại diện cho người dùng, nhóm hoặc tổ
@@ -526,14 +494,8 @@ export default function AvatarShowcase() {
526
494
  </DocsP>
527
495
  </ShowcaseDocs>
528
496
  }
529
- tabs={[
530
- {
531
- label: "Micro (Primitive)",
532
- content: <AvatarMicroShowcase globalSize={globalSize} /> },
533
- {
534
- label: "Macro (Preset)",
535
- content: <AvatarMacroShowcase globalSize={globalSize} /> },
536
- ]}
497
+ micro={{ content: <AvatarMicroShowcase globalSize={globalSize} /> }}
498
+ macro={{ content: <AvatarMacroShowcase globalSize={globalSize} /> }}
537
499
  />
538
500
  );
539
501
  }