@object-ui/components 0.3.0 → 0.5.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 (423) hide show
  1. package/.turbo/turbo-build.log +47 -0
  2. package/CHANGELOG.md +10 -0
  3. package/README.md +32 -1
  4. package/README_SHADCN_SYNC.md +281 -0
  5. package/TESTING.md +335 -0
  6. package/dist/index.css +1 -1
  7. package/dist/index.js +45067 -34357
  8. package/dist/index.umd.cjs +54 -42
  9. package/dist/src/SchemaRenderer.d.ts +3 -0
  10. package/dist/src/{ui → custom}/button-group.d.ts +1 -1
  11. package/dist/src/custom/combobox.d.ts +22 -0
  12. package/dist/src/custom/date-picker.d.ts +15 -0
  13. package/dist/src/custom/field.d.ts +19 -0
  14. package/dist/src/{ui → custom}/filter-builder.d.ts +7 -0
  15. package/dist/src/custom/index.d.ts +12 -0
  16. package/dist/src/custom/input-group.d.ts +14 -0
  17. package/dist/src/{ui → custom}/item.d.ts +8 -1
  18. package/dist/src/{ui → custom}/kbd.d.ts +7 -0
  19. package/dist/src/custom/native-select.d.ts +12 -0
  20. package/dist/src/custom/sort-builder.d.ts +22 -0
  21. package/dist/src/custom/spinner.d.ts +10 -0
  22. package/dist/src/hooks/use-mobile.d.ts +7 -0
  23. package/dist/src/index.d.ts +5 -1
  24. package/dist/src/renderers/basic/button-group.d.ts +8 -0
  25. package/dist/src/renderers/basic/div.d.ts +7 -0
  26. package/dist/src/renderers/basic/html.d.ts +7 -0
  27. package/dist/src/renderers/basic/icon.d.ts +7 -0
  28. package/dist/src/renderers/basic/image.d.ts +7 -0
  29. package/dist/src/renderers/basic/navigation-menu.d.ts +8 -0
  30. package/dist/src/renderers/basic/pagination.d.ts +8 -0
  31. package/dist/src/renderers/basic/separator.d.ts +7 -0
  32. package/dist/src/renderers/basic/span.d.ts +7 -0
  33. package/dist/src/renderers/basic/text.d.ts +7 -0
  34. package/dist/src/renderers/complex/carousel.d.ts +7 -0
  35. package/dist/src/renderers/complex/data-table.d.ts +7 -0
  36. package/dist/src/renderers/complex/filter-builder.d.ts +7 -0
  37. package/dist/src/renderers/complex/resizable.d.ts +7 -0
  38. package/dist/src/renderers/complex/scroll-area.d.ts +7 -0
  39. package/dist/src/renderers/complex/table.d.ts +7 -0
  40. package/dist/src/renderers/data-display/alert.d.ts +7 -0
  41. package/dist/src/renderers/data-display/avatar.d.ts +7 -0
  42. package/dist/src/renderers/data-display/badge.d.ts +7 -0
  43. package/dist/src/renderers/data-display/breadcrumb.d.ts +8 -0
  44. package/dist/src/renderers/data-display/kbd.d.ts +8 -0
  45. package/dist/src/renderers/data-display/list.d.ts +7 -0
  46. package/dist/src/renderers/data-display/statistic.d.ts +7 -0
  47. package/dist/src/renderers/data-display/table.d.ts +8 -0
  48. package/dist/src/renderers/data-display/tree-view.d.ts +7 -0
  49. package/dist/src/renderers/disclosure/accordion.d.ts +7 -0
  50. package/dist/src/renderers/disclosure/collapsible.d.ts +7 -0
  51. package/dist/src/renderers/disclosure/toggle-group.d.ts +8 -0
  52. package/dist/src/renderers/feedback/empty.d.ts +8 -0
  53. package/dist/src/renderers/feedback/loading.d.ts +7 -0
  54. package/dist/src/renderers/feedback/progress.d.ts +7 -0
  55. package/dist/src/renderers/feedback/skeleton.d.ts +7 -0
  56. package/dist/src/renderers/feedback/sonner.d.ts +8 -0
  57. package/dist/src/renderers/feedback/spinner.d.ts +8 -0
  58. package/dist/src/renderers/feedback/toast.d.ts +8 -0
  59. package/dist/src/renderers/feedback/toaster.d.ts +7 -0
  60. package/dist/src/renderers/form/button.d.ts +7 -0
  61. package/dist/src/renderers/form/calendar.d.ts +7 -0
  62. package/dist/src/renderers/form/checkbox.d.ts +7 -0
  63. package/dist/src/renderers/form/combobox.d.ts +8 -0
  64. package/dist/src/renderers/form/command.d.ts +8 -0
  65. package/dist/src/renderers/form/date-picker.d.ts +7 -0
  66. package/dist/src/renderers/form/file-upload.d.ts +7 -0
  67. package/dist/src/renderers/form/form.d.ts +7 -0
  68. package/dist/src/renderers/form/input-otp.d.ts +7 -0
  69. package/dist/src/renderers/form/input.d.ts +7 -0
  70. package/dist/src/renderers/form/label.d.ts +7 -0
  71. package/dist/src/renderers/form/radio-group.d.ts +7 -0
  72. package/dist/src/renderers/form/select.d.ts +7 -0
  73. package/dist/src/renderers/form/slider.d.ts +7 -0
  74. package/dist/src/renderers/form/switch.d.ts +7 -0
  75. package/dist/src/renderers/form/textarea.d.ts +7 -0
  76. package/dist/src/renderers/form/toggle.d.ts +7 -0
  77. package/dist/src/renderers/layout/aspect-ratio.d.ts +8 -0
  78. package/dist/src/renderers/layout/card.d.ts +7 -0
  79. package/dist/src/renderers/layout/container.d.ts +7 -0
  80. package/dist/src/renderers/layout/flex.d.ts +7 -0
  81. package/dist/src/renderers/layout/grid.d.ts +7 -0
  82. package/dist/src/renderers/layout/page.d.ts +1 -1
  83. package/dist/src/renderers/layout/semantic.d.ts +7 -0
  84. package/dist/src/renderers/layout/stack.d.ts +7 -0
  85. package/dist/src/renderers/layout/tabs.d.ts +7 -0
  86. package/dist/src/renderers/navigation/header-bar.d.ts +7 -0
  87. package/dist/src/renderers/navigation/sidebar.d.ts +7 -0
  88. package/dist/src/renderers/overlay/alert-dialog.d.ts +7 -0
  89. package/dist/src/renderers/overlay/context-menu.d.ts +7 -0
  90. package/dist/src/renderers/overlay/dialog.d.ts +7 -0
  91. package/dist/src/renderers/overlay/drawer.d.ts +7 -0
  92. package/dist/src/renderers/overlay/dropdown-menu.d.ts +7 -0
  93. package/dist/src/renderers/overlay/hover-card.d.ts +7 -0
  94. package/dist/src/renderers/overlay/menubar.d.ts +8 -0
  95. package/dist/src/renderers/overlay/popover.d.ts +7 -0
  96. package/dist/src/renderers/overlay/sheet.d.ts +7 -0
  97. package/dist/src/renderers/overlay/tooltip.d.ts +7 -0
  98. package/dist/src/renderers/placeholders.d.ts +9 -0
  99. package/dist/src/ui/accordion.d.ts +11 -4
  100. package/dist/src/ui/alert-dialog.d.ts +24 -11
  101. package/dist/src/ui/alert.d.ts +11 -5
  102. package/dist/src/ui/aspect-ratio.d.ts +8 -1
  103. package/dist/src/ui/avatar.d.ts +10 -3
  104. package/dist/src/ui/badge.d.ts +10 -3
  105. package/dist/src/ui/breadcrumb.d.ts +23 -8
  106. package/dist/src/ui/button.d.ts +10 -5
  107. package/dist/src/ui/calendar.d.ts +8 -1
  108. package/dist/src/ui/card.d.ts +14 -8
  109. package/dist/src/ui/carousel.d.ts +12 -6
  110. package/dist/src/ui/chart.d.ts +62 -0
  111. package/dist/src/ui/checkbox.d.ts +8 -1
  112. package/dist/src/ui/collapsible.d.ts +10 -3
  113. package/dist/src/ui/command.d.ts +85 -16
  114. package/dist/src/ui/context-menu.d.ts +21 -12
  115. package/dist/src/ui/dialog.d.ts +24 -13
  116. package/dist/src/ui/drawer.d.ts +26 -10
  117. package/dist/src/ui/dropdown-menu.d.ts +27 -18
  118. package/dist/src/ui/form.d.ts +13 -7
  119. package/dist/src/ui/hover-card.d.ts +10 -3
  120. package/dist/src/ui/index.d.ts +10 -11
  121. package/dist/src/ui/input-otp.d.ts +37 -7
  122. package/dist/src/ui/input.d.ts +7 -0
  123. package/dist/src/ui/label.d.ts +9 -1
  124. package/dist/src/ui/menubar.d.ts +26 -17
  125. package/dist/src/ui/navigation-menu.d.ts +16 -11
  126. package/dist/src/ui/pagination.d.ts +32 -10
  127. package/dist/src/ui/popover.d.ts +11 -5
  128. package/dist/src/ui/progress.d.ts +8 -1
  129. package/dist/src/ui/radio-group.d.ts +9 -2
  130. package/dist/src/ui/resizable.d.ts +12 -8
  131. package/dist/src/ui/scroll-area.d.ts +9 -2
  132. package/dist/src/ui/select.d.ts +18 -13
  133. package/dist/src/ui/separator.d.ts +7 -0
  134. package/dist/src/ui/sheet.d.ts +30 -11
  135. package/dist/src/ui/sidebar.d.ts +41 -38
  136. package/dist/src/ui/skeleton.d.ts +8 -1
  137. package/dist/src/ui/slider.d.ts +8 -1
  138. package/dist/src/ui/sonner.d.ts +2 -1
  139. package/dist/src/ui/switch.d.ts +9 -2
  140. package/dist/src/ui/table.d.ts +15 -8
  141. package/dist/src/ui/tabs.d.ts +8 -1
  142. package/dist/src/ui/textarea.d.ts +8 -1
  143. package/dist/src/ui/toast.d.ts +22 -0
  144. package/dist/src/ui/toggle-group.d.ts +15 -5
  145. package/dist/src/ui/toggle.d.ts +11 -1
  146. package/dist/src/ui/tooltip.d.ts +11 -4
  147. package/dist/src/ui/typography.d.ts +21 -0
  148. package/metadata/ObjectGrid.component.yml +72 -0
  149. package/package.json +35 -13
  150. package/postcss.config.js +9 -1
  151. package/shadcn-components.json +315 -0
  152. package/src/SchemaRenderer.tsx +28 -0
  153. package/src/__tests__/PageRendererRegions.test.tsx +59 -0
  154. package/src/__tests__/README.md +124 -0
  155. package/src/__tests__/Registry.test.ts +21 -0
  156. package/src/__tests__/basic-renderers.test.tsx +255 -0
  157. package/src/__tests__/complex-disclosure-renderers.test.tsx +302 -0
  158. package/src/__tests__/feedback-overlay-renderers.test.tsx +349 -0
  159. package/src/__tests__/form-renderers.test.tsx +364 -0
  160. package/src/__tests__/layout-data-renderers.test.tsx +340 -0
  161. package/src/__tests__/test-utils.tsx +190 -0
  162. package/src/{ui → custom}/button-group.tsx +9 -1
  163. package/src/custom/combobox.tsx +104 -0
  164. package/src/custom/date-picker.tsx +61 -0
  165. package/src/{ui → custom}/empty.tsx +8 -0
  166. package/src/custom/field.tsx +81 -0
  167. package/src/{ui → custom}/filter-builder.tsx +11 -3
  168. package/src/custom/index.ts +12 -0
  169. package/src/custom/input-group.tsx +53 -0
  170. package/src/{ui → custom}/item.tsx +9 -1
  171. package/src/{ui → custom}/kbd.tsx +8 -0
  172. package/src/custom/native-select.tsx +33 -0
  173. package/src/custom/sort-builder.tsx +129 -0
  174. package/src/custom/spinner.tsx +26 -0
  175. package/src/hooks/use-mobile.tsx +8 -0
  176. package/src/index.css +105 -54
  177. package/src/index.test.ts +8 -0
  178. package/src/index.ts +22 -1
  179. package/src/lib/utils.tsx +8 -0
  180. package/src/new-components.test.ts +8 -9
  181. package/src/renderers/basic/button-group.tsx +79 -0
  182. package/src/renderers/basic/div.tsx +21 -2
  183. package/src/renderers/basic/html.tsx +9 -0
  184. package/src/renderers/basic/icon.tsx +67 -3
  185. package/src/renderers/basic/image.tsx +13 -1
  186. package/src/renderers/basic/index.ts +11 -0
  187. package/src/renderers/basic/navigation-menu.tsx +81 -0
  188. package/src/renderers/basic/pagination.tsx +109 -0
  189. package/src/renderers/basic/separator.tsx +10 -1
  190. package/src/renderers/basic/span.tsx +21 -2
  191. package/src/renderers/basic/text.tsx +12 -2
  192. package/src/renderers/complex/__tests__/data-table.test.ts +8 -0
  193. package/src/renderers/complex/carousel.tsx +12 -3
  194. package/src/renderers/complex/data-table.tsx +150 -96
  195. package/src/renderers/complex/filter-builder.tsx +10 -1
  196. package/src/renderers/complex/index.ts +9 -3
  197. package/src/renderers/complex/resizable.tsx +10 -1
  198. package/src/renderers/complex/scroll-area.tsx +33 -7
  199. package/src/renderers/complex/table.tsx +11 -2
  200. package/src/renderers/data-display/alert.tsx +9 -0
  201. package/src/renderers/data-display/avatar.tsx +9 -0
  202. package/src/renderers/data-display/badge.tsx +9 -0
  203. package/src/renderers/data-display/breadcrumb.tsx +60 -0
  204. package/src/renderers/data-display/index.ts +12 -0
  205. package/src/renderers/data-display/kbd.tsx +50 -0
  206. package/src/renderers/data-display/list.tsx +29 -49
  207. package/src/renderers/data-display/statistic.tsx +45 -48
  208. package/src/renderers/data-display/table.tsx +78 -0
  209. package/src/renderers/data-display/tree-view.tsx +32 -37
  210. package/src/renderers/disclosure/accordion.tsx +9 -0
  211. package/src/renderers/disclosure/collapsible.tsx +9 -0
  212. package/src/renderers/disclosure/index.ts +9 -0
  213. package/src/renderers/disclosure/toggle-group.tsx +79 -0
  214. package/src/renderers/feedback/empty.tsx +49 -0
  215. package/src/renderers/feedback/index.ts +12 -0
  216. package/src/renderers/feedback/loading.tsx +10 -1
  217. package/src/renderers/feedback/progress.tsx +9 -0
  218. package/src/renderers/feedback/skeleton.tsx +9 -0
  219. package/src/renderers/feedback/sonner.tsx +56 -0
  220. package/src/renderers/feedback/spinner.tsx +55 -0
  221. package/src/renderers/feedback/toast.tsx +59 -0
  222. package/src/renderers/feedback/toaster.tsx +14 -17
  223. package/src/renderers/form/button.tsx +43 -1
  224. package/src/renderers/form/calendar.tsx +9 -0
  225. package/src/renderers/form/checkbox.tsx +46 -16
  226. package/src/renderers/form/combobox.tsx +48 -0
  227. package/src/renderers/form/command.tsx +58 -0
  228. package/src/renderers/form/date-picker.tsx +11 -2
  229. package/src/renderers/form/file-upload.tsx +11 -2
  230. package/src/renderers/form/form.tsx +104 -18
  231. package/src/renderers/form/index.ts +10 -0
  232. package/src/renderers/form/input-otp.tsx +35 -15
  233. package/src/renderers/form/input.tsx +92 -50
  234. package/src/renderers/form/label.tsx +9 -0
  235. package/src/renderers/form/radio-group.tsx +9 -0
  236. package/src/renderers/form/select.tsx +43 -15
  237. package/src/renderers/form/slider.tsx +17 -1
  238. package/src/renderers/form/switch.tsx +9 -0
  239. package/src/renderers/form/textarea.tsx +58 -27
  240. package/src/renderers/form/toggle.tsx +11 -45
  241. package/src/renderers/index.ts +8 -0
  242. package/src/renderers/layout/aspect-ratio.tsx +51 -0
  243. package/src/renderers/layout/card.tsx +18 -2
  244. package/src/renderers/layout/container.tsx +21 -12
  245. package/src/renderers/layout/flex.tsx +17 -8
  246. package/src/renderers/layout/grid.tsx +31 -8
  247. package/src/renderers/layout/index.ts +9 -0
  248. package/src/renderers/layout/page.tsx +44 -24
  249. package/src/renderers/layout/semantic.tsx +9 -0
  250. package/src/renderers/layout/stack.tsx +18 -9
  251. package/src/renderers/layout/tabs.tsx +51 -17
  252. package/src/renderers/navigation/header-bar.tsx +10 -1
  253. package/src/renderers/navigation/index.ts +8 -0
  254. package/src/renderers/navigation/sidebar.tsx +13 -0
  255. package/src/renderers/overlay/alert-dialog.tsx +9 -0
  256. package/src/renderers/overlay/context-menu.tsx +10 -1
  257. package/src/renderers/overlay/dialog.tsx +9 -0
  258. package/src/renderers/overlay/drawer.tsx +9 -0
  259. package/src/renderers/overlay/dropdown-menu.tsx +9 -0
  260. package/src/renderers/overlay/hover-card.tsx +9 -0
  261. package/src/renderers/overlay/index.ts +9 -0
  262. package/src/renderers/overlay/menubar.tsx +76 -0
  263. package/src/renderers/overlay/popover.tsx +9 -0
  264. package/src/renderers/overlay/sheet.tsx +9 -0
  265. package/src/renderers/overlay/tooltip.tsx +9 -0
  266. package/src/renderers/placeholders.tsx +107 -0
  267. package/src/stories/CRMApp.stories.tsx +706 -0
  268. package/src/stories/Guide.mdx +55 -0
  269. package/src/stories/Introduction.mdx +34 -0
  270. package/src/stories/MockedData.stories.tsx +71 -0
  271. package/src/stories/assets/accessibility.png +0 -0
  272. package/src/stories/assets/accessibility.svg +1 -0
  273. package/src/stories/assets/addon-library.png +0 -0
  274. package/src/stories/assets/assets.png +0 -0
  275. package/src/stories/assets/avif-test-image.avif +0 -0
  276. package/src/stories/assets/context.png +0 -0
  277. package/src/stories/assets/discord.svg +1 -0
  278. package/src/stories/assets/docs.png +0 -0
  279. package/src/stories/assets/figma-plugin.png +0 -0
  280. package/src/stories/assets/github.svg +1 -0
  281. package/src/stories/assets/share.png +0 -0
  282. package/src/stories/assets/styling.png +0 -0
  283. package/src/stories/assets/testing.png +0 -0
  284. package/src/stories/assets/theming.png +0 -0
  285. package/src/stories/assets/tutorials.svg +1 -0
  286. package/src/stories/assets/youtube.svg +1 -0
  287. package/src/stories/button.css +30 -0
  288. package/src/stories/header.css +32 -0
  289. package/src/stories/page.css +68 -0
  290. package/src/stories-json/accordion.stories.tsx +43 -0
  291. package/src/stories-json/aggrid.stories.tsx +103 -0
  292. package/src/stories-json/alert.stories.tsx +39 -0
  293. package/src/stories-json/aspect-ratio.stories.tsx +34 -0
  294. package/src/stories-json/avatar.stories.tsx +38 -0
  295. package/src/stories-json/badge.stories.tsx +53 -0
  296. package/src/stories-json/breadcrumb.stories.tsx +30 -0
  297. package/src/stories-json/button-group.stories.tsx +43 -0
  298. package/src/stories-json/button.stories.tsx +73 -0
  299. package/src/stories-json/calendar.stories.tsx +85 -0
  300. package/src/stories-json/card.stories.tsx +48 -0
  301. package/src/stories-json/carousel.stories.tsx +33 -0
  302. package/src/stories-json/charts.stories.tsx +195 -0
  303. package/src/stories-json/chatbot.stories.tsx +248 -0
  304. package/src/stories-json/code-editor.stories.tsx +92 -0
  305. package/src/stories-json/collapsible.stories.tsx +40 -0
  306. package/src/stories-json/controls.stories.tsx +36 -0
  307. package/src/stories-json/dashboard.stories.tsx +318 -0
  308. package/src/stories-json/data-table.stories.tsx +60 -0
  309. package/src/stories-json/data_display_extras.stories.tsx +102 -0
  310. package/src/stories-json/date-picker.stories.tsx +28 -0
  311. package/src/stories-json/detail-view.stories.tsx +258 -0
  312. package/src/stories-json/dialog.stories.tsx +43 -0
  313. package/src/stories-json/feedback_extras.stories.tsx +40 -0
  314. package/src/stories-json/feedback_others.stories.tsx +46 -0
  315. package/src/stories-json/form_advanced.stories.tsx +117 -0
  316. package/src/stories-json/form_extras.stories.tsx +123 -0
  317. package/src/stories-json/grid.stories.tsx +56 -0
  318. package/src/stories-json/icon.stories.tsx +36 -0
  319. package/src/stories-json/input.stories.tsx +52 -0
  320. package/src/stories-json/kanban.stories.tsx +295 -0
  321. package/src/stories-json/layout_extended.stories.tsx +76 -0
  322. package/src/stories-json/layout_flex.stories.tsx +107 -0
  323. package/src/stories-json/list-view.stories.tsx +97 -0
  324. package/src/stories-json/markdown.stories.tsx +129 -0
  325. package/src/stories-json/menus.stories.tsx +63 -0
  326. package/src/stories-json/metric-card.stories.tsx +143 -0
  327. package/src/stories-json/navigation-menu.stories.tsx +37 -0
  328. package/src/stories-json/object-aggrid.stories.tsx +252 -0
  329. package/src/stories-json/object-form.stories.tsx +130 -0
  330. package/src/stories-json/object-gantt.stories.tsx +114 -0
  331. package/src/stories-json/object-grid.stories.tsx +157 -0
  332. package/src/stories-json/object-map.stories.tsx +116 -0
  333. package/src/stories-json/object-view.stories.tsx +118 -0
  334. package/src/stories-json/overlay_extras.stories.tsx +113 -0
  335. package/src/stories-json/overlay_others.stories.tsx +76 -0
  336. package/src/stories-json/page.stories.tsx +55 -0
  337. package/src/stories-json/reports.stories.tsx +163 -0
  338. package/src/stories-json/resizable.stories.tsx +44 -0
  339. package/src/stories-json/select.stories.tsx +34 -0
  340. package/src/stories-json/separator.stories.tsx +41 -0
  341. package/src/stories-json/sidebar.stories.tsx +147 -0
  342. package/src/stories-json/statistic.stories.tsx +44 -0
  343. package/src/stories-json/tabs.stories.tsx +51 -0
  344. package/src/stories-json/timeline.stories.tsx +188 -0
  345. package/src/stories-json/typography.stories.tsx +45 -0
  346. package/src/ui/accordion.tsx +55 -53
  347. package/src/ui/alert-dialog.tsx +111 -117
  348. package/src/ui/alert.tsx +46 -57
  349. package/src/ui/aspect-ratio.tsx +9 -5
  350. package/src/ui/avatar.tsx +49 -42
  351. package/src/ui/badge.tsx +18 -20
  352. package/src/ui/breadcrumb.tsx +89 -75
  353. package/src/ui/button.tsx +38 -37
  354. package/src/ui/calendar.tsx +37 -53
  355. package/src/ui/card.tsx +59 -110
  356. package/src/ui/carousel.tsx +144 -113
  357. package/src/ui/chart.tsx +367 -0
  358. package/src/ui/checkbox.tsx +28 -22
  359. package/src/ui/collapsible.tsx +13 -25
  360. package/src/ui/command.tsx +114 -135
  361. package/src/ui/context-menu.tsx +77 -116
  362. package/src/ui/dialog.tsx +102 -113
  363. package/src/ui/drawer.tsx +90 -99
  364. package/src/ui/dropdown-menu.tsx +142 -188
  365. package/src/ui/form.tsx +59 -40
  366. package/src/ui/hover-card.tsx +26 -33
  367. package/src/ui/index.ts +11 -11
  368. package/src/ui/input-otp.tsx +53 -55
  369. package/src/ui/input.tsx +21 -15
  370. package/src/ui/label.tsx +25 -15
  371. package/src/ui/menubar.tsx +196 -206
  372. package/src/ui/navigation-menu.tsx +104 -136
  373. package/src/ui/pagination.tsx +94 -96
  374. package/src/ui/popover.tsx +29 -38
  375. package/src/ui/progress.tsx +29 -34
  376. package/src/ui/radio-group.tsx +27 -20
  377. package/src/ui/resizable.tsx +40 -42
  378. package/src/ui/scroll-area.tsx +46 -48
  379. package/src/ui/select.tsx +140 -160
  380. package/src/ui/separator.tsx +10 -2
  381. package/src/ui/sheet.tsx +118 -107
  382. package/src/ui/sidebar.tsx +471 -418
  383. package/src/ui/skeleton.tsx +14 -11
  384. package/src/ui/slider.tsx +27 -54
  385. package/src/ui/sonner.tsx +29 -19
  386. package/src/ui/switch.tsx +27 -21
  387. package/src/ui/table.tsx +102 -97
  388. package/src/ui/tabs.tsx +14 -37
  389. package/src/ui/textarea.tsx +16 -4
  390. package/src/ui/toast.tsx +137 -0
  391. package/src/ui/toggle-group.tsx +37 -55
  392. package/src/ui/toggle.tsx +30 -27
  393. package/src/ui/tooltip.tsx +29 -52
  394. package/src/ui/typography.tsx +85 -0
  395. package/tsconfig.json +2 -1
  396. package/vite.config.ts +20 -2
  397. package/vitest.config.ts +5 -0
  398. package/dist/src/index.test.d.ts +0 -1
  399. package/dist/src/new-components.test.d.ts +0 -1
  400. package/dist/src/renderers/complex/__tests__/data-table.test.d.ts +0 -0
  401. package/dist/src/renderers/complex/calendar-view.d.ts +0 -1
  402. package/dist/src/renderers/complex/chatbot.d.ts +0 -1
  403. package/dist/src/renderers/complex/chatbot.test.d.ts +0 -1
  404. package/dist/src/renderers/complex/timeline.d.ts +0 -1
  405. package/dist/src/ui/calendar-view.d.ts +0 -21
  406. package/dist/src/ui/chatbot.d.ts +0 -36
  407. package/dist/src/ui/field.d.ts +0 -24
  408. package/dist/src/ui/input-group.d.ts +0 -16
  409. package/dist/src/ui/spinner.d.ts +0 -3
  410. package/dist/src/ui/timeline.d.ts +0 -25
  411. package/metadata/ObjectTable.component.yml +0 -41
  412. package/src/renderers/complex/calendar-view.tsx +0 -219
  413. package/src/renderers/complex/chatbot.test.ts +0 -44
  414. package/src/renderers/complex/chatbot.tsx +0 -185
  415. package/src/renderers/complex/timeline.tsx +0 -466
  416. package/src/ui/calendar-view.tsx +0 -503
  417. package/src/ui/chatbot.tsx +0 -240
  418. package/src/ui/field.tsx +0 -246
  419. package/src/ui/input-group.tsx +0 -170
  420. package/src/ui/spinner.tsx +0 -38
  421. package/src/ui/timeline.tsx +0 -266
  422. package/tailwind.config.js +0 -75
  423. /package/dist/src/{ui → custom}/empty.d.ts +0 -0
