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,470 @@
1
+ import { useDevContext } from "../../dev/components/dev-context";
2
+ import {
3
+ DocsP,
4
+ ExampleGrid,
5
+ ExampleSection,
6
+ Showcase,
7
+ ShowcaseDocs,
8
+ } from "../../dev/components/showcase";
9
+ import {
10
+ CheckCircle2Icon,
11
+ CheckIcon,
12
+ LayersIcon,
13
+ UserIcon,
14
+ } from "lucide-react";
15
+ import { useState } from "react";
16
+
17
+ import { AvatarPreset } from "../../components/macro/avatar-preset";
18
+ import {
19
+ Avatar,
20
+ AvatarBadge,
21
+ AvatarFallback,
22
+ AvatarGroup,
23
+ AvatarGroupCount,
24
+ AvatarImage,
25
+ } from "../../components/micro/avatar";
26
+ import { type Size } from "../../lib/types";
27
+
28
+ // ──────────────────────────────────────────────────────────
29
+ // SECTION 1: Macro Content
30
+ // ──────────────────────────────────────────────────────────
31
+ function AvatarMacroShowcase({ globalSize }: { globalSize: Size }) {
32
+ return (
33
+ <div className="space-y-10 mt-6">
34
+ <ExampleGrid>
35
+ <ExampleSection
36
+ label="Tiêu chuẩn (Standard)"
37
+ description="Avatar tự động fallback dựa vào tên truyền vào alt."
38
+ codeString={`<div className="flex items-center gap-4">
39
+ <AvatarPreset src="https://github.com/shadcn.png" alt="Shadcn" />
40
+ <AvatarPreset alt="John Doe" />
41
+ <AvatarPreset />
42
+ </div>
43
+ `}
44
+ >
45
+ <div className="flex items-center gap-4">
46
+ <AvatarPreset
47
+ size={globalSize}
48
+ src="https://github.com/shadcn.png"
49
+ alt="Shadcn"
50
+ />
51
+ <AvatarPreset size={globalSize} alt="John Doe" />
52
+ <AvatarPreset size={globalSize} />
53
+ </div>
54
+ </ExampleSection>
55
+
56
+ <ExampleSection
57
+ label="Trạng thái (Status)"
58
+ description="Hỗ trợ sẵn các trạng thái: online, offline, away."
59
+ codeString={`<div className="flex items-center gap-4">
60
+ <AvatarPreset src="https://github.com/shadcn.png" alt="Shadcn" status="online" />
61
+ <AvatarPreset alt="Alice" status="away" />
62
+ <AvatarPreset status="offline" />
63
+ </div>
64
+ `}
65
+ >
66
+ <div className="flex items-center gap-4">
67
+ <AvatarPreset
68
+ size={globalSize}
69
+ src="https://github.com/shadcn.png"
70
+ alt="Shadcn"
71
+ status="online"
72
+ />
73
+ <AvatarPreset size={globalSize} alt="Alice" status="away" />
74
+ <AvatarPreset size={globalSize} status="offline" />
75
+ </div>
76
+ </ExampleSection>
77
+ </ExampleGrid>
78
+
79
+ <ExampleSection
80
+ label="Nhóm Avatar (Avatar Group)"
81
+ description="Kết hợp Preset với AvatarGroup để tiết kiệm code."
82
+ fullWidth
83
+ codeString={`<AvatarGroup>
84
+ <AvatarPreset src="https://github.com/shadcn.png" alt="Shadcn" />
85
+ <AvatarPreset alt="Alice Smith" />
86
+ <AvatarPreset alt="Bob Jones" />
87
+ <AvatarGroupCount>+3</AvatarGroupCount>
88
+ </AvatarGroup>`}
89
+ >
90
+ <div className="flex flex-col gap-4">
91
+ <AvatarGroup>
92
+ <AvatarPreset
93
+ size={globalSize}
94
+ src="https://github.com/shadcn.png"
95
+ alt="Shadcn"
96
+ />
97
+ <AvatarPreset size={globalSize} alt="Alice Smith" />
98
+ <AvatarPreset size={globalSize} alt="Bob Jones" />
99
+ <AvatarGroupCount size={globalSize}>+3</AvatarGroupCount>
100
+ </AvatarGroup>
101
+ </div>
102
+ </ExampleSection>
103
+ </div>
104
+ );
105
+ }
106
+
107
+ // ──────────────────────────────────────────────────────────
108
+ // SECTION 2: Micro Content
109
+ // ──────────────────────────────────────────────────────────
110
+ function AvatarMicroShowcase({ globalSize }: { globalSize: Size }) {
111
+ return (
112
+ <div className="space-y-10 mt-6">
113
+ <ExampleGrid>
114
+ <ExampleSection
115
+ label="Với Hình ảnh (With Image)"
116
+ description="Hiển thị ảnh và sẽ fallback về chữ nếu ảnh lỗi."
117
+ codeString={`<div className="flex items-center gap-4">
118
+ <Avatar>
119
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
120
+ <AvatarFallback>CN</AvatarFallback>
121
+ </Avatar>
122
+ <Avatar>
123
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
124
+ <AvatarFallback>VC</AvatarFallback>
125
+ </Avatar>
126
+ <Avatar>
127
+ <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
128
+ <AvatarFallback>LR</AvatarFallback>
129
+ </Avatar>
130
+ </div>
131
+ `}
132
+ >
133
+ <div className="flex items-center gap-4">
134
+ <Avatar size={globalSize}>
135
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
136
+ <AvatarFallback>CN</AvatarFallback>
137
+ </Avatar>
138
+ <Avatar size={globalSize}>
139
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
140
+ <AvatarFallback>VC</AvatarFallback>
141
+ </Avatar>
142
+ <Avatar size={globalSize}>
143
+ <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
144
+ <AvatarFallback>LR</AvatarFallback>
145
+ </Avatar>
146
+ </div>
147
+ </ExampleSection>
148
+
149
+ <ExampleSection
150
+ label="Lỗi Ảnh & Chỉ có Fallback"
151
+ description="Khi không có ảnh hoặc ảnh lỗi, fallback sẽ hiển thị."
152
+ codeString={`<div className="flex items-center gap-4">
153
+ <Avatar>
154
+ <AvatarImage src="https://broken-url.invalid/avatar.png" alt="broken" />
155
+ <AvatarFallback>BR</AvatarFallback>
156
+ </Avatar>
157
+ <Avatar>
158
+ <AvatarFallback>JD</AvatarFallback>
159
+ </Avatar>
160
+ <Avatar>
161
+ <AvatarFallback>
162
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="size-4"><path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
163
+ </AvatarFallback>
164
+ </Avatar>
165
+ </div>
166
+ `}
167
+ >
168
+ <div className="flex items-center gap-4">
169
+ <Avatar size={globalSize}>
170
+ <AvatarImage
171
+ src="https://broken-url.invalid/avatar.png"
172
+ alt="broken"
173
+ />
174
+ <AvatarFallback>BR</AvatarFallback>
175
+ </Avatar>
176
+ <Avatar size={globalSize}>
177
+ <AvatarFallback>JD</AvatarFallback>
178
+ </Avatar>
179
+ <Avatar size={globalSize}>
180
+ <AvatarFallback>
181
+ <svg
182
+ xmlns="http://www.w3.org/2000/svg"
183
+ width="24"
184
+ height="24"
185
+ viewBox="0 0 24 24"
186
+ fill="none"
187
+ stroke="currentColor"
188
+ strokeWidth="2"
189
+ strokeLinecap="round"
190
+ strokeLinejoin="round"
191
+ className="size-4"
192
+ >
193
+ <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2" />
194
+ <circle cx="12" cy="7" r="4" />
195
+ </svg>
196
+ </AvatarFallback>
197
+ </Avatar>
198
+ </div>
199
+ </ExampleSection>
200
+ </ExampleGrid>
201
+
202
+ <ExampleSection
203
+ label="Huy hiệu (With Badge)"
204
+ description="Bạn có thể tự định vị Badge ở bất cứ đâu trên Avatar."
205
+ codeString={`<div className="flex items-center gap-6">
206
+ <div className="flex flex-col items-center gap-2">
207
+ <Avatar>
208
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
209
+ <AvatarFallback>CN</AvatarFallback>
210
+ <AvatarBadge className="absolute z-10 right-0 bottom-0 bg-green-500" />
211
+ </Avatar>
212
+ <span className="text-xs text-muted-foreground">Online</span>
213
+ </div>
214
+ <div className="flex flex-col items-center gap-2">
215
+ <Avatar>
216
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
217
+ <AvatarFallback>VC</AvatarFallback>
218
+ <AvatarBadge className="absolute z-10 right-0 top-0 bg-red-500" />
219
+ </Avatar>
220
+ <span className="text-xs text-muted-foreground">Notification</span>
221
+ </div>
222
+ </div>
223
+ `}
224
+ >
225
+ <div className="flex items-center gap-6">
226
+ <div className="flex flex-col items-center gap-2">
227
+ <Avatar size={globalSize}>
228
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
229
+ <AvatarFallback>CN</AvatarFallback>
230
+ <AvatarBadge className="absolute z-10 right-0 bottom-0 bg-green-500" />
231
+ </Avatar>
232
+ <span className="text-xs text-muted-foreground">Online</span>
233
+ </div>
234
+ <div className="flex flex-col items-center gap-2">
235
+ <Avatar size={globalSize}>
236
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
237
+ <AvatarFallback>VC</AvatarFallback>
238
+ <AvatarBadge className="absolute z-10 right-0 top-0 bg-red-500" />
239
+ </Avatar>
240
+ <span className="text-xs text-muted-foreground">Notification</span>
241
+ </div>
242
+ </div>
243
+ </ExampleSection>
244
+
245
+ <ExampleGrid>
246
+ <ExampleSection
247
+ label="Nhóm cơ bản (Basic Group)"
248
+ description="Xếp chồng nhiều avatar lên nhau."
249
+ codeString={`<AvatarGroup>
250
+ <Avatar>
251
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
252
+ <AvatarFallback>CN</AvatarFallback>
253
+ </Avatar>
254
+ <Avatar>
255
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
256
+ <AvatarFallback>VC</AvatarFallback>
257
+ </Avatar>
258
+ <Avatar>
259
+ <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
260
+ <AvatarFallback>LR</AvatarFallback>
261
+ </Avatar>
262
+ </AvatarGroup>
263
+ `}
264
+ >
265
+ <AvatarGroup>
266
+ <Avatar size={globalSize}>
267
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
268
+ <AvatarFallback>CN</AvatarFallback>
269
+ </Avatar>
270
+ <Avatar size={globalSize}>
271
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
272
+ <AvatarFallback>VC</AvatarFallback>
273
+ </Avatar>
274
+ <Avatar size={globalSize}>
275
+ <AvatarImage src="https://github.com/leerob.png" alt="@leerob" />
276
+ <AvatarFallback>LR</AvatarFallback>
277
+ </Avatar>
278
+ </AvatarGroup>
279
+ </ExampleSection>
280
+
281
+ <ExampleSection
282
+ label="Kèm bộ đếm (With Count)"
283
+ description="Hiển thị những avatar còn lại bị ẩn."
284
+ codeString={`<AvatarGroup>
285
+ <Avatar>
286
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
287
+ <AvatarFallback>CN</AvatarFallback>
288
+ </Avatar>
289
+ <Avatar>
290
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
291
+ <AvatarFallback>VC</AvatarFallback>
292
+ </Avatar>
293
+ <AvatarGroupCount>+12</AvatarGroupCount>
294
+ </AvatarGroup>
295
+ `}
296
+ >
297
+ <AvatarGroup>
298
+ <Avatar size={globalSize}>
299
+ <AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
300
+ <AvatarFallback>CN</AvatarFallback>
301
+ </Avatar>
302
+ <Avatar size={globalSize}>
303
+ <AvatarImage src="https://github.com/vercel.png" alt="@vercel" />
304
+ <AvatarFallback>VC</AvatarFallback>
305
+ </Avatar>
306
+ <AvatarGroupCount size={globalSize}>+12</AvatarGroupCount>
307
+ </AvatarGroup>
308
+ </ExampleSection>
309
+
310
+ {/* ── Use Case Comparison ─────────────────────── */}
311
+ <ExampleSection
312
+ label="🧭 Use Case Comparison"
313
+ description="Các kịch bản thực tế giúp bạn quyết định nên dùng Micro hay Macro."
314
+ fullWidth
315
+ codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
316
+ {/* ── Story 1: Macro wins ── */}
317
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
318
+ <div className="flex items-start gap-3">
319
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
320
+ <CheckCircle2Icon className="size-4" aria-hidden="true" />
321
+ </span>
322
+ <div>
323
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
324
+ Story 1 · Dùng Macro
325
+ </p>
326
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
327
+ Hiển thị Avatar chuẩn với URL và Fallback
328
+ </h3>
329
+ </div>
330
+ </div>
331
+ <p className="text-xs text-muted-foreground leading-relaxed">
332
+ Hầu hết các trường hợp bạn chỉ có một URL hình ảnh và một cái tên. Macro tự động hiển thị ảnh, nếu ảnh lỗi thì tự sinh chữ viết tắt dựa trên tên cực kỳ tiện lợi mà không cần viết nhiều code.
333
+ </p>
334
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
335
+ <AvatarPreset src="https://github.com/shadcn.png" alt="Shadcn" size="lg" />
336
+ </div>
337
+ </div>
338
+
339
+ {/* ── Story 2: Micro wins ── */}
340
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
341
+ <div className="flex items-start gap-3">
342
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
343
+ <LayersIcon className="size-4" aria-hidden="true" />
344
+ </span>
345
+ <div>
346
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
347
+ Story 2 · Dùng Micro
348
+ </p>
349
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
350
+ Layout Fallback phức tạp hoặc tích hợp Badge đặc thù
351
+ </h3>
352
+ </div>
353
+ </div>
354
+ <p className="text-xs text-muted-foreground leading-relaxed">
355
+ Khi bạn muốn Fallback là một Icon thay vì Text, hoặc muốn đính kèm một Badge tùy chỉnh hoàn toàn tự do (như icon viền, thông báo tin nhắn), bạn phải dùng Primitive để lắp ghép.
356
+ </p>
357
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
358
+ <Avatar size="lg">
359
+ <AvatarImage src="/broken.png" alt="Avatar" />
360
+ <AvatarFallback>
361
+ <UserIcon className="size-1/2 text-muted-foreground" />
362
+ </AvatarFallback>
363
+ <AvatarBadge className="bg-blue-500">
364
+ <CheckIcon className="size-2 text-white" />
365
+ </AvatarBadge>
366
+ </Avatar>
367
+ </div>
368
+ </div>
369
+ </div>`}
370
+ >
371
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
372
+ {/* ── Story 1: Macro wins ── */}
373
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
374
+ <div className="flex items-start gap-3">
375
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
376
+ <CheckCircle2Icon className="size-4" aria-hidden="true" />
377
+ </span>
378
+ <div>
379
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
380
+ Story 1 · Dùng Macro
381
+ </p>
382
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
383
+ Hiển thị Avatar chuẩn với URL và Fallback
384
+ </h3>
385
+ </div>
386
+ </div>
387
+ <p className="text-xs text-muted-foreground leading-relaxed">
388
+ Hầu hết các trường hợp bạn chỉ có một URL hình ảnh và một cái
389
+ tên. Macro tự động hiển thị ảnh, nếu ảnh lỗi thì tự sinh chữ
390
+ viết tắt dựa trên tên cực kỳ tiện lợi mà không cần viết nhiều
391
+ code.
392
+ </p>
393
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
394
+ <AvatarPreset
395
+ size={globalSize === "sm" ? "md" : "lg"}
396
+ src="https://github.com/shadcn.png"
397
+ alt="Shadcn"
398
+ />
399
+ </div>
400
+ </div>
401
+
402
+ {/* ── Story 2: Micro wins ── */}
403
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
404
+ <div className="flex items-start gap-3">
405
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
406
+ <LayersIcon className="size-4" aria-hidden="true" />
407
+ </span>
408
+ <div>
409
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
410
+ Story 2 · Dùng Micro
411
+ </p>
412
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
413
+ Layout Fallback phức tạp hoặc tích hợp Badge đặc thù
414
+ </h3>
415
+ </div>
416
+ </div>
417
+ <p className="text-xs text-muted-foreground leading-relaxed">
418
+ Khi bạn muốn Fallback là một Icon thay vì Text, hoặc muốn đính
419
+ kèm một Badge tùy chỉnh hoàn toàn tự do (như icon viền, thông
420
+ báo tin nhắn), bạn phải dùng Primitive để lắp ghép.
421
+ </p>
422
+ <div className="rounded-lg bg-muted/50 p-3 flex justify-center">
423
+ <Avatar size={globalSize === "sm" ? "md" : "lg"}>
424
+ <AvatarImage src="/broken.png" alt="Avatar" />
425
+ <AvatarFallback>
426
+ <UserIcon className="size-1/2 text-muted-foreground" />
427
+ </AvatarFallback>
428
+ <AvatarBadge className="bg-blue-500">
429
+ <CheckIcon className="size-2 text-white" />
430
+ </AvatarBadge>
431
+ </Avatar>
432
+ </div>
433
+ </div>
434
+ </div>
435
+ </ExampleSection>
436
+ </ExampleGrid>
437
+ </div>
438
+ );
439
+ }
440
+
441
+ // ──────────────────────────────────────────────────────────
442
+ // SECTION 3: Entry point
443
+ // ──────────────────────────────────────────────────────────
444
+ export default function AvatarShowcase() {
445
+ const { size: globalSize } = useDevContext();
446
+ return (
447
+ <Showcase
448
+ title="Avatar"
449
+ description="Hiển thị hình ảnh đại diện của người dùng hoặc các thực thể khác."
450
+ generalConcept={
451
+ <ShowcaseDocs>
452
+ <DocsP>
453
+ Dùng để hiển thị hình ảnh đại diện cho người dùng, nhóm hoặc tổ
454
+ chức. Hỗ trợ tự động hiển thị chữ cái viết tắt hoặc icon mặc định khi không tải được ảnh.
455
+ </DocsP>
456
+ </ShowcaseDocs>
457
+ }
458
+ tabs={[
459
+ {
460
+ label: "Micro (Primitive)",
461
+ content: <AvatarMicroShowcase globalSize={globalSize} />,
462
+ },
463
+ {
464
+ label: "Macro (Preset)",
465
+ content: <AvatarMacroShowcase globalSize={globalSize} />,
466
+ },
467
+ ]}
468
+ />
469
+ );
470
+ }