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
@@ -30,25 +30,19 @@ import { useDevContext } from "../../dev/components/dev-context";
30
30
  import {
31
31
  DocsP,
32
32
  ExampleGrid,
33
- ExampleSection,
33
+ ShowcaseExample,
34
34
  Showcase,
35
35
  ShowcaseDocs
36
36
  } from "../../dev/components/showcase";
37
37
  import { type Size } from "../../lib/types";
38
38
 
39
- // ──────────────────────────────────────────────────────────
40
- // SECTION 1: Macro Content (không export)
41
- // ──────────────────────────────────────────────────────────
42
39
  function AlertDialogMacroShowcase({ globalSize }: { globalSize: Size }) {
43
40
  const [controlledOpen, setControlledOpen] = useState(false);
44
41
 
45
42
  return (
46
- <div className="space-y-10 mt-6">
43
+ <div className="space-y-10">
47
44
  <ExampleGrid>
48
- <ExampleSection
49
- label="Hành Động Nguy Danger (Destructive)"
50
- description="Sử dụng actionColor='destructive' để tạo nút hành động nguy hiểm."
51
- codeString={`<AlertDialogPreset
45
+ <ShowcaseExample title="Hành Động Nguy Danger (Destructive)" description="Sử dụng actionColor='destructive' để tạo nút hành động nguy hiểm." code={`<AlertDialogPreset
52
46
  trigger={
53
47
  <Button variant="outline" color="destructive">
54
48
  Xoá Tài Khoản
@@ -59,58 +53,54 @@ function AlertDialogMacroShowcase({ globalSize }: { globalSize: Size }) {
59
53
  cancelLabel="Huỷ"
60
54
  actionLabel="Xoá"
61
55
  actionColor="destructive"
62
- onAction={() => console.log("Deleted!")}
63
- />`}
64
- >
65
- <AlertDialogPreset
66
- size={globalSize}
67
- trigger={
68
- <Button variant="outline" color="destructive" size={globalSize}>
69
- Xoá Tài Khoản
70
- </Button>
71
- }
72
- title="Bạn có chắc chắn muốn xoá?"
73
- description="Hành động này không thể hoàn tác. Tài khoản và toàn bộ dữ liệu của bạn trên hệ thống sẽ bị xoá vĩnh viễn."
74
- cancelLabel="Huỷ"
75
- actionLabel="Xoá"
76
- actionColor="destructive"
77
- onAction={() => console.log("Deleted!")}
78
- />
79
- </ExampleSection>
80
-
81
- <ExampleSection
82
- label="Xác Nhận Tiêu Chuẩn"
83
- description="Dialog xác nhận thông thường chỉ với Text."
84
- codeString={`<AlertDialogPreset
56
+ onAction={() => console.log("Đã xoá!")}
57
+ />`} preview={
58
+ <>
59
+ <AlertDialogPreset
60
+ size={globalSize}
61
+ trigger={
62
+ <Button variant="outline" color="destructive" size={globalSize}>
63
+ Xoá Tài Khoản
64
+ </Button>
65
+ }
66
+ title="Bạn có chắc chắn muốn xoá?"
67
+ description="Hành động này không thể hoàn tác. Tài khoản và toàn bộ dữ liệu của bạn trên hệ thống sẽ bị xoá vĩnh viễn."
68
+ cancelLabel="Huỷ"
69
+ actionLabel="Xoá"
70
+ actionColor="destructive"
71
+ onAction={() => console.log("Đã xoá!")}
72
+ />
73
+ </>
74
+ } />
75
+
76
+ <ShowcaseExample title="Xác Nhận Tiêu Chuẩn" description="Dialog xác nhận thông thường chỉ với Text." code={`<AlertDialogPreset
85
77
  trigger={<Button variant="outline">Đăng Xuất</Button>}
86
78
  title="Đăng xuất khỏi tài khoản?"
87
79
  description="Bạn sẽ cần nhập lại thông tin đăng nhập để truy cập vào tài khoản."
88
80
  cancelLabel="Ở Lại"
89
81
  actionLabel="Đăng Xuất"
90
82
  onAction={() => console.log("Logged out!")}
91
- />`}
92
- >
93
- <AlertDialogPreset
94
- size={globalSize}
95
- trigger={
96
- <Button variant="outline" size={globalSize}>
97
- Đăng Xuất
98
- </Button>
99
- }
100
- title="Đăng xuất khỏi tài khoản?"
101
- description="Bạn sẽ cần nhập lại thông tin đăng nhập để truy cập vào tài khoản."
102
- cancelLabel="Ở Lại"
103
- actionLabel="Đăng Xuất"
104
- onAction={() => console.log("Logged out!")}
105
- />
106
- </ExampleSection>
83
+ />`} preview={
84
+ <>
85
+ <AlertDialogPreset
86
+ size={globalSize}
87
+ trigger={
88
+ <Button variant="outline" size={globalSize}>
89
+ Đăng Xuất
90
+ </Button>
91
+ }
92
+ title="Đăng xuất khỏi tài khoản?"
93
+ description="Bạn sẽ cần nhập lại thông tin đăng nhập để truy cập vào tài khoản."
94
+ cancelLabel="Ở Lại"
95
+ actionLabel="Đăng Xuất"
96
+ onAction={() => console.log("Logged out!")}
97
+ />
98
+ </>
99
+ } />
107
100
  </ExampleGrid>
108
101
 
109
102
  <ExampleGrid>
110
- <ExampleSection
111
- label="Kèm Media (Icon/Image)"
112
- description="Tự động chia cột Flexbox Side-by-Side khi truyền prop 'icon'."
113
- codeString={`<AlertDialogPreset
103
+ <ShowcaseExample title="Kèm Media (Icon/Image)" description="Tự động chia cột Flexbox Side-by-Side khi truyền prop 'icon'." code={`<AlertDialogPreset
114
104
  trigger={
115
105
  <Button variant="outline" color="warning">
116
106
  Thu Hồi Quyền
@@ -127,33 +117,31 @@ function AlertDialogMacroShowcase({ globalSize }: { globalSize: Size }) {
127
117
  actionLabel="Thu Hồi"
128
118
  actionColor="warning"
129
119
  onAction={() => console.log("Revoked!")}
130
- />`}
131
- >
132
- <AlertDialogPreset
133
- size={globalSize}
134
- trigger={
135
- <Button variant="outline" color="warning" size={globalSize}>
136
- Thu Hồi Quyền
137
- </Button>
138
- }
139
- icon={
140
- <div className="flex size-full items-center justify-center rounded-full bg-warning/10">
141
- <ShieldAlertIcon className="text-warning" />
142
- </div>
143
- }
144
- title="Thu hồi quyền truy cập API?"
145
- description="Tất cả các ứng dụng đang sử dụng API key này sẽ bị mất quyền truy cập ngay lập tức."
146
- cancelLabel="Giữ Lại"
147
- actionLabel="Thu Hồi"
148
- actionColor="warning"
149
- onAction={() => console.log("Revoked!")}
150
- />
151
- </ExampleSection>
152
-
153
- <ExampleSection
154
- label="Trạng Thái Controlled"
155
- description="Quản lý trạng thái đóng mở thông qua React State thay vì dùng prop Trigger."
156
- codeString={`const [controlledOpen, setControlledOpen] = useState(false);
120
+ />`} preview={
121
+ <>
122
+ <AlertDialogPreset
123
+ size={globalSize}
124
+ trigger={
125
+ <Button variant="outline" color="warning" size={globalSize}>
126
+ Thu Hồi Quyền
127
+ </Button>
128
+ }
129
+ icon={
130
+ <div className="flex size-full items-center justify-center rounded-full bg-warning/10">
131
+ <ShieldAlertIcon className="text-warning" />
132
+ </div>
133
+ }
134
+ title="Thu hồi quyền truy cập API?"
135
+ description="Tất cả các ứng dụng đang sử dụng API key này sẽ bị mất quyền truy cập ngay lập tức."
136
+ cancelLabel="Giữ Lại"
137
+ actionLabel="Thu Hồi"
138
+ actionColor="warning"
139
+ onAction={() => console.log("Revoked!")}
140
+ />
141
+ </>
142
+ } />
143
+
144
+ <ShowcaseExample title="Trạng Thái Controlled" description="Quản lý trạng thái đóng mở thông qua React State thay vì dùng prop Trigger." code={`const [controlledOpen, setControlledOpen] = useState(false);
157
145
  return (
158
146
  <>
159
147
  <Button variant="outline" color="info" onClick={() => setControlledOpen(true)}>
@@ -171,43 +159,41 @@ return (
171
159
  onAction={() => console.log("Airplane mode on!")}
172
160
  />
173
161
  </>
174
- );`}
175
- >
176
- <div className="flex w-full flex-col items-center gap-3">
177
- <p className="text-xs text-muted-foreground">
178
- State:{" "}
179
- <code className="rounded bg-muted px-1.5 py-0.5 text-xs font-mono">
180
- {controlledOpen ? "true" : "false"}
181
- </code>
182
- </p>
183
- <Button
184
- variant="outline"
185
- color="info"
186
- size={globalSize}
187
- onClick={() => setControlledOpen(true)}
188
- >
189
- Bật Chế Độ Máy Bay
190
- </Button>
191
- <AlertDialogPreset
192
- open={controlledOpen}
193
- onOpenChange={setControlledOpen}
194
- size={globalSize}
195
- title="Bật chế độ máy bay?"
196
- description="Tất cả các kết nối mạng bao gồm Wi-Fi và Bluetooth sẽ bị ngắt."
197
- cancelLabel="Huỷ"
198
- actionLabel="Đồng Ý"
199
- actionColor="info"
200
- onAction={() => console.log("Airplane mode on!")}
201
- />
202
- </div>
203
- </ExampleSection>
162
+ );`} preview={
163
+ <>
164
+ <div className="flex w-full flex-col items-center gap-3">
165
+ <p className="text-xs text-muted-foreground">
166
+ State:{" "}
167
+ <code className="rounded bg-muted px-1.5 py-0.5 text-xs font-mono">
168
+ {controlledOpen ? "true" : "false"}
169
+ </code>
170
+ </p>
171
+ <Button
172
+ variant="outline"
173
+ color="info"
174
+ size={globalSize}
175
+ onClick={() => setControlledOpen(true)}
176
+ >
177
+ Bật Chế Độ Máy Bay
178
+ </Button>
179
+ <AlertDialogPreset
180
+ open={controlledOpen}
181
+ onOpenChange={setControlledOpen}
182
+ size={globalSize}
183
+ title="Bật chế độ máy bay?"
184
+ description="Tất cả các kết nối mạng bao gồm Wi-Fi và Bluetooth sẽ bị ngắt."
185
+ cancelLabel="Huỷ"
186
+ actionLabel="Đồng Ý"
187
+ actionColor="info"
188
+ onAction={() => console.log("Airplane mode on!")}
189
+ />
190
+ </div>
191
+ </>
192
+ } />
204
193
  </ExampleGrid>
205
194
 
206
195
  <ExampleGrid>
207
- <ExampleSection
208
- label="Custom Button Variants"
209
- description="Tuỳ chỉnh variant cho cả nút Action (soft) và Cancel (ghost) thông qua actionVariant/cancelVariant."
210
- codeString={`<AlertDialogPreset
196
+ <ShowcaseExample title="Custom Button Variants" description="Tuỳ chỉnh variant cho cả nút Action (soft) và Cancel (ghost) thông qua actionVariant/cancelVariant." code={`<AlertDialogPreset
211
197
  trigger={
212
198
  <Button variant="outline">Custom Variants</Button>
213
199
  }
@@ -224,35 +210,33 @@ return (
224
210
  actionColor="info"
225
211
  actionVariant="soft"
226
212
  onAction={() => console.log("Feedback sent!")}
227
- />`}
228
- >
229
- <AlertDialogPreset
230
- size={globalSize}
231
- trigger={
232
- <Button variant="outline" size={globalSize}>
233
- Custom Variants
234
- </Button>
235
- }
236
- icon={
237
- <div className="flex size-full items-center justify-center rounded-full bg-info/10">
238
- <MailWarningIcon className="text-info" />
239
- </div>
240
- }
241
- title="Gửi phản hồi?"
242
- description="Phản hồi của bạn sẽ được gửi ẩn danh tới đội ngũ phát triển."
243
- cancelLabel="Bỏ qua"
244
- cancelVariant="ghost"
245
- actionLabel="Gửi"
246
- actionColor="info"
247
- actionVariant="soft"
248
- onAction={() => console.log("Feedback sent!")}
249
- />
250
- </ExampleSection>
251
-
252
- <ExampleSection
253
- label="Children (Nội dung bổ sung)"
254
- description="Prop children cho phép chèn thêm nội dung tuỳ ý vào phần Header."
255
- codeString={`<AlertDialogPreset
213
+ />`} preview={
214
+ <>
215
+ <AlertDialogPreset
216
+ size={globalSize}
217
+ trigger={
218
+ <Button variant="outline" size={globalSize}>
219
+ Custom Variants
220
+ </Button>
221
+ }
222
+ icon={
223
+ <div className="flex size-full items-center justify-center rounded-full bg-info/10">
224
+ <MailWarningIcon className="text-info" />
225
+ </div>
226
+ }
227
+ title="Gửi phản hồi?"
228
+ description="Phản hồi của bạn sẽ được gửi ẩn danh tới đội ngũ phát triển."
229
+ cancelLabel="Bỏ qua"
230
+ cancelVariant="ghost"
231
+ actionLabel="Gửi"
232
+ actionColor="info"
233
+ actionVariant="soft"
234
+ onAction={() => console.log("Feedback sent!")}
235
+ />
236
+ </>
237
+ } />
238
+
239
+ <ShowcaseExample title="Children (Nội dung bổ sung)" description="Prop children cho phép chèn thêm nội dung tuỳ ý vào phần Header." code={`<AlertDialogPreset
256
240
  trigger={
257
241
  <Button variant="outline" color="warning">
258
242
  Báo Cáo Lỗi
@@ -270,36 +254,34 @@ return (
270
254
  <p>Timestamp: 2026-07-05T14:30:00Z</p>
271
255
  <p>Module: api/gateway</p>
272
256
  </div>
273
- </AlertDialogPreset>`}
274
- >
275
- <AlertDialogPreset
276
- size={globalSize}
277
- trigger={
278
- <Button variant="outline" color="warning" size={globalSize}>
279
- Báo Cáo Lỗi
280
- </Button>
281
- }
282
- title="Báo cáo lỗi hệ thống"
283
- description="Vui lòng kiểm tra thông tin lỗi bên dưới trước khi gửi."
284
- cancelLabel="Huỷ"
285
- actionLabel="Gửi Báo Cáo"
286
- actionColor="warning"
287
- onAction={() => console.log("Report sent!")}
288
- >
289
- <div className="mt-2 rounded-md border border-border bg-muted/50 p-3 font-mono text-xs text-muted-foreground">
290
- <p>Error Code: ERR_NETWORK_TIMEOUT</p>
291
- <p>Timestamp: 2026-07-05T14:30:00Z</p>
292
- <p>Module: api/gateway</p>
293
- </div>
294
- </AlertDialogPreset>
295
- </ExampleSection>
257
+ </AlertDialogPreset>`} preview={
258
+ <>
259
+ <AlertDialogPreset
260
+ size={globalSize}
261
+ trigger={
262
+ <Button variant="outline" color="warning" size={globalSize}>
263
+ Báo Cáo Lỗi
264
+ </Button>
265
+ }
266
+ title="Báo cáo lỗi hệ thống"
267
+ description="Vui lòng kiểm tra thông tin lỗi bên dưới trước khi gửi."
268
+ cancelLabel="Huỷ"
269
+ actionLabel="Gửi Báo Cáo"
270
+ actionColor="warning"
271
+ onAction={() => console.log("Report sent!")}
272
+ >
273
+ <div className="mt-2 rounded-md border border-border bg-muted/50 p-3 font-mono text-xs text-muted-foreground">
274
+ <p>Error Code: ERR_NETWORK_TIMEOUT</p>
275
+ <p>Timestamp: 2026-07-05T14:30:00Z</p>
276
+ <p>Module: api/gateway</p>
277
+ </div>
278
+ </AlertDialogPreset>
279
+ </>
280
+ } />
296
281
  </ExampleGrid>
297
282
 
298
283
  <ExampleGrid>
299
- <ExampleSection
300
- label="Giao Diện Nhỏ (Compact)"
301
- description="Khi dùng size='sm', nội dung sẽ được căn giữa và footer tự động dàn hàng ngang 2 cột."
302
- codeString={`<AlertDialogPreset
284
+ <ShowcaseExample title="Giao Diện Nhỏ (Compact)" description="Khi dùng size='sm', nội dung sẽ được căn giữa và footer tự động dàn hàng ngang 2 cột." code={`<AlertDialogPreset
303
285
  size="sm"
304
286
  trigger={
305
287
  <Button variant="outline">Xác Nhận Nhanh</Button>
@@ -313,26 +295,27 @@ return (
313
295
  description="Đây là dialog dạng nhỏ, phù hợp cho các thao tác nhanh với 2 nút nằm ngang."
314
296
  cancelLabel="Không"
315
297
  actionLabel="Có"
316
- />`}
317
- >
318
- <AlertDialogPreset
319
- size="sm"
320
- trigger={
321
- <Button variant="outline" size={globalSize}>
322
- Xác Nhận Nhanh
323
- </Button>
324
- }
325
- icon={
326
- <div className="flex size-full items-center justify-center rounded-full bg-muted">
327
- <InfoIcon />
328
- </div>
329
- }
330
- title="Xác nhận hành động?"
331
- description="Đây là dialog dạng nhỏ, phù hợp cho các thao tác nhanh với 2 nút nằm ngang."
332
- cancelLabel="Không"
333
- actionLabel="Có"
334
- />
335
- </ExampleSection>
298
+ />`} preview={
299
+ <>
300
+ <AlertDialogPreset
301
+ size="sm"
302
+ trigger={
303
+ <Button variant="outline" size={globalSize}>
304
+ Xác Nhận Nhanh
305
+ </Button>
306
+ }
307
+ icon={
308
+ <div className="flex size-full items-center justify-center rounded-full bg-muted">
309
+ <InfoIcon />
310
+ </div>
311
+ }
312
+ title="Xác nhận hành động?"
313
+ description="Đây là dialog dạng nhỏ, phù hợp cho các thao tác nhanh với 2 nút nằm ngang."
314
+ cancelLabel="Không"
315
+ actionLabel="Có"
316
+ />
317
+ </>
318
+ } />
336
319
  </ExampleGrid>
337
320
  </div>
338
321
  );
@@ -343,12 +326,9 @@ return (
343
326
  // ──────────────────────────────────────────────────────────
344
327
  function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
345
328
  return (
346
- <div className="space-y-10 mt-6">
329
+ <div className="space-y-10">
347
330
  <ExampleGrid>
348
- <ExampleSection
349
- label="Sử dụng Cơ bản"
350
- description="Lắp ráp thủ công các khối Header, Title, Description, Footer."
351
- codeString={`<AlertDialog>
331
+ <ShowcaseExample title="Sử dụng Cơ bản" description="Lắp ráp thủ công các khối Header, Title, Description, Footer." code={`<AlertDialog>
352
332
  <AlertDialogTrigger
353
333
  render={
354
334
  <Button variant="outline">Mở Dialog Trắng</Button>
@@ -372,42 +352,40 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
372
352
  </AlertDialogFooter>
373
353
  </AlertDialogContent>
374
354
 
375
- </AlertDialog>`}
376
- >
377
- <AlertDialog>
378
- <AlertDialogTrigger
379
- render={
380
- <Button variant="outline" size={globalSize}>
381
- Mở Dialog Trắng
382
- </Button>
383
- }
384
- />
385
-
386
- <AlertDialogContent size={globalSize}>
387
- <AlertDialogHeader>
388
- <AlertDialogTitle>Cấu trúc nguyên thuỷ</AlertDialogTitle>
389
- <AlertDialogDescription>
390
- Không có bất kỳ layout "thần thánh" nào ép buộc ở đây. Các
391
- thành phần chỉ xếp dọc (flex-col) mặc định.
392
- </AlertDialogDescription>
393
- </AlertDialogHeader>
394
- <AlertDialogFooter>
395
- <AlertDialogCancel size={globalSize}>
396
- Huỷ bỏ
397
- </AlertDialogCancel>
398
- <AlertDialogAction size={globalSize}>
399
- Tiếp tục
400
- </AlertDialogAction>
401
- </AlertDialogFooter>
402
- </AlertDialogContent>
403
-
404
- </AlertDialog>
405
- </ExampleSection>
406
-
407
- <ExampleSection
408
- label="Tự Do Custom Layout"
409
- description="Bởi vì Micro component rất 'dumb', bạn có thể tự chèn thẻ div, custom flexbox để làm ra bất kỳ giao diện nào."
410
- codeString={`<AlertDialog>
355
+ </AlertDialog>`} preview={
356
+ <>
357
+ <AlertDialog>
358
+ <AlertDialogTrigger
359
+ render={
360
+ <Button variant="outline" size={globalSize}>
361
+ Mở Dialog Trắng
362
+ </Button>
363
+ }
364
+ />
365
+
366
+ <AlertDialogContent size={globalSize}>
367
+ <AlertDialogHeader>
368
+ <AlertDialogTitle>Cấu trúc nguyên thuỷ</AlertDialogTitle>
369
+ <AlertDialogDescription>
370
+ Không có bất kỳ layout "thần thánh" nào ép buộc ở đây. Các
371
+ thành phần chỉ xếp dọc (flex-col) mặc định.
372
+ </AlertDialogDescription>
373
+ </AlertDialogHeader>
374
+ <AlertDialogFooter>
375
+ <AlertDialogCancel size={globalSize}>
376
+ Huỷ bỏ
377
+ </AlertDialogCancel>
378
+ <AlertDialogAction size={globalSize}>
379
+ Tiếp tục
380
+ </AlertDialogAction>
381
+ </AlertDialogFooter>
382
+ </AlertDialogContent>
383
+
384
+ </AlertDialog>
385
+ </>
386
+ } />
387
+
388
+ <ShowcaseExample title="Tự Do Custom Layout" description="Bởi vì Micro component rất 'dumb', bạn có thể tự chèn thẻ div, custom flexbox để làm ra bất kỳ giao diện nào." code={`<AlertDialog>
411
389
  <AlertDialogTrigger
412
390
  render={
413
391
  <Button variant="outline" color="warning">
@@ -436,49 +414,47 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
436
414
  </AlertDialogFooter>
437
415
  </AlertDialogContent>
438
416
 
439
- </AlertDialog>`}
440
- >
441
- <AlertDialog>
442
- <AlertDialogTrigger
443
- render={
444
- <Button variant="outline" color="warning" size={globalSize}>
445
- Giao Diện Custom
446
- </Button>
447
- }
448
- />
449
-
450
- <AlertDialogContent
451
- size={globalSize}
452
- className="border-warning/50"
453
- >
454
- <div className="flex flex-col-reverse items-center justify-center gap-4 py-4 sm:flex-row">
455
- <div className="size-16 rounded-lg bg-warning/20 border border-warning" />
456
- <AlertDialogHeader className="sm:text-left">
457
- <AlertDialogTitle className="text-warning">
458
- Cảnh báo Tùy chỉnh
459
- </AlertDialogTitle>
460
- <AlertDialogDescription>
461
- Icon đang nằm bên trái, hoặc có thể dời sang phải tuỳ ý
462
- bạn vì bạn đang kiểm soát HTML.
463
- </AlertDialogDescription>
464
- </AlertDialogHeader>
465
- </div>
466
- <AlertDialogFooter className="border-t-0 bg-transparent">
467
- <AlertDialogCancel size={globalSize} className="w-full">
468
- Tôi đã hiểu
469
- </AlertDialogCancel>
470
- </AlertDialogFooter>
471
- </AlertDialogContent>
472
-
473
- </AlertDialog>
474
- </ExampleSection>
417
+ </AlertDialog>`} preview={
418
+ <>
419
+ <AlertDialog>
420
+ <AlertDialogTrigger
421
+ render={
422
+ <Button variant="outline" color="warning" size={globalSize}>
423
+ Giao Diện Custom
424
+ </Button>
425
+ }
426
+ />
427
+
428
+ <AlertDialogContent
429
+ size={globalSize}
430
+ className="border-warning/50"
431
+ >
432
+ <div className="flex flex-col-reverse items-center justify-center gap-4 py-4 sm:flex-row">
433
+ <div className="size-16 rounded-lg bg-warning/20 border border-warning" />
434
+ <AlertDialogHeader className="sm:text-left">
435
+ <AlertDialogTitle className="text-warning">
436
+ Cảnh báo Tùy chỉnh
437
+ </AlertDialogTitle>
438
+ <AlertDialogDescription>
439
+ Icon đang nằm bên trái, hoặc có thể dời sang phải tuỳ ý
440
+ bạn vì bạn đang kiểm soát HTML.
441
+ </AlertDialogDescription>
442
+ </AlertDialogHeader>
443
+ </div>
444
+ <AlertDialogFooter className="border-t-0 bg-transparent">
445
+ <AlertDialogCancel size={globalSize} className="w-full">
446
+ Tôi đã hiểu
447
+ </AlertDialogCancel>
448
+ </AlertDialogFooter>
449
+ </AlertDialogContent>
450
+
451
+ </AlertDialog>
452
+ </>
453
+ } />
475
454
  </ExampleGrid>
476
455
 
477
456
  <ExampleGrid>
478
- <ExampleSection
479
- label="AlertDialogMedia"
480
- description="Khối chứa Icon/Image, tự scale theo size của AlertDialogContent."
481
- codeString={`<AlertDialog>
457
+ <ShowcaseExample title="AlertDialogMedia" description="Khối chứa Icon/Image, tự scale theo size của AlertDialogContent." code={`<AlertDialog>
482
458
  <AlertDialogTrigger
483
459
  render={<Button variant="outline">Với Media</Button>}
484
460
  />
@@ -507,45 +483,43 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
507
483
  </AlertDialogFooter>
508
484
  </AlertDialogContent>
509
485
 
510
- </AlertDialog>`}
511
- >
512
- <AlertDialog>
513
- <AlertDialogTrigger
514
- render={
515
- <Button variant="outline" size={globalSize}>
516
- Với Media
517
- </Button>
518
- }
519
- />
520
-
521
- <AlertDialogContent size={globalSize}>
522
- <div className="flex flex-col gap-1.5 sm:flex-row sm:gap-4">
523
- <AlertDialogMedia className="mx-auto mb-2 shrink-0 sm:mx-0 sm:mb-0">
524
- <ShieldAlertIcon className="text-warning" />
525
- </AlertDialogMedia>
526
- <AlertDialogHeader>
527
- <AlertDialogTitle>Cảnh báo bảo mật</AlertDialogTitle>
528
- <AlertDialogDescription>
529
- AlertDialogMedia là khối div chứa icon, tự động scale kích
530
- thước theo data-size của AlertDialogContent.
531
- </AlertDialogDescription>
532
- </AlertDialogHeader>
533
- </div>
534
- <AlertDialogFooter>
535
- <AlertDialogCancel size={globalSize}>Huỷ</AlertDialogCancel>
536
- <AlertDialogAction size={globalSize} color="warning">
537
- Xác nhận
538
- </AlertDialogAction>
539
- </AlertDialogFooter>
540
- </AlertDialogContent>
541
-
542
- </AlertDialog>
543
- </ExampleSection>
544
-
545
- <ExampleSection
546
- label="AlertDialogClose"
547
- description="Primitive đóng dialog cơ bản, cho phép render bất kỳ element nào (không bị ép thành Button)."
548
- codeString={`<AlertDialog>
486
+ </AlertDialog>`} preview={
487
+ <>
488
+ <AlertDialog>
489
+ <AlertDialogTrigger
490
+ render={
491
+ <Button variant="outline" size={globalSize}>
492
+ Với Media
493
+ </Button>
494
+ }
495
+ />
496
+
497
+ <AlertDialogContent size={globalSize}>
498
+ <div className="flex flex-col gap-1.5 sm:flex-row sm:gap-4">
499
+ <AlertDialogMedia className="mx-auto mb-2 shrink-0 sm:mx-0 sm:mb-0">
500
+ <ShieldAlertIcon className="text-warning" />
501
+ </AlertDialogMedia>
502
+ <AlertDialogHeader>
503
+ <AlertDialogTitle>Cảnh báo bảo mật</AlertDialogTitle>
504
+ <AlertDialogDescription>
505
+ AlertDialogMedia là khối div chứa icon, tự động scale kích
506
+ thước theo data-size của AlertDialogContent.
507
+ </AlertDialogDescription>
508
+ </AlertDialogHeader>
509
+ </div>
510
+ <AlertDialogFooter>
511
+ <AlertDialogCancel size={globalSize}>Huỷ</AlertDialogCancel>
512
+ <AlertDialogAction size={globalSize} color="warning">
513
+ Xác nhận
514
+ </AlertDialogAction>
515
+ </AlertDialogFooter>
516
+ </AlertDialogContent>
517
+
518
+ </AlertDialog>
519
+ </>
520
+ } />
521
+
522
+ <ShowcaseExample title="AlertDialogClose" description="Primitive đóng dialog cơ bản, cho phép render bất kỳ element nào (không bị ép thành Button)." code={`<AlertDialog>
549
523
  <AlertDialogTrigger
550
524
  render={
551
525
  <Button variant="outline">Dialog Có Nút X</Button>
@@ -573,47 +547,45 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
573
547
  </AlertDialogFooter>
574
548
  </AlertDialogContent>
575
549
 
576
- </AlertDialog>`}
577
- >
578
- <AlertDialog>
579
- <AlertDialogTrigger
580
- render={
581
- <Button variant="outline" size={globalSize}>
582
- Dialog Có Nút X
583
- </Button>
584
- }
585
- />
586
-
587
- <AlertDialogContent size={globalSize}>
588
- <AlertDialogClose className="absolute top-3 right-3 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none">
589
- <XIcon className="size-4" />
590
- <span className="sr-only">Đóng</span>
591
- </AlertDialogClose>
592
- <AlertDialogHeader>
593
- <AlertDialogTitle>AlertDialogClose</AlertDialogTitle>
594
- <AlertDialogDescription>
595
- Khác với AlertDialogCancel (luôn render Button),
596
- AlertDialogClose là bare-bone — bạn có thể render icon X,
597
- link, hay bất kỳ thứ gì.
598
- </AlertDialogDescription>
599
- </AlertDialogHeader>
600
- <AlertDialogFooter>
601
- <AlertDialogCancel size={globalSize}>Huỷ</AlertDialogCancel>
602
- <AlertDialogAction size={globalSize}>
603
- Đồng ý
604
- </AlertDialogAction>
605
- </AlertDialogFooter>
606
- </AlertDialogContent>
607
-
608
- </AlertDialog>
609
- </ExampleSection>
550
+ </AlertDialog>`} preview={
551
+ <>
552
+ <AlertDialog>
553
+ <AlertDialogTrigger
554
+ render={
555
+ <Button variant="outline" size={globalSize}>
556
+ Dialog Có Nút X
557
+ </Button>
558
+ }
559
+ />
560
+
561
+ <AlertDialogContent size={globalSize}>
562
+ <AlertDialogClose className="absolute top-3 right-3 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none">
563
+ <XIcon className="size-4" />
564
+ <span className="sr-only">Đóng</span>
565
+ </AlertDialogClose>
566
+ <AlertDialogHeader>
567
+ <AlertDialogTitle>AlertDialogClose</AlertDialogTitle>
568
+ <AlertDialogDescription>
569
+ Khác với AlertDialogCancel (luôn render Button),
570
+ AlertDialogClose là bare-bone — bạn có thể render icon X,
571
+ link, hay bất kỳ thứ gì.
572
+ </AlertDialogDescription>
573
+ </AlertDialogHeader>
574
+ <AlertDialogFooter>
575
+ <AlertDialogCancel size={globalSize}>Huỷ</AlertDialogCancel>
576
+ <AlertDialogAction size={globalSize}>
577
+ Đồng ý
578
+ </AlertDialogAction>
579
+ </AlertDialogFooter>
580
+ </AlertDialogContent>
581
+
582
+ </AlertDialog>
583
+ </>
584
+ } />
610
585
  </ExampleGrid>
611
586
 
612
587
  <ExampleGrid>
613
- <ExampleSection
614
- label="Action Colors"
615
- description="AlertDialogAction hỗ trợ prop color để thay đổi ngữ nghĩa hành động."
616
- codeString={`<AlertDialog>
588
+ <ShowcaseExample title="Action Colors" description="AlertDialogAction hỗ trợ prop color để thay đổi ngữ nghĩa hành động." code={`<AlertDialog>
617
589
  <AlertDialogTrigger
618
590
  render={
619
591
  <Button variant="outline" color="destructive">
@@ -645,46 +617,44 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
645
617
  </AlertDialogFooter>
646
618
  </AlertDialogContent>
647
619
 
648
- </AlertDialog>`}
649
- >
650
- <AlertDialog>
651
- <AlertDialogTrigger
652
- render={
653
- <Button variant="outline" color="destructive" size={globalSize}>
654
- Xoá Tài Khoản
655
- </Button>
656
- }
657
- />
658
-
659
- <AlertDialogContent size={globalSize}>
660
- <div className="flex flex-col gap-1.5 sm:flex-row sm:gap-4">
661
- <AlertDialogMedia className="mx-auto mb-2 shrink-0 sm:mx-0 sm:mb-0">
662
- <TrashIcon className="text-destructive" />
663
- </AlertDialogMedia>
664
- <AlertDialogHeader>
665
- <AlertDialogTitle>
666
- Xoá tài khoản vĩnh viễn?
667
- </AlertDialogTitle>
668
- <AlertDialogDescription>
669
- Tất cả dữ liệu sẽ bị xoá và không thể khôi phục.
670
- </AlertDialogDescription>
671
- </AlertDialogHeader>
672
- </div>
673
- <AlertDialogFooter>
674
- <AlertDialogCancel size={globalSize}>Huỷ</AlertDialogCancel>
675
- <AlertDialogAction size={globalSize} color="destructive">
676
- Xoá vĩnh viễn
677
- </AlertDialogAction>
678
- </AlertDialogFooter>
679
- </AlertDialogContent>
680
-
681
- </AlertDialog>
682
- </ExampleSection>
683
-
684
- <ExampleSection
685
- label="Action & Cancel Variants"
686
- description="Tuỳ chỉnh variant cho cả Action (soft) và Cancel (ghost)."
687
- codeString={`<AlertDialog>
620
+ </AlertDialog>`} preview={
621
+ <>
622
+ <AlertDialog>
623
+ <AlertDialogTrigger
624
+ render={
625
+ <Button variant="outline" color="destructive" size={globalSize}>
626
+ Xoá Tài Khoản
627
+ </Button>
628
+ }
629
+ />
630
+
631
+ <AlertDialogContent size={globalSize}>
632
+ <div className="flex flex-col gap-1.5 sm:flex-row sm:gap-4">
633
+ <AlertDialogMedia className="mx-auto mb-2 shrink-0 sm:mx-0 sm:mb-0">
634
+ <TrashIcon className="text-destructive" />
635
+ </AlertDialogMedia>
636
+ <AlertDialogHeader>
637
+ <AlertDialogTitle>
638
+ Xoá tài khoản vĩnh viễn?
639
+ </AlertDialogTitle>
640
+ <AlertDialogDescription>
641
+ Tất cả dữ liệu sẽ bị xoá và không thể khôi phục.
642
+ </AlertDialogDescription>
643
+ </AlertDialogHeader>
644
+ </div>
645
+ <AlertDialogFooter>
646
+ <AlertDialogCancel size={globalSize}>Huỷ</AlertDialogCancel>
647
+ <AlertDialogAction size={globalSize} color="destructive">
648
+ Xoá vĩnh viễn
649
+ </AlertDialogAction>
650
+ </AlertDialogFooter>
651
+ </AlertDialogContent>
652
+
653
+ </AlertDialog>
654
+ </>
655
+ } />
656
+
657
+ <ShowcaseExample title="Action & Cancel Variants" description="Tuỳ chỉnh variant cho cả Action (soft) và Cancel (ghost)." code={`<AlertDialog>
688
658
  <AlertDialogTrigger
689
659
  render={
690
660
  <Button variant="outline">Custom Variants</Button>
@@ -714,55 +684,51 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
714
684
  </AlertDialogFooter>
715
685
  </AlertDialogContent>
716
686
 
717
- </AlertDialog>`}
718
- >
719
- <AlertDialog>
720
- <AlertDialogTrigger
721
- render={
722
- <Button variant="outline" size={globalSize}>
723
- Custom Variants
724
- </Button>
725
- }
726
- />
727
-
728
- <AlertDialogContent size={globalSize}>
729
- <div className="flex flex-col gap-1.5 sm:flex-row sm:gap-4">
730
- <AlertDialogMedia className="mx-auto mb-2 shrink-0 sm:mx-0 sm:mb-0">
731
- <LogOutIcon />
732
- </AlertDialogMedia>
733
- <AlertDialogHeader>
734
- <AlertDialogTitle>Đăng xuất?</AlertDialogTitle>
735
- <AlertDialogDescription>
736
- Phiên đăng nhập của bạn sẽ kết thúc. Bạn cần nhập lại mật
737
- khẩu để quay lại.
738
- </AlertDialogDescription>
739
- </AlertDialogHeader>
740
- </div>
741
- <AlertDialogFooter>
742
- <AlertDialogCancel size={globalSize} variant="ghost">
743
- Ở lại
744
- </AlertDialogCancel>
745
- <AlertDialogAction
746
- size={globalSize}
747
- variant="soft"
748
- color="info"
749
- >
750
- Đăng xuất
751
- </AlertDialogAction>
752
- </AlertDialogFooter>
753
- </AlertDialogContent>
754
-
755
- </AlertDialog>
756
- </ExampleSection>
687
+ </AlertDialog>`} preview={
688
+ <>
689
+ <AlertDialog>
690
+ <AlertDialogTrigger
691
+ render={
692
+ <Button variant="outline" size={globalSize}>
693
+ Custom Variants
694
+ </Button>
695
+ }
696
+ />
697
+
698
+ <AlertDialogContent size={globalSize}>
699
+ <div className="flex flex-col gap-1.5 sm:flex-row sm:gap-4">
700
+ <AlertDialogMedia className="mx-auto mb-2 shrink-0 sm:mx-0 sm:mb-0">
701
+ <LogOutIcon />
702
+ </AlertDialogMedia>
703
+ <AlertDialogHeader>
704
+ <AlertDialogTitle>Đăng xuất?</AlertDialogTitle>
705
+ <AlertDialogDescription>
706
+ Phiên đăng nhập của bạn sẽ kết thúc. Bạn cần nhập lại mật
707
+ khẩu để quay lại.
708
+ </AlertDialogDescription>
709
+ </AlertDialogHeader>
710
+ </div>
711
+ <AlertDialogFooter>
712
+ <AlertDialogCancel size={globalSize} variant="ghost">
713
+ Ở lại
714
+ </AlertDialogCancel>
715
+ <AlertDialogAction
716
+ size={globalSize}
717
+ variant="soft"
718
+ color="info"
719
+ >
720
+ Đăng xuất
721
+ </AlertDialogAction>
722
+ </AlertDialogFooter>
723
+ </AlertDialogContent>
724
+
725
+ </AlertDialog>
726
+ </>
727
+ } />
757
728
  </ExampleGrid>
758
729
 
759
730
  {/* ── Use Case Comparison ─────────────────────── */}
760
- <ExampleSection
761
- label="🧭 Use Case Comparison"
762
- description="Các kịch bản thực tế giúp bạn quyết định nên dùng Micro hay Macro."
763
- fullWidth
764
- codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
765
- {/* ── Story 1: Macro wins ── */}
731
+ <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">
766
732
  <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
767
733
  <div className="flex items-start gap-3">
768
734
  <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
@@ -819,7 +785,6 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
819
785
  </div>
820
786
  </div>
821
787
 
822
- {/* ── Story 2: Micro wins ── */}
823
788
  <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
824
789
  <div className="flex items-start gap-3">
825
790
  <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
@@ -890,130 +855,131 @@ function AlertDialogMicroShowcase({ globalSize }: { globalSize: Size }) {
890
855
  </p>
891
856
  </div>
892
857
  </div>
893
- </div>`}
894
- >
895
- <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
896
- {/* ── Story 1: Macro wins ── */}
897
- <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
898
- <div className="flex items-start gap-3">
899
- <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
900
- <ShieldAlertIcon className="size-4" aria-hidden="true" />
901
- </span>
902
- <div>
903
- <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
904
- Story 1 · Dùng Macro
905
- </p>
906
- <h3 className="mt-0.5 text-sm font-semibold text-foreground">
907
- Xác nhận chuẩn mực với Icon
908
- </h3>
909
- </div>
910
- </div>
911
-
912
- <p className="text-xs text-muted-foreground leading-relaxed">
913
- Bạn cần làm một dialog xác nhận xoá với layout Side-by-Side (Icon
914
- nằm bên trái trên màn hình lớn, nằm ở trên cùng trên màn hình
915
- nhỏ).
916
- </p>
917
-
918
- <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
919
- <AlertDialogPreset
920
- size="sm"
921
- trigger={
922
- <Button variant="outline" size="sm">
923
- Xem Demo
924
- </Button>
925
- }
926
- icon={
927
- <div className="flex size-full items-center justify-center rounded-full bg-muted">
928
- <InfoIcon />
929
- </div>
930
- }
931
- title="Xác nhận thao tác"
932
- description="Macro bọc mọi thứ vào một component duy nhất."
933
- cancelLabel="Huỷ"
934
- actionLabel="Tiếp tục"
935
- />
936
- </div>
937
-
938
- <div className="rounded-md border border-border border-green-500/20 bg-green-500/5 px-3 py-2">
939
- <p className="text-xs font-medium text-green-700 dark:text-green-400">
940
- ✅ Dùng <code className="font-mono">AlertDialogPreset</code> —
941
- Viết đúng 1 element. Tự động xử lý Grid/Flex responsive siêu
942
- phức tạp.
943
- </p>
944
- </div>
945
- </div>
946
-
947
- {/* ── Story 2: Micro wins ── */}
948
- <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
949
- <div className="flex items-start gap-3">
950
- <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
951
- <MessageSquareWarningIcon
952
- className="size-4"
953
- aria-hidden="true"
954
- />
955
- </span>
956
- <div>
957
- <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
958
- Story 2 · Dùng Micro
959
- </p>
960
- <h3 className="mt-0.5 text-sm font-semibold text-foreground">
961
- Custom Layout độc lạ
962
- </h3>
963
- </div>
964
- </div>
965
-
966
- <p className="text-xs text-muted-foreground leading-relaxed">
967
- Designer yêu cầu một Modal có Layout đặc thù: Image bự ở trên
968
- cùng, Text ở dưới, Footer có 3 nút. Không có bất kỳ Preset nào
969
- support layout này.
970
- </p>
971
-
972
- <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
973
- <AlertDialog>
974
- <AlertDialogTrigger
975
- render={
976
- <Button variant="outline" size="sm">
977
- Xem Demo
978
- </Button>
979
- }
980
- />
981
-
982
- <AlertDialogContent size="sm">
983
- <div className="h-24 w-full rounded-md bg-muted flex items-center justify-center text-xs text-muted-foreground">
984
- Custom Image
858
+ </div>`} preview={
859
+ <>
860
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
861
+ {/* ── Story 1: Macro wins ── */}
862
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
863
+ <div className="flex items-start gap-3">
864
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
865
+ <ShieldAlertIcon className="size-4" aria-hidden="true" />
866
+ </span>
867
+ <div>
868
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
869
+ Story 1 · Dùng Macro
870
+ </p>
871
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
872
+ Xác nhận chuẩn mực với Icon
873
+ </h3>
874
+ </div>
875
+ </div>
876
+
877
+ <p className="text-xs text-muted-foreground leading-relaxed">
878
+ Bạn cần làm một dialog xác nhận xoá với layout Side-by-Side (Icon
879
+ nằm bên trái trên màn hình lớn, nằm ở trên cùng trên màn hình
880
+ nhỏ).
881
+ </p>
882
+
883
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
884
+ <AlertDialogPreset
885
+ size="sm"
886
+ trigger={
887
+ <Button variant="outline" size="sm">
888
+ Xem Demo
889
+ </Button>
890
+ }
891
+ icon={
892
+ <div className="flex size-full items-center justify-center rounded-full bg-muted">
893
+ <InfoIcon />
894
+ </div>
895
+ }
896
+ title="Xác nhận thao tác"
897
+ description="Macro bọc mọi thứ vào một component duy nhất."
898
+ cancelLabel="Huỷ"
899
+ actionLabel="Tiếp tục"
900
+ />
901
+ </div>
902
+
903
+ <div className="rounded-md border border-border border-green-500/20 bg-green-500/5 px-3 py-2">
904
+ <p className="text-xs font-medium text-green-700 dark:text-green-400">
905
+ ✅ Dùng <code className="font-mono">AlertDialogPreset</code> —
906
+ Viết đúng 1 element. Tự động xử lý Grid/Flex responsive siêu
907
+ phức tạp.
908
+ </p>
909
+ </div>
985
910
  </div>
986
- <AlertDialogHeader>
987
- <AlertDialogTitle>Tùy biến 100%</AlertDialogTitle>
988
- </AlertDialogHeader>
989
- <AlertDialogFooter className="flex-col gap-2 sm:flex-col">
990
- <Button className="w-full">Action 1</Button>
991
- <Button
992
- color="secondary"
993
- variant="soft"
994
- className="w-full"
995
- >
996
- Action 2
997
- </Button>
998
- <AlertDialogCancel className="w-full">
999
- Cancel
1000
- </AlertDialogCancel>
1001
- </AlertDialogFooter>
1002
- </AlertDialogContent>
1003
-
1004
- </AlertDialog>
1005
- </div>
1006
911
 
1007
- <div className="rounded-md border border-border border-blue-500/20 bg-blue-500/5 px-3 py-2">
1008
- <p className="text-xs font-medium text-blue-700 dark:text-blue-400">
1009
- ✅ Dùng <code className="font-mono">AlertDialog</code> (Micro) —
1010
- Không bị ràng buộc bởi bất kỳ layout định sẵn nào. Lắp ráp thẻ
1011
- tự do.
1012
- </p>
1013
- </div>
1014
- </div>
1015
- </div>
1016
- </ExampleSection>
912
+ {/* ── Story 2: Micro wins ── */}
913
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
914
+ <div className="flex items-start gap-3">
915
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
916
+ <MessageSquareWarningIcon
917
+ className="size-4"
918
+ aria-hidden="true"
919
+ />
920
+ </span>
921
+ <div>
922
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
923
+ Story 2 · Dùng Micro
924
+ </p>
925
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
926
+ Custom Layout độc lạ
927
+ </h3>
928
+ </div>
929
+ </div>
930
+
931
+ <p className="text-xs text-muted-foreground leading-relaxed">
932
+ Designer yêu cầu một Modal có Layout đặc thù: Image bự ở trên
933
+ cùng, Text ở dưới, Footer có 3 nút. Không có bất kỳ Preset nào
934
+ support layout này.
935
+ </p>
936
+
937
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
938
+ <AlertDialog>
939
+ <AlertDialogTrigger
940
+ render={
941
+ <Button variant="outline" size="sm">
942
+ Xem Demo
943
+ </Button>
944
+ }
945
+ />
946
+
947
+ <AlertDialogContent size="sm">
948
+ <div className="h-24 w-full rounded-md bg-muted flex items-center justify-center text-xs text-muted-foreground">
949
+ Custom Image
950
+ </div>
951
+ <AlertDialogHeader>
952
+ <AlertDialogTitle>Tùy biến 100%</AlertDialogTitle>
953
+ </AlertDialogHeader>
954
+ <AlertDialogFooter className="flex-col gap-2 sm:flex-col">
955
+ <Button className="w-full">Action 1</Button>
956
+ <Button
957
+ color="secondary"
958
+ variant="soft"
959
+ className="w-full"
960
+ >
961
+ Action 2
962
+ </Button>
963
+ <AlertDialogCancel className="w-full">
964
+ Cancel
965
+ </AlertDialogCancel>
966
+ </AlertDialogFooter>
967
+ </AlertDialogContent>
968
+
969
+ </AlertDialog>
970
+ </div>
971
+
972
+ <div className="rounded-md border border-border border-blue-500/20 bg-blue-500/5 px-3 py-2">
973
+ <p className="text-xs font-medium text-blue-700 dark:text-blue-400">
974
+ ✅ Dùng <code className="font-mono">AlertDialog</code> (Micro) —
975
+ Không bị ràng buộc bởi bất kỳ layout định sẵn nào. Lắp ráp thẻ
976
+ tự do.
977
+ </p>
978
+ </div>
979
+ </div>
980
+ </div>
981
+ </>
982
+ } />
1017
983
  </div>
1018
984
  );
1019
985
  }
@@ -1027,7 +993,7 @@ export default function AlertDialogShowcase() {
1027
993
  <Showcase
1028
994
  title="Alert Dialog"
1029
995
  description="Dialog gián đoạn yêu cầu người dùng xác nhận các hành động quan trọng hoặc mang tính phá hủy."
1030
- generalConcept={
996
+ guideline={
1031
997
  <ShowcaseDocs>
1032
998
  <DocsP>
1033
999
  Dùng để làm gián đoạn người dùng với một thông báo hoặc xác nhận cực
@@ -1037,14 +1003,8 @@ export default function AlertDialogShowcase() {
1037
1003
  </DocsP>
1038
1004
  </ShowcaseDocs>
1039
1005
  }
1040
- tabs={[
1041
- {
1042
- label: "Micro (Primitive)",
1043
- content: <AlertDialogMicroShowcase globalSize={globalSize} /> },
1044
- {
1045
- label: "Macro (Preset)",
1046
- content: <AlertDialogMacroShowcase globalSize={globalSize} /> },
1047
- ]}
1006
+ micro={{ content: <AlertDialogMicroShowcase globalSize={globalSize} /> }}
1007
+ macro={{ content: <AlertDialogMacroShowcase globalSize={globalSize} /> }}
1048
1008
  />
1049
1009
  );
1050
1010
  }