@@ -1,9 +1,17 @@
1
+ /**
2
+ * ObjectUI
3
+ * Copyright (c) 2024-present ObjectStack Inc.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+
1
9
  "use client"
2
10
 
3
11
  import * as React from "react"
4
12
  import { Slot } from "@radix-ui/react-slot"
5
13
  import { cva, type VariantProps } from "class-variance-authority"
6
- import { PanelLeftIcon } from "lucide-react"
14
+ import { PanelLeft } from "lucide-react"
7
15
 
8
16
  import { useIsMobile } from "../hooks/use-mobile"
9
17
  import { cn } from "../lib/utils"
@@ -53,248 +61,267 @@ function useSidebar() {
53
61
  return context
54
62
  }
55
63
 
56
- function SidebarProvider({
57
- defaultOpen = true,
58
- open: openProp,
59
- onOpenChange: setOpenProp,
60
- className,
61
- style,
62
- children,
63
- ...props
64
- }: React.ComponentProps<"div"> & {
65
- defaultOpen?: boolean
66
- open?: boolean
67
- onOpenChange?: (open: boolean) => void
68
- }) {
69
- const isMobile = useIsMobile()
70
- const [openMobile, setOpenMobile] = React.useState(false)
71
-
72
- // This is the internal state of the sidebar.
73
- // We use openProp and setOpenProp for control from outside the component.
74
- const [_open, _setOpen] = React.useState(defaultOpen)
75
- const open = openProp ?? _open
76
- const setOpen = React.useCallback(
77
- (value: boolean | ((value: boolean) => boolean)) => {
78
- const openState = typeof value === "function" ? value(open) : value
79
- if (setOpenProp) {
80
- setOpenProp(openState)
81
- } else {
82
- _setOpen(openState)
83
- }
84
-
85
- // This sets the cookie to keep the sidebar state.
86
- document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
64
+ const SidebarProvider = React.forwardRef<
65
+ HTMLDivElement,
66
+ React.ComponentProps<"div"> & {
67
+ defaultOpen?: boolean
68
+ open?: boolean
69
+ onOpenChange?: (open: boolean) => void
70
+ }
71
+ >(
72
+ (
73
+ {
74
+ defaultOpen = true,
75
+ open: openProp,
76
+ onOpenChange: setOpenProp,
77
+ className,
78
+ style,
79
+ children,
80
+ ...props
87
81
  },
88
- [setOpenProp, open]
89
- )
82
+ ref
83
+ ) => {
84
+ const isMobile = useIsMobile()
85
+ const [openMobile, setOpenMobile] = React.useState(false)
86
+
87
+ // This is the internal state of the sidebar.
88
+ // We use openProp and setOpenProp for control from outside the component.
89
+ const [_open, _setOpen] = React.useState(defaultOpen)
90
+ const open = openProp ?? _open
91
+ const setOpen = React.useCallback(
92
+ (value: boolean | ((value: boolean) => boolean)) => {
93
+ const openState = typeof value === "function" ? value(open) : value
94
+ if (setOpenProp) {
95
+ setOpenProp(openState)
96
+ } else {
97
+ _setOpen(openState)
98
+ }
90
99
 
91
- // Helper to toggle the sidebar.
92
- const toggleSidebar = React.useCallback(() => {
93
- return isMobile ? setOpenMobile((open) => !open) : setOpen((open) => !open)
94
- }, [isMobile, setOpen, setOpenMobile])
95
-
96
- // Adds a keyboard shortcut to toggle the sidebar.
97
- React.useEffect(() => {
98
- const handleKeyDown = (event: KeyboardEvent) => {
99
- if (
100
- event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
101
- (event.metaKey || event.ctrlKey)
102
- ) {
103
- event.preventDefault()
104
- toggleSidebar()
100
+ // This sets the cookie to keep the sidebar state.
101
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${openState}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`
102
+ },
103
+ [setOpenProp, open]
104
+ )
105
+
106
+ // Helper to toggle the sidebar.
107
+ const toggleSidebar = React.useCallback(() => {
108
+ return isMobile
109
+ ? setOpenMobile((open) => !open)
110
+ : setOpen((open) => !open)
111
+ }, [isMobile, setOpen, setOpenMobile])
112
+
113
+ // Adds a keyboard shortcut to toggle the sidebar.
114
+ React.useEffect(() => {
115
+ const handleKeyDown = (event: KeyboardEvent) => {
116
+ if (
117
+ event.key === SIDEBAR_KEYBOARD_SHORTCUT &&
118
+ (event.metaKey || event.ctrlKey)
119
+ ) {
120
+ event.preventDefault()
121
+ toggleSidebar()
122
+ }
105
123
  }
106
- }
107
124
 
108
- window.addEventListener("keydown", handleKeyDown)
109
- return () => window.removeEventListener("keydown", handleKeyDown)
110
- }, [toggleSidebar])
111
-
112
- // We add a state so that we can do data-state="expanded" or "collapsed".
113
- // This makes it easier to style the sidebar with Tailwind classes.
114
- const state = open ? "expanded" : "collapsed"
115
-
116
- const contextValue = React.useMemo<SidebarContextProps>(
117
- () => ({
118
- state,
119
- open,
120
- setOpen,
121
- isMobile,
122
- openMobile,
123
- setOpenMobile,
124
- toggleSidebar,
125
- }),
126
- [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
127
- )
125
+ window.addEventListener("keydown", handleKeyDown)
126
+ return () => window.removeEventListener("keydown", handleKeyDown)
127
+ }, [toggleSidebar])
128
+
129
+ // We add a state so that we can do data-state="expanded" or "collapsed".
130
+ // This makes it easier to style the sidebar with Tailwind classes.
131
+ const state = open ? "expanded" : "collapsed"
132
+
133
+ const contextValue = React.useMemo<SidebarContextProps>(
134
+ () => ({
135
+ state,
136
+ open,
137
+ setOpen,
138
+ isMobile,
139
+ openMobile,
140
+ setOpenMobile,
141
+ toggleSidebar,
142
+ }),
143
+ [state, open, setOpen, isMobile, openMobile, setOpenMobile, toggleSidebar]
144
+ )
128
145
 
129
- return (
130
- <SidebarContext.Provider value={contextValue}>
131
- <TooltipProvider delayDuration={0}>
146
+ return (
147
+ <SidebarContext.Provider value={contextValue}>
148
+ <TooltipProvider delayDuration={0}>
149
+ <div
150
+ style={
151
+ {
152
+ "--sidebar-width": SIDEBAR_WIDTH,
153
+ "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
154
+ ...style,
155
+ } as React.CSSProperties
156
+ }
157
+ className={cn(
158
+ "group/sidebar-wrapper flex min-h-svh w-full has-[[data-variant=inset]]:bg-sidebar",
159
+ className
160
+ )}
161
+ ref={ref}
162
+ {...props}
163
+ >
164
+ {children}
165
+ </div>
166
+ </TooltipProvider>
167
+ </SidebarContext.Provider>
168
+ )
169
+ }
170
+ )
171
+ SidebarProvider.displayName = "SidebarProvider"
172
+
173
+ const Sidebar = React.forwardRef<
174
+ HTMLDivElement,
175
+ React.ComponentProps<"div"> & {
176
+ side?: "left" | "right"
177
+ variant?: "sidebar" | "floating" | "inset"
178
+ collapsible?: "offcanvas" | "icon" | "none"
179
+ }
180
+ >(
181
+ (
182
+ {
183
+ side = "left",
184
+ variant = "sidebar",
185
+ collapsible = "offcanvas",
186
+ className,
187
+ children,
188
+ ...props
189
+ },
190
+ ref
191
+ ) => {
192
+ const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
193
+
194
+ if (collapsible === "none") {
195
+ return (
132
196
  <div
133
- data-slot="sidebar-wrapper"
134
- style={
135
- {
136
- "--sidebar-width": SIDEBAR_WIDTH,
137
- "--sidebar-width-icon": SIDEBAR_WIDTH_ICON,
138
- ...style,
139
- } as React.CSSProperties
140
- }
141
197
  className={cn(
142
- "group/sidebar-wrapper has-data-[variant=inset]:bg-sidebar flex min-h-svh w-full",
198
+ "flex h-full w-[var(--sidebar-width)] flex-col bg-sidebar text-sidebar-foreground",
143
199
  className
144
200
  )}
201
+ ref={ref}
145
202
  {...props}
146
203
  >
147
204
  {children}
148
205
  </div>
149
- </TooltipProvider>
150
- </SidebarContext.Provider>
151
- )
152
- }
206
+ )
207
+ }
153
208
 
154
- function Sidebar({
155
- side = "left",
156
- variant = "sidebar",
157
- collapsible = "offcanvas",
158
- className,
159
- children,
160
- ...props
161
- }: React.ComponentProps<"div"> & {
162
- side?: "left" | "right"
163
- variant?: "sidebar" | "floating" | "inset"
164
- collapsible?: "offcanvas" | "icon" | "none"
165
- }) {
166
- const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
167
-
168
- if (collapsible === "none") {
169
- return (
170
- <div
171
- data-slot="sidebar"
172
- className={cn(
173
- "bg-sidebar text-sidebar-foreground flex h-full w-(--sidebar-width) flex-col",
174
- className
175
- )}
176
- {...props}
177
- >
178
- {children}
179
- </div>
180
- )
181
- }
209
+ if (isMobile) {
210
+ return (
211
+ <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
212
+ <SheetContent
213
+ data-sidebar="sidebar"
214
+ data-mobile="true"
215
+ className="w-[var(--sidebar-width)] bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden"
216
+ style={
217
+ {
218
+ "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
219
+ } as React.CSSProperties
220
+ }
221
+ side={side}
222
+ >
223
+ <SheetHeader className="sr-only">
224
+ <SheetTitle>Sidebar</SheetTitle>
225
+ <SheetDescription>Displays the mobile sidebar.</SheetDescription>
226
+ </SheetHeader>
227
+ <div className="flex h-full w-full flex-col">{children}</div>
228
+ </SheetContent>
229
+ </Sheet>
230
+ )
231
+ }
182
232
 
183
- if (isMobile) {
184
233
  return (
185
- <Sheet open={openMobile} onOpenChange={setOpenMobile} {...props}>
186
- <SheetContent
187
- data-sidebar="sidebar"
188
- data-slot="sidebar"
189
- data-mobile="true"
190
- className="bg-sidebar text-sidebar-foreground w-[--sidebar-width] p-0 [&>button]:hidden"
191
- style={
192
- {
193
- "--sidebar-width": SIDEBAR_WIDTH_MOBILE,
194
- } as React.CSSProperties
195
- }
196
- side={side}
197
- >
198
- <SheetHeader className="sr-only">
199
- <SheetTitle>Sidebar</SheetTitle>
200
- <SheetDescription>Displays the mobile sidebar.</SheetDescription>
201
- </SheetHeader>
202
- <div className="flex h-full w-full flex-col">{children}</div>
203
- </SheetContent>
204
- </Sheet>
205
- )
206
- }
207
-
208
- return (
209
- <div
210
- className="group peer text-sidebar-foreground hidden md:block"
211
- data-state={state}
212
- data-collapsible={state === "collapsed" ? collapsible : ""}
213
- data-variant={variant}
214
- data-side={side}
215
- data-slot="sidebar"
216
- >
217
- {/* This is what handles the sidebar gap on desktop */}
218
- <div
219
- data-slot="sidebar-gap"
220
- className={cn(
221
- "relative w-[--sidebar-width] bg-transparent transition-[width] duration-200 ease-linear",
222
- "group-data-[collapsible=offcanvas]:w-0",
223
- "group-data-[side=right]:rotate-180",
224
- variant === "floating" || variant === "inset"
225
- ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+1rem)]"
226
- : "group-data-[collapsible=icon]:w-[--sidebar-width-icon]"
227
- )}
228
- />
229
234
  <div
