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,312 @@
1
+ import { useDevContext } from "../../dev/components/dev-context";
2
+ import {
3
+ DocsCode,
4
+ DocsH3,
5
+ DocsP,
6
+ ExampleGrid,
7
+ ExampleSection,
8
+ Showcase,
9
+ ShowcaseDocs,
10
+ } from "../../dev/components/showcase";
11
+ import { useState } from "react";
12
+
13
+ import { PaginationPreset } from "../../components/macro/pagination-preset";
14
+ import {
15
+ Pagination,
16
+ PaginationContent,
17
+ PaginationEllipsis,
18
+ PaginationItem,
19
+ PaginationLink,
20
+ PaginationNext,
21
+ PaginationPrevious,
22
+ } from "../../components/micro/pagination";
23
+ import { type Size } from "../../lib/types";
24
+
25
+ // ──────────────────────────────────────────────────────────
26
+ // SECTION 1: Macro Content
27
+ // ──────────────────────────────────────────────────────────
28
+ function PaginationMacroShowcase({ globalSize }: { globalSize: Size }) {
29
+ const [currentPage, setCurrentPage] = useState(1);
30
+
31
+ return (
32
+ <div className="space-y-10 mt-6">
33
+ <ExampleGrid>
34
+ <ExampleSection
35
+ label="Tiêu chuẩn (Standard)"
36
+ description="Phân trang cơ bản với state điều khiển."
37
+ codeString={`const [currentPage, setCurrentPage] = useState(1);
38
+
39
+ return (
40
+ <PaginationPreset
41
+ currentPage={currentPage}
42
+ totalPages={10}
43
+ onPageChange={setCurrentPage}
44
+ />
45
+ );`}
46
+ >
47
+ <PaginationPreset
48
+ currentPage={currentPage}
49
+ totalPages={10}
50
+ onPageChange={setCurrentPage}
51
+ size={globalSize}
52
+ />
53
+ </ExampleSection>
54
+
55
+ <ExampleSection
56
+ label="Nhiều trang (Many Pages)"
57
+ description="Tự động thêm dấu ba chấm (ellipsis) khi số trang lớn."
58
+ codeString={`<PaginationPreset currentPage={50} totalPages={100} />
59
+ `}
60
+ >
61
+ <PaginationPreset
62
+ currentPage={50}
63
+ totalPages={100}
64
+ size={globalSize}
65
+ />
66
+ </ExampleSection>
67
+ </ExampleGrid>
68
+
69
+ <ExampleGrid>
70
+ <ExampleSection
71
+ label="Trang đầu tiên (First Page)"
72
+ description="Nút Previous tự động bị mờ đi."
73
+ codeString={`<PaginationPreset currentPage={1} totalPages={5} />
74
+ `}
75
+ >
76
+ <PaginationPreset currentPage={1} totalPages={5} size={globalSize} />
77
+ </ExampleSection>
78
+
79
+ <ExampleSection
80
+ label="Trang cuối cùng (Last Page)"
81
+ description="Nút Next tự động bị mờ đi."
82
+ codeString={`<PaginationPreset currentPage={5} totalPages={5} />
83
+ `}
84
+ >
85
+ <PaginationPreset currentPage={5} totalPages={5} size={globalSize} />
86
+ </ExampleSection>
87
+ </ExampleGrid>
88
+ </div>
89
+ );
90
+ }
91
+
92
+ // ──────────────────────────────────────────────────────────
93
+ // SECTION 2: Micro Content
94
+ // ──────────────────────────────────────────────────────────
95
+ function PaginationMicroShowcase({ globalSize }: { globalSize: Size }) {
96
+ return (
97
+ <div className="space-y-10 mt-6">
98
+ <ExampleSection
99
+ label="Cơ bản (Default)"
100
+ description="Lắp ráp thủ công các item và link. Hỗ trợ prop size."
101
+ codeString={`<Pagination>
102
+ <PaginationContent>
103
+ <PaginationItem>
104
+ <PaginationPrevious href="#" />
105
+ </PaginationItem>
106
+ <PaginationItem>
107
+ <PaginationLink href="#">
108
+ 1
109
+ </PaginationLink>
110
+ </PaginationItem>
111
+ <PaginationItem>
112
+ <PaginationLink href="#" isActive>
113
+ 2
114
+ </PaginationLink>
115
+ </PaginationItem>
116
+ <PaginationItem>
117
+ <PaginationLink href="#">
118
+ 3
119
+ </PaginationLink>
120
+ </PaginationItem>
121
+ <PaginationItem>
122
+ <PaginationEllipsis />
123
+ </PaginationItem>
124
+ <PaginationItem>
125
+ <PaginationNext href="#" />
126
+ </PaginationItem>
127
+ </PaginationContent>
128
+ </Pagination>
129
+ `}
130
+ >
131
+ <Pagination>
132
+ <PaginationContent>
133
+ <PaginationItem>
134
+ <PaginationPrevious href="#" size={globalSize} />
135
+ </PaginationItem>
136
+ <PaginationItem>
137
+ <PaginationLink href="#" size={globalSize}>
138
+ 1
139
+ </PaginationLink>
140
+ </PaginationItem>
141
+ <PaginationItem>
142
+ <PaginationLink href="#" isActive size={globalSize}>
143
+ 2
144
+ </PaginationLink>
145
+ </PaginationItem>
146
+ <PaginationItem>
147
+ <PaginationLink href="#" size={globalSize}>
148
+ 3
149
+ </PaginationLink>
150
+ </PaginationItem>
151
+ <PaginationItem>
152
+ <PaginationEllipsis />
153
+ </PaginationItem>
154
+ <PaginationItem>
155
+ <PaginationNext href="#" size={globalSize} />
156
+ </PaginationItem>
157
+ </PaginationContent>
158
+ </Pagination>
159
+ </ExampleSection>
160
+
161
+ <ExampleSection
162
+ label="🧭 Use Case Comparison"
163
+ description="So sánh nhanh khi nào dùng Micro và Macro."
164
+ fullWidth
165
+ codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
166
+ {/* Story 1: Macro wins */}
167
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
168
+ <div className="flex items-start gap-3">
169
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
170
+ <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>
171
+ </span>
172
+ <div>
173
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Story 1 · Dùng Macro</p>
174
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">Xử lý tự động</h3>
175
+ </div>
176
+ </div>
177
+ <p className="text-xs text-muted-foreground leading-relaxed">
178
+ Dùng Preset khi bạn chỉ muốn truyền vào <DocsCode>currentPage</DocsCode> và <DocsCode>totalPages</DocsCode> để tự động sinh ra UI phân trang chuẩn xác (bao gồm dấu ba chấm).
179
+ </p>
180
+ </div>
181
+
182
+ {/* Story 2: Micro wins */}
183
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
184
+ <div className="flex items-start gap-3">
185
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
186
+ <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>
187
+ </span>
188
+ <div>
189
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Story 2 · Dùng Micro</p>
190
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">Tuỳ biến HTML / SEO</h3>
191
+ </div>
192
+ </div>
193
+ <p className="text-xs text-muted-foreground leading-relaxed">
194
+ Dùng Micro khi bạn muốn dùng <DocsCode>&lt;a&gt;</DocsCode> tag thực sự thay vì onClick (tốt cho SEO) hoặc khi bạn có luồng logic hiển thị pagination đặc biệt.
195
+ </p>
196
+ </div>
197
+ </div>`}
198
+ >
199
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
200
+ {/* Story 1: Macro wins */}
201
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
202
+ <div className="flex items-start gap-3">
203
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
204
+ <svg
205
+ xmlns="http://www.w3.org/2000/svg"
206
+ className="size-4"
207
+ viewBox="0 0 24 24"
208
+ fill="none"
209
+ stroke="currentColor"
210
+ strokeWidth="2"
211
+ strokeLinecap="round"
212
+ strokeLinejoin="round"
213
+ aria-hidden="true"
214
+ >
215
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
216
+ </svg>
217
+ </span>
218
+ <div>
219
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
220
+ Story 1 · Dùng Macro
221
+ </p>
222
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
223
+ Xử lý tự động
224
+ </h3>
225
+ </div>
226
+ </div>
227
+ <p className="text-xs text-muted-foreground leading-relaxed">
228
+ Dùng Preset khi bạn chỉ muốn truyền vào{" "}
229
+ <DocsCode>currentPage</DocsCode> và{" "}
230
+ <DocsCode>totalPages</DocsCode> để tự động sinh ra UI phân trang
231
+ chuẩn xác (bao gồm dấu ba chấm).
232
+ </p>
233
+ </div>
234
+
235
+ {/* Story 2: Micro wins */}
236
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
237
+ <div className="flex items-start gap-3">
238
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
239
+ <svg
240
+ xmlns="http://www.w3.org/2000/svg"
241
+ className="size-4"
242
+ viewBox="0 0 24 24"
243
+ fill="none"
244
+ stroke="currentColor"
245
+ strokeWidth="2"
246
+ strokeLinecap="round"
247
+ strokeLinejoin="round"
248
+ aria-hidden="true"
249
+ >
250
+ <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" />
251
+ </svg>
252
+ </span>
253
+ <div>
254
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
255
+ Story 2 · Dùng Micro
256
+ </p>
257
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
258
+ Tuỳ biến HTML / SEO
259
+ </h3>
260
+ </div>
261
+ </div>
262
+ <p className="text-xs text-muted-foreground leading-relaxed">
263
+ Dùng Micro khi bạn muốn dùng <DocsCode>&lt;a&gt;</DocsCode> tag
264
+ thực sự thay vì onClick (tốt cho SEO) hoặc khi bạn có luồng logic
265
+ hiển thị pagination đặc biệt.
266
+ </p>
267
+ </div>
268
+ </div>
269
+ </ExampleSection>
270
+ </div>
271
+ );
272
+ }
273
+
274
+ // ──────────────────────────────────────────────────────────
275
+ // SECTION 3: Entry point
276
+ // ──────────────────────────────────────────────────────────
277
+ export default function PaginationShowcase() {
278
+ const { size: globalSize } = useDevContext();
279
+ return (
280
+ <Showcase
281
+ title="Pagination"
282
+ description="Thanh phân trang với điều hướng trước/sau, tự động rút gọn dấu ba chấm."
283
+ generalConcept={
284
+ <ShowcaseDocs>
285
+ <DocsH3>Khi nào nên dùng Macro</DocsH3>
286
+ <DocsP>
287
+ <DocsCode>PaginationPreset</DocsCode> tự động tính toán số trang,
288
+ dấu ba chấm (ellipsis) và vô hiệu hóa nút Prev/Next. Bạn chỉ cần
289
+ truyền <DocsCode>currentPage</DocsCode> và{" "}
290
+ <DocsCode>totalPages</DocsCode>.
291
+ </DocsP>
292
+ <DocsH3>Khi nào nên dùng Micro</DocsH3>
293
+ <DocsP>
294
+ Dùng <DocsCode>Pagination</DocsCode> khi bạn muốn tự kiểm soát cấu
295
+ trúc HTML, thay đổi icon, hoặc dùng phân trang dạng tĩnh (như SEO
296
+ link /page/1, /page/2) thay vì phụ thuộc vào React state.
297
+ </DocsP>
298
+ </ShowcaseDocs>
299
+ }
300
+ tabs={[
301
+ {
302
+ label: "Micro (Primitive)",
303
+ content: <PaginationMicroShowcase globalSize={globalSize} />,
304
+ },
305
+ {
306
+ label: "Macro (Preset)",
307
+ content: <PaginationMacroShowcase globalSize={globalSize} />,
308
+ },
309
+ ]}
310
+ />
311
+ );
312
+ }
@@ -0,0 +1,374 @@
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 { useState } from "react";
10
+
11
+ import { Button } from "../../components/micro/button";
12
+ import { Input } from "../../components/micro/input";
13
+ import { Label } from "../../components/micro/label";
14
+ import {
15
+ Popover,
16
+ PopoverContent,
17
+ PopoverDescription,
18
+ PopoverHeader,
19
+ PopoverTitle,
20
+ PopoverTrigger,
21
+ PopoverPortal,
22
+ } from "../../components/micro/popover";
23
+ import { type Size } from "../../lib/types";
24
+ import { Bell, Settings } from "lucide-react";
25
+
26
+ // ──────────────────────────────────────────────────────────
27
+ // SECTION 2: Micro Content (không export)
28
+ // ──────────────────────────────────────────────────────────
29
+ function PopoverMicroShowcase({ globalSize }: { globalSize: Size }) {
30
+ const [isOpen, setIsOpen] = useState(false);
31
+
32
+ return (
33
+ <div className="space-y-10 mt-6">
34
+ <ExampleGrid>
35
+ <ExampleSection
36
+ label="Default"
37
+ description="Cửa sổ Popover tiêu chuẩn."
38
+ codeString={`<Popover>
39
+ <PopoverTrigger
40
+ render={
41
+ <Button variant="outline" size="${globalSize}">
42
+ Open Popover
43
+ </Button>
44
+ }
45
+ />
46
+ <PopoverPortal><PopoverContent className="w-80" sideOffset={8}>
47
+ <PopoverHeader>
48
+ <PopoverTitle>Dimensions</PopoverTitle>
49
+ <PopoverDescription>
50
+ Cài đặt kích thước cho layer.
51
+ </PopoverDescription>
52
+ </PopoverHeader>
53
+ <div className="grid gap-4 mt-4">
54
+ <div className="grid grid-cols-3 items-center gap-4">
55
+ <Label htmlFor="width">Width</Label>
56
+ <Input
57
+ id="width"
58
+ defaultValue="100%"
59
+ className="col-span-2 h-8"
60
+ />
61
+ </div>
62
+ <div className="grid grid-cols-3 items-center gap-4">
63
+ <Label htmlFor="height">Height</Label>
64
+ <Input
65
+ id="height"
66
+ defaultValue="200px"
67
+ className="col-span-2 h-8"
68
+ />
69
+ </div>
70
+ </div>
71
+ </PopoverContent></PopoverPortal>
72
+ </Popover>
73
+ `}
74
+ >
75
+ <Popover>
76
+ <PopoverTrigger
77
+ render={
78
+ <Button variant="outline" size={globalSize}>
79
+ Open Popover
80
+ </Button>
81
+ }
82
+ />
83
+
84
+ <PopoverPortal>
85
+ <PopoverContent className="w-80" sideOffset={8}>
86
+ <PopoverHeader>
87
+ <PopoverTitle>Dimensions</PopoverTitle>
88
+ <PopoverDescription>
89
+ Cài đặt kích thước cho layer.
90
+ </PopoverDescription>
91
+ </PopoverHeader>
92
+ <div className="grid gap-4 mt-4">
93
+ <div className="grid grid-cols-3 items-center gap-4">
94
+ <Label htmlFor="width">Width</Label>
95
+ <Input
96
+ id="width"
97
+ defaultValue="100%"
98
+ className="col-span-2 h-8"
99
+ />
100
+ </div>
101
+ <div className="grid grid-cols-3 items-center gap-4">
102
+ <Label htmlFor="height">Height</Label>
103
+ <Input
104
+ id="height"
105
+ defaultValue="200px"
106
+ className="col-span-2 h-8"
107
+ />
108
+ </div>
109
+ </div>
110
+ </PopoverContent>
111
+ </PopoverPortal>
112
+ </Popover>
113
+ </ExampleSection>
114
+
115
+ <ExampleSection
116
+ label="Icon Trigger"
117
+ description="Mở Popover bằng Icon Button."
118
+ codeString={`<div className="flex gap-4">
119
+ <Popover>
120
+ <PopoverTrigger
121
+ render={
122
+ <Button
123
+ variant="ghost"
124
+ size="md"
125
+ iconOnly
126
+ className="rounded-full"
127
+ >
128
+ <Bell className="size-4" />
129
+ </Button>
130
+ }
131
+ />
132
+ <PopoverPortal><PopoverContent className="w-64" sideOffset={8} align="start">
133
+ <PopoverHeader>
134
+ <PopoverTitle>Thông báo</PopoverTitle>
135
+ <PopoverDescription>
136
+ Bạn có 3 tin nhắn chưa đọc.
137
+ </PopoverDescription>
138
+ </PopoverHeader>
139
+ </PopoverContent></PopoverPortal>
140
+ </Popover>
141
+
142
+ <Popover>
143
+ <PopoverTrigger
144
+ render={
145
+ <Button variant="outline" size="md" iconOnly>
146
+ <Settings className="size-4" />
147
+ </Button>
148
+ }
149
+ />
150
+ <PopoverPortal><PopoverContent className="w-56" sideOffset={8}>
151
+ <PopoverHeader>
152
+ <PopoverTitle>Cài đặt nhanh</PopoverTitle>
153
+ </PopoverHeader>
154
+ <div className="flex flex-col gap-2 mt-2">
155
+ <Button variant="ghost" className="justify-start">
156
+ Tài khoản
157
+ </Button>
158
+ <Button variant="ghost" className="justify-start">
159
+ Giao diện
160
+ </Button>
161
+ <Button
162
+ variant="ghost"
163
+ className="justify-start text-destructive hover:text-destructive"
164
+ >
165
+ Đăng xuất
166
+ </Button>
167
+ </div>
168
+ </PopoverContent></PopoverPortal>
169
+ </Popover>
170
+ </div>
171
+ `}
172
+ >
173
+ <div className="flex gap-4">
174
+ <Popover>
175
+ <PopoverTrigger
176
+ render={
177
+ <Button
178
+ variant="ghost"
179
+ size="md"
180
+ iconOnly
181
+ className="rounded-full"
182
+ >
183
+ <Bell className="size-4" />
184
+ </Button>
185
+ }
186
+ />
187
+
188
+ <PopoverPortal>
189
+ <PopoverContent className="w-64" sideOffset={8} align="start">
190
+ <PopoverHeader>
191
+ <PopoverTitle>Thông báo</PopoverTitle>
192
+ <PopoverDescription>
193
+ Bạn có 3 tin nhắn chưa đọc.
194
+ </PopoverDescription>
195
+ </PopoverHeader>
196
+ </PopoverContent>
197
+ </PopoverPortal>
198
+ </Popover>
199
+
200
+ <Popover>
201
+ <PopoverTrigger
202
+ render={
203
+ <Button variant="outline" size="md" iconOnly>
204
+ <Settings className="size-4" />
205
+ </Button>
206
+ }
207
+ />
208
+
209
+ <PopoverPortal>
210
+ <PopoverContent className="w-56" sideOffset={8}>
211
+ <PopoverHeader>
212
+ <PopoverTitle>Cài đặt nhanh</PopoverTitle>
213
+ </PopoverHeader>
214
+ <div className="flex flex-col gap-2 mt-2">
215
+ <Button variant="ghost" className="justify-start">
216
+ Tài khoản
217
+ </Button>
218
+ <Button variant="ghost" className="justify-start">
219
+ Giao diện
220
+ </Button>
221
+ <Button
222
+ variant="ghost"
223
+ className="justify-start text-destructive hover:text-destructive"
224
+ >
225
+ Đăng xuất
226
+ </Button>
227
+ </div>
228
+ </PopoverContent>
229
+ </PopoverPortal>
230
+ </Popover>
231
+ </div>
232
+ </ExampleSection>
233
+ </ExampleGrid>
234
+
235
+ <ExampleSection
236
+ label="Placement (Vị trí)"
237
+ description="Popover có thể hiển thị ở nhiều hướng khác nhau so với trigger (Top, Bottom, Left, Right)."
238
+ codeString={`<Popover>
239
+ <PopoverTrigger asChild>
240
+ <Button variant="outline">top</Button>
241
+ </PopoverTrigger>
242
+ <PopoverPortal><PopoverContent side="top" sideOffset={8} className="w-48 text-center text-sm p-4">
243
+ Hiển thị ở phía <strong>top</strong>
244
+ </PopoverContent></PopoverPortal>
245
+ </Popover>`}
246
+ >
247
+ <div className="flex flex-wrap items-center justify-center gap-4 py-8">
248
+ {(["top", "right", "bottom", "left"] as const).map((side) => (
249
+ <Popover key={side}>
250
+ <PopoverTrigger
251
+ render={
252
+ <Button
253
+ variant="outline"
254
+ size={globalSize}
255
+ className="capitalize"
256
+ >
257
+ {side}
258
+ </Button>
259
+ }
260
+ />
261
+ <PopoverPortal>
262
+ <PopoverContent
263
+ side={side}
264
+ sideOffset={8}
265
+ className="w-48 text-center text-sm p-4"
266
+ >
267
+ Hiển thị ở phía <strong className="capitalize">{side}</strong>
268
+ </PopoverContent>
269
+ </PopoverPortal>
270
+ </Popover>
271
+ ))}
272
+ </div>
273
+ </ExampleSection>
274
+
275
+ <ExampleSection
276
+ label="Controlled State"
277
+ description="Quản lý trạng thái đóng/mở của Popover thông qua React state (open và onOpenChange)."
278
+ codeString={`const [isOpen, setIsOpen] = React.useState(false)
279
+
280
+ return (
281
+ <Popover open={isOpen} onOpenChange={setIsOpen}>
282
+ <PopoverTrigger asChild>
283
+ <Button variant="outline">Toggle Controlled Popover</Button>
284
+ </PopoverTrigger>
285
+ <PopoverPortal><PopoverContent className="w-80" sideOffset={8}>
286
+ <PopoverHeader>
287
+ <PopoverTitle>Controlled Mode</PopoverTitle>
288
+ <PopoverDescription>
289
+ Popover này được control bởi state. Bạn có thể đóng nó bằng nút bên dưới hoặc click ra ngoài.
290
+ </PopoverDescription>
291
+ </PopoverHeader>
292
+ <div className="mt-4 flex justify-end">
293
+ <Button size="sm" color="secondary" onClick={() => setIsOpen(false)}>
294
+ Đóng Popover
295
+ </Button>
296
+ </div>
297
+ </PopoverContent></PopoverPortal>
298
+ </Popover>
299
+ )`}
300
+ >
301
+ <div className="flex items-center gap-4">
302
+ <Popover open={isOpen} onOpenChange={setIsOpen}>
303
+ <PopoverTrigger
304
+ render={
305
+ <Button variant="outline" size={globalSize}>
306
+ Toggle Controlled Popover
307
+ </Button>
308
+ }
309
+ />
310
+ <PopoverPortal>
311
+ <PopoverContent className="w-80" sideOffset={8}>
312
+ <PopoverHeader>
313
+ <PopoverTitle>Controlled Mode</PopoverTitle>
314
+ <PopoverDescription>
315
+ Popover này được control bởi state. Bạn có thể đóng nó bằng
316
+ nút bên dưới hoặc click ra ngoài.
317
+ </PopoverDescription>
318
+ </PopoverHeader>
319
+ <div className="mt-4 flex justify-end">
320
+ <Button
321
+ size="sm"
322
+ color="secondary"
323
+ onClick={() => setIsOpen(false)}
324
+ >
325
+ Đóng Popover
326
+ </Button>
327
+ </div>
328
+ </PopoverContent>
329
+ </PopoverPortal>
330
+ </Popover>
331
+
332
+ <div className="text-sm text-muted-foreground">
333
+ Trạng thái hiện tại:{" "}
334
+ <strong
335
+ data-active={isOpen ? "" : undefined}
336
+ className="data-active:text-primary"
337
+ >
338
+ {isOpen ? "Mở" : "Đóng"}
339
+ </strong>
340
+ </div>
341
+ </div>
342
+ </ExampleSection>
343
+ </div>
344
+ );
345
+ }
346
+
347
+ // ──────────────────────────────────────────────────────────
348
+ // SECTION 3: Entry point (export default)
349
+ // ──────────────────────────────────────────────────────────
350
+ export default function PopoverShowcase() {
351
+ const { size: globalSize } = useDevContext();
352
+ return (
353
+ <Showcase
354
+ title="Popover"
355
+ description="Popup nội dung phong phú, kích hoạt bằng một nút hoặc trigger."
356
+ generalConcept={
357
+ <ShowcaseDocs>
358
+ <DocsP>
359
+ Popover là một floating panel hiển thị khi người dùng click vào một
360
+ phần tử (trigger). Khác với Tooltip (hiển thị khi hover), Popover
361
+ dùng cho những nội dung phong phú hơn, chứa các tương tác phức tạp
362
+ như form, danh sách cài đặt, v.v.
363
+ </DocsP>
364
+ </ShowcaseDocs>
365
+ }
366
+ tabs={[
367
+ {
368
+ label: "Micro (Primitive)",
369
+ content: <PopoverMicroShowcase globalSize={globalSize} />,
370
+ },
371
+ ]}
372
+ />
373
+ );
374
+ }