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