230
- data-slot="sidebar-container"
231
- className={cn(
232
- "fixed inset-y-0 z-10 hidden h-svh w-[--sidebar-width] transition-[left,right,width] duration-200 ease-linear md:flex",
233
- side === "left"
234
- ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
235
- : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
236
- // Adjust the padding for floating and inset variants.
237
- variant === "floating" || variant === "inset"
238
- ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+1rem+2px)]"
239
- : "group-data-[collapsible=icon]:w-[--sidebar-width-icon] group-data-[side=left]:border-r group-data-[side=right]:border-l",
240
- className
241
- )}
242
- {...props}
235
+ ref={ref}
236
+ className="group peer hidden text-sidebar-foreground md:block"
237
+ data-state={state}
238
+ data-collapsible={state === "collapsed" ? collapsible : ""}
239
+ data-variant={variant}
240
+ data-side={side}
243
241
  >
242
+ {/* This is what handles the sidebar gap on desktop */}
243
+ <div
244
+ className={cn(
245
+ "relative w-[var(--sidebar-width)] bg-transparent transition-[width] duration-200 ease-linear",
246
+ "group-data-[collapsible=offcanvas]:w-0",
247
+ "group-data-[side=right]:rotate-180",
248
+ variant === "floating" || variant === "inset"
249
+ ? "group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4))]"
250
+ : "group-data-[collapsible=icon]:w-[var(--sidebar-width-icon)]"
251
+ )}
252
+ />
244
253
  <div
