gladvn 0.2.14

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