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,611 @@
1
+ import { useDevContext } from "../../dev/components/dev-context";
2
+ import { zodResolver } from "@hookform/resolvers/zod";
3
+ import { CheckIcon, MinusIcon } from "lucide-react";
4
+ import { useState } from "react";
5
+ import { Controller, useForm } from "react-hook-form";
6
+ import * as z from "zod";
7
+
8
+ import {
9
+ DocsP,
10
+ ExampleGrid,
11
+ ExampleSection,
12
+ Showcase,
13
+ ShowcaseDocs,
14
+ } from "../../dev/components/showcase";
15
+ import { type Size } from "../../lib/types";
16
+
17
+ import { CheckboxPreset } from "../../components/macro/checkbox-preset";
18
+ import { Button } from "../../components/micro/button";
19
+ import { Checkbox, CheckboxIndicator } from "../../components/micro/checkbox";
20
+ import {
21
+ Field,
22
+ FieldDescription,
23
+ FieldError,
24
+ FieldLabel,
25
+ } from "../../components/micro/field";
26
+ import { Label } from "../../components/micro/label";
27
+
28
+ // ──────────────────────────────────────────────────────────
29
+ // RHF Form Demo (Macro)
30
+ // ──────────────────────────────────────────────────────────
31
+ const formSchema = z.object({
32
+ mobile: z.boolean().default(false).optional(),
33
+ });
34
+ type FormValues = z.infer<typeof formSchema>;
35
+
36
+ function CheckboxForm({ size }: { size: Size }) {
37
+ const form = useForm<FormValues>({
38
+ resolver: zodResolver(formSchema),
39
+ defaultValues: { mobile: false },
40
+ });
41
+
42
+ function onSubmit(values: FormValues) {
43
+ alert(JSON.stringify(values, null, 2));
44
+ }
45
+
46
+ return (
47
+ <form
48
+ onSubmit={form.handleSubmit(onSubmit)}
49
+ className="w-full max-w-sm space-y-6"
50
+ >
51
+ <Controller
52
+ control={form.control}
53
+ name="mobile"
54
+ render={({ field, fieldState }) => (
55
+ <CheckboxPreset
56
+ size={size}
57
+ label="Use mobile device"
58
+ description="Cho phép chúng tôi gửi thông báo đến thiết bị di động của bạn."
59
+ checked={field.value}
60
+ onCheckedChange={field.onChange}
61
+ errorMessage={fieldState.error?.message}
62
+ />
63
+ )}
64
+ />
65
+ <Button type="submit" size={size}>
66
+ Lưu cài đặt
67
+ </Button>
68
+ </form>
69
+ );
70
+ }
71
+
72
+ const rhfCode = `const formSchema = z.object({ mobile: z.boolean().default(false).optional() });
73
+
74
+ function CheckboxForm({ size }: { size: Size }) {
75
+ const form = useForm({
76
+ resolver: zodResolver(formSchema),
77
+ defaultValues: { mobile: false },
78
+ });
79
+
80
+ return (
81
+ <form onSubmit={form.handleSubmit(console.log)} className="space-y-6">
82
+ <Controller
83
+ control={form.control}
84
+ name="mobile"
85
+ render={({ field, fieldState }) => (
86
+ <CheckboxPreset
87
+ size={size}
88
+ label="Use mobile device"
89
+ description="Cho phép chúng tôi gửi thông báo đến thiết bị di động của bạn."
90
+ checked={field.value}
91
+ onCheckedChange={field.onChange}
92
+ errorMessage={fieldState.error?.message}
93
+ />
94
+ )}
95
+ />
96
+ <Button type="submit" size={size}>Submit</Button>
97
+ </form>
98
+ );
99
+ }`;
100
+
101
+ // ──────────────────────────────────────────────────────────
102
+ // SECTION 1: Macro Content
103
+ // ──────────────────────────────────────────────────────────
104
+ function CheckboxMacroShowcase({ globalSize }: { globalSize: Size }) {
105
+ const [checked, setChecked] = useState(false);
106
+
107
+ return (
108
+ <div className="space-y-10 mt-6">
109
+ <ExampleGrid>
110
+ <ExampleSection
111
+ label="Tiêu chuẩn"
112
+ description="Checkbox cơ bản kèm nhãn và mô tả."
113
+ codeString={`<CheckboxPreset
114
+ label="Đồng ý với điều khoản"
115
+ description="Bạn phải đồng ý với các điều khoản và điều kiện sử dụng."
116
+ className="w-full"
117
+ />
118
+ `}
119
+ >
120
+ <CheckboxPreset
121
+ size={globalSize}
122
+ label="Đồng ý với điều khoản"
123
+ description="Bạn phải đồng ý với các điều khoản và điều kiện sử dụng."
124
+ className="w-full"
125
+ />
126
+ </ExampleSection>
127
+
128
+ <ExampleSection
129
+ label="Trạng thái Lỗi (Error)"
130
+ description="Báo lỗi khi chưa check vào ô (thường dùng trong form)."
131
+ codeString={`<div className="w-full flex flex-col gap-6">
132
+ <CheckboxPreset
133
+ label="Xác nhận đủ 18 tuổi"
134
+ errorMessage="Bạn phải xác nhận đủ tuổi để tiếp tục."
135
+ />
136
+ </div>
137
+ `}
138
+ >
139
+ <div className="w-full flex flex-col gap-6">
140
+ <CheckboxPreset
141
+ size={globalSize}
142
+ label="Xác nhận đủ 18 tuổi"
143
+ errorMessage="Bạn phải xác nhận đủ tuổi để tiếp tục."
144
+ />
145
+ </div>
146
+ </ExampleSection>
147
+ </ExampleGrid>
148
+
149
+ <ExampleGrid>
150
+ <ExampleSection
151
+ label="Trạng thái Khóa (Disabled)"
152
+ description="Checkbox bị vô hiệu hóa, không thể click."
153
+ codeString={`<div className="w-full flex flex-col gap-6">
154
+ <CheckboxPreset
155
+ label="Đăng ký nhận bản tin"
156
+ description="Tính năng này đang được bảo trì."
157
+ disabled
158
+ />
159
+ <CheckboxPreset
160
+ label="Cho phép thu thập log"
161
+ description="Hệ thống mặc định thu thập log bảo mật."
162
+ defaultChecked
163
+ disabled
164
+ />
165
+ </div>
166
+ `}
167
+ >
168
+ <div className="w-full flex flex-col gap-6">
169
+ <CheckboxPreset
170
+ size={globalSize}
171
+ label="Đăng ký nhận bản tin"
172
+ description="Tính năng này đang được bảo trì."
173
+ disabled
174
+ />
175
+ <CheckboxPreset
176
+ size={globalSize}
177
+ label="Cho phép thu thập log"
178
+ description="Hệ thống mặc định thu thập log bảo mật."
179
+ defaultChecked
180
+ disabled
181
+ />
182
+ </div>
183
+ </ExampleSection>
184
+
185
+ <ExampleSection
186
+ label="React Node Label (Custom Content)"
187
+ description="Label có thể chứa các component React phức tạp như Badge."
188
+ codeString={`<CheckboxPreset
189
+ label={
190
+ <span className="flex items-center gap-2">
191
+ Tham gia chương trình BETA{" "}
192
+ <span className="rounded bg-primary/20 px-1.5 py-0.5 text-[10px] font-semibold text-primary">
193
+ NEW
194
+ </span>
195
+ </span>
196
+ }
197
+ description="Được trải nghiệm sớm các tính năng mới trước khi phát hành chính thức. Có thể xảy ra lỗi."
198
+ className="w-full"
199
+ />
200
+ `}
201
+ >
202
+ <CheckboxPreset
203
+ size={globalSize}
204
+ label={
205
+ <span className="flex items-center gap-2">
206
+ Tham gia chương trình BETA{" "}
207
+ <span className="rounded bg-primary/20 px-1.5 py-0.5 text-[10px] font-semibold text-primary">
208
+ NEW
209
+ </span>
210
+ </span>
211
+ }
212
+ description="Được trải nghiệm sớm các tính năng mới trước khi phát hành chính thức. Có thể xảy ra lỗi."
213
+ className="w-full"
214
+ />
215
+ </ExampleSection>
216
+ </ExampleGrid>
217
+
218
+ <ExampleGrid>
219
+ <ExampleSection
220
+ label="React State (Controlled Mode)"
221
+ description="Sử dụng biến state của React để điều khiển."
222
+ codeString={`const [checked, setChecked] = useState(false);
223
+
224
+ return (
225
+ <CheckboxPreset
226
+ checked={checked}
227
+ onCheckedChange={(c) => setChecked(!!c)}
228
+ label="Checkbox có kiểm soát"
229
+ description="React quản lý trạng thái của checkbox này."
230
+ />
231
+ );`}
232
+ >
233
+ <div className="w-full flex flex-col gap-4">
234
+ <CheckboxPreset
235
+ size={globalSize}
236
+ checked={checked}
237
+ onCheckedChange={(c) => setChecked(!!c)}
238
+ label="Checkbox có kiểm soát"
239
+ description="React quản lý trạng thái của checkbox này."
240
+ />
241
+ <p className="text-sm text-muted-foreground">
242
+ Giá trị hiện tại:{" "}
243
+ <span className="font-mono font-bold text-foreground">
244
+ {checked ? "TRUE" : "FALSE"}
245
+ </span>
246
+ </p>
247
+ </div>
248
+ </ExampleSection>
249
+
250
+ <ExampleSection
251
+ label="Tích hợp React Hook Form"
252
+ description="Dùng Controller của RHF để bọc CheckboxPreset."
253
+ codeString={rhfCode}
254
+ >
255
+ <CheckboxForm size={globalSize} />
256
+ </ExampleSection>
257
+ </ExampleGrid>
258
+ </div>
259
+ );
260
+ }
261
+
262
+ // ──────────────────────────────────────────────────────────
263
+ // SECTION 2: Micro Content
264
+ // ──────────────────────────────────────────────────────────
265
+ function CheckboxMicroShowcase({ globalSize }: { globalSize: Size }) {
266
+ const [checked, setChecked] = useState(false);
267
+
268
+ return (
269
+ <div className="space-y-10 mt-6">
270
+ <ExampleGrid>
271
+ <ExampleSection
272
+ label="Cơ bản (Primitive)"
273
+ description="Kết nối thủ công Checkbox với thẻ Label html."
274
+ codeString={`<div className="flex items-center gap-3">
275
+ <Checkbox id="cb-micro-default">
276
+ <CheckboxIndicator>
277
+ <CheckIcon />
278
+ </CheckboxIndicator>
279
+ </Checkbox>
280
+ <Label htmlFor="cb-micro-default" className="font-normal cursor-pointer">
281
+ Đồng ý với điều khoản
282
+ </Label>
283
+ </div>`}
284
+ >
285
+ <div className="flex items-center gap-3">
286
+ <Checkbox id="cb-micro-default" size={globalSize}>
287
+ <CheckboxIndicator>
288
+ <CheckIcon />
289
+ </CheckboxIndicator>
290
+ </Checkbox>
291
+ <Label
292
+ htmlFor="cb-micro-default"
293
+ className="font-normal cursor-pointer"
294
+ >
295
+ Đồng ý với điều khoản
296
+ </Label>
297
+ </div>
298
+ </ExampleSection>
299
+
300
+ <ExampleSection
301
+ label="Icon Tuỳ Biến (Custom Icon)"
302
+ description="Vì dùng Composition, bạn có thể truyền bất kỳ icon nào (VD: MinusIcon) vào Indicator."
303
+ codeString={`<div className="flex items-center gap-3">
304
+ <Checkbox id="cb-custom-icon">
305
+ <CheckboxIndicator>
306
+ <MinusIcon />
307
+ </CheckboxIndicator>
308
+ </Checkbox>
309
+ <Label htmlFor="cb-custom-icon" className="font-normal cursor-pointer">
310
+ Trạng thái vô định (Indeterminate)
311
+ </Label>
312
+ </div>`}
313
+ >
314
+ <div className="flex items-center gap-3">
315
+ <Checkbox id="cb-custom-icon" size={globalSize}>
316
+ <CheckboxIndicator>
317
+ <MinusIcon />
318
+ </CheckboxIndicator>
319
+ </Checkbox>
320
+ <Label
321
+ htmlFor="cb-custom-icon"
322
+ className="font-normal cursor-pointer"
323
+ >
324
+ Trạng thái vô định (Indeterminate)
325
+ </Label>
326
+ </div>
327
+ </ExampleSection>
328
+ </ExampleGrid>
329
+
330
+ <ExampleGrid>
331
+ <ExampleSection
332
+ label="Ghép nối với Field"
333
+ description="Lắp ráp thủ công các thành phần Field khi cần layout phức tạp."
334
+ codeString={`<Field className="flex items-start gap-3">
335
+ {/* 1 khoảng trắng vô hình để căn chỉnh cho Label và Checkbox thẳng hàng với nhau theo dòng chữ đầu tiên */}
336
+ <div className="flex items-center text-sm leading-snug group-data-[size=sm]/field:text-xs">
337
+ &#8203;
338
+ <Checkbox id="cb-field-micro">
339
+ <CheckboxIndicator><CheckIcon /></CheckboxIndicator>
340
+ </Checkbox>
341
+ </div>
342
+ <div className="grid gap-1.5 leading-none">
343
+ <FieldLabel htmlFor="cb-field-micro" className="font-medium cursor-pointer">
344
+ Lưu mật khẩu
345
+ </FieldLabel>
346
+ <FieldDescription>
347
+ Tự động đăng nhập vào lần sau.
348
+ </FieldDescription>
349
+ </div>
350
+ </Field>
351
+ `}
352
+ >
353
+ <Field className="flex items-start gap-3" data-size={globalSize}>
354
+ {/* 1 khoảng trắng vô hình để căn chỉnh cho Label và Checkbox thẳng hàng với nhau theo dòng chữ đầu tiên */}
355
+ <div className="flex items-center text-sm leading-snug group-data-[size=sm]/field:text-xs">
356
+ &#8203;
357
+ <Checkbox id="cb-field-micro" size={globalSize}>
358
+ <CheckboxIndicator>
359
+ <CheckIcon />
360
+ </CheckboxIndicator>
361
+ </Checkbox>
362
+ </div>
363
+ <div className="grid gap-1.5 leading-none">
364
+ <FieldLabel
365
+ htmlFor="cb-field-micro"
366
+ className="font-medium cursor-pointer"
367
+ >
368
+ Lưu mật khẩu
369
+ </FieldLabel>
370
+ <FieldDescription>
371
+ Tự động đăng nhập vào lần sau.
372
+ </FieldDescription>
373
+ </div>
374
+ </Field>
375
+ </ExampleSection>
376
+
377
+ <ExampleSection
378
+ label="Trạng thái Lỗi thủ công"
379
+ description="Tự gắn aria-invalid vào Checkbox và dùng FieldError."
380
+ codeString={`<Field className="flex flex-row items-start gap-3" data-invalid={true}>
381
+ <div className="flex items-center text-sm leading-snug group-data-[size=sm]/field:text-xs">
382
+ &#8203;
383
+ <Checkbox id="cb-err-micro" aria-invalid={true}>
384
+ <CheckboxIndicator><CheckIcon /></CheckboxIndicator>
385
+ </Checkbox>
386
+ </div>
387
+ <div className="grid gap-1.5 leading-none">
388
+ <FieldLabel htmlFor="cb-err-micro" className="font-medium cursor-pointer">Đồng ý quy định</FieldLabel>
389
+ <FieldError>Bắt buộc phải chọn ô này.</FieldError>
390
+ </div>
391
+ </Field>
392
+ `}
393
+ >
394
+ <Field
395
+ className="flex flex-row items-start gap-3"
396
+ data-invalid={true}
397
+ data-size={globalSize}
398
+ >
399
+ <div className="flex items-center text-sm leading-snug group-data-[size=sm]/field:text-xs">
400
+ &#8203;
401
+ <Checkbox id="cb-err-micro" size={globalSize} aria-invalid={true}>
402
+ <CheckboxIndicator>
403
+ <CheckIcon />
404
+ </CheckboxIndicator>
405
+ </Checkbox>
406
+ </div>
407
+ <div className="grid gap-1.5 leading-none">
408
+ <FieldLabel
409
+ htmlFor="cb-err-micro"
410
+ className="font-medium cursor-pointer"
411
+ >
412
+ Đồng ý quy định
413
+ </FieldLabel>
414
+ <FieldError>Bắt buộc phải chọn ô này.</FieldError>
415
+ </div>
416
+ </Field>
417
+ </ExampleSection>
418
+ </ExampleGrid>
419
+
420
+ <ExampleSection
421
+ label="🧭 Use Case Comparison"
422
+ description="So sánh nhanh khi nào dùng Micro và Macro."
423
+ fullWidth
424
+ codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
425
+ {/* Story 1: Macro wins */}
426
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
427
+ <div className="flex items-start gap-3">
428
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
429
+ <svg xmlns="http://www.w3.org/2000/svg" className="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/></svg>
430
+ </span>
431
+ <div>
432
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Story 1 · Dùng Macro</p>
433
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">Checkbox trong trang Cài đặt</h3>
434
+ </div>
435
+ </div>
436
+ <p className="text-xs text-muted-foreground leading-relaxed">
437
+ Form cài đặt có rất nhiều tuỳ chọn dạng "Bật / Tắt" với mô tả dài. Code sẽ rất sạch và ngắn.
438
+ </p>
439
+ <div className="rounded-lg bg-muted/50 p-3 flex flex-col gap-4">
440
+ <CheckboxPreset size="sm" label="Nhận Email Marketing" description="Gửi email cho bạn về các chương trình khuyến mãi hàng tuần." />
441
+ <CheckboxPreset size="sm" label="Thông báo bảo mật" description="Cảnh báo khi có thiết bị lạ đăng nhập." defaultChecked />
442
+ </div>
443
+ </div>
444
+
445
+ {/* Story 2: Micro wins */}
446
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
447
+ <div className="flex items-start gap-3">
448
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
449
+ <svg xmlns="http://www.w3.org/2000/svg" className="size-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
450
+ </span>
451
+ <div>
452
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Story 2 · Dùng Micro</p>
453
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">Table Row Selection</h3>
454
+ </div>
455
+ </div>
456
+ <p className="text-xs text-muted-foreground leading-relaxed">
457
+ Bạn cần ô Checkbox ở đầu mỗi dòng trong bảng để chọn nhiều hàng. Ở đây Checkbox đứng độc lập, hoàn toàn không cần Label hay Description đi kèm.
458
+ </p>
459
+ <div className="rounded-lg bg-muted/50 p-3">
460
+ <div className="border border-border rounded-md divide-y overflow-hidden">
461
+ <div className="flex items-center gap-3 p-2 bg-muted">
462
+ <Checkbox size="sm"><CheckboxIndicator><MinusIcon /></CheckboxIndicator></Checkbox>
463
+ <span className="text-xs font-semibold">Tên nhân viên</span>
464
+ </div>
465
+ <div className="flex items-center gap-3 p-2 bg-background hover:bg-muted/50">
466
+ <Checkbox size="sm" defaultChecked><CheckboxIndicator><CheckIcon /></CheckboxIndicator></Checkbox>
467
+ <span className="text-xs">John Doe</span>
468
+ </div>
469
+ </div>
470
+ </div>
471
+ </div>
472
+ </div>
473
+ `}
474
+ >
475
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
476
+ {/* Story 1: Macro wins */}
477
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
478
+ <div className="flex items-start gap-3">
479
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
480
+ <svg
481
+ xmlns="http://www.w3.org/2000/svg"
482
+ className="size-4"
483
+ viewBox="0 0 24 24"
484
+ fill="none"
485
+ stroke="currentColor"
486
+ strokeWidth="2"
487
+ strokeLinecap="round"
488
+ strokeLinejoin="round"
489
+ aria-hidden="true"
490
+ >
491
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
492
+ </svg>
493
+ </span>
494
+ <div>
495
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
496
+ Story 1 · Dùng Macro
497
+ </p>
498
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
499
+ Checkbox trong trang Cài đặt
500
+ </h3>
501
+ </div>
502
+ </div>
503
+ <p className="text-xs text-muted-foreground leading-relaxed">
504
+ Form cài đặt có rất nhiều tuỳ chọn dạng "Bật / Tắt" với mô tả dài.
505
+ Code sẽ rất sạch và ngắn.
506
+ </p>
507
+ <div className="rounded-lg bg-muted/50 p-3 flex flex-col gap-4">
508
+ <CheckboxPreset
509
+ size="sm"
510
+ label="Nhận Email Marketing"
511
+ description="Gửi email cho bạn về các chương trình khuyến mãi hàng tuần."
512
+ />
513
+ <CheckboxPreset
514
+ size="sm"
515
+ label="Thông báo bảo mật"
516
+ description="Cảnh báo khi có thiết bị lạ đăng nhập."
517
+ defaultChecked
518
+ />
519
+ </div>
520
+ </div>
521
+
522
+ {/* Story 2: Micro wins */}
523
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
524
+ <div className="flex items-start gap-3">
525
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
526
+ <svg
527
+ xmlns="http://www.w3.org/2000/svg"
528
+ className="size-4"
529
+ viewBox="0 0 24 24"
530
+ fill="none"
531
+ stroke="currentColor"
532
+ strokeWidth="2"
533
+ strokeLinecap="round"
534
+ strokeLinejoin="round"
535
+ aria-hidden="true"
536
+ >
537
+ <path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" />
538
+ </svg>
539
+ </span>
540
+ <div>
541
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
542
+ Story 2 · Dùng Micro
543
+ </p>
544
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
545
+ Table Row Selection
546
+ </h3>
547
+ </div>
548
+ </div>
549
+ <p className="text-xs text-muted-foreground leading-relaxed">
550
+ Bạn cần ô Checkbox ở đầu mỗi dòng trong bảng để chọn nhiều hàng. Ở
551
+ đây Checkbox đứng độc lập, hoàn toàn không cần Label hay
552
+ Description đi kèm.
553
+ </p>
554
+ <div className="rounded-lg bg-muted/50 p-3">
555
+ <div className="border border-border rounded-md divide-y overflow-hidden">
556
+ <div className="flex items-center gap-3 p-2 bg-muted">
557
+ <Checkbox size="sm">
558
+ <CheckboxIndicator>
559
+ <MinusIcon />
560
+ </CheckboxIndicator>
561
+ </Checkbox>
562
+ <span className="text-xs font-semibold">Tên nhân viên</span>
563
+ </div>
564
+ <div className="flex items-center gap-3 p-2 bg-background hover:bg-muted/50">
565
+ <Checkbox size="sm" defaultChecked>
566
+ <CheckboxIndicator>
567
+ <CheckIcon />
568
+ </CheckboxIndicator>
569
+ </Checkbox>
570
+ <span className="text-xs">John Doe</span>
571
+ </div>
572
+ </div>
573
+ </div>
574
+ </div>
575
+ </div>
576
+ </ExampleSection>
577
+ </div>
578
+ );
579
+ }
580
+
581
+ // ──────────────────────────────────────────────────────────
582
+ // SECTION 3: Entry point
583
+ // ──────────────────────────────────────────────────────────
584
+ export default function CheckboxShowcase() {
585
+ const { size: globalSize } = useDevContext();
586
+ return (
587
+ <Showcase
588
+ title="Checkbox"
589
+ description="Thành phần cho phép người dùng chọn hoặc bỏ chọn một tuỳ chọn độc lập."
590
+ generalConcept={
591
+ <ShowcaseDocs>
592
+ <DocsP>
593
+ Dùng để thu thập đầu vào dạng đúng/sai hoặc nhiều lựa chọn độc lập
594
+ từ người dùng. Thường đi kèm với nhãn (label) và mô tả để giải thích
595
+ ý nghĩa của tùy chọn.
596
+ </DocsP>
597
+ </ShowcaseDocs>
598
+ }
599
+ tabs={[
600
+ {
601
+ label: "Micro (Primitive)",
602
+ content: <CheckboxMicroShowcase globalSize={globalSize} />,
603
+ },
604
+ {
605
+ label: "Macro (Preset)",
606
+ content: <CheckboxMacroShowcase globalSize={globalSize} />,
607
+ },
608
+ ]}
609
+ />
610
+ );
611
+ }