245
- data-sidebar="sidebar"
246
- data-slot="sidebar-inner"
247
- className="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
254
+ className={cn(
255
+ "fixed inset-y-0 z-10 hidden h-svh w-[var(--sidebar-width)] transition-[left,right,width] duration-200 ease-linear md:flex",
256
+ side === "left"
257
+ ? "left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]"
258
+ : "right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]",
259
+ // Adjust the padding for floating and inset variants.
260
+ variant === "floating" || variant === "inset"
261
+ ? "p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)_+_theme(spacing.4)_+2px)]"
262
+ : "group-data-[collapsible=icon]:w-[var(--sidebar-width-icon)] group-data-[side=left]:border-r group-data-[side=right]:border-l",
263
+ className
264
+ )}
265
+ {...props}
248
266
  >
249
- {children}
267
+ <div
268
+ data-sidebar="sidebar"
269
+ className="flex h-full w-full flex-col bg-sidebar group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:border-sidebar-border group-data-[variant=floating]:shadow"
270
+ >
271
+ {children}
272
+ </div>
250
273
  </div>
251
274
  </div>
252
- </div>
253
- )
254
- }
275
+ )
276
+ }
277
+ )
278
+ Sidebar.displayName = "Sidebar"
255
279
 
256
- function SidebarTrigger({
257
- className,
258
- onClick,
259
- ...props
260
- }: React.ComponentProps<typeof Button>) {
280
+ const SidebarTrigger = React.forwardRef<
281
+ React.ElementRef<typeof Button>,
282
+ React.ComponentProps<typeof Button>
283
+ >(({ className, onClick, ...props }, ref) => {
261
284
  const { toggleSidebar } = useSidebar()
262
285
 
263
286
  return (
264
287
  <Button
288
+ ref={ref}
265
289
  data-sidebar="trigger"
266
- data-slot="sidebar-trigger"
267
290
  variant="ghost"
268
291
  size="icon"
269
- className={cn("size-7", className)}
292
+ className={cn("h-7 w-7", className)}
270
293
  onClick={(event) => {
271
294
  onClick?.(event)
272
295
  toggleSidebar()
273
296
  }}
274
297
  {...props}
275
298
  >
276
- <PanelLeftIcon />
299
+ <PanelLeft />
277
300
  <span className="sr-only">Toggle Sidebar</span>
278
301
  </Button>
279
302
  )
280
- }
303
+ })
304
+ SidebarTrigger.displayName = "SidebarTrigger"
281
305
 
