@gv-tech/design-system 1.1.0 → 2.0.0

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 (347) hide show
  1. package/.agent/skills/dogfood-components/SKILL.md +34 -0
  2. package/.agent/skills/maintain-component/SKILL.md +42 -0
  3. package/.github/workflows/release-please.yml +2 -2
  4. package/.prettierignore +2 -0
  5. package/.release-please-manifest.json +3 -0
  6. package/CHANGELOG.md +90 -0
  7. package/dist/App.d.ts.map +1 -1
  8. package/dist/components/docs/Footer.d.ts.map +1 -1
  9. package/dist/components/docs/PropsTable.d.ts +13 -0
  10. package/dist/components/docs/PropsTable.d.ts.map +1 -0
  11. package/dist/components/docs/Sidebar.d.ts.map +1 -1
  12. package/dist/components/docs/index.d.ts +1 -0
  13. package/dist/components/docs/index.d.ts.map +1 -1
  14. package/dist/components/ui/accordion.test.d.ts +2 -0
  15. package/dist/components/ui/accordion.test.d.ts.map +1 -0
  16. package/dist/components/ui/alert-dialog.test.d.ts +2 -0
  17. package/dist/components/ui/alert-dialog.test.d.ts.map +1 -0
  18. package/dist/components/ui/alert.test.d.ts +2 -0
  19. package/dist/components/ui/alert.test.d.ts.map +1 -0
  20. package/dist/components/ui/aspect-ratio.test.d.ts +2 -0
  21. package/dist/components/ui/aspect-ratio.test.d.ts.map +1 -0
  22. package/dist/components/ui/avatar.test.d.ts +2 -0
  23. package/dist/components/ui/avatar.test.d.ts.map +1 -0
  24. package/dist/components/ui/badge.test.d.ts +2 -0
  25. package/dist/components/ui/badge.test.d.ts.map +1 -0
  26. package/dist/components/ui/breadcrumb.test.d.ts +2 -0
  27. package/dist/components/ui/breadcrumb.test.d.ts.map +1 -0
  28. package/dist/components/ui/button.test.d.ts +2 -0
  29. package/dist/components/ui/button.test.d.ts.map +1 -0
  30. package/dist/components/ui/calendar.d.ts.map +1 -1
  31. package/dist/components/ui/calendar.test.d.ts +2 -0
  32. package/dist/components/ui/calendar.test.d.ts.map +1 -0
  33. package/dist/components/ui/card.test.d.ts +2 -0
  34. package/dist/components/ui/card.test.d.ts.map +1 -0
  35. package/dist/components/ui/carousel.test.d.ts +2 -0
  36. package/dist/components/ui/carousel.test.d.ts.map +1 -0
  37. package/dist/components/ui/chart.test.d.ts +2 -0
  38. package/dist/components/ui/chart.test.d.ts.map +1 -0
  39. package/dist/components/ui/checkbox.test.d.ts +2 -0
  40. package/dist/components/ui/checkbox.test.d.ts.map +1 -0
  41. package/dist/components/ui/collapsible.test.d.ts +2 -0
  42. package/dist/components/ui/collapsible.test.d.ts.map +1 -0
  43. package/dist/components/ui/command.test.d.ts +2 -0
  44. package/dist/components/ui/command.test.d.ts.map +1 -0
  45. package/dist/components/ui/context-menu.test.d.ts +2 -0
  46. package/dist/components/ui/context-menu.test.d.ts.map +1 -0
  47. package/dist/components/ui/dialog.test.d.ts +2 -0
  48. package/dist/components/ui/dialog.test.d.ts.map +1 -0
  49. package/dist/components/ui/drawer.test.d.ts +2 -0
  50. package/dist/components/ui/drawer.test.d.ts.map +1 -0
  51. package/dist/components/ui/dropdown-menu.test.d.ts +2 -0
  52. package/dist/components/ui/dropdown-menu.test.d.ts.map +1 -0
  53. package/dist/components/ui/form.test.d.ts +2 -0
  54. package/dist/components/ui/form.test.d.ts.map +1 -0
  55. package/dist/components/ui/hover-card.test.d.ts +2 -0
  56. package/dist/components/ui/hover-card.test.d.ts.map +1 -0
  57. package/dist/components/ui/input.test.d.ts +2 -0
  58. package/dist/components/ui/input.test.d.ts.map +1 -0
  59. package/dist/components/ui/label.test.d.ts +2 -0
  60. package/dist/components/ui/label.test.d.ts.map +1 -0
  61. package/dist/components/ui/menubar.test.d.ts +2 -0
  62. package/dist/components/ui/menubar.test.d.ts.map +1 -0
  63. package/dist/components/ui/navigation-menu.test.d.ts +2 -0
  64. package/dist/components/ui/navigation-menu.test.d.ts.map +1 -0
  65. package/dist/components/ui/pagination.test.d.ts +2 -0
  66. package/dist/components/ui/pagination.test.d.ts.map +1 -0
  67. package/dist/components/ui/popover.test.d.ts +2 -0
  68. package/dist/components/ui/popover.test.d.ts.map +1 -0
  69. package/dist/components/ui/progress.d.ts.map +1 -1
  70. package/dist/components/ui/progress.test.d.ts +2 -0
  71. package/dist/components/ui/progress.test.d.ts.map +1 -0
  72. package/dist/components/ui/radio-group.test.d.ts +2 -0
  73. package/dist/components/ui/radio-group.test.d.ts.map +1 -0
  74. package/dist/components/ui/resizable.test.d.ts +2 -0
  75. package/dist/components/ui/resizable.test.d.ts.map +1 -0
  76. package/dist/components/ui/scroll-area.test.d.ts +2 -0
  77. package/dist/components/ui/scroll-area.test.d.ts.map +1 -0
  78. package/dist/components/ui/search.d.ts +16 -0
  79. package/dist/components/ui/search.d.ts.map +1 -0
  80. package/dist/components/ui/search.test.d.ts +2 -0
  81. package/dist/components/ui/search.test.d.ts.map +1 -0
  82. package/dist/components/ui/select.test.d.ts +2 -0
  83. package/dist/components/ui/select.test.d.ts.map +1 -0
  84. package/dist/components/ui/separator.test.d.ts +2 -0
  85. package/dist/components/ui/separator.test.d.ts.map +1 -0
  86. package/dist/components/ui/sheet.test.d.ts +2 -0
  87. package/dist/components/ui/sheet.test.d.ts.map +1 -0
  88. package/dist/components/ui/skeleton.test.d.ts +2 -0
  89. package/dist/components/ui/skeleton.test.d.ts.map +1 -0
  90. package/dist/components/ui/slider.test.d.ts +2 -0
  91. package/dist/components/ui/slider.test.d.ts.map +1 -0
  92. package/dist/components/ui/sonner.test.d.ts +2 -0
  93. package/dist/components/ui/sonner.test.d.ts.map +1 -0
  94. package/dist/components/ui/switch.test.d.ts +2 -0
  95. package/dist/components/ui/switch.test.d.ts.map +1 -0
  96. package/dist/components/ui/table.test.d.ts +2 -0
  97. package/dist/components/ui/table.test.d.ts.map +1 -0
  98. package/dist/components/ui/tabs.test.d.ts +2 -0
  99. package/dist/components/ui/tabs.test.d.ts.map +1 -0
  100. package/dist/components/ui/textarea.test.d.ts +2 -0
  101. package/dist/components/ui/textarea.test.d.ts.map +1 -0
  102. package/dist/components/ui/theme-toggle.d.ts +17 -0
  103. package/dist/components/ui/theme-toggle.d.ts.map +1 -0
  104. package/dist/components/ui/toast.test.d.ts +2 -0
  105. package/dist/components/ui/toast.test.d.ts.map +1 -0
  106. package/dist/components/ui/toggle-group.test.d.ts +2 -0
  107. package/dist/components/ui/toggle-group.test.d.ts.map +1 -0
  108. package/dist/components/ui/toggle.test.d.ts +2 -0
  109. package/dist/components/ui/toggle.test.d.ts.map +1 -0
  110. package/dist/components/ui/tooltip.test.d.ts +2 -0
  111. package/dist/components/ui/tooltip.test.d.ts.map +1 -0
  112. package/dist/index.cjs.js +3 -3
  113. package/dist/index.cjs.js.map +1 -1
  114. package/dist/index.d.ts +2 -0
  115. package/dist/index.d.ts.map +1 -1
  116. package/dist/index.es.js +978 -860
  117. package/dist/index.es.js.map +1 -1
  118. package/dist/lib/tokens.d.ts +54 -0
  119. package/dist/lib/tokens.d.ts.map +1 -0
  120. package/dist/pages/ColorTokensDocs.d.ts +2 -0
  121. package/dist/pages/ColorTokensDocs.d.ts.map +1 -0
  122. package/dist/pages/GettingStarted.d.ts.map +1 -1
  123. package/dist/pages/components/AccordionDocs.d.ts.map +1 -1
  124. package/dist/pages/components/AlertDialogDocs.d.ts.map +1 -1
  125. package/dist/pages/components/AlertDocs.d.ts.map +1 -1
  126. package/dist/pages/components/AspectRatioDocs.d.ts.map +1 -1
  127. package/dist/pages/components/AvatarDocs.d.ts.map +1 -1
  128. package/dist/pages/components/BadgeDocs.d.ts.map +1 -1
  129. package/dist/pages/components/BreadcrumbDocs.d.ts.map +1 -1
  130. package/dist/pages/components/ButtonDocs.d.ts.map +1 -1
  131. package/dist/pages/components/CalendarDocs.d.ts.map +1 -1
  132. package/dist/pages/components/CardDocs.d.ts.map +1 -1
  133. package/dist/pages/components/CarouselDocs.d.ts.map +1 -1
  134. package/dist/pages/components/ChartDocs.d.ts.map +1 -1
  135. package/dist/pages/components/CheckboxDocs.d.ts.map +1 -1
  136. package/dist/pages/components/CollapsibleDocs.d.ts.map +1 -1
  137. package/dist/pages/components/CommandDocs.d.ts.map +1 -1
  138. package/dist/pages/components/ContextMenuDocs.d.ts.map +1 -1
  139. package/dist/pages/components/DialogDocs.d.ts.map +1 -1
  140. package/dist/pages/components/DrawerDocs.d.ts.map +1 -1
  141. package/dist/pages/components/DropdownMenuDocs.d.ts.map +1 -1
  142. package/dist/pages/components/FormDocs.d.ts.map +1 -1
  143. package/dist/pages/components/HoverCardDocs.d.ts.map +1 -1
  144. package/dist/pages/components/InputDocs.d.ts.map +1 -1
  145. package/dist/pages/components/LabelDocs.d.ts.map +1 -1
  146. package/dist/pages/components/MenubarDocs.d.ts.map +1 -1
  147. package/dist/pages/components/NavigationMenuDocs.d.ts.map +1 -1
  148. package/dist/pages/components/PaginationDocs.d.ts.map +1 -1
  149. package/dist/pages/components/PopoverDocs.d.ts.map +1 -1
  150. package/dist/pages/components/ProgressDocs.d.ts.map +1 -1
  151. package/dist/pages/components/RadioGroupDocs.d.ts.map +1 -1
  152. package/dist/pages/components/ResizableDocs.d.ts.map +1 -1
  153. package/dist/pages/components/ScrollAreaDocs.d.ts.map +1 -1
  154. package/dist/pages/components/SearchDocs.d.ts +2 -0
  155. package/dist/pages/components/SearchDocs.d.ts.map +1 -0
  156. package/dist/pages/components/SelectDocs.d.ts.map +1 -1
  157. package/dist/pages/components/SeparatorDocs.d.ts.map +1 -1
  158. package/dist/pages/components/SheetDocs.d.ts.map +1 -1
  159. package/dist/pages/components/SkeletonDocs.d.ts.map +1 -1
  160. package/dist/pages/components/SliderDocs.d.ts.map +1 -1
  161. package/dist/pages/components/SonnerDocs.d.ts.map +1 -1
  162. package/dist/pages/components/SwitchDocs.d.ts.map +1 -1
  163. package/dist/pages/components/TableDocs.d.ts.map +1 -1
  164. package/dist/pages/components/TabsDocs.d.ts.map +1 -1
  165. package/dist/pages/components/TextareaDocs.d.ts.map +1 -1
  166. package/dist/pages/components/ThemeToggleDocs.d.ts +2 -0
  167. package/dist/pages/components/ThemeToggleDocs.d.ts.map +1 -0
  168. package/dist/pages/components/ToastDocs.d.ts.map +1 -1
  169. package/dist/pages/components/ToggleDocs.d.ts.map +1 -1
  170. package/dist/pages/components/ToggleGroupDocs.d.ts.map +1 -1
  171. package/dist/pages/components/TooltipDocs.d.ts.map +1 -1
  172. package/dist/pages/index.d.ts +3 -0
  173. package/dist/pages/index.d.ts.map +1 -1
  174. package/dist/registry/accordion.test.json +13 -0
  175. package/dist/registry/alert-dialog.test.json +13 -0
  176. package/dist/registry/alert.test.json +13 -0
  177. package/dist/registry/aspect-ratio.test.json +13 -0
  178. package/dist/registry/avatar.test.json +13 -0
  179. package/dist/registry/badge.test.json +13 -0
  180. package/dist/registry/breadcrumb.test.json +13 -0
  181. package/dist/registry/button.test.json +13 -0
  182. package/dist/registry/calendar.json +1 -1
  183. package/dist/registry/calendar.test.json +13 -0
  184. package/dist/registry/card.test.json +13 -0
  185. package/dist/registry/carousel.test.json +13 -0
  186. package/dist/registry/chart.test.json +13 -0
  187. package/dist/registry/checkbox.test.json +13 -0
  188. package/dist/registry/collapsible.test.json +13 -0
  189. package/dist/registry/command.test.json +13 -0
  190. package/dist/registry/context-menu.test.json +13 -0
  191. package/dist/registry/dialog.test.json +13 -0
  192. package/dist/registry/drawer.test.json +13 -0
  193. package/dist/registry/dropdown-menu.test.json +13 -0
  194. package/dist/registry/form.test.json +13 -0
  195. package/dist/registry/hover-card.test.json +13 -0
  196. package/dist/registry/index.json +336 -0
  197. package/dist/registry/input.test.json +13 -0
  198. package/dist/registry/label.test.json +13 -0
  199. package/dist/registry/menubar.test.json +13 -0
  200. package/dist/registry/navigation-menu.test.json +13 -0
  201. package/dist/registry/pagination.test.json +13 -0
  202. package/dist/registry/popover.test.json +13 -0
  203. package/dist/registry/progress.json +1 -1
  204. package/dist/registry/progress.test.json +13 -0
  205. package/dist/registry/radio-group.test.json +13 -0
  206. package/dist/registry/resizable.test.json +13 -0
  207. package/dist/registry/scroll-area.test.json +13 -0
  208. package/dist/registry/search.json +13 -0
  209. package/dist/registry/search.test.json +13 -0
  210. package/dist/registry/select.test.json +13 -0
  211. package/dist/registry/separator.test.json +13 -0
  212. package/dist/registry/sheet.test.json +13 -0
  213. package/dist/registry/skeleton.test.json +13 -0
  214. package/dist/registry/slider.test.json +13 -0
  215. package/dist/registry/sonner.test.json +13 -0
  216. package/dist/registry/switch.test.json +13 -0
  217. package/dist/registry/table.test.json +13 -0
  218. package/dist/registry/tabs.test.json +13 -0
  219. package/dist/registry/textarea.test.json +13 -0
  220. package/dist/registry/theme-toggle.json +13 -0
  221. package/dist/registry/toast.test.json +13 -0
  222. package/dist/registry/toggle-group.test.json +13 -0
  223. package/dist/registry/toggle.test.json +13 -0
  224. package/dist/registry/tooltip.test.json +13 -0
  225. package/dist/setupTests.d.ts +2 -0
  226. package/dist/setupTests.d.ts.map +1 -0
  227. package/dist/{vendor-ZhQmrf1h.mjs → vendor-BLvpSabH.mjs} +7238 -7136
  228. package/dist/vendor-BLvpSabH.mjs.map +1 -0
  229. package/dist/vendor-n4WFhtJT.js +73 -0
  230. package/dist/vendor-n4WFhtJT.js.map +1 -0
  231. package/eslint.config.mjs +8 -81
  232. package/package.json +44 -46
  233. package/release-please-config.json +36 -0
  234. package/src/App.tsx +70 -7
  235. package/src/components/docs/Footer.tsx +51 -30
  236. package/src/components/docs/PropsTable.tsx +43 -0
  237. package/src/components/docs/Sidebar.tsx +57 -71
  238. package/src/components/docs/index.ts +1 -0
  239. package/src/components/ui/accordion.test.tsx +86 -0
  240. package/src/components/ui/alert-dialog.test.tsx +89 -0
  241. package/src/components/ui/alert.test.tsx +33 -0
  242. package/src/components/ui/aspect-ratio.test.tsx +34 -0
  243. package/src/components/ui/avatar.test.tsx +33 -0
  244. package/src/components/ui/badge.test.tsx +24 -0
  245. package/src/components/ui/breadcrumb.test.tsx +55 -0
  246. package/src/components/ui/button.test.tsx +62 -0
  247. package/src/components/ui/calendar.test.tsx +23 -0
  248. package/src/components/ui/calendar.tsx +14 -10
  249. package/src/components/ui/card.test.tsx +35 -0
  250. package/src/components/ui/carousel.test.tsx +37 -0
  251. package/src/components/ui/chart.test.tsx +62 -0
  252. package/src/components/ui/checkbox.test.tsx +30 -0
  253. package/src/components/ui/collapsible.test.tsx +51 -0
  254. package/src/components/ui/command.test.tsx +79 -0
  255. package/src/components/ui/context-menu.test.tsx +37 -0
  256. package/src/components/ui/dialog.test.tsx +66 -0
  257. package/src/components/ui/drawer.test.tsx +68 -0
  258. package/src/components/ui/dropdown-menu.test.tsx +93 -0
  259. package/src/components/ui/form.test.tsx +85 -0
  260. package/src/components/ui/hover-card.test.tsx +48 -0
  261. package/src/components/ui/input.test.tsx +33 -0
  262. package/src/components/ui/label.test.tsx +27 -0
  263. package/src/components/ui/menubar.test.tsx +92 -0
  264. package/src/components/ui/navigation-menu.test.tsx +53 -0
  265. package/src/components/ui/pagination.test.tsx +57 -0
  266. package/src/components/ui/popover.test.tsx +31 -0
  267. package/src/components/ui/progress.test.tsx +18 -0
  268. package/src/components/ui/progress.tsx +1 -0
  269. package/src/components/ui/radio-group.test.tsx +39 -0
  270. package/src/components/ui/resizable.test.tsx +23 -0
  271. package/src/components/ui/scroll-area.test.tsx +15 -0
  272. package/src/components/ui/search.test.tsx +75 -0
  273. package/src/components/ui/search.tsx +93 -0
  274. package/src/components/ui/select.test.tsx +42 -0
  275. package/src/components/ui/separator.test.tsx +16 -0
  276. package/src/components/ui/sheet.test.tsx +48 -0
  277. package/src/components/ui/skeleton.test.tsx +13 -0
  278. package/src/components/ui/slider.test.tsx +18 -0
  279. package/src/components/ui/sonner.test.tsx +13 -0
  280. package/src/components/ui/switch.test.tsx +22 -0
  281. package/src/components/ui/table.test.tsx +29 -0
  282. package/src/components/ui/tabs.test.tsx +43 -0
  283. package/src/components/ui/textarea.test.tsx +21 -0
  284. package/src/components/ui/theme-toggle.tsx +108 -0
  285. package/src/components/ui/toast.test.tsx +42 -0
  286. package/src/components/ui/toggle-group.test.tsx +40 -0
  287. package/src/components/ui/toggle.test.tsx +21 -0
  288. package/src/components/ui/tooltip.test.tsx +25 -0
  289. package/src/globals.css +39 -34
  290. package/src/index.ts +2 -0
  291. package/src/lib/tokens.ts +54 -0
  292. package/src/pages/ColorTokensDocs.tsx +181 -0
  293. package/src/pages/GettingStarted.tsx +55 -35
  294. package/src/pages/components/AccordionDocs.tsx +109 -0
  295. package/src/pages/components/AlertDialogDocs.tsx +88 -0
  296. package/src/pages/components/AlertDocs.tsx +20 -0
  297. package/src/pages/components/AspectRatioDocs.tsx +21 -0
  298. package/src/pages/components/AvatarDocs.tsx +48 -0
  299. package/src/pages/components/BadgeDocs.tsx +20 -0
  300. package/src/pages/components/BreadcrumbDocs.tsx +33 -0
  301. package/src/pages/components/ButtonDocs.tsx +43 -0
  302. package/src/pages/components/CalendarDocs.tsx +43 -0
  303. package/src/pages/components/CardDocs.tsx +20 -0
  304. package/src/pages/components/CarouselDocs.tsx +31 -0
  305. package/src/pages/components/ChartDocs.tsx +131 -101
  306. package/src/pages/components/CheckboxDocs.tsx +58 -0
  307. package/src/pages/components/CollapsibleDocs.tsx +51 -0
  308. package/src/pages/components/CommandDocs.tsx +109 -0
  309. package/src/pages/components/ContextMenuDocs.tsx +65 -0
  310. package/src/pages/components/DialogDocs.tsx +98 -11
  311. package/src/pages/components/DrawerDocs.tsx +210 -15
  312. package/src/pages/components/DropdownMenuDocs.tsx +273 -11
  313. package/src/pages/components/FormDocs.tsx +149 -70
  314. package/src/pages/components/HoverCardDocs.tsx +82 -5
  315. package/src/pages/components/InputDocs.tsx +51 -20
  316. package/src/pages/components/LabelDocs.tsx +40 -9
  317. package/src/pages/components/MenubarDocs.tsx +191 -18
  318. package/src/pages/components/NavigationMenuDocs.tsx +147 -49
  319. package/src/pages/components/PaginationDocs.tsx +27 -2
  320. package/src/pages/components/PopoverDocs.tsx +124 -2
  321. package/src/pages/components/ProgressDocs.tsx +54 -24
  322. package/src/pages/components/RadioGroupDocs.tsx +95 -1
  323. package/src/pages/components/ResizableDocs.tsx +102 -75
  324. package/src/pages/components/ScrollAreaDocs.tsx +64 -51
  325. package/src/pages/components/SearchDocs.tsx +194 -0
  326. package/src/pages/components/SelectDocs.tsx +119 -48
  327. package/src/pages/components/SeparatorDocs.tsx +37 -2
  328. package/src/pages/components/SheetDocs.tsx +112 -38
  329. package/src/pages/components/SkeletonDocs.tsx +16 -20
  330. package/src/pages/components/SliderDocs.tsx +96 -10
  331. package/src/pages/components/SonnerDocs.tsx +89 -61
  332. package/src/pages/components/SwitchDocs.tsx +65 -10
  333. package/src/pages/components/TableDocs.tsx +89 -14
  334. package/src/pages/components/TabsDocs.tsx +149 -37
  335. package/src/pages/components/TextareaDocs.tsx +38 -32
  336. package/src/pages/components/ThemeToggleDocs.tsx +122 -0
  337. package/src/pages/components/ToastDocs.tsx +104 -65
  338. package/src/pages/components/ToggleDocs.tsx +55 -38
  339. package/src/pages/components/ToggleGroupDocs.tsx +96 -58
  340. package/src/pages/components/TooltipDocs.tsx +112 -3
  341. package/src/pages/index.ts +3 -0
  342. package/src/setupTests.ts +47 -0
  343. package/temp.md +292 -0
  344. package/vitest.config.ts +4 -0
  345. package/dist/vendor-CMSUBoIg.js +0 -73
  346. package/dist/vendor-CMSUBoIg.js.map +0 -1
  347. package/dist/vendor-ZhQmrf1h.mjs.map +0 -1
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "popover.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/popover.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Popover, PopoverContent, PopoverTrigger } from './popover';\n\ndescribe('Popover', () => {\n it('renders trigger correctly', () => {\n render(\n <Popover>\n <PopoverTrigger>Open</PopoverTrigger>\n <PopoverContent>Content</PopoverContent>\n </Popover>,\n );\n\n expect(screen.getByText('Open')).toBeInTheDocument();\n });\n\n it('opens content on click', async () => {\n const user = userEvent.setup();\n render(\n <Popover>\n <PopoverTrigger>Open</PopoverTrigger>\n <PopoverContent>Content</PopoverContent>\n </Popover>,\n );\n\n await user.click(screen.getByText('Open'));\n\n expect(screen.getByText('Content')).toBeVisible();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -6,7 +6,7 @@
6
6
  "files": [
7
7
  {
8
8
  "path": "ui/progress.tsx",
9
- "content": "import * as ProgressPrimitive from '@radix-ui/react-progress';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\nconst Progress = React.forwardRef<\n React.ElementRef<typeof ProgressPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n <ProgressPrimitive.Root\n ref={ref}\n className={cn('relative h-2 w-full overflow-hidden rounded-full bg-primary/20', className)}\n {...props}\n >\n <ProgressPrimitive.Indicator\n className=\"h-full w-full flex-1 bg-primary transition-all\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n));\nProgress.displayName = ProgressPrimitive.Root.displayName;\n\nexport { Progress };\n",
9
+ "content": "import * as ProgressPrimitive from '@radix-ui/react-progress';\nimport * as React from 'react';\n\nimport { cn } from '@/lib/utils';\n\nconst Progress = React.forwardRef<\n React.ElementRef<typeof ProgressPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof ProgressPrimitive.Root>\n>(({ className, value, ...props }, ref) => (\n <ProgressPrimitive.Root\n ref={ref}\n className={cn('relative h-2 w-full overflow-hidden rounded-full bg-primary/20', className)}\n value={value}\n {...props}\n >\n <ProgressPrimitive.Indicator\n className=\"h-full w-full flex-1 bg-primary transition-all\"\n style={{ transform: `translateX(-${100 - (value || 0)}%)` }}\n />\n </ProgressPrimitive.Root>\n));\nProgress.displayName = ProgressPrimitive.Root.displayName;\n\nexport { Progress };\n",
10
10
  "type": "registry:ui"
11
11
  }
12
12
  ]
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "progress.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/progress.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { Progress } from './progress';\n\ndescribe('Progress', () => {\n it('renders correctly', () => {\n render(<Progress value={50} aria-label=\"progress-bar\" />);\n expect(screen.getByRole('progressbar')).toBeInTheDocument();\n expect(screen.getByRole('progressbar')).toHaveAttribute('aria-valuenow', '50');\n });\n\n it('renders correctly with no value', () => {\n render(<Progress aria-label=\"progress-bar\" />);\n expect(screen.getByRole('progressbar')).toBeInTheDocument();\n // When value is undefined, Radix UI might behave in specific ways, typically indeterminate or 0.\n // Our wrapper: transform: `translateX(-${100 - (value || 0)}%)` -> -100%\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "radio-group.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/radio-group.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { RadioGroup, RadioGroupItem } from './radio-group';\n\ndescribe('RadioGroup', () => {\n it('renders correctly', () => {\n render(\n <RadioGroup defaultValue=\"option-one\">\n <RadioGroupItem value=\"option-one\" id=\"option-one\" aria-label=\"Option One\" />\n <RadioGroupItem value=\"option-two\" id=\"option-two\" aria-label=\"Option Two\" />\n </RadioGroup>,\n );\n\n expect(screen.getByRole('radio', { name: /Option One/i })).toBeInTheDocument();\n // Radix RadioGroup renders standard inputs visually hidden.\n // Testing library query by role 'radio' should find them.\n // However, since we didn't provide labels, we might need to rely on 'checked' state or IDs.\n\n const radio1 = screen.getByRole('radio', { checked: true });\n expect(radio1).toBeInTheDocument();\n expect(radio1).toHaveValue('option-one');\n });\n\n it('changes value on click', async () => {\n const user = userEvent.setup();\n render(\n <RadioGroup defaultValue=\"option-one\">\n <RadioGroupItem value=\"option-one\" />\n <RadioGroupItem value=\"option-two\" data-testid=\"radio-two\" />\n </RadioGroup>,\n );\n\n const radio2 = screen.getByTestId('radio-two');\n await user.click(radio2);\n\n expect(radio2).toBeChecked();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "resizable.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/resizable.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { ResizableHandle, ResizablePanel, ResizablePanelGroup } from './resizable';\n\ndescribe('Resizable', () => {\n it('renders correctly', () => {\n // Basic render test\n render(\n <ResizablePanelGroup direction=\"horizontal\">\n <ResizablePanel defaultSize={50}>\n <div>One</div>\n </ResizablePanel>\n <ResizableHandle />\n <ResizablePanel defaultSize={50}>\n <div>Two</div>\n </ResizablePanel>\n </ResizablePanelGroup>,\n );\n\n expect(screen.getByText('One')).toBeInTheDocument();\n expect(screen.getByText('Two')).toBeInTheDocument();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "scroll-area.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/scroll-area.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { ScrollArea, ScrollBar } from './scroll-area';\n\ndescribe('ScrollArea', () => {\n it('renders correctly', () => {\n render(\n <ScrollArea className=\"h-[200px] w-[350px]\">\n <div>Content</div>\n <ScrollBar />\n </ScrollArea>,\n );\n expect(screen.getByText('Content')).toBeInTheDocument();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "search",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/search.tsx",
9
+ "content": "'use client';\n\nimport { Button } from '@/components/ui/button';\nimport {\n CommandDialog,\n CommandEmpty,\n CommandGroup,\n CommandInput,\n CommandItem,\n CommandList,\n} from '@/components/ui/command';\nimport { cn } from '@/lib/utils';\nimport { Search as SearchIcon } from 'lucide-react';\nimport * as React from 'react';\n\nexport interface SearchProps {\n children?: React.ReactNode;\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n}\n\nexport function Search({ children, open: customOpen, onOpenChange }: SearchProps) {\n const [open, setOpen] = React.useState(false);\n\n const isControlled = customOpen !== undefined;\n const isOpen = isControlled ? customOpen : open;\n\n const setIsOpen = React.useCallback(\n (value: boolean | ((prev: boolean) => boolean)) => {\n if (isControlled) {\n const nextValue = typeof value === 'function' ? value(isOpen) : value;\n onOpenChange?.(nextValue);\n } else {\n setOpen(value);\n }\n },\n [isControlled, isOpen, onOpenChange],\n );\n\n React.useEffect(() => {\n const down = (e: KeyboardEvent) => {\n if (e.key === 'k' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n setIsOpen((prev) => !prev);\n }\n };\n\n document.addEventListener('keydown', down);\n return () => document.removeEventListener('keydown', down);\n }, [setIsOpen]);\n\n return (\n <CommandDialog open={isOpen} onOpenChange={setIsOpen}>\n {children}\n </CommandDialog>\n );\n}\n\nexport interface SearchTriggerProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n className?: string;\n placeholder?: string;\n variant?: 'default' | 'compact';\n}\n\nexport const SearchTrigger = React.forwardRef<HTMLButtonElement, SearchTriggerProps>(\n ({ className, placeholder = 'Search docs...', variant = 'default', ...props }, ref) => {\n return (\n <Button\n variant=\"outline\"\n className={cn(\n 'relative h-9 text-sm text-muted-foreground transition-all transition-colors',\n variant === 'default'\n ? 'w-full justify-start sm:pr-12 md:w-40 lg:w-64'\n : 'w-9 justify-center px-0 sm:w-24 sm:justify-start sm:px-3 sm:pr-12',\n className,\n )}\n ref={ref}\n {...props}\n >\n <span className=\"inline-flex items-center gap-2\">\n <SearchIcon className=\"h-4 w-4 shrink-0\" />\n {variant === 'default' && <span className=\"truncate\">{placeholder}</span>}\n </span>\n <kbd className=\"pointer-events-none absolute right-1.5 top-1.5 hidden h-6 select-none items-center gap-1 rounded border bg-muted px-1.5 font-mono text-[10px] font-medium opacity-100 sm:flex\">\n <span className=\"text-xs\">⌘</span>K\n </kbd>\n </Button>\n );\n },\n);\nSearchTrigger.displayName = 'SearchTrigger';\n\nexport { CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList };\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "search.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/search.test.tsx",
9
+ "content": "import { fireEvent, render, screen } from '@testing-library/react';\nimport * as React from 'react';\nimport { describe, expect, it, vi } from 'vitest';\nimport { CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, Search, SearchTrigger } from './search';\n\n// Mock CommandDialog since it uses Radix Dialog which might need a portal\nvi.mock('@/components/ui/dialog', () => ({\n Dialog: ({ children, open }: { children: React.ReactNode; open: boolean }) => (open ? <div>{children}</div> : null),\n DialogContent: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,\n DialogPortal: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,\n DialogOverlay: () => null,\n}));\n\ndescribe('Search', () => {\n it('renders search trigger', () => {\n render(<SearchTrigger />);\n expect(screen.getByText('Search docs...')).toBeInTheDocument();\n });\n\n it('opens search dialog when trigger is clicked (controlled)', () => {\n const onOpenChange = vi.fn();\n render(\n <Search open={false} onOpenChange={onOpenChange}>\n <CommandInput placeholder=\"Search...\" />\n </Search>,\n );\n\n // The dialog should be closed initially\n expect(screen.queryByPlaceholderText('Search...')).not.toBeInTheDocument();\n });\n\n it('responds to keyboard shortcuts', () => {\n render(\n <Search>\n <CommandInput placeholder=\"Search...\" />\n <CommandList>\n <CommandItem>Result 1</CommandItem>\n </CommandList>\n </Search>,\n );\n\n // Simulate Cmd+K\n fireEvent.keyDown(document, { key: 'k', metaKey: true });\n\n // Check if dialog content is visible\n expect(screen.getByPlaceholderText('Search...')).toBeInTheDocument();\n });\n\n it('filters results correctly', () => {\n render(\n <Search open={true}>\n <CommandInput placeholder=\"Search...\" />\n <CommandList>\n <CommandEmpty>No results.</CommandEmpty>\n <CommandGroup heading=\"Components\">\n <SearchItem>Button</SearchItem>\n <SearchItem>Input</SearchItem>\n </CommandGroup>\n </CommandList>\n </Search>,\n );\n\n const input = screen.getByPlaceholderText('Search...');\n fireEvent.change(input, { target: { value: 'But' } });\n\n expect(screen.getByText('Button')).toBeInTheDocument();\n // cmdk removes non-matching items from the DOM\n expect(screen.queryByText('Input')).not.toBeInTheDocument();\n });\n});\n\n// Helper component for testing\nfunction SearchItem({ children }: { children: React.ReactNode }) {\n return <CommandItem>{children}</CommandItem>;\n}\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "select.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/select.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from './select';\n\ndescribe('Select', () => {\n it('renders correctly', () => {\n render(\n <Select>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an option\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"option1\">Option 1</SelectItem>\n <SelectItem value=\"option2\">Option 2</SelectItem>\n </SelectContent>\n </Select>,\n );\n expect(screen.getByText('Select an option')).toBeInTheDocument();\n });\n\n it('opens and selects an option', async () => {\n const user = userEvent.setup();\n render(\n <Select>\n <SelectTrigger>\n <SelectValue placeholder=\"Select an option\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"option1\">Option 1</SelectItem>\n <SelectItem value=\"option2\">Option 2</SelectItem>\n </SelectContent>\n </Select>,\n );\n\n await user.click(screen.getByRole('combobox'));\n expect(screen.getByText('Option 1')).toBeVisible();\n\n await user.click(screen.getByText('Option 1'));\n expect(screen.getByText('Option 1')).toBeInTheDocument();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "separator.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/separator.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { Separator } from './separator';\n\ndescribe('Separator', () => {\n it('renders correctly', () => {\n render(<Separator data-testid=\"separator\" />);\n expect(screen.getByTestId('separator')).toBeInTheDocument();\n expect(screen.getByTestId('separator')).toHaveClass('bg-border');\n });\n\n it('applies orientation classes', () => {\n render(<Separator orientation=\"vertical\" data-testid=\"separator-vertical\" />);\n expect(screen.getByTestId('separator-vertical')).toHaveClass('h-full w-[1px]');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "sheet.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/sheet.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it, vi } from 'vitest';\nimport { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle, SheetTrigger } from './sheet';\n\n// Mock ResizeObserver for Radix UI\nglobal.ResizeObserver = vi.fn().mockImplementation(() => ({\n observe: vi.fn(),\n unobserve: vi.fn(),\n disconnect: vi.fn(),\n}));\n\ndescribe('Sheet', () => {\n it('renders trigger correctly', () => {\n render(\n <Sheet>\n <SheetTrigger>Open Sheet</SheetTrigger>\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Title</SheetTitle>\n <SheetDescription>Description</SheetDescription>\n </SheetHeader>\n </SheetContent>\n </Sheet>,\n );\n\n expect(screen.getByText('Open Sheet')).toBeInTheDocument();\n });\n\n it('opens content on click', async () => {\n const user = userEvent.setup();\n render(\n <Sheet>\n <SheetTrigger>Open Sheet</SheetTrigger>\n <SheetContent>\n <SheetHeader>\n <SheetTitle>Title</SheetTitle>\n <SheetDescription>Description</SheetDescription>\n </SheetHeader>\n <div>Sheet Content</div>\n </SheetContent>\n </Sheet>,\n );\n\n await user.click(screen.getByText('Open Sheet'));\n expect(screen.getByText('Sheet Content')).toBeVisible();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "skeleton.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/skeleton.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { Skeleton } from './skeleton';\n\ndescribe('Skeleton', () => {\n it('renders correctly', () => {\n render(<Skeleton data-testid=\"skeleton\" className=\"h-4 w-[250px]\" />);\n const skeleton = screen.getByTestId('skeleton');\n expect(skeleton).toBeInTheDocument();\n expect(skeleton).toHaveClass('animate-pulse');\n expect(skeleton).toHaveClass('h-4');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "slider.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/slider.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { Slider } from './slider';\n\ndescribe('Slider', () => {\n it('renders correctly', () => {\n // Radix Slider uses ResizeObserver\n global.ResizeObserver = class ResizeObserver {\n observe() {}\n unobserve() {}\n disconnect() {}\n };\n\n render(<Slider defaultValue={[50]} max={100} step={1} />);\n expect(screen.getByRole('slider')).toBeInTheDocument();\n expect(screen.getByRole('slider')).toHaveAttribute('aria-valuenow', '50');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "sonner.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/sonner.test.tsx",
9
+ "content": "import { render } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { Toaster } from './sonner';\n\ndescribe('Sonner Toaster', () => {\n it('renders correctly', () => {\n const { container } = render(<Toaster />);\n // Sonner renders a list/container. Since it's a portal or fixed, we check presence.\n // However, without triggering a toast, it might be empty or hidden.\n // We check if the container renders without crashing.\n expect(container).toBeInTheDocument();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "switch.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/switch.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Switch } from './switch';\n\ndescribe('Switch', () => {\n it('renders correctly', () => {\n render(<Switch data-testid=\"switch\" />);\n expect(screen.getByRole('switch')).toBeInTheDocument();\n });\n\n it('toggles state', async () => {\n const user = userEvent.setup();\n render(<Switch />);\n\n const switchEl = screen.getByRole('switch');\n expect(switchEl).toHaveAttribute('aria-checked', 'false');\n\n await user.click(switchEl);\n expect(switchEl).toHaveAttribute('aria-checked', 'true');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "table.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/table.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport { describe, expect, it } from 'vitest';\nimport { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from './table';\n\ndescribe('Table', () => {\n it('renders correctly', () => {\n render(\n <Table>\n <TableCaption>A list of invoices.</TableCaption>\n <TableHeader>\n <TableRow>\n <TableHead className=\"w-[100px]\">Invoice</TableHead>\n <TableHead>Status</TableHead>\n </TableRow>\n </TableHeader>\n <TableBody>\n <TableRow>\n <TableCell className=\"font-medium\">INV001</TableCell>\n <TableCell>Paid</TableCell>\n </TableRow>\n </TableBody>\n </Table>,\n );\n\n expect(screen.getByRole('table')).toBeInTheDocument();\n expect(screen.getByText('A list of invoices.')).toBeInTheDocument();\n expect(screen.getByText('INV001')).toBeInTheDocument();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "tabs.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/tabs.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from './tabs';\n\ndescribe('Tabs', () => {\n it('renders correctly', () => {\n render(\n <Tabs defaultValue=\"account\">\n <TabsList>\n <TabsTrigger value=\"account\">Account</TabsTrigger>\n <TabsTrigger value=\"password\">Password</TabsTrigger>\n </TabsList>\n <TabsContent value=\"account\">Account Content</TabsContent>\n <TabsContent value=\"password\">Password Content</TabsContent>\n </Tabs>,\n );\n\n expect(screen.getByRole('tablist')).toBeInTheDocument();\n expect(screen.getByRole('tab', { name: 'Account' })).toBeInTheDocument();\n\n // Default value shows Account Content\n expect(screen.getByText('Account Content')).toBeVisible();\n expect(screen.queryByText('Password Content')).not.toBeInTheDocument();\n });\n\n it('switches tabs', async () => {\n const user = userEvent.setup();\n render(\n <Tabs defaultValue=\"account\">\n <TabsList>\n <TabsTrigger value=\"account\">Account</TabsTrigger>\n <TabsTrigger value=\"password\">Password</TabsTrigger>\n </TabsList>\n <TabsContent value=\"account\">Account Content</TabsContent>\n <TabsContent value=\"password\">Password Content</TabsContent>\n </Tabs>,\n );\n\n await user.click(screen.getByRole('tab', { name: 'Password' }));\n expect(screen.getByText('Password Content')).toBeVisible();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "textarea.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/textarea.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Textarea } from './textarea';\n\ndescribe('Textarea', () => {\n it('renders correctly', () => {\n render(<Textarea placeholder=\"Type here\" />);\n expect(screen.getByRole('textbox')).toBeInTheDocument();\n expect(screen.getByPlaceholderText('Type here')).toBeInTheDocument();\n });\n\n it('accepts user input', async () => {\n const user = userEvent.setup();\n render(<Textarea />);\n const textarea = screen.getByRole('textbox');\n\n await user.type(textarea, 'Hello World');\n expect(textarea).toHaveValue('Hello World');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "theme-toggle",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/theme-toggle.tsx",
9
+ "content": "import { Button } from '@/components/ui/button';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu';\nimport { cn } from '@/lib/utils';\nimport { Moon, Sun, SunMoon } from 'lucide-react';\nimport { useTheme } from 'next-themes';\n\nexport interface ThemeToggleProps {\n /**\n * The mode of the theme toggle. 'binary' allows toggling between light and dark. 'ternary' allows choosing between\n * light, dark, and system.\n *\n * @default 'binary'\n */\n variant?: 'binary' | 'ternary';\n /** Optional callback when the theme changes. */\n onThemeChange?: (theme: string) => void;\n /** Optional current theme value for external control. */\n customTheme?: string;\n /** Optional className for the button. */\n className?: string;\n}\n\nexport function ThemeToggle({ variant = 'binary', onThemeChange, customTheme, className }: ThemeToggleProps) {\n const { theme: nextTheme, setTheme: setNextTheme, resolvedTheme } = useTheme();\n\n // Use customTheme if provided, otherwise fallback to next-themes\n const currentTheme = customTheme ?? nextTheme;\n\n // Determine the effective theme for icon rendering\n const effectiveTheme = customTheme ? customTheme : resolvedTheme;\n const isDark = effectiveTheme === 'dark';\n const isSystem = currentTheme === 'system';\n\n const handleThemeChange = (newTheme: string) => {\n if (onThemeChange) {\n onThemeChange(newTheme);\n } else {\n setNextTheme(newTheme);\n }\n };\n\n const IconToggle = () => (\n <>\n <Sun\n className={cn(\n 'h-[1.2rem] w-[1.2rem] transition-all',\n !isSystem && !isDark ? 'rotate-0 scale-100' : '-rotate-90 scale-0',\n )}\n />\n <Moon\n className={cn(\n 'absolute h-[1.2rem] w-[1.2rem] transition-all',\n !isSystem && isDark ? 'rotate-0 scale-100' : 'rotate-90 scale-0',\n )}\n />\n <SunMoon\n className={cn(\n 'absolute h-[1.2rem] w-[1.2rem] transition-all',\n isSystem ? 'rotate-0 scale-100' : 'rotate-90 scale-0',\n )}\n />\n <span className=\"sr-only\">Toggle theme</span>\n </>\n );\n\n if (variant === 'ternary') {\n return (\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button variant=\"ghost\" size=\"icon\" className={cn('relative h-9 w-9', className)}>\n <IconToggle />\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuItem onClick={() => handleThemeChange('light')}>\n <Sun className=\"mr-2 h-4 w-4\" />\n <span>Light</span>\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => handleThemeChange('dark')}>\n <Moon className=\"mr-2 h-4 w-4\" />\n <span>Dark</span>\n </DropdownMenuItem>\n <DropdownMenuItem onClick={() => handleThemeChange('system')}>\n <SunMoon className=\"mr-2 h-4 w-4\" />\n <span>System</span>\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n );\n }\n\n return (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className={cn('relative h-9 w-9', className)}\n onClick={() => handleThemeChange(currentTheme === 'dark' ? 'light' : 'dark')}\n aria-label=\"Toggle theme\"\n >\n <IconToggle />\n </Button>\n );\n}\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "toast.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/toast.test.tsx",
9
+ "content": "import { useToast } from '@/hooks/use-toast';\nimport { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Toaster } from './toaster';\n\n// Test component to trigger toasts\nconst ToastTrigger = () => {\n const { toast } = useToast();\n return (\n <button\n onClick={() =>\n toast({\n title: 'Test Toast',\n description: 'This is a test message',\n })\n }\n >\n Show Toast\n </button>\n );\n};\n\ndescribe('Toast', () => {\n it('shows toast when triggered', async () => {\n const user = userEvent.setup();\n render(\n <>\n <Toaster />\n <ToastTrigger />\n </>,\n );\n\n expect(screen.queryByText('Test Toast')).not.toBeInTheDocument();\n\n await user.click(screen.getByText('Show Toast'));\n\n // Toast might take a moment to appear (animation)\n expect(await screen.findByText('Test Toast')).toBeInTheDocument();\n expect(screen.getByText('This is a test message')).toBeInTheDocument();\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "toggle-group.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/toggle-group.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { ToggleGroup, ToggleGroupItem } from './toggle-group';\n\ndescribe('ToggleGroup', () => {\n it('renders correctly', () => {\n render(\n <ToggleGroup type=\"single\">\n <ToggleGroupItem value=\"a\" aria-label=\"Toggle A\">\n A\n </ToggleGroupItem>\n <ToggleGroupItem value=\"b\" aria-label=\"Toggle B\">\n B\n </ToggleGroupItem>\n </ToggleGroup>,\n );\n\n expect(screen.getByLabelText('Toggle A')).toBeInTheDocument();\n expect(screen.getByLabelText('Toggle B')).toBeInTheDocument();\n });\n\n it('toggles selection', async () => {\n const user = userEvent.setup();\n render(\n <ToggleGroup type=\"single\">\n <ToggleGroupItem value=\"a\" aria-label=\"Toggle A\">\n A\n </ToggleGroupItem>\n <ToggleGroupItem value=\"b\" aria-label=\"Toggle B\">\n B\n </ToggleGroupItem>\n </ToggleGroup>,\n );\n\n const toggleA = screen.getByLabelText('Toggle A');\n await user.click(toggleA);\n expect(toggleA).toHaveAttribute('aria-checked', 'true');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "toggle.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/toggle.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Toggle } from './toggle';\n\ndescribe('Toggle', () => {\n it('renders correctly', () => {\n render(<Toggle aria-label=\"Toggle bold\">B</Toggle>);\n expect(screen.getByLabelText('Toggle bold')).toBeInTheDocument();\n });\n\n it('toggles state', async () => {\n const user = userEvent.setup();\n render(<Toggle aria-label=\"Toggle italic\" />);\n const toggle = screen.getByLabelText('Toggle italic');\n\n expect(toggle).toHaveAttribute('aria-pressed', 'false');\n await user.click(toggle);\n expect(toggle).toHaveAttribute('aria-pressed', 'true');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "tooltip.test",
3
+ "type": "registry:ui",
4
+ "dependencies": [],
5
+ "registryDependencies": [],
6
+ "files": [
7
+ {
8
+ "path": "ui/tooltip.test.tsx",
9
+ "content": "import { render, screen } from '@testing-library/react';\nimport userEvent from '@testing-library/user-event';\nimport { describe, expect, it } from 'vitest';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip';\n\ndescribe('Tooltip', () => {\n it('shows content on hover', async () => {\n const user = userEvent.setup();\n render(\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger>Hover me</TooltipTrigger>\n <TooltipContent>Tooltip content</TooltipContent>\n </Tooltip>\n </TooltipProvider>,\n );\n\n expect(screen.queryByText('Tooltip content')).not.toBeInTheDocument();\n\n await user.hover(screen.getByText('Hover me'));\n const tooltip = await screen.findByRole('tooltip');\n expect(tooltip).toBeInTheDocument();\n expect(tooltip).toHaveTextContent('Tooltip content');\n });\n});\n",
10
+ "type": "registry:ui"
11
+ }
12
+ ]
13
+ }
@@ -0,0 +1,2 @@
1
+ import '@testing-library/jest-dom';
2
+ //# sourceMappingURL=setupTests.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupTests.d.ts","sourceRoot":"","sources":["../src/setupTests.ts"],"names":[],"mappings":"AAAA,OAAO,2BAA2B,CAAC"}