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,376 @@
1
+ import { toast } from "sonner";
2
+
3
+ import { Button } from "../../components/micro/button";
4
+ import { Toaster } from "../../components/micro/sonner";
5
+ import {
6
+ DocsCode,
7
+ DocsP,
8
+ ExampleGrid,
9
+ ExampleSection,
10
+ Showcase,
11
+ ShowcaseDocs,
12
+ } from "../../dev/components/showcase";
13
+
14
+ // Simulated async operation for Promise demo
15
+ const mockSave = () =>
16
+ new Promise<{ name: string }>((resolve) =>
17
+ setTimeout(() => resolve({ name: "Sonner" }), 1500),
18
+ );
19
+
20
+ const mockFail = () =>
21
+ new Promise<void>((_, reject) =>
22
+ setTimeout(() => reject(new Error("Server error")), 1500),
23
+ );
24
+
25
+ // ──────────────────────────────────────────────────────────
26
+ // SECTION 2: Micro Content (không export)
27
+ // ──────────────────────────────────────────────────────────
28
+ function SonnerMicroShowcase() {
29
+ return (
30
+ <div className="space-y-10 mt-6">
31
+ {/* Toaster phải mount ở đây để toast() hoạt động trong showcase */}
32
+ <Toaster position="bottom-right" />
33
+ {/* ── Toast Types ── */}
34
+ <ExampleSection
35
+ label="Loại Toast"
36
+ description="Năm loại toast cơ bản: default, success, error, warning, info."
37
+ codeString={`import { toast } from "sonner";
38
+
39
+ // Default
40
+ toast("Event has been created", {
41
+ description: "Sunday, December 03, 2023 at 9:00 AM",
42
+ action: { label: "Undo", onClick: () => console.log("Undo") },
43
+ });
44
+
45
+ // Typed variants
46
+ toast.success("Successfully saved!");
47
+ toast.error("An error occurred.");
48
+ toast.warning("Connection is unstable.");
49
+ toast.info("Update is available.");`}
50
+ >
51
+ <div className="flex flex-wrap gap-2">
52
+ <Button
53
+ variant="outline"
54
+ onClick={() =>
55
+ toast("Event has been created", {
56
+ description: "Sunday, December 03, 2023 at 9:00 AM",
57
+ action: { label: "Undo", onClick: () => console.log("Undo") },
58
+ })
59
+ }
60
+ >
61
+ Default
62
+ </Button>
63
+ <Button
64
+ variant="outline"
65
+ color="success"
66
+ onClick={() => toast.success("Successfully saved!")}
67
+ >
68
+ Success
69
+ </Button>
70
+ <Button
71
+ variant="outline"
72
+ color="destructive"
73
+ onClick={() => toast.error("An error occurred.")}
74
+ >
75
+ Error
76
+ </Button>
77
+ <Button
78
+ variant="outline"
79
+ color="warning"
80
+ onClick={() => toast.warning("Connection is unstable.")}
81
+ >
82
+ Warning
83
+ </Button>
84
+ <Button
85
+ variant="outline"
86
+ color="info"
87
+ onClick={() => toast.info("Update is available.")}
88
+ >
89
+ Info
90
+ </Button>
91
+ </div>
92
+ </ExampleSection>
93
+
94
+ {/* ── Mô tả & Action ── */}
95
+ <ExampleSection
96
+ label="Mô tả & Action Button"
97
+ description="Toast kèm description phụ và action button — pattern phổ biến cho undo/redo, navigation."
98
+ codeString={`toast("File deleted", {
99
+ description: "draft-v2.docx has been moved to trash.",
100
+ action: {
101
+ label: "Undo",
102
+ onClick: () => console.log("Undo delete"),
103
+ },
104
+ cancel: {
105
+ label: "Dismiss",
106
+ onClick: () => {},
107
+ },
108
+ });`}
109
+ >
110
+ <div className="flex flex-wrap gap-2">
111
+ <Button
112
+ variant="outline"
113
+ onClick={() =>
114
+ toast("File deleted", {
115
+ description: "draft-v2.docx has been moved to trash.",
116
+ action: {
117
+ label: "Undo",
118
+ onClick: () => console.log("Undo delete"),
119
+ },
120
+ cancel: {
121
+ label: "Dismiss",
122
+ onClick: () => {},
123
+ },
124
+ })
125
+ }
126
+ >
127
+ File Deleted (with Action)
128
+ </Button>
129
+ <Button
130
+ variant="outline"
131
+ onClick={() =>
132
+ toast.success("Profile updated", {
133
+ description: "Your changes have been saved successfully.",
134
+ })
135
+ }
136
+ >
137
+ Success with Description
138
+ </Button>
139
+ </div>
140
+ </ExampleSection>
141
+
142
+ {/* ── Promise ── */}
143
+ <ExampleGrid>
144
+ <ExampleSection
145
+ label="Promise — Thành công"
146
+ description="toast.promise() tự quản lý trạng thái loading → success/error theo kết quả của Promise."
147
+ codeString={`const saveData = () =>
148
+ new Promise<{ name: string }>((resolve) =>
149
+ setTimeout(() => resolve({ name: "Sonner" }), 1500),
150
+ );
151
+
152
+ toast.promise(saveData(), {
153
+ loading: "Đang lưu...",
154
+ success: (data) => \`Đã lưu \${data.name} thành công!\`,
155
+ error: "Lưu thất bại!",
156
+ });`}
157
+ >
158
+ <Button
159
+ variant="outline"
160
+ onClick={() =>
161
+ toast.promise(mockSave(), {
162
+ loading: "Đang lưu...",
163
+ success: (data) => `Đã lưu ${data.name} thành công!`,
164
+ error: "Lưu thất bại!",
165
+ })
166
+ }
167
+ >
168
+ Promise (Success)
169
+ </Button>
170
+ </ExampleSection>
171
+
172
+ <ExampleSection
173
+ label="Promise — Thất bại"
174
+ description="Promise bị reject sẽ tự chuyển sang trạng thái error toast."
175
+ codeString={`const failRequest = () =>
176
+ new Promise<void>((_, reject) =>
177
+ setTimeout(() => reject(new Error("Server error")), 1500),
178
+ );
179
+
180
+ toast.promise(failRequest(), {
181
+ loading: "Đang gửi yêu cầu...",
182
+ success: "Yêu cầu thành công!",
183
+ error: "Yêu cầu thất bại!",
184
+ });`}
185
+ >
186
+ <Button
187
+ variant="outline"
188
+ color="destructive"
189
+ onClick={() =>
190
+ toast.promise(mockFail(), {
191
+ loading: "Đang gửi yêu cầu...",
192
+ success: "Yêu cầu thành công!",
193
+ error: "Yêu cầu thất bại!",
194
+ })
195
+ }
196
+ >
197
+ Promise (Error)
198
+ </Button>
199
+ </ExampleSection>
200
+ </ExampleGrid>
201
+
202
+ {/* ── Loading & Dismiss ── */}
203
+ <ExampleSection
204
+ label="Loading & Dismiss"
205
+ description="toast.loading() tạo toast thủ công, sau đó dùng toast.success/error(id) để cập nhật, hoặc toast.dismiss(id) để huỷ."
206
+ codeString={`// Tạo loading toast và giữ id
207
+ const toastId = toast.loading("Đang xử lý...");
208
+
209
+ // Sau khi async xong — cập nhật cùng toast
210
+ setTimeout(() => {
211
+ toast.success("Hoàn tất!", { id: toastId });
212
+ }, 2000);
213
+
214
+ // Hoặc huỷ thủ công
215
+ toast.dismiss(toastId);`}
216
+ >
217
+ <div className="flex flex-wrap gap-2">
218
+ <Button
219
+ variant="outline"
220
+ onClick={() => {
221
+ const id = toast.loading("Đang xử lý...");
222
+ setTimeout(() => toast.success("Hoàn tất!", { id }), 2000);
223
+ }}
224
+ >
225
+ Loading → Success (2s)
226
+ </Button>
227
+ <Button
228
+ variant="outline"
229
+ onClick={() => {
230
+ const id = toast.loading("Đang tải dữ liệu...");
231
+ setTimeout(() => toast.error("Mất kết nối!", { id }), 2000);
232
+ }}
233
+ >
234
+ Loading → Error (2s)
235
+ </Button>
236
+ <Button
237
+ variant="outline"
238
+ color="destructive"
239
+ onClick={() => toast.dismiss()}
240
+ >
241
+ Dismiss All
242
+ </Button>
243
+ </div>
244
+ </ExampleSection>
245
+
246
+ {/* ── Position ── */}
247
+ <ExampleSection
248
+ label="Position"
249
+ description="Toaster nhận prop position để xác định vị trí hiển thị — cấu hình một lần ở root layout. Nhấn vào từng vùng để xem toast xuất hiện ở đâu."
250
+ codeString={`// Trong root layout (app/layout.tsx):
251
+ <Toaster position="bottom-right" /> // mặc định
252
+
253
+ // Các vị trí hỗ trợ:
254
+ // "top-left" | "top-center" | "top-right"
255
+ // "bottom-left" | "bottom-center" | "bottom-right"`}
256
+ >
257
+ {/* Visual 3×2 position grid */}
258
+ <div className="w-full max-w-sm">
259
+ <p className="mb-3 text-xs text-muted-foreground">
260
+ Nhấn từng ô để xem toast xuất hiện đúng vị trí tương ứng.
261
+ </p>
262
+ <div className="grid grid-cols-3 gap-1.5">
263
+ <Button
264
+ variant="outline"
265
+ size="sm"
266
+ className="text-xs"
267
+ onClick={() =>
268
+ toast("Toast: top-left", {
269
+ description: 'position="top-left"',
270
+ position: "top-left",
271
+ })
272
+ }
273
+ >
274
+ top-left
275
+ </Button>
276
+ <Button
277
+ variant="outline"
278
+ size="sm"
279
+ className="text-xs"
280
+ onClick={() =>
281
+ toast("Toast: top-center", {
282
+ description: 'position="top-center"',
283
+ position: "top-center",
284
+ })
285
+ }
286
+ >
287
+ top-center
288
+ </Button>
289
+ <Button
290
+ variant="outline"
291
+ size="sm"
292
+ className="text-xs"
293
+ onClick={() =>
294
+ toast("Toast: top-right", {
295
+ description: 'position="top-right"',
296
+ position: "top-right",
297
+ })
298
+ }
299
+ >
300
+ top-right
301
+ </Button>
302
+ <Button
303
+ variant="outline"
304
+ size="sm"
305
+ className="text-xs"
306
+ onClick={() =>
307
+ toast("Toast: bottom-left", {
308
+ description: 'position="bottom-left"',
309
+ position: "bottom-left",
310
+ })
311
+ }
312
+ >
313
+ bottom-left
314
+ </Button>
315
+ <Button
316
+ variant="outline"
317
+ size="sm"
318
+ className="text-xs"
319
+ onClick={() =>
320
+ toast("Toast: bottom-center", {
321
+ description: 'position="bottom-center"',
322
+ position: "bottom-center",
323
+ })
324
+ }
325
+ >
326
+ bottom-center
327
+ </Button>
328
+ <Button
329
+ variant="outline"
330
+ size="sm"
331
+ className="text-xs"
332
+ onClick={() =>
333
+ toast("Toast: bottom-right", {
334
+ description: 'position="bottom-right"',
335
+ position: "bottom-right",
336
+ })
337
+ }
338
+ >
339
+ bottom-right
340
+ </Button>
341
+ </div>
342
+ </div>
343
+ </ExampleSection>
344
+ </div>
345
+ );
346
+ }
347
+
348
+ // ──────────────────────────────────────────────────────────
349
+ // SECTION 3: Entry point (export default)
350
+ // ──────────────────────────────────────────────────────────
351
+ export default function SonnerShowcase() {
352
+ return (
353
+ <Showcase
354
+ title="Sonner"
355
+ description="Hệ thống thông báo toast nhẹ, đẹp, và linh hoạt — tích hợp với design system qua CSS Variables."
356
+ generalConcept={
357
+ <ShowcaseDocs>
358
+ <DocsP>
359
+ <DocsCode>Toaster</DocsCode> là wrapper của thư viện{" "}
360
+ <DocsCode>sonner</DocsCode>, được tích hợp với design system qua CSS
361
+ Variables — màu sắc của toast tự động đồng bộ với theme (light/dark)
362
+ và các token màu (success, destructive, warning, info).
363
+ </DocsP>
364
+ <DocsP>
365
+ Đặt <DocsCode>&lt;Toaster /&gt;</DocsCode> một lần duy nhất ở root
366
+ layout. Sau đó gọi <DocsCode>toast()</DocsCode> từ{" "}
367
+ <DocsCode>sonner</DocsCode> ở bất cứ đâu trong ứng dụng.{" "}
368
+ <DocsCode>toast.promise()</DocsCode> rất hữu ích cho async
369
+ operations — tự quản lý loading → success/error.
370
+ </DocsP>
371
+ </ShowcaseDocs>
372
+ }
373
+ tabs={[{ label: "Micro (Primitive)", content: <SonnerMicroShowcase /> }]}
374
+ />
375
+ );
376
+ }
@@ -0,0 +1,124 @@
1
+ import { useDevContext } from "../../dev/components/dev-context";
2
+ import { useState } from "react";
3
+
4
+ import { Spinner } from "../../components/micro/spinner";
5
+ import { type Size } from "../../lib/types";
6
+ import {
7
+ DocsCode,
8
+ DocsH3,
9
+ DocsP,
10
+ ExampleGrid,
11
+ ExampleSection,
12
+ Showcase,
13
+ ShowcaseDocs,
14
+ } from "../../dev/components/showcase";
15
+
16
+ // ──────────────────────────────────────────────────────────
17
+ // SECTION 1: Micro Content
18
+ // ──────────────────────────────────────────────────────────
19
+ function SpinnerMicroShowcase({ globalSize }: { globalSize: Size }) {
20
+ return (
21
+ <div className="space-y-10 mt-6">
22
+ {/* Default */}
23
+ <ExampleSection
24
+ label="Default"
25
+ description="Spinner mặc định với kích thước được kiểm soát bởi size toggle ở trên."
26
+ codeString={`<Spinner />
27
+ <Spinner size="sm" />
28
+ <Spinner size="md" />
29
+ <Spinner size="lg" />`}
30
+ >
31
+ <Spinner size={globalSize} />
32
+ </ExampleSection>
33
+
34
+ {/* Colors */}
35
+ <ExampleGrid>
36
+ <ExampleSection
37
+ label="Custom Colors"
38
+ description="Truyền className để override màu sắc — Spinner kế thừa currentColor của SVG."
39
+ codeString={`<Spinner className="text-primary" />
40
+ <Spinner className="text-destructive" />
41
+ <Spinner className="text-warning" />
42
+ <Spinner className="text-success" />`}
43
+ >
44
+ <div className="flex items-center gap-4">
45
+ <Spinner size={globalSize} className="text-primary" />
46
+ <Spinner size={globalSize} className="text-destructive" />
47
+ <Spinner size={globalSize} className="text-warning" />
48
+ <Spinner size={globalSize} className="text-success" />
49
+ </div>
50
+ </ExampleSection>
51
+
52
+ <ExampleSection
53
+ label="In Context — Button Loading"
54
+ description="Kết hợp Spinner trong Button để mô phỏng trạng thái loading."
55
+ codeString={`<button disabled className="flex items-center gap-2 px-4 py-2 rounded-md bg-primary text-primary-foreground text-sm opacity-70">
56
+ <Spinner size="sm" className="text-primary-foreground" />
57
+ Đang lưu...
58
+ </button>`}
59
+ >
60
+ <button
61
+ disabled
62
+ className="flex items-center gap-2 px-4 py-2 rounded-md bg-primary text-primary-foreground text-sm opacity-70 cursor-not-allowed"
63
+ >
64
+ <Spinner size="sm" className="text-primary-foreground" />
65
+ Đang lưu...
66
+ </button>
67
+ </ExampleSection>
68
+ </ExampleGrid>
69
+
70
+ {/* Overlay / Fullscreen */}
71
+ <ExampleSection
72
+ label="Overlay Loading"
73
+ description="Đặt Spinner trên một overlay để chặn tương tác trong khi tải nội dung."
74
+ codeString={`<div className="relative rounded-xl border border-border bg-card h-32">
75
+ <div className="absolute inset-0 flex items-center justify-center bg-background/60 rounded-xl">
76
+ <Spinner size="lg" className="text-primary" />
77
+ </div>
78
+ </div>`}
79
+ >
80
+ <div className="relative rounded-xl border border-border bg-card h-32 w-full max-w-sm">
81
+ <div className="absolute inset-0 flex items-center justify-center bg-background/60 rounded-xl">
82
+ <Spinner size="lg" className="text-primary" />
83
+ </div>
84
+ <div className="p-4 text-sm text-muted-foreground">
85
+ Nội dung đang tải...
86
+ </div>
87
+ </div>
88
+ </ExampleSection>
89
+ </div>
90
+ );
91
+ }
92
+
93
+ // ──────────────────────────────────────────────────────────
94
+ // SECTION 2: Entry point
95
+ // ──────────────────────────────────────────────────────────
96
+ export default function SpinnerShowcase() {
97
+ const { size: globalSize } = useDevContext();
98
+ return (
99
+ <Showcase
100
+ title="Spinner"
101
+ description="Chỉ báo trạng thái đang tải, hỗ trợ nhiều kích thước và màu sắc."
102
+ generalConcept={
103
+ <ShowcaseDocs>
104
+ <DocsH3>Spinner</DocsH3>
105
+ <DocsP>
106
+ <DocsCode>Spinner</DocsCode> render icon{" "}
107
+ <DocsCode>Loader2Icon</DocsCode> với animation{" "}
108
+ <DocsCode>animate-spin</DocsCode>. Tự động tắt animation khi người
109
+ dùng bật <DocsCode>prefers-reduced-motion</DocsCode> (
110
+ <DocsCode>motion-reduce:animate-none</DocsCode>
111
+ ). Màu mặc định là <DocsCode>currentColor</DocsCode> — override bằng{" "}
112
+ <DocsCode>className="text-primary"</DocsCode> hoặc tương tự.
113
+ </DocsP>
114
+ </ShowcaseDocs>
115
+ }
116
+ tabs={[
117
+ {
118
+ label: "Micro (Primitive)",
119
+ content: <SpinnerMicroShowcase globalSize={globalSize} />,
120
+ },
121
+ ]}
122
+ />
123
+ );
124
+ }