282
- function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
306
+ const SidebarRail = React.forwardRef<
307
+ HTMLButtonElement,
308
+ React.ComponentProps<"button">
309
+ >(({ className, ...props }, ref) => {
283
310
  const { toggleSidebar } = useSidebar()
284
311
 
285
312
  return (
286
313
  <button
314
+ ref={ref}
287
315
  data-sidebar="rail"
288
- data-slot="sidebar-rail"
289
316
  aria-label="Toggle Sidebar"
290
317
  tabIndex={-1}
291
318
  onClick={toggleSidebar}
292
319
  title="Toggle Sidebar"
293
320
  className={cn(
294
- "hover:after:bg-sidebar-border absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear group-data-[side=left]:-right-4 group-data-[side=right]:left-0 after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] sm:flex",
295
- "in-data-[side=left]:cursor-w-resize in-data-[side=right]:cursor-e-resize",
321
+ "absolute inset-y-0 z-20 hidden w-4 -translate-x-1/2 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] hover:after:bg-sidebar-border group-data-[side=left]:-right-4 group-data-[side=right]:left-0 sm:flex",
322
+ "[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize",
296
323
  "[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize",
297
- "hover:group-data-[collapsible=offcanvas]:bg-sidebar group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full",
324
+ "group-data-[collapsible=offcanvas]:translate-x-0 group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar",
298
325
  "[[data-side=left][data-collapsible=offcanvas]_&]:-right-2",
299
326
  "[[data-side=right][data-collapsible=offcanvas]_&]:-left-2",
300
327
  className
@@ -302,76 +329,97 @@ function SidebarRail({ className, ...props }: React.ComponentProps<"button">) {
302
329
  {...props}
303
330
  />
304
331
  )
305
- }
332
+ })
333
+ SidebarRail.displayName = "SidebarRail"
306
334
 
307
- function SidebarInset({ className, ...props }: React.ComponentProps<"main">) {
335
+ const SidebarInset = React.forwardRef<
336
+ HTMLDivElement,
337
+ React.ComponentProps<"main">
338
+ >(({ className, ...props }, ref) => {
308
339
  return (
309
340
  <main
310
- data-slot="sidebar-inset"
341
+ ref={ref}
311
342
  className={cn(
312
- "bg-background relative flex w-full flex-1 flex-col",
313
- "md:peer-data-[variant=inset]:m-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow-sm md:peer-data-[variant=inset]:peer-data-[state=collapsed]:ml-2",
343
+ "relative flex w-full flex-1 flex-col bg-background",
344
+ "md:peer-data-[variant=inset]:m-2 md:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[variant=inset]:ml-0 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow",
314
345
  className
315
346
  )}
316
347
  {...props}
317
348
  />
318
349
  )
319
- }
350
+ })
351
+ SidebarInset.displayName = "SidebarInset"
320
352
 
321
- function SidebarInput({
322
- className,
323
- ...props
324
- }: React.ComponentProps<typeof Input>) {
353
+ const SidebarInput = React.forwardRef<
354
+ React.ElementRef<typeof Input>,
355
+ React.ComponentProps<typeof Input>
356
+ >(({ className, ...props }, ref) => {
325
357
  return (
326
358
  <Input
327
- data-slot="sidebar-input"
359
+ ref={ref}
328
360
  data-sidebar="input"
329
- className={cn("bg-background h-8 w-full shadow-none", className)}
361
+ className={cn(
362
+ "h-8 w-full bg-background shadow-none focus-visible:ring-2 focus-visible:ring-sidebar-ring",
363
+ className
364
+ )}
330
365
  {...props}
331
366
  />
332
367
  )
333
- }
368
+ })
369
+ SidebarInput.displayName = "SidebarInput"
334
370
 
335
- function SidebarHeader({ className, ...props }: React.ComponentProps<"div">) {
371
+ const SidebarHeader = React.forwardRef<
372
+ HTMLDivElement,
373
+ React.ComponentProps<"div">
374
+ >(({ className, ...props }, ref) => {
336
375
  return (
337
376
  <div
338
- data-slot="sidebar-header"
377
+ ref={ref}
339
378
  data-sidebar="header"
340
379
  className={cn("flex flex-col gap-2 p-2", className)}
341
380
  {...props}
342
381
  />
343
382
  )
344
- }
383
+ })
384
+ SidebarHeader.displayName = "SidebarHeader"
345
385
 
346
- function SidebarFooter({ className, ...props }: React.ComponentProps<"div">) {
386
+ const SidebarFooter = React.forwardRef<
387
+ HTMLDivElement,
388
+ React.ComponentProps<"div">
389
+ >(({ className, ...props }, ref) => {
347
390
  return (
348
391
  <div
349
- data-slot="sidebar-footer"
392
+ ref={ref}
350
393
  data-sidebar="footer"
351
394
  className={cn("flex flex-col gap-2 p-2", className)}
352
395
  {...props}
353
396
  />
354
397
  )
355
- }
398
+ })
399
+ SidebarFooter.displayName = "SidebarFooter"
356
400
 
357
- function SidebarSeparator({
358
- className,
359
- ...props
360
- }: React.ComponentProps<typeof Separator>) {
401
+ const SidebarSeparator = React.forwardRef<
402
+ React.ElementRef<typeof Separator>,
403
+ React.ComponentProps<typeof Separator>
404
+ >(({ className, ...props }, ref) => {
361
405
  return (
362
406
  <Separator
363
- data-slot="sidebar-separator"
407
+ ref={ref}
364
408
  data-sidebar="separator"
365
- className={cn("bg-sidebar-border mx-2 w-auto", className)}
409
+ className={cn("mx-2 w-auto bg-sidebar-border", className)}
366
410
  {...props}
367
411
  />
368
412
  )
369
- }
413
+ })
414
+ SidebarSeparator.displayName = "SidebarSeparator"
370
415
 
371
- function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
416
+ const SidebarContent = React.forwardRef<
417
+ HTMLDivElement,
418
+ React.ComponentProps<"div">
419
+ >(({ className, ...props }, ref) => {
372
420
  return (
373
421
  <div
374
- data-slot="sidebar-content"
422
+ ref={ref}
375
423
  data-sidebar="content"
376
424
  className={cn(
377
425
  "flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden",
@@ -380,101 +428,109 @@ function SidebarContent({ className, ...props }: React.ComponentProps<"div">) {
380
428
  {...props}
381
429
  />
382
430
  )
383
- }
431
+ })
432
+ SidebarContent.displayName = "SidebarContent"
384
433
 
385
- function SidebarGroup({ className, ...props }: React.ComponentProps<"div">) {
434
+ const SidebarGroup = React.forwardRef<
435
+ HTMLDivElement,
436
+ React.ComponentProps<"div">
437
+ >(({ className, ...props }, ref) => {
386
438
  return (
387
439
  <div
388
- data-slot="sidebar-group"
440
+ ref={ref}
389
441
  data-sidebar="group"
390
442
  className={cn("relative flex w-full min-w-0 flex-col p-2", className)}
391
443
  {...props}
392
444
  />
393
445
  )
394
- }
446
+ })
447
+ SidebarGroup.displayName = "SidebarGroup"
395
448
 
396
- function SidebarGroupLabel({
397
- className,
398
- asChild = false,
399
- ...props
400
- }: React.ComponentProps<"div"> & { asChild?: boolean }) {
449
+ const SidebarGroupLabel = React.forwardRef<
450
+ HTMLDivElement,
451
+ React.ComponentProps<"div"> & { asChild?: boolean }
452
+ >(({ className, asChild = false, ...props }, ref) => {
401
453
  const Comp = asChild ? Slot : "div"
402
454
 
403
455
  return (
404
456
  <Comp
405
- data-slot="sidebar-group-label"
457
+ ref={ref}
406
458
  data-sidebar="group-label"
407
459
  className={cn(
408
- "text-sidebar-foreground/70 ring-sidebar-ring flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium outline-hidden transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
460
+ "flex h-8 shrink-0 items-center rounded-md px-2 text-xs font-medium text-sidebar-foreground/70 outline-none ring-sidebar-ring transition-[margin,opacity] duration-200 ease-linear focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
409
461
  "group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0",
410
462
  className
411
463
  )}
412
464
  {...props}
413
465
  />
414
466
  )
415
- }
467
+ })
468
+ SidebarGroupLabel.displayName = "SidebarGroupLabel"
416
469
 
417
- function SidebarGroupAction({
418
- className,
419
- asChild = false,
420
- ...props
421
- }: React.ComponentProps<"button"> & { asChild?: boolean }) {
470
+ const SidebarGroupAction = React.forwardRef<
471
+ HTMLButtonElement,
472
+ React.ComponentProps<"button"> & { asChild?: boolean }
473
+ >(({ className, asChild = false, ...props }, ref) => {
422
474
  const Comp = asChild ? Slot : "button"
423
475
 
424
476
  return (
425
477
  <Comp
426
- data-slot="sidebar-group-action"
478
+ ref={ref}
427
479
  data-sidebar="group-action"
428
480
  className={cn(
429
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground absolute top-3.5 right-3 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
481
+ "absolute right-3 top-3.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
430
482
  // Increases the hit area of the button on mobile.
431
- "after:absolute after:-inset-2 md:after:hidden",
483
+ "after:absolute after:-inset-2 after:md:hidden",
432
484
  "group-data-[collapsible=icon]:hidden",
433
485
  className
434
486
  )}
435
487
  {...props}
436
488
  />
437
489
  )
438
- }
439
-
440
- function SidebarGroupContent({
441
- className,
442
- ...props
443
- }: React.ComponentProps<"div">) {
444
- return (
445
- <div
446
- data-slot="sidebar-group-content"
447
- data-sidebar="group-content"
448
- className={cn("w-full text-sm", className)}
449
- {...props}
450
- />
451
- )
452
- }
453
-
454
- function SidebarMenu({ className, ...props }: React.ComponentProps<"ul">) {
455
- return (
456
- <ul
457
- data-slot="sidebar-menu"
458
- data-sidebar="menu"
459
- className={cn("flex w-full min-w-0 flex-col gap-1", className)}
460
- {...props}
461
- />
462
- )
463
- }
464
-
465
- function SidebarMenuItem({ className, ...props }: React.ComponentProps<"li">) {
466
- return (
467
- <li
468
- data-slot="sidebar-menu-item"
469
- data-sidebar="menu-item"
470
- className={cn("group/menu-item relative", className)}
471
- {...props}
472
- />
473
- )
474
- }
490
+ })
491
+ SidebarGroupAction.displayName = "SidebarGroupAction"
492
+
493
+ const SidebarGroupContent = React.forwardRef<
494
+ HTMLDivElement,
495
+ React.ComponentProps<"div">
496
+ >(({ className, ...props }, ref) => (
497
+ <div
498
+ ref={ref}
499
+ data-sidebar="group-content"
500
+ className={cn("w-full text-sm", className)}
501
+ {...props}
502
+ />
503
+ ))
504
+ SidebarGroupContent.displayName = "SidebarGroupContent"
505
+
506
+ const SidebarMenu = React.forwardRef<
507
+ HTMLUListElement,
508
+ React.ComponentProps<"ul">
509
+ >(({ className, ...props }, ref) => (
510
+ <ul
511
+ ref={ref}
512
+ data-sidebar="menu"
513
+ className={cn("flex w-full min-w-0 flex-col gap-1", className)}
514
+ {...props}
515
+ />
516
+ ))
517
+ SidebarMenu.displayName = "SidebarMenu"
518
+
519
+ const SidebarMenuItem = React.forwardRef<
520
+ HTMLLIElement,
521
+ React.ComponentProps<"li">
522
+ >(({ className, ...props }, ref) => (
523
+ <li
524
+ ref={ref}
525
+ data-sidebar="menu-item"
526
+ className={cn("group/menu-item relative", className)}
527
+ {...props}
528
+ />
529
+ ))
530
+ SidebarMenuItem.displayName = "SidebarMenuItem"
475
531
 
476
532
  const sidebarMenuButtonVariants = cva(
477
- "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-hidden ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-data-[sidebar=menu-action]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:size-8! group-data-[collapsible=icon]:p-2! [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
533
+ "peer/menu-button flex w-full items-center gap-2 overflow-hidden rounded-md p-2 text-left text-sm outline-none ring-sidebar-ring transition-[width,height,padding] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 group-has-[[data-sidebar=menu-action]]/menu-item:pr-8 aria-disabled:pointer-events-none aria-disabled:opacity-50 data-[active=true]:bg-sidebar-accent data-[active=true]:font-medium data-[active=true]:text-sidebar-accent-foreground data-[state=open]:hover:bg-sidebar-accent data-[state=open]:hover:text-sidebar-accent-foreground group-data-[collapsible=icon]:!size-8 group-data-[collapsible=icon]:!p-2 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
478
534
  {
479
535
  variants: {
480
536
  variant: {
@@ -485,7 +541,7 @@ const sidebarMenuButtonVariants = cva(
485
541
  size: {
486
542
  default: "h-8 text-sm",
487
543
  sm: "h-7 text-xs",
488
- lg: "h-12 text-sm group-data-[collapsible=icon]:p-0!",
544
+ lg: "h-12 text-sm group-data-[collapsible=icon]:!p-0",
489
545
  },
490
546
  },
491
547
  defaultVariants: {
@@ -495,125 +551,129 @@ const sidebarMenuButtonVariants = cva(
495
551
  }
496
552
  )
497
553
 
498
- function SidebarMenuButton({
499
- asChild = false,
500
- isActive = false,
501
- variant = "default",
502
- size = "default",
503
- tooltip,
504
- className,
505
- ...props
506
- }: React.ComponentProps<"button"> & {
507
- asChild?: boolean
508
- isActive?: boolean
509
- tooltip?: string | React.ComponentProps<typeof TooltipContent>
510
- } & VariantProps<typeof sidebarMenuButtonVariants>) {
511
- const Comp = asChild ? Slot : "button"
512
- const { isMobile, state } = useSidebar()
513
-
514
- const button = (
515
- <Comp
516
- data-slot="sidebar-menu-button"
517
- data-sidebar="menu-button"
518
- data-size={size}
519
- data-active={isActive}
520
- className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
521
- {...props}
522
- />
523
- )
554
+ const SidebarMenuButton = React.forwardRef<
555
+ HTMLButtonElement,
556
+ React.ComponentProps<"button"> & {
557
+ asChild?: boolean
558
+ isActive?: boolean
559
+ tooltip?: string | React.ComponentProps<typeof TooltipContent>
560
+ } & VariantProps<typeof sidebarMenuButtonVariants>
561
+ >(
562
+ (
563
+ {
564
+ asChild = false,
565
+ isActive = false,
566
+ variant = "default",
567
+ size = "default",
568
+ tooltip,
569
+ className,
570
+ ...props
571
+ },
572
+ ref
573
+ ) => {
574
+ const Comp = asChild ? Slot : "button"
575
+ const { isMobile, state } = useSidebar()
576
+
577
+ const button = (
578
+ <Comp
579
+ ref={ref}
580
+ data-sidebar="menu-button"
581
+ data-size={size}
582
+ data-active={isActive}
583
+ className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
584
+ {...props}
585
+ />
586
+ )
524
587
 
525
- if (!tooltip) {
526
- return button
527
- }
588
+ if (!tooltip) {
589
+ return button
590
+ }
528
591
 
529
- if (typeof tooltip === "string") {
530
- tooltip = {
531
- children: tooltip,
592
+ if (typeof tooltip === "string") {
593
+ tooltip = {
594
+ children: tooltip,
595
+ }
532
596
  }
533
- }
534
597
 
535
- return (
536
- <Tooltip>
537
- <TooltipTrigger asChild>{button}</TooltipTrigger>
538
- <TooltipContent
539
- side="right"
540
- align="center"
541
- hidden={state !== "collapsed" || isMobile}
542
- {...tooltip}
543
- />
544
- </Tooltip>
545
- )
546
- }
598
+ return (
599
+ <Tooltip>
600
+ <TooltipTrigger asChild>{button}</TooltipTrigger>
601
+ <TooltipContent
602
+ side="right"
603
+ align="center"
604
+ hidden={state !== "collapsed" || isMobile}
605
+ {...tooltip}
606
+ />
607
+ </Tooltip>
608
+ )
609
+ }
610
+ )
611
+ SidebarMenuButton.displayName = "SidebarMenuButton"
547
612
 
548
- function SidebarMenuAction({
549
- className,
550
- asChild = false,
551
- showOnHover = false,
552
- ...props
553
- }: React.ComponentProps<"button"> & {
554
- asChild?: boolean
555
- showOnHover?: boolean
556
- }) {
613
+ const SidebarMenuAction = React.forwardRef<
614
+ HTMLButtonElement,
615
+ React.ComponentProps<"button"> & {
616
+ asChild?: boolean
617
+ showOnHover?: boolean
618
+ }
619
+ >(({ className, asChild = false, showOnHover = false, ...props }, ref) => {
557
620
  const Comp = asChild ? Slot : "button"
558
621
 
559
622
  return (
560
623
  <Comp
561
- data-slot="sidebar-menu-action"
624
+ ref={ref}
562
625
  data-sidebar="menu-action"
563
626
  className={cn(
564
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground peer-hover/menu-button:text-sidebar-accent-foreground absolute top-1.5 right-1 flex aspect-square w-5 items-center justify-center rounded-md p-0 outline-hidden transition-transform focus-visible:ring-2 [&>svg]:size-4 [&>svg]:shrink-0",
627
+ "absolute right-1 top-1.5 flex aspect-square w-5 items-center justify-center rounded-md p-0 text-sidebar-foreground outline-none ring-sidebar-ring transition-transform hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 peer-hover/menu-button:text-sidebar-accent-foreground [&>svg]:size-4 [&>svg]:shrink-0",
565
628
  // Increases the hit area of the button on mobile.
566
- "after:absolute after:-inset-2 md:after:hidden",
629
+ "after:absolute after:-inset-2 after:md:hidden",
567
630
  "peer-data-[size=sm]/menu-button:top-1",
568
631
  "peer-data-[size=default]/menu-button:top-1.5",
569
632
  "peer-data-[size=lg]/menu-button:top-2.5",
570
633
  "group-data-[collapsible=icon]:hidden",
571
634
  showOnHover &&
572
- "peer-data-[active=true]/menu-button:text-sidebar-accent-foreground group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 md:opacity-0",
635
+ "group-focus-within/menu-item:opacity-100 group-hover/menu-item:opacity-100 data-[state=open]:opacity-100 peer-data-[active=true]/menu-button:text-sidebar-accent-foreground md:opacity-0",
573
636
  className
574
637
  )}
575
638
  {...props}
576
639
  />
577
640
  )
578
- }
579
-
580
- function SidebarMenuBadge({
581
- className,
582
- ...props
583
- }: React.ComponentProps<"div">) {
584
- return (
585
- <div
586
- data-slot="sidebar-menu-badge"
587
- data-sidebar="menu-badge"
588
- className={cn(
589
- "text-sidebar-foreground pointer-events-none absolute right-1 flex h-5 min-w-5 items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums select-none",
590
- "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
591
- "peer-data-[size=sm]/menu-button:top-1",
592
- "peer-data-[size=default]/menu-button:top-1.5",
593
- "peer-data-[size=lg]/menu-button:top-2.5",
594
- "group-data-[collapsible=icon]:hidden",
595
- className
596
- )}
597
- {...props}
598
- />
599
- )
600
- }
601
-
602
- function SidebarMenuSkeleton({
603
- className,
604
- showIcon = false,
605
- ...props
606
- }: React.ComponentProps<"div"> & {
607
- showIcon?: boolean
608
- }) {
641
+ })
642
+ SidebarMenuAction.displayName = "SidebarMenuAction"
643
+
644
+ const SidebarMenuBadge = React.forwardRef<
645
+ HTMLDivElement,
646
+ React.ComponentProps<"div">
647
+ >(({ className, ...props }, ref) => (
648
+ <div
649
+ ref={ref}
650
+ data-sidebar="menu-badge"
651
+ className={cn(
652
+ "pointer-events-none absolute right-1 flex h-5 min-w-5 select-none items-center justify-center rounded-md px-1 text-xs font-medium tabular-nums text-sidebar-foreground",
653
+ "peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground",
654
+ "peer-data-[size=sm]/menu-button:top-1",
655
+ "peer-data-[size=default]/menu-button:top-1.5",
656
+ "peer-data-[size=lg]/menu-button:top-2.5",
657
+ "group-data-[collapsible=icon]:hidden",
658
+ className
659
+ )}
660
+ {...props}
661
+ />
662
+ ))
663
+ SidebarMenuBadge.displayName = "SidebarMenuBadge"
664
+
665
+ const SidebarMenuSkeleton = React.forwardRef<
666
+ HTMLDivElement,
667
+ React.ComponentProps<"div"> & {
668
+ showIcon?: boolean
669
+ }
670
+ >(({ className, showIcon = false, ...props }, ref) => {
609
671
  // Random width between 50 to 90%.
610
- const [width] = React.useState(() => {
611
- return `${Math.floor(Math.random() * 40) + 50}%`
612
- })
672
+ const [width] = React.useState(() => `${Math.floor(Math.random() * 40) + 50}%`)
613
673
 
614
674
  return (
615
675
  <div
616
- data-slot="sidebar-menu-skeleton"
676
+ ref={ref}
617
677
  data-sidebar="menu-skeleton"
618
678
  className={cn("flex h-8 items-center gap-2 rounded-md px-2", className)}
619
679
  {...props}
@@ -625,7 +685,7 @@ function SidebarMenuSkeleton({
625
685
  />
626
686
  )}
627
687
  <Skeleton
628
- className="h-4 max-w-(--skeleton-width) flex-1"
688
+ className="h-4 max-w-[--skeleton-width] flex-1"
629
689
  data-sidebar="menu-skeleton-text"
630
690
  style={
631
691
  {
@@ -635,58 +695,50 @@ function SidebarMenuSkeleton({
635
695
  />
636
696
  </div>
637
697
  )
638
- }
639
-
640
- function SidebarMenuSub({ className, ...props }: React.ComponentProps<"ul">) {
641
- return (
642
- <ul
643
- data-slot="sidebar-menu-sub"
644
- data-sidebar="menu-sub"
645
- className={cn(
646
- "border-sidebar-border mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l px-2.5 py-0.5",
647
- "group-data-[collapsible=icon]:hidden",
648
- className
649
- )}
650
- {...props}
651
- />
652
- )
653
- }
654
-
655
- function SidebarMenuSubItem({
656
- className,
657
- ...props
658
- }: React.ComponentProps<"li">) {
659
- return (
660
- <li
661
- data-slot="sidebar-menu-sub-item"
662
- data-sidebar="menu-sub-item"
663
- className={cn("group/menu-sub-item relative", className)}
664
- {...props}
665
- />
666
- )
667
- }
668
-
669
- function SidebarMenuSubButton({
670
- asChild = false,
671
- size = "md",
672
- isActive = false,
673
- className,
674
- ...props
675
- }: React.ComponentProps<"a"> & {
676
- asChild?: boolean
677
- size?: "sm" | "md"
678
- isActive?: boolean
679
- }) {
698
+ })
699
+ SidebarMenuSkeleton.displayName = "SidebarMenuSkeleton"
700
+
701
+ const SidebarMenuSub = React.forwardRef<
702
+ HTMLUListElement,
703
+ React.ComponentProps<"ul">
704
+ >(({ className, ...props }, ref) => (
705
+ <ul
706
+ ref={ref}
707
+ data-sidebar="menu-sub"
708
+ className={cn(
709
+ "mx-3.5 flex min-w-0 translate-x-px flex-col gap-1 border-l border-sidebar-border px-2.5 py-0.5",
710
+ "group-data-[collapsible=icon]:hidden",
711
+ className
712
+ )}
713
+ {...props}
714
+ />
715
+ ))
716
+ SidebarMenuSub.displayName = "SidebarMenuSub"
717
+
718
+ const SidebarMenuSubItem = React.forwardRef<
719
+ HTMLLIElement,
720
+ React.ComponentProps<"li">
721
+ >(({ ...props }, ref) => <li ref={ref} {...props} />)
722
+ SidebarMenuSubItem.displayName = "SidebarMenuSubItem"
723
+
724
+ const SidebarMenuSubButton = React.forwardRef<
725
+ HTMLAnchorElement,
726
+ React.ComponentProps<"a"> & {
727
+ asChild?: boolean
728
+ size?: "sm" | "md"
729
+ isActive?: boolean
730
+ }
731
+ >(({ asChild = false, size = "md", isActive, className, ...props }, ref) => {
680
732
  const Comp = asChild ? Slot : "a"
681
733
 
682
734
  return (
683
735
  <Comp
684
- data-slot="sidebar-menu-sub-button"
736
+ ref={ref}
685
737
  data-sidebar="menu-sub-button"
686
738
  data-size={size}
687
739
  data-active={isActive}
688
740
  className={cn(
689
- "text-sidebar-foreground ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground active:bg-sidebar-accent active:text-sidebar-accent-foreground [&>svg]:text-sidebar-accent-foreground flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 outline-hidden focus-visible:ring-2 disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0",
741
+ "flex h-7 min-w-0 -translate-x-px items-center gap-2 overflow-hidden rounded-md px-2 text-sidebar-foreground outline-none ring-sidebar-ring hover:bg-sidebar-accent hover:text-sidebar-accent-foreground focus-visible:ring-2 active:bg-sidebar-accent active:text-sidebar-accent-foreground disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 [&>span:last-child]:truncate [&>svg]:size-4 [&>svg]:shrink-0 [&>svg]:text-sidebar-accent-foreground",
690
742
  "data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground",
691
743
  size === "sm" && "text-xs",
692
744
  size === "md" && "text-sm",
@@ -696,7 +748,8 @@ function SidebarMenuSubButton({
696
748
  {...props}
697
749
  />
698
750
  )
699
- }
751
+ })
752
+ SidebarMenuSubButton.displayName = "SidebarMenuSubButton"
700
753
 
701
754
  export {
702
755
  Sidebar,