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,498 @@
1
+ import { useDevContext } from "../../dev/components/dev-context";
2
+ import { TextareaPreset } from "../../components/macro/textarea-preset";
3
+ import {
4
+ Field,
5
+ FieldContent,
6
+ FieldError,
7
+ FieldLabel,
8
+ } from "../../components/micro/field";
9
+ import {
10
+ InputGroup,
11
+ InputGroupAddon,
12
+ InputGroupText,
13
+ InputGroupTextarea,
14
+ } from "../../components/micro/input-group";
15
+ import { Textarea } from "../../components/micro/textarea";
16
+ import {
17
+ DocsCode,
18
+ DocsH3,
19
+ DocsP,
20
+ ExampleGrid,
21
+ ExampleSection,
22
+ Showcase,
23
+ ShowcaseDocs,
24
+ } from "../../dev/components/showcase";
25
+ import { type Size } from "../../lib/types";
26
+ import { useState } from "react";
27
+
28
+ // ──────────────────────────────────────────────────────────
29
+ // SECTION 1: Macro Content
30
+ // ──────────────────────────────────────────────────────────
31
+ function TextareaMacroShowcase({ globalSize }: { globalSize: Size }) {
32
+ const [bio, setBio] = useState("");
33
+ const maxLength = 280;
34
+
35
+ return (
36
+ <div className="space-y-10 mt-6">
37
+ <ExampleGrid>
38
+ <ExampleSection
39
+ label="Tiêu chuẩn"
40
+ description="Trường văn bản nhiều dòng với nhãn và mô tả."
41
+ codeString={`<TextareaPreset
42
+ label="Phản hồi (Feedback)"
43
+ description="Đóng góp ý kiến của bạn về sản phẩm."
44
+ placeholder="Viết phản hồi..."
45
+ className="w-full"
46
+ />
47
+ `}
48
+ >
49
+ <TextareaPreset
50
+ label="Phản hồi (Feedback)"
51
+ description="Đóng góp ý kiến của bạn về sản phẩm."
52
+ placeholder="Viết phản hồi..."
53
+ size={globalSize}
54
+ className="w-full"
55
+ />
56
+ </ExampleSection>
57
+
58
+ <ExampleSection
59
+ label="Lỗi xác thực (Validation Error)"
60
+ description="Hiển thị thông báo lỗi khi đầu vào không hợp lệ."
61
+ codeString={`<TextareaPreset
62
+ label="Khiếu nại"
63
+ placeholder="Mô tả vấn đề..."
64
+ errorMessage="Vui lòng cung cấp ít nhất 20 ký tự để chúng tôi hỗ trợ tốt hơn."
65
+ className="w-full"
66
+ rows={3}
67
+ />
68
+ `}
69
+ >
70
+ <TextareaPreset
71
+ label="Khiếu nại"
72
+ placeholder="Mô tả vấn đề..."
73
+ errorMessage="Vui lòng cung cấp ít nhất 20 ký tự để chúng tôi hỗ trợ tốt hơn."
74
+ size={globalSize}
75
+ className="w-full"
76
+ rows={3}
77
+ />
78
+ </ExampleSection>
79
+ </ExampleGrid>
80
+
81
+ <ExampleGrid>
82
+ <ExampleSection
83
+ label="Giới hạn ký tự (Character Count)"
84
+ description="Sử dụng React state và slot description để đếm ngược số ký tự."
85
+ codeString={`const [bio, setBio] = useState("");
86
+ const maxLength = 280;
87
+
88
+ return (
89
+ <TextareaPreset
90
+ label="Tiểu sử"
91
+ size="\${globalSize}"
92
+ description={
93
+ <span className="flex justify-between">
94
+ <span>Mô tả ngắn gọn về bản thân bạn.</span>
95
+ <span
96
+ data-invalid={bio.length > maxLength ? "" : undefined}
97
+ className="data-invalid:text-destructive data-invalid:font-medium"
98
+ >
99
+ {bio.length}/{maxLength}
100
+ </span>
101
+ </span>
102
+ }
103
+ placeholder="I'm a developer who loves..."
104
+ value={bio}
105
+ onChange={(e) => setBio(e.target.value)}
106
+ maxLength={maxLength}
107
+ errorMessage={bio.length > maxLength ? \`Vượt quá \${bio.length - maxLength} ký tự.\` : undefined}
108
+ rows={4}
109
+ />
110
+ );`}
111
+ >
112
+ <TextareaPreset
113
+ label="Tiểu sử"
114
+ description={
115
+ <span className="flex justify-between">
116
+ <span>Mô tả ngắn gọn về bản thân bạn.</span>
117
+ <span
118
+ data-invalid={bio.length > maxLength ? "" : undefined}
119
+ className="data-invalid:text-destructive data-invalid:font-medium"
120
+ >
121
+ {bio.length}/{maxLength}
122
+ </span>
123
+ </span>
124
+ }
125
+ placeholder="I'm a developer who loves..."
126
+ value={bio}
127
+ onChange={(e) => setBio(e.target.value)}
128
+ maxLength={maxLength}
129
+ errorMessage={
130
+ bio.length > maxLength
131
+ ? `Vượt quá ${bio.length - maxLength} ký tự.`
132
+ : undefined
133
+ }
134
+ size={globalSize}
135
+ className="w-full"
136
+ rows={4}
137
+ />
138
+ </ExampleSection>
139
+
140
+ <ExampleSection
141
+ label="Khóa / Bất hoạt (Disabled)"
142
+ description="Trường văn bản không thể tương tác."
143
+ codeString={`<TextareaPreset
144
+ label="Ghi chú lưu trữ"
145
+ description="Những ghi chú này ở dạng chỉ đọc."
146
+ defaultValue="Dự án này đã hoàn thành vào năm 2023. Không thể thay đổi nội dung."
147
+ disabled
148
+ className="w-full"
149
+ rows={4}
150
+ />
151
+ `}
152
+ >
153
+ <TextareaPreset
154
+ label="Ghi chú lưu trữ"
155
+ description="Những ghi chú này ở dạng chỉ đọc."
156
+ defaultValue="Dự án này đã hoàn thành vào năm 2023. Không thể thay đổi nội dung."
157
+ disabled
158
+ size={globalSize}
159
+ className="w-full"
160
+ rows={4}
161
+ />
162
+ </ExampleSection>
163
+ </ExampleGrid>
164
+
165
+ <ExampleSection
166
+ label="Thực tế sử dụng (Real-world Form)"
167
+ description="Bố cục thực tế trong một form hoàn chỉnh."
168
+ fullWidth
169
+ codeString={`<div className="w-full max-w-lg rounded-xl border border-border bg-card p-5 shadow-sm">
170
+ <h3 className="mb-4 font-semibold">Tạo Ticket Hỗ Trợ</h3>
171
+ <TextareaPreset
172
+ label="Mô tả sự cố"
173
+ description="Vui lòng cung cấp chi tiết lỗi, các bước tái hiện và cấu hình môi trường."
174
+ placeholder="Ví dụ: Khi tôi click vào nút Submit, hệ thống báo lỗi 500..."
175
+ className="w-full"
176
+ rows={6}
177
+ />
178
+ </div>
179
+ `}
180
+ >
181
+ <div className="w-full max-w-lg rounded-xl border border-border bg-card p-5 shadow-sm">
182
+ <h3 className="mb-4 font-semibold">Tạo Ticket Hỗ Trợ</h3>
183
+ <TextareaPreset
184
+ label="Mô tả sự cố"
185
+ description="Vui lòng cung cấp chi tiết lỗi, các bước tái hiện và cấu hình môi trường."
186
+ placeholder="Ví dụ: Khi tôi click vào nút Submit, hệ thống báo lỗi 500..."
187
+ size={globalSize}
188
+ className="w-full"
189
+ rows={6}
190
+ />
191
+ </div>
192
+ </ExampleSection>
193
+ </div>
194
+ );
195
+ }
196
+
197
+ // ──────────────────────────────────────────────────────────
198
+ // SECTION 2: Micro Content
199
+ // ──────────────────────────────────────────────────────────
200
+ function TextareaMicroShowcase({ globalSize }: { globalSize: Size }) {
201
+ return (
202
+ <div className="space-y-10 mt-6">
203
+ <ExampleGrid>
204
+ <ExampleSection
205
+ label="Cơ bản (Primitive)"
206
+ description="Khung nhập văn bản nhiều dòng không có nhãn."
207
+ codeString={`<Textarea
208
+ rows={4}
209
+ placeholder="Viết một đoạn văn dài ở đây..."
210
+ className="w-full"
211
+ />
212
+ `}
213
+ >
214
+ <Textarea
215
+ size={globalSize}
216
+ rows={4}
217
+ placeholder="Viết một đoạn văn dài ở đây..."
218
+ className="w-full"
219
+ />
220
+ </ExampleSection>
221
+
222
+ <ExampleSection
223
+ label="Auto Resize (CSS content)"
224
+ description="Giãn chiều cao tự động nhờ class field-sizing-content (nếu trình duyệt hỗ trợ)."
225
+ codeString={`<Textarea
226
+ placeholder="Gõ nhiều dòng để xem nó tự giãn..."
227
+ defaultValue={"Dòng 1\nDòng 2\nDòng 3\nDòng 4"}
228
+ className="w-full"
229
+ />
230
+ `}
231
+ >
232
+ <Textarea
233
+ size={globalSize}
234
+ placeholder="Gõ nhiều dòng để xem nó tự giãn..."
235
+ defaultValue={"Dòng 1\nDòng 2\nDòng 3\nDòng 4"}
236
+ className="w-full"
237
+ />
238
+ </ExampleSection>
239
+ </ExampleGrid>
240
+
241
+ <ExampleGrid>
242
+ <ExampleSection
243
+ label="InputGroup + Textarea"
244
+ description="Textarea bên trong InputGroup với Addon. Sử dụng InputGroupTextarea."
245
+ codeString={`<Field className="w-full">
246
+ <FieldLabel htmlFor="tf-group-textarea">Bình luận</FieldLabel>
247
+ <FieldContent>
248
+ <InputGroup className="items-start">
249
+ <InputGroupAddon align="start" className="mt-2">
250
+ <InputGroupText>💬</InputGroupText>
251
+ </InputGroupAddon>
252
+ <InputGroupTextarea
253
+ id="tf-group-textarea"
254
+ rows={3}
255
+ placeholder="Để lại bình luận của bạn..."
256
+ />
257
+ </InputGroup>
258
+ </FieldContent>
259
+ </Field>
260
+ `}
261
+ >
262
+ <Field size={globalSize} className="w-full">
263
+ <FieldLabel htmlFor="tf-group-textarea">Bình luận</FieldLabel>
264
+ <FieldContent>
265
+ <InputGroup size={globalSize} className="items-start">
266
+ <InputGroupAddon align="start" className="mt-2">
267
+ <InputGroupText>💬</InputGroupText>
268
+ </InputGroupAddon>
269
+ <InputGroupTextarea
270
+ id="tf-group-textarea"
271
+ rows={3}
272
+ placeholder="Để lại bình luận của bạn..."
273
+ />
274
+ </InputGroup>
275
+ </FieldContent>
276
+ </Field>
277
+ </ExampleSection>
278
+
279
+ <ExampleSection
280
+ label="Trạng thái Lỗi thủ công"
281
+ description="Tự gắn aria-invalid vào Textarea và dùng FieldError."
282
+ codeString={`<Field className="w-full">
283
+ <FieldLabel htmlFor="tf-invalid">Mô tả hệ thống</FieldLabel>
284
+ <FieldContent>
285
+ <Textarea
286
+ id="tf-invalid"
287
+ rows={3}
288
+ aria-invalid
289
+ placeholder="Mô tả..."
290
+ defaultValue="Quá ngắn"
291
+ />
292
+ </FieldContent>
293
+ <FieldError>Mô tả không đạt đủ độ dài tối thiểu.</FieldError>
294
+ </Field>
295
+ `}
296
+ >
297
+ <Field size={globalSize} className="w-full">
298
+ <FieldLabel htmlFor="tf-invalid">Mô tả hệ thống</FieldLabel>
299
+ <FieldContent>
300
+ <Textarea
301
+ id="tf-invalid"
302
+ size={globalSize}
303
+ rows={3}
304
+ aria-invalid
305
+ placeholder="Mô tả..."
306
+ defaultValue="Quá ngắn"
307
+ />
308
+ </FieldContent>
309
+ <FieldError>Mô tả không đạt đủ độ dài tối thiểu.</FieldError>
310
+ </Field>
311
+ </ExampleSection>
312
+ </ExampleGrid>
313
+
314
+ <ExampleSection
315
+ label="🧭 Use Case Comparison"
316
+ description="So sánh nhanh khi nào dùng Micro và Macro."
317
+ fullWidth
318
+ codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
319
+ {/* Story 1: Macro wins */}
320
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
321
+ <div className="flex items-start gap-3">
322
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
323
+ <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>
324
+ </span>
325
+ <div>
326
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Story 1 · Dùng Macro</p>
327
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">Form lấy thông tin thông thường</h3>
328
+ </div>
329
+ </div>
330
+ <p className="text-xs text-muted-foreground leading-relaxed">
331
+ Bạn cần ô nhập có tên trường rõ ràng, có gợi ý nhập liệu. Chỉ việc truyền props vào <DocsCode>TextareaPreset</DocsCode> là xong.
332
+ </p>
333
+ <div className="rounded-lg bg-muted/50 p-3">
334
+ <TextareaPreset
335
+ size="sm"
336
+ label="Mục tiêu nghề nghiệp"
337
+ description="Tối đa 500 từ."
338
+ className="w-full"
339
+ />
340
+ </div>
341
+ </div>
342
+
343
+ {/* Story 2: Micro wins */}
344
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
345
+ <div className="flex items-start gap-3">
346
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
347
+ <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>
348
+ </span>
349
+ <div>
350
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">Story 2 · Dùng Micro</p>
351
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">Layout kết hợp Addon đặc thù</h3>
352
+ </div>
353
+ </div>
354
+ <p className="text-xs text-muted-foreground leading-relaxed">
355
+ Khi bạn cần nối một icon vào ngay bên cạnh khung textarea giống như giao diện chat. Macro không hỗ trợ layout này cho Textarea.
356
+ </p>
357
+ <div className="rounded-lg bg-muted/50 p-3">
358
+ <InputGroup size="sm" className="items-end w-full">
359
+ <InputGroupTextarea rows={2} placeholder="Tin nhắn..." />
360
+ <button className="h-full px-3 shrink-0 rounded-r-md border-l border-input bg-muted/50 text-xs font-semibold text-primary transition-colors hover:bg-muted">GỬI</button>
361
+ </InputGroup>
362
+ </div>
363
+ </div>
364
+ </div>
365
+ `}
366
+ >
367
+ <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
368
+ {/* Story 1: Macro wins */}
369
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
370
+ <div className="flex items-start gap-3">
371
+ <span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
372
+ <svg
373
+ xmlns="http://www.w3.org/2000/svg"
374
+ className="size-4"
375
+ viewBox="0 0 24 24"
376
+ fill="none"
377
+ stroke="currentColor"
378
+ strokeWidth="2"
379
+ strokeLinecap="round"
380
+ strokeLinejoin="round"
381
+ aria-hidden="true"
382
+ >
383
+ <path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
384
+ </svg>
385
+ </span>
386
+ <div>
387
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
388
+ Story 1 · Dùng Macro
389
+ </p>
390
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
391
+ Form lấy thông tin thông thường
392
+ </h3>
393
+ </div>
394
+ </div>
395
+ <p className="text-xs text-muted-foreground leading-relaxed">
396
+ Bạn cần ô nhập có tên trường rõ ràng, có gợi ý nhập liệu. Chỉ việc
397
+ truyền props vào <DocsCode>TextareaPreset</DocsCode> là xong.
398
+ </p>
399
+ <div className="rounded-lg bg-muted/50 p-3">
400
+ <TextareaPreset
401
+ size="sm"
402
+ label="Mục tiêu nghề nghiệp"
403
+ description="Tối đa 500 từ."
404
+ className="w-full"
405
+ />
406
+ </div>
407
+ </div>
408
+
409
+ {/* Story 2: Micro wins */}
410
+ <div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
411
+ <div className="flex items-start gap-3">
412
+ <span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
413
+ <svg
414
+ xmlns="http://www.w3.org/2000/svg"
415
+ className="size-4"
416
+ viewBox="0 0 24 24"
417
+ fill="none"
418
+ stroke="currentColor"
419
+ strokeWidth="2"
420
+ strokeLinecap="round"
421
+ strokeLinejoin="round"
422
+ aria-hidden="true"
423
+ >
424
+ <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" />
425
+ </svg>
426
+ </span>
427
+ <div>
428
+ <p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
429
+ Story 2 · Dùng Micro
430
+ </p>
431
+ <h3 className="mt-0.5 text-sm font-semibold text-foreground">
432
+ Layout kết hợp Addon đặc thù
433
+ </h3>
434
+ </div>
435
+ </div>
436
+ <p className="text-xs text-muted-foreground leading-relaxed">
437
+ Khi bạn cần nối một icon vào ngay bên cạnh khung textarea giống
438
+ như giao diện chat. Macro không hỗ trợ layout này cho Textarea.
439
+ </p>
440
+ <div className="rounded-lg bg-muted/50 p-3">
441
+ <InputGroup size="sm" className="items-end w-full">
442
+ <InputGroupTextarea rows={2} placeholder="Tin nhắn..." />
443
+ <button className="h-full px-3 shrink-0 rounded-r-md border-l border-input bg-muted/50 text-xs font-semibold text-primary transition-colors hover:bg-muted">
444
+ GỬI
445
+ </button>
446
+ </InputGroup>
447
+ </div>
448
+ </div>
449
+ </div>
450
+ </ExampleSection>
451
+ </div>
452
+ );
453
+ }
454
+
455
+ // ──────────────────────────────────────────────────────────
456
+ // SECTION 3: Entry point
457
+ // ──────────────────────────────────────────────────────────
458
+ export default function TextareaShowcase() {
459
+ const { size: globalSize } = useDevContext();
460
+ return (
461
+ <Showcase
462
+ title="Textarea"
463
+ description="Trường văn bản nhiều dòng dành cho nội dung dài, phản hồi hoặc mô tả."
464
+ generalConcept={
465
+ <div className="space-y-4">
466
+ <ShowcaseDocs>
467
+ <DocsH3>Khi nào nên dùng Macro</DocsH3>
468
+ <DocsP>
469
+ <DocsCode>TextareaPreset</DocsCode> là một component hoàn chỉnh,
470
+ tích hợp sẵn Label, Description và Error Message. Sử dụng nó cho
471
+ đa số các trường hợp để giữ code ngắn gọn và đảm bảo tính nhất
472
+ quán (Accessibility).
473
+ </DocsP>
474
+ </ShowcaseDocs>
475
+ <ShowcaseDocs>
476
+ <DocsH3>Khi nào nên dùng Micro</DocsH3>
477
+ <DocsP>
478
+ <DocsCode>Textarea</DocsCode> chỉ là một ô nhập liệu độc lập. Dùng
479
+ nó khi bạn tự quản lý <DocsCode>Field</DocsCode> thủ công hoặc khi
480
+ chèn Textarea vào bên trong một <DocsCode>InputGroup</DocsCode>.
481
+ </DocsP>
482
+ </ShowcaseDocs>
483
+ </div>
484
+ }
485
+
486
+ tabs={[
487
+ {
488
+ label: "Micro (Primitive)",
489
+ content: <TextareaMicroShowcase globalSize={globalSize} />,
490
+ },
491
+ {
492
+ label: "Macro (Preset)",
493
+ content: <TextareaMacroShowcase globalSize={globalSize} />,
494
+ },
495
+ ]}
496
+ />
497
+ );
498
+ }