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