@mihcm/ui 0.14.1

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 (737) hide show
  1. package/README.md +138 -0
  2. package/dist/AccessLevelGroup.d.ts +37 -0
  3. package/dist/AccessLevelGroup.d.ts.map +1 -0
  4. package/dist/AccessLevelGroup.js +39 -0
  5. package/dist/AccessLevelGroup.js.map +1 -0
  6. package/dist/AccessLevelGroup.native.d.ts +18 -0
  7. package/dist/AccessLevelGroup.native.d.ts.map +1 -0
  8. package/dist/AccessLevelGroup.native.js +40 -0
  9. package/dist/AccessLevelGroup.native.js.map +1 -0
  10. package/dist/Accordion.d.ts +52 -0
  11. package/dist/Accordion.d.ts.map +1 -0
  12. package/dist/Accordion.js +90 -0
  13. package/dist/Accordion.js.map +1 -0
  14. package/dist/Accordion.native.d.ts +36 -0
  15. package/dist/Accordion.native.d.ts.map +1 -0
  16. package/dist/Accordion.native.js +86 -0
  17. package/dist/Accordion.native.js.map +1 -0
  18. package/dist/Alert.d.ts +33 -0
  19. package/dist/Alert.d.ts.map +1 -0
  20. package/dist/Alert.js +45 -0
  21. package/dist/Alert.js.map +1 -0
  22. package/dist/Alert.native.d.ts +26 -0
  23. package/dist/Alert.native.d.ts.map +1 -0
  24. package/dist/Alert.native.js +41 -0
  25. package/dist/Alert.native.js.map +1 -0
  26. package/dist/AlertDialog.d.ts +57 -0
  27. package/dist/AlertDialog.d.ts.map +1 -0
  28. package/dist/AlertDialog.js +91 -0
  29. package/dist/AlertDialog.js.map +1 -0
  30. package/dist/AlertDialog.native.d.ts +66 -0
  31. package/dist/AlertDialog.native.d.ts.map +1 -0
  32. package/dist/AlertDialog.native.js +71 -0
  33. package/dist/AlertDialog.native.js.map +1 -0
  34. package/dist/AspectRatio.d.ts +18 -0
  35. package/dist/AspectRatio.d.ts.map +1 -0
  36. package/dist/AspectRatio.js +19 -0
  37. package/dist/AspectRatio.js.map +1 -0
  38. package/dist/AspectRatio.native.d.ts +7 -0
  39. package/dist/AspectRatio.native.d.ts.map +1 -0
  40. package/dist/AspectRatio.native.js +13 -0
  41. package/dist/AspectRatio.native.js.map +1 -0
  42. package/dist/Avatar.d.ts +45 -0
  43. package/dist/Avatar.d.ts.map +1 -0
  44. package/dist/Avatar.js +69 -0
  45. package/dist/Avatar.js.map +1 -0
  46. package/dist/Avatar.native.d.ts +38 -0
  47. package/dist/Avatar.native.d.ts.map +1 -0
  48. package/dist/Avatar.native.js +56 -0
  49. package/dist/Avatar.native.js.map +1 -0
  50. package/dist/AvatarGroup.d.ts +32 -0
  51. package/dist/AvatarGroup.d.ts.map +1 -0
  52. package/dist/AvatarGroup.js +45 -0
  53. package/dist/AvatarGroup.js.map +1 -0
  54. package/dist/AvatarGroup.native.d.ts +18 -0
  55. package/dist/AvatarGroup.native.d.ts.map +1 -0
  56. package/dist/AvatarGroup.native.js +35 -0
  57. package/dist/AvatarGroup.native.js.map +1 -0
  58. package/dist/Badge.d.ts +26 -0
  59. package/dist/Badge.d.ts.map +1 -0
  60. package/dist/Badge.js +44 -0
  61. package/dist/Badge.js.map +1 -0
  62. package/dist/Badge.native.d.ts +23 -0
  63. package/dist/Badge.native.d.ts.map +1 -0
  64. package/dist/Badge.native.js +49 -0
  65. package/dist/Badge.native.js.map +1 -0
  66. package/dist/Banner.d.ts +27 -0
  67. package/dist/Banner.d.ts.map +1 -0
  68. package/dist/Banner.js +41 -0
  69. package/dist/Banner.js.map +1 -0
  70. package/dist/Banner.native.d.ts +24 -0
  71. package/dist/Banner.native.d.ts.map +1 -0
  72. package/dist/Banner.native.js +39 -0
  73. package/dist/Banner.native.js.map +1 -0
  74. package/dist/BarList.d.ts +27 -0
  75. package/dist/BarList.d.ts.map +1 -0
  76. package/dist/BarList.js +25 -0
  77. package/dist/BarList.js.map +1 -0
  78. package/dist/Breadcrumb.d.ts +67 -0
  79. package/dist/Breadcrumb.d.ts.map +1 -0
  80. package/dist/Breadcrumb.js +63 -0
  81. package/dist/Breadcrumb.js.map +1 -0
  82. package/dist/Breadcrumb.native.d.ts +64 -0
  83. package/dist/Breadcrumb.native.d.ts.map +1 -0
  84. package/dist/Breadcrumb.native.js +50 -0
  85. package/dist/Breadcrumb.native.js.map +1 -0
  86. package/dist/Button.d.ts +42 -0
  87. package/dist/Button.d.ts.map +1 -0
  88. package/dist/Button.js +68 -0
  89. package/dist/Button.js.map +1 -0
  90. package/dist/Button.native.d.ts +38 -0
  91. package/dist/Button.native.d.ts.map +1 -0
  92. package/dist/Button.native.js +51 -0
  93. package/dist/Button.native.js.map +1 -0
  94. package/dist/Calendar.d.ts +16 -0
  95. package/dist/Calendar.d.ts.map +1 -0
  96. package/dist/Calendar.js +94 -0
  97. package/dist/Calendar.js.map +1 -0
  98. package/dist/Calendar.native.d.ts +21 -0
  99. package/dist/Calendar.native.d.ts.map +1 -0
  100. package/dist/Calendar.native.js +15 -0
  101. package/dist/Calendar.native.js.map +1 -0
  102. package/dist/Card.d.ts +29 -0
  103. package/dist/Card.d.ts.map +1 -0
  104. package/dist/Card.js +44 -0
  105. package/dist/Card.js.map +1 -0
  106. package/dist/Card.native.d.ts +20 -0
  107. package/dist/Card.native.d.ts.map +1 -0
  108. package/dist/Card.native.js +32 -0
  109. package/dist/Card.native.js.map +1 -0
  110. package/dist/Carousel.d.ts +46 -0
  111. package/dist/Carousel.d.ts.map +1 -0
  112. package/dist/Carousel.js +115 -0
  113. package/dist/Carousel.js.map +1 -0
  114. package/dist/Carousel.native.d.ts +59 -0
  115. package/dist/Carousel.native.d.ts.map +1 -0
  116. package/dist/Carousel.native.js +93 -0
  117. package/dist/Carousel.native.js.map +1 -0
  118. package/dist/CategoryBar.d.ts +22 -0
  119. package/dist/CategoryBar.d.ts.map +1 -0
  120. package/dist/CategoryBar.js +27 -0
  121. package/dist/CategoryBar.js.map +1 -0
  122. package/dist/Chart.d.ts +77 -0
  123. package/dist/Chart.d.ts.map +1 -0
  124. package/dist/Chart.js +197 -0
  125. package/dist/Chart.js.map +1 -0
  126. package/dist/Checkbox.d.ts +28 -0
  127. package/dist/Checkbox.d.ts.map +1 -0
  128. package/dist/Checkbox.js +44 -0
  129. package/dist/Checkbox.js.map +1 -0
  130. package/dist/Checkbox.native.d.ts +13 -0
  131. package/dist/Checkbox.native.d.ts.map +1 -0
  132. package/dist/Checkbox.native.js +34 -0
  133. package/dist/Checkbox.native.js.map +1 -0
  134. package/dist/CheckboxGrid.d.ts +49 -0
  135. package/dist/CheckboxGrid.d.ts.map +1 -0
  136. package/dist/CheckboxGrid.js +79 -0
  137. package/dist/CheckboxGrid.js.map +1 -0
  138. package/dist/CheckboxGrid.native.d.ts +14 -0
  139. package/dist/CheckboxGrid.native.d.ts.map +1 -0
  140. package/dist/CheckboxGrid.native.js +47 -0
  141. package/dist/CheckboxGrid.native.js.map +1 -0
  142. package/dist/Collapsible.d.ts +51 -0
  143. package/dist/Collapsible.d.ts.map +1 -0
  144. package/dist/Collapsible.js +101 -0
  145. package/dist/Collapsible.js.map +1 -0
  146. package/dist/Collapsible.native.d.ts +53 -0
  147. package/dist/Collapsible.native.d.ts.map +1 -0
  148. package/dist/Collapsible.native.js +109 -0
  149. package/dist/Collapsible.native.js.map +1 -0
  150. package/dist/Combobox.d.ts +42 -0
  151. package/dist/Combobox.d.ts.map +1 -0
  152. package/dist/Combobox.js +96 -0
  153. package/dist/Combobox.js.map +1 -0
  154. package/dist/Combobox.native.d.ts +21 -0
  155. package/dist/Combobox.native.d.ts.map +1 -0
  156. package/dist/Combobox.native.js +28 -0
  157. package/dist/Combobox.native.js.map +1 -0
  158. package/dist/Command.d.ts +107 -0
  159. package/dist/Command.d.ts.map +1 -0
  160. package/dist/Command.js +68 -0
  161. package/dist/Command.js.map +1 -0
  162. package/dist/Command.native.d.ts +41 -0
  163. package/dist/Command.native.d.ts.map +1 -0
  164. package/dist/Command.native.js +31 -0
  165. package/dist/Command.native.js.map +1 -0
  166. package/dist/ContextMenu.d.ts +48 -0
  167. package/dist/ContextMenu.d.ts.map +1 -0
  168. package/dist/ContextMenu.js +79 -0
  169. package/dist/ContextMenu.js.map +1 -0
  170. package/dist/ContextMenu.native.d.ts +81 -0
  171. package/dist/ContextMenu.native.d.ts.map +1 -0
  172. package/dist/ContextMenu.native.js +82 -0
  173. package/dist/ContextMenu.native.js.map +1 -0
  174. package/dist/DataTable.d.ts +98 -0
  175. package/dist/DataTable.d.ts.map +1 -0
  176. package/dist/DataTable.js +291 -0
  177. package/dist/DataTable.js.map +1 -0
  178. package/dist/DataTable.native.d.ts +31 -0
  179. package/dist/DataTable.native.d.ts.map +1 -0
  180. package/dist/DataTable.native.js +22 -0
  181. package/dist/DataTable.native.js.map +1 -0
  182. package/dist/DatePicker.d.ts +63 -0
  183. package/dist/DatePicker.d.ts.map +1 -0
  184. package/dist/DatePicker.js +106 -0
  185. package/dist/DatePicker.js.map +1 -0
  186. package/dist/DatePicker.native.d.ts +21 -0
  187. package/dist/DatePicker.native.d.ts.map +1 -0
  188. package/dist/DatePicker.native.js +15 -0
  189. package/dist/DatePicker.native.js.map +1 -0
  190. package/dist/Dialog.d.ts +52 -0
  191. package/dist/Dialog.d.ts.map +1 -0
  192. package/dist/Dialog.js +93 -0
  193. package/dist/Dialog.js.map +1 -0
  194. package/dist/Dialog.native.d.ts +57 -0
  195. package/dist/Dialog.native.d.ts.map +1 -0
  196. package/dist/Dialog.native.js +62 -0
  197. package/dist/Dialog.native.js.map +1 -0
  198. package/dist/Drawer.d.ts +36 -0
  199. package/dist/Drawer.d.ts.map +1 -0
  200. package/dist/Drawer.js +57 -0
  201. package/dist/Drawer.js.map +1 -0
  202. package/dist/Drawer.native.d.ts +50 -0
  203. package/dist/Drawer.native.d.ts.map +1 -0
  204. package/dist/Drawer.native.js +43 -0
  205. package/dist/Drawer.native.js.map +1 -0
  206. package/dist/DropdownMenu.d.ts +57 -0
  207. package/dist/DropdownMenu.d.ts.map +1 -0
  208. package/dist/DropdownMenu.js +192 -0
  209. package/dist/DropdownMenu.js.map +1 -0
  210. package/dist/DropdownMenu.native.d.ts +53 -0
  211. package/dist/DropdownMenu.native.d.ts.map +1 -0
  212. package/dist/DropdownMenu.native.js +71 -0
  213. package/dist/DropdownMenu.native.js.map +1 -0
  214. package/dist/Dropzone.d.ts +27 -0
  215. package/dist/Dropzone.d.ts.map +1 -0
  216. package/dist/Dropzone.js +33 -0
  217. package/dist/Dropzone.js.map +1 -0
  218. package/dist/EmptyState.d.ts +21 -0
  219. package/dist/EmptyState.d.ts.map +1 -0
  220. package/dist/EmptyState.js +16 -0
  221. package/dist/EmptyState.js.map +1 -0
  222. package/dist/EmptyState.native.d.ts +19 -0
  223. package/dist/EmptyState.native.d.ts.map +1 -0
  224. package/dist/EmptyState.native.js +16 -0
  225. package/dist/EmptyState.native.js.map +1 -0
  226. package/dist/Form.d.ts +310 -0
  227. package/dist/Form.d.ts.map +1 -0
  228. package/dist/Form.js +260 -0
  229. package/dist/Form.js.map +1 -0
  230. package/dist/Form.native.d.ts +36 -0
  231. package/dist/Form.native.d.ts.map +1 -0
  232. package/dist/Form.native.js +33 -0
  233. package/dist/Form.native.js.map +1 -0
  234. package/dist/HoverCard.d.ts +47 -0
  235. package/dist/HoverCard.d.ts.map +1 -0
  236. package/dist/HoverCard.js +86 -0
  237. package/dist/HoverCard.js.map +1 -0
  238. package/dist/HoverCard.native.d.ts +48 -0
  239. package/dist/HoverCard.native.d.ts.map +1 -0
  240. package/dist/HoverCard.native.js +19 -0
  241. package/dist/HoverCard.native.js.map +1 -0
  242. package/dist/IconSidebar.d.ts +50 -0
  243. package/dist/IconSidebar.d.ts.map +1 -0
  244. package/dist/IconSidebar.js +121 -0
  245. package/dist/IconSidebar.js.map +1 -0
  246. package/dist/IconSidebar.native.d.ts +40 -0
  247. package/dist/IconSidebar.native.d.ts.map +1 -0
  248. package/dist/IconSidebar.native.js +24 -0
  249. package/dist/IconSidebar.native.js.map +1 -0
  250. package/dist/Input.d.ts +52 -0
  251. package/dist/Input.d.ts.map +1 -0
  252. package/dist/Input.js +57 -0
  253. package/dist/Input.js.map +1 -0
  254. package/dist/Input.native.d.ts +37 -0
  255. package/dist/Input.native.d.ts.map +1 -0
  256. package/dist/Input.native.js +39 -0
  257. package/dist/Input.native.js.map +1 -0
  258. package/dist/InputOTP.d.ts +30 -0
  259. package/dist/InputOTP.d.ts.map +1 -0
  260. package/dist/InputOTP.js +47 -0
  261. package/dist/InputOTP.js.map +1 -0
  262. package/dist/InputOTP.native.d.ts +32 -0
  263. package/dist/InputOTP.native.d.ts.map +1 -0
  264. package/dist/InputOTP.native.js +48 -0
  265. package/dist/InputOTP.native.js.map +1 -0
  266. package/dist/Label.d.ts +26 -0
  267. package/dist/Label.d.ts.map +1 -0
  268. package/dist/Label.js +35 -0
  269. package/dist/Label.js.map +1 -0
  270. package/dist/Label.native.d.ts +26 -0
  271. package/dist/Label.native.d.ts.map +1 -0
  272. package/dist/Label.native.js +30 -0
  273. package/dist/Label.native.js.map +1 -0
  274. package/dist/Link.d.ts +21 -0
  275. package/dist/Link.d.ts.map +1 -0
  276. package/dist/Link.js +46 -0
  277. package/dist/Link.js.map +1 -0
  278. package/dist/Link.native.d.ts +23 -0
  279. package/dist/Link.native.d.ts.map +1 -0
  280. package/dist/Link.native.js +59 -0
  281. package/dist/Link.native.js.map +1 -0
  282. package/dist/Logo.d.ts +25 -0
  283. package/dist/Logo.d.ts.map +1 -0
  284. package/dist/Logo.js +58 -0
  285. package/dist/Logo.js.map +1 -0
  286. package/dist/Logo.native.d.ts +22 -0
  287. package/dist/Logo.native.d.ts.map +1 -0
  288. package/dist/Logo.native.js +46 -0
  289. package/dist/Logo.native.js.map +1 -0
  290. package/dist/MainSidebar.d.ts +2 -0
  291. package/dist/MainSidebar.d.ts.map +1 -0
  292. package/dist/MainSidebar.js +3 -0
  293. package/dist/MainSidebar.js.map +1 -0
  294. package/dist/MainSidebar.native.d.ts +2 -0
  295. package/dist/MainSidebar.native.d.ts.map +1 -0
  296. package/dist/MainSidebar.native.js +2 -0
  297. package/dist/MainSidebar.native.js.map +1 -0
  298. package/dist/Menubar.d.ts +70 -0
  299. package/dist/Menubar.d.ts.map +1 -0
  300. package/dist/Menubar.js +142 -0
  301. package/dist/Menubar.js.map +1 -0
  302. package/dist/NavigationMenu.d.ts +12 -0
  303. package/dist/NavigationMenu.d.ts.map +1 -0
  304. package/dist/NavigationMenu.js +63 -0
  305. package/dist/NavigationMenu.js.map +1 -0
  306. package/dist/NavigationMenu.native.d.ts +44 -0
  307. package/dist/NavigationMenu.native.d.ts.map +1 -0
  308. package/dist/NavigationMenu.native.js +43 -0
  309. package/dist/NavigationMenu.native.js.map +1 -0
  310. package/dist/NotificationBadge.d.ts +33 -0
  311. package/dist/NotificationBadge.d.ts.map +1 -0
  312. package/dist/NotificationBadge.js +49 -0
  313. package/dist/NotificationBadge.js.map +1 -0
  314. package/dist/NotificationBadge.native.d.ts +25 -0
  315. package/dist/NotificationBadge.native.d.ts.map +1 -0
  316. package/dist/NotificationBadge.native.js +41 -0
  317. package/dist/NotificationBadge.native.js.map +1 -0
  318. package/dist/PageShell.d.ts +24 -0
  319. package/dist/PageShell.d.ts.map +1 -0
  320. package/dist/PageShell.js +24 -0
  321. package/dist/PageShell.js.map +1 -0
  322. package/dist/PageShell.native.d.ts +21 -0
  323. package/dist/PageShell.native.d.ts.map +1 -0
  324. package/dist/PageShell.native.js +19 -0
  325. package/dist/PageShell.native.js.map +1 -0
  326. package/dist/Pagination.d.ts +53 -0
  327. package/dist/Pagination.d.ts.map +1 -0
  328. package/dist/Pagination.js +79 -0
  329. package/dist/Pagination.js.map +1 -0
  330. package/dist/Pagination.native.d.ts +48 -0
  331. package/dist/Pagination.native.d.ts.map +1 -0
  332. package/dist/Pagination.native.js +55 -0
  333. package/dist/Pagination.native.js.map +1 -0
  334. package/dist/Popover.d.ts +57 -0
  335. package/dist/Popover.d.ts.map +1 -0
  336. package/dist/Popover.js +71 -0
  337. package/dist/Popover.js.map +1 -0
  338. package/dist/Popover.native.d.ts +48 -0
  339. package/dist/Popover.native.d.ts.map +1 -0
  340. package/dist/Popover.native.js +65 -0
  341. package/dist/Popover.native.js.map +1 -0
  342. package/dist/Popper.d.ts +54 -0
  343. package/dist/Popper.d.ts.map +1 -0
  344. package/dist/Popper.js +219 -0
  345. package/dist/Popper.js.map +1 -0
  346. package/dist/Progress.d.ts +79 -0
  347. package/dist/Progress.d.ts.map +1 -0
  348. package/dist/Progress.js +110 -0
  349. package/dist/Progress.js.map +1 -0
  350. package/dist/Progress.native.d.ts +42 -0
  351. package/dist/Progress.native.d.ts.map +1 -0
  352. package/dist/Progress.native.js +91 -0
  353. package/dist/Progress.native.js.map +1 -0
  354. package/dist/ProgressCircle.d.ts +69 -0
  355. package/dist/ProgressCircle.d.ts.map +1 -0
  356. package/dist/ProgressCircle.js +78 -0
  357. package/dist/ProgressCircle.js.map +1 -0
  358. package/dist/RadioCardGroup.d.ts +26 -0
  359. package/dist/RadioCardGroup.d.ts.map +1 -0
  360. package/dist/RadioCardGroup.js +26 -0
  361. package/dist/RadioCardGroup.js.map +1 -0
  362. package/dist/RadioGroup.d.ts +35 -0
  363. package/dist/RadioGroup.d.ts.map +1 -0
  364. package/dist/RadioGroup.js +68 -0
  365. package/dist/RadioGroup.js.map +1 -0
  366. package/dist/RadioGroup.native.d.ts +33 -0
  367. package/dist/RadioGroup.native.d.ts.map +1 -0
  368. package/dist/RadioGroup.native.js +55 -0
  369. package/dist/RadioGroup.native.js.map +1 -0
  370. package/dist/Resizable.d.ts +32 -0
  371. package/dist/Resizable.d.ts.map +1 -0
  372. package/dist/Resizable.js +31 -0
  373. package/dist/Resizable.js.map +1 -0
  374. package/dist/Resizable.native.d.ts +32 -0
  375. package/dist/Resizable.native.d.ts.map +1 -0
  376. package/dist/Resizable.native.js +23 -0
  377. package/dist/Resizable.native.js.map +1 -0
  378. package/dist/RichTextEditor.d.ts +38 -0
  379. package/dist/RichTextEditor.d.ts.map +1 -0
  380. package/dist/RichTextEditor.js +218 -0
  381. package/dist/RichTextEditor.js.map +1 -0
  382. package/dist/ScrollArea.d.ts +4 -0
  383. package/dist/ScrollArea.d.ts.map +1 -0
  384. package/dist/ScrollArea.js +26 -0
  385. package/dist/ScrollArea.js.map +1 -0
  386. package/dist/ScrollArea.native.d.ts +19 -0
  387. package/dist/ScrollArea.native.d.ts.map +1 -0
  388. package/dist/ScrollArea.native.js +19 -0
  389. package/dist/ScrollArea.native.js.map +1 -0
  390. package/dist/SearchField.d.ts +43 -0
  391. package/dist/SearchField.d.ts.map +1 -0
  392. package/dist/SearchField.js +34 -0
  393. package/dist/SearchField.js.map +1 -0
  394. package/dist/SearchField.native.d.ts +31 -0
  395. package/dist/SearchField.native.d.ts.map +1 -0
  396. package/dist/SearchField.native.js +30 -0
  397. package/dist/SearchField.native.js.map +1 -0
  398. package/dist/SectionHeader.d.ts +58 -0
  399. package/dist/SectionHeader.d.ts.map +1 -0
  400. package/dist/SectionHeader.js +95 -0
  401. package/dist/SectionHeader.js.map +1 -0
  402. package/dist/SectionHeader.native.d.ts +45 -0
  403. package/dist/SectionHeader.native.d.ts.map +1 -0
  404. package/dist/SectionHeader.native.js +92 -0
  405. package/dist/SectionHeader.native.js.map +1 -0
  406. package/dist/Select.d.ts +78 -0
  407. package/dist/Select.d.ts.map +1 -0
  408. package/dist/Select.js +310 -0
  409. package/dist/Select.js.map +1 -0
  410. package/dist/Select.native.d.ts +53 -0
  411. package/dist/Select.native.d.ts.map +1 -0
  412. package/dist/Select.native.js +86 -0
  413. package/dist/Select.native.js.map +1 -0
  414. package/dist/Separator.d.ts +20 -0
  415. package/dist/Separator.d.ts.map +1 -0
  416. package/dist/Separator.js +20 -0
  417. package/dist/Separator.js.map +1 -0
  418. package/dist/Separator.native.d.ts +8 -0
  419. package/dist/Separator.native.d.ts.map +1 -0
  420. package/dist/Separator.native.js +17 -0
  421. package/dist/Separator.native.js.map +1 -0
  422. package/dist/Sheet.d.ts +54 -0
  423. package/dist/Sheet.d.ts.map +1 -0
  424. package/dist/Sheet.js +191 -0
  425. package/dist/Sheet.js.map +1 -0
  426. package/dist/Sheet.native.d.ts +55 -0
  427. package/dist/Sheet.native.d.ts.map +1 -0
  428. package/dist/Sheet.native.js +112 -0
  429. package/dist/Sheet.native.js.map +1 -0
  430. package/dist/Sidebar.d.ts +131 -0
  431. package/dist/Sidebar.d.ts.map +1 -0
  432. package/dist/Sidebar.js +328 -0
  433. package/dist/Sidebar.js.map +1 -0
  434. package/dist/Skeleton.d.ts +14 -0
  435. package/dist/Skeleton.d.ts.map +1 -0
  436. package/dist/Skeleton.js +17 -0
  437. package/dist/Skeleton.js.map +1 -0
  438. package/dist/Skeleton.native.d.ts +6 -0
  439. package/dist/Skeleton.native.d.ts.map +1 -0
  440. package/dist/Skeleton.native.js +26 -0
  441. package/dist/Skeleton.native.js.map +1 -0
  442. package/dist/Slider.d.ts +63 -0
  443. package/dist/Slider.d.ts.map +1 -0
  444. package/dist/Slider.js +109 -0
  445. package/dist/Slider.js.map +1 -0
  446. package/dist/Slider.native.d.ts +38 -0
  447. package/dist/Slider.native.d.ts.map +1 -0
  448. package/dist/Slider.native.js +18 -0
  449. package/dist/Slider.native.js.map +1 -0
  450. package/dist/SortableList.d.ts +26 -0
  451. package/dist/SortableList.d.ts.map +1 -0
  452. package/dist/SortableList.js +44 -0
  453. package/dist/SortableList.js.map +1 -0
  454. package/dist/SparkChart.d.ts +34 -0
  455. package/dist/SparkChart.d.ts.map +1 -0
  456. package/dist/SparkChart.js +55 -0
  457. package/dist/SparkChart.js.map +1 -0
  458. package/dist/StatCard.d.ts +35 -0
  459. package/dist/StatCard.d.ts.map +1 -0
  460. package/dist/StatCard.js +37 -0
  461. package/dist/StatCard.js.map +1 -0
  462. package/dist/StatCard.native.d.ts +28 -0
  463. package/dist/StatCard.native.d.ts.map +1 -0
  464. package/dist/StatCard.native.js +31 -0
  465. package/dist/StatCard.native.js.map +1 -0
  466. package/dist/StatusBadge.d.ts +23 -0
  467. package/dist/StatusBadge.d.ts.map +1 -0
  468. package/dist/StatusBadge.js +33 -0
  469. package/dist/StatusBadge.js.map +1 -0
  470. package/dist/StatusBadge.native.d.ts +21 -0
  471. package/dist/StatusBadge.native.d.ts.map +1 -0
  472. package/dist/StatusBadge.native.js +37 -0
  473. package/dist/StatusBadge.native.js.map +1 -0
  474. package/dist/Switch.d.ts +31 -0
  475. package/dist/Switch.d.ts.map +1 -0
  476. package/dist/Switch.js +46 -0
  477. package/dist/Switch.js.map +1 -0
  478. package/dist/Switch.native.d.ts +16 -0
  479. package/dist/Switch.native.d.ts.map +1 -0
  480. package/dist/Switch.native.js +41 -0
  481. package/dist/Switch.native.js.map +1 -0
  482. package/dist/TabNavigation.d.ts +49 -0
  483. package/dist/TabNavigation.d.ts.map +1 -0
  484. package/dist/TabNavigation.js +121 -0
  485. package/dist/TabNavigation.js.map +1 -0
  486. package/dist/Table.d.ts +54 -0
  487. package/dist/Table.d.ts.map +1 -0
  488. package/dist/Table.js +96 -0
  489. package/dist/Table.js.map +1 -0
  490. package/dist/Table.native.d.ts +37 -0
  491. package/dist/Table.native.d.ts.map +1 -0
  492. package/dist/Table.native.js +37 -0
  493. package/dist/Table.native.js.map +1 -0
  494. package/dist/Tabs.d.ts +45 -0
  495. package/dist/Tabs.d.ts.map +1 -0
  496. package/dist/Tabs.js +94 -0
  497. package/dist/Tabs.js.map +1 -0
  498. package/dist/Tabs.native.d.ts +47 -0
  499. package/dist/Tabs.native.d.ts.map +1 -0
  500. package/dist/Tabs.native.js +57 -0
  501. package/dist/Tabs.native.js.map +1 -0
  502. package/dist/Tag.d.ts +24 -0
  503. package/dist/Tag.d.ts.map +1 -0
  504. package/dist/Tag.js +41 -0
  505. package/dist/Tag.js.map +1 -0
  506. package/dist/Tag.native.d.ts +23 -0
  507. package/dist/Tag.native.d.ts.map +1 -0
  508. package/dist/Tag.native.js +55 -0
  509. package/dist/Tag.native.js.map +1 -0
  510. package/dist/Text.d.ts +26 -0
  511. package/dist/Text.d.ts.map +1 -0
  512. package/dist/Text.js +63 -0
  513. package/dist/Text.js.map +1 -0
  514. package/dist/Text.native.d.ts +18 -0
  515. package/dist/Text.native.d.ts.map +1 -0
  516. package/dist/Text.native.js +58 -0
  517. package/dist/Text.native.js.map +1 -0
  518. package/dist/Textarea.d.ts +23 -0
  519. package/dist/Textarea.d.ts.map +1 -0
  520. package/dist/Textarea.js +39 -0
  521. package/dist/Textarea.js.map +1 -0
  522. package/dist/Textarea.native.d.ts +16 -0
  523. package/dist/Textarea.native.d.ts.map +1 -0
  524. package/dist/Textarea.native.js +30 -0
  525. package/dist/Textarea.native.js.map +1 -0
  526. package/dist/TiptapEditor.d.ts +24 -0
  527. package/dist/TiptapEditor.d.ts.map +1 -0
  528. package/dist/TiptapEditor.js +84 -0
  529. package/dist/TiptapEditor.js.map +1 -0
  530. package/dist/TitleBar.d.ts +31 -0
  531. package/dist/TitleBar.d.ts.map +1 -0
  532. package/dist/TitleBar.js +27 -0
  533. package/dist/TitleBar.js.map +1 -0
  534. package/dist/TitleBar.native.d.ts +19 -0
  535. package/dist/TitleBar.native.d.ts.map +1 -0
  536. package/dist/TitleBar.native.js +16 -0
  537. package/dist/TitleBar.native.js.map +1 -0
  538. package/dist/Toast.d.ts +72 -0
  539. package/dist/Toast.d.ts.map +1 -0
  540. package/dist/Toast.js +194 -0
  541. package/dist/Toast.js.map +1 -0
  542. package/dist/Toast.native.d.ts +65 -0
  543. package/dist/Toast.native.d.ts.map +1 -0
  544. package/dist/Toast.native.js +182 -0
  545. package/dist/Toast.native.js.map +1 -0
  546. package/dist/Toggle.d.ts +46 -0
  547. package/dist/Toggle.d.ts.map +1 -0
  548. package/dist/Toggle.js +70 -0
  549. package/dist/Toggle.js.map +1 -0
  550. package/dist/Toggle.native.d.ts +42 -0
  551. package/dist/Toggle.native.d.ts.map +1 -0
  552. package/dist/Toggle.native.js +56 -0
  553. package/dist/Toggle.native.js.map +1 -0
  554. package/dist/Tooltip.d.ts +32 -0
  555. package/dist/Tooltip.d.ts.map +1 -0
  556. package/dist/Tooltip.js +43 -0
  557. package/dist/Tooltip.js.map +1 -0
  558. package/dist/Tooltip.native.d.ts +25 -0
  559. package/dist/Tooltip.native.d.ts.map +1 -0
  560. package/dist/Tooltip.native.js +25 -0
  561. package/dist/Tooltip.native.js.map +1 -0
  562. package/dist/TopBar.d.ts +105 -0
  563. package/dist/TopBar.d.ts.map +1 -0
  564. package/dist/TopBar.js +90 -0
  565. package/dist/TopBar.js.map +1 -0
  566. package/dist/TopBar.native.d.ts +67 -0
  567. package/dist/TopBar.native.d.ts.map +1 -0
  568. package/dist/TopBar.native.js +41 -0
  569. package/dist/TopBar.native.js.map +1 -0
  570. package/dist/Tracker.d.ts +44 -0
  571. package/dist/Tracker.d.ts.map +1 -0
  572. package/dist/Tracker.js +92 -0
  573. package/dist/Tracker.js.map +1 -0
  574. package/dist/TransferList.d.ts +51 -0
  575. package/dist/TransferList.d.ts.map +1 -0
  576. package/dist/TransferList.js +107 -0
  577. package/dist/TransferList.js.map +1 -0
  578. package/dist/TransferList.native.d.ts +14 -0
  579. package/dist/TransferList.native.d.ts.map +1 -0
  580. package/dist/TransferList.native.js +57 -0
  581. package/dist/TransferList.native.js.map +1 -0
  582. package/dist/index.d.ts +78 -0
  583. package/dist/index.d.ts.map +1 -0
  584. package/dist/index.js +79 -0
  585. package/dist/index.js.map +1 -0
  586. package/dist/internal/cn.d.ts +7 -0
  587. package/dist/internal/cn.d.ts.map +1 -0
  588. package/dist/internal/cn.js +30 -0
  589. package/dist/internal/cn.js.map +1 -0
  590. package/package.json +499 -0
  591. package/src/AccessLevelGroup.native.tsx +103 -0
  592. package/src/AccessLevelGroup.tsx +103 -0
  593. package/src/Accordion.native.tsx +199 -0
  594. package/src/Accordion.tsx +279 -0
  595. package/src/Alert.native.tsx +100 -0
  596. package/src/Alert.tsx +101 -0
  597. package/src/AlertDialog.native.tsx +189 -0
  598. package/src/AlertDialog.tsx +194 -0
  599. package/src/AspectRatio.native.tsx +28 -0
  600. package/src/AspectRatio.tsx +35 -0
  601. package/src/Avatar.native.tsx +142 -0
  602. package/src/Avatar.tsx +155 -0
  603. package/src/AvatarGroup.native.tsx +81 -0
  604. package/src/AvatarGroup.tsx +114 -0
  605. package/src/Badge.native.tsx +85 -0
  606. package/src/Badge.tsx +93 -0
  607. package/src/Banner.native.tsx +77 -0
  608. package/src/Banner.tsx +95 -0
  609. package/src/BarList.tsx +102 -0
  610. package/src/Breadcrumb.native.tsx +238 -0
  611. package/src/Breadcrumb.tsx +258 -0
  612. package/src/Button.native.tsx +123 -0
  613. package/src/Button.tsx +153 -0
  614. package/src/Calendar.native.tsx +28 -0
  615. package/src/Calendar.tsx +211 -0
  616. package/src/Card.native.tsx +82 -0
  617. package/src/Card.tsx +94 -0
  618. package/src/Carousel.native.tsx +224 -0
  619. package/src/Carousel.tsx +292 -0
  620. package/src/CategoryBar.tsx +85 -0
  621. package/src/Chart.tsx +467 -0
  622. package/src/Checkbox.native.tsx +69 -0
  623. package/src/Checkbox.tsx +108 -0
  624. package/src/CheckboxGrid.native.tsx +160 -0
  625. package/src/CheckboxGrid.tsx +262 -0
  626. package/src/Collapsible.native.tsx +240 -0
  627. package/src/Collapsible.tsx +241 -0
  628. package/src/Combobox.native.tsx +171 -0
  629. package/src/Combobox.tsx +272 -0
  630. package/src/Command.native.tsx +71 -0
  631. package/src/Command.tsx +203 -0
  632. package/src/ContextMenu.native.tsx +313 -0
  633. package/src/ContextMenu.tsx +238 -0
  634. package/src/DataTable.native.tsx +70 -0
  635. package/src/DataTable.tsx +989 -0
  636. package/src/DatePicker.native.tsx +46 -0
  637. package/src/DatePicker.tsx +357 -0
  638. package/src/Dialog.native.tsx +181 -0
  639. package/src/Dialog.tsx +224 -0
  640. package/src/Drawer.native.tsx +134 -0
  641. package/src/Drawer.tsx +119 -0
  642. package/src/DropdownMenu.native.tsx +258 -0
  643. package/src/DropdownMenu.tsx +387 -0
  644. package/src/Dropzone.tsx +95 -0
  645. package/src/EmptyState.native.tsx +43 -0
  646. package/src/EmptyState.tsx +52 -0
  647. package/src/Form.native.tsx +94 -0
  648. package/src/Form.tsx +1324 -0
  649. package/src/HoverCard.native.tsx +63 -0
  650. package/src/HoverCard.tsx +181 -0
  651. package/src/IconSidebar.native.tsx +94 -0
  652. package/src/IconSidebar.tsx +448 -0
  653. package/src/Input.native.tsx +99 -0
  654. package/src/Input.tsx +132 -0
  655. package/src/InputOTP.native.tsx +154 -0
  656. package/src/InputOTP.tsx +119 -0
  657. package/src/Label.native.tsx +55 -0
  658. package/src/Label.tsx +60 -0
  659. package/src/Link.native.tsx +89 -0
  660. package/src/Link.tsx +85 -0
  661. package/src/Logo.native.tsx +114 -0
  662. package/src/Logo.tsx +153 -0
  663. package/src/MainSidebar.native.tsx +8 -0
  664. package/src/MainSidebar.tsx +10 -0
  665. package/src/Menubar.tsx +485 -0
  666. package/src/NavigationMenu.native.tsx +136 -0
  667. package/src/NavigationMenu.tsx +180 -0
  668. package/src/NotificationBadge.native.tsx +80 -0
  669. package/src/NotificationBadge.tsx +91 -0
  670. package/src/PageShell.native.tsx +43 -0
  671. package/src/PageShell.tsx +50 -0
  672. package/src/Pagination.native.tsx +217 -0
  673. package/src/Pagination.tsx +250 -0
  674. package/src/Popover.native.tsx +139 -0
  675. package/src/Popover.tsx +175 -0
  676. package/src/Popper.tsx +399 -0
  677. package/src/Progress.native.tsx +197 -0
  678. package/src/Progress.tsx +286 -0
  679. package/src/ProgressCircle.tsx +200 -0
  680. package/src/RadioCardGroup.tsx +97 -0
  681. package/src/RadioGroup.native.tsx +153 -0
  682. package/src/RadioGroup.tsx +201 -0
  683. package/src/Resizable.native.tsx +76 -0
  684. package/src/Resizable.tsx +88 -0
  685. package/src/RichTextEditor.tsx +513 -0
  686. package/src/ScrollArea.native.tsx +36 -0
  687. package/src/ScrollArea.tsx +62 -0
  688. package/src/SearchField.native.tsx +104 -0
  689. package/src/SearchField.tsx +136 -0
  690. package/src/SectionHeader.native.tsx +226 -0
  691. package/src/SectionHeader.tsx +250 -0
  692. package/src/Select.native.tsx +299 -0
  693. package/src/Select.tsx +710 -0
  694. package/src/Separator.native.tsx +38 -0
  695. package/src/Separator.tsx +43 -0
  696. package/src/Sheet.native.tsx +233 -0
  697. package/src/Sheet.tsx +329 -0
  698. package/src/Sidebar.tsx +956 -0
  699. package/src/Skeleton.native.tsx +47 -0
  700. package/src/Skeleton.tsx +29 -0
  701. package/src/Slider.native.tsx +64 -0
  702. package/src/Slider.tsx +284 -0
  703. package/src/SortableList.tsx +158 -0
  704. package/src/SparkChart.tsx +143 -0
  705. package/src/StatCard.native.tsx +64 -0
  706. package/src/StatCard.tsx +75 -0
  707. package/src/StatusBadge.native.tsx +57 -0
  708. package/src/StatusBadge.tsx +52 -0
  709. package/src/Switch.native.tsx +78 -0
  710. package/src/Switch.tsx +94 -0
  711. package/src/TabNavigation.tsx +329 -0
  712. package/src/Table.native.tsx +183 -0
  713. package/src/Table.tsx +260 -0
  714. package/src/Tabs.native.tsx +139 -0
  715. package/src/Tabs.tsx +216 -0
  716. package/src/Tag.native.tsx +87 -0
  717. package/src/Tag.tsx +93 -0
  718. package/src/Text.native.tsx +95 -0
  719. package/src/Text.tsx +93 -0
  720. package/src/Textarea.native.tsx +64 -0
  721. package/src/Textarea.tsx +66 -0
  722. package/src/TitleBar.native.tsx +46 -0
  723. package/src/TitleBar.tsx +64 -0
  724. package/src/Toast.native.tsx +366 -0
  725. package/src/Toast.tsx +408 -0
  726. package/src/Toggle.native.tsx +162 -0
  727. package/src/Toggle.tsx +169 -0
  728. package/src/Tooltip.native.tsx +62 -0
  729. package/src/Tooltip.tsx +88 -0
  730. package/src/TopBar.native.tsx +223 -0
  731. package/src/TopBar.tsx +436 -0
  732. package/src/Tracker.tsx +244 -0
  733. package/src/TransferList.native.tsx +180 -0
  734. package/src/TransferList.tsx +297 -0
  735. package/src/globals.d.ts +1 -0
  736. package/src/index.ts +502 -0
  737. package/src/internal/cn.ts +31 -0
@@ -0,0 +1,956 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Sidebar (web-only — React DOM).
5
+ *
6
+ * A composable, collapsible sidebar with mobile sheet support,
7
+ * keyboard shortcuts (Ctrl/Cmd+B), and cookie persistence.
8
+ *
9
+ * Composes: Button, Sheet, Separator, Skeleton, Tooltip, Input.
10
+ *
11
+ * <SidebarProvider>
12
+ * <Sidebar>
13
+ * <SidebarHeader />
14
+ * <SidebarContent>
15
+ * <SidebarGroup>
16
+ * <SidebarGroupLabel>Navigation</SidebarGroupLabel>
17
+ * <SidebarGroupContent>
18
+ * <SidebarMenu>
19
+ * <SidebarMenuItem>
20
+ * <SidebarMenuButton>Dashboard</SidebarMenuButton>
21
+ * </SidebarMenuItem>
22
+ * </SidebarMenu>
23
+ * </SidebarGroupContent>
24
+ * </SidebarGroup>
25
+ * </SidebarContent>
26
+ * <SidebarFooter />
27
+ * </Sidebar>
28
+ * <SidebarInset>…main content…</SidebarInset>
29
+ * </SidebarProvider>
30
+ *
31
+ * Wiki: docs/components/Sidebar.md
32
+ */
33
+ import {
34
+ createContext,
35
+ forwardRef,
36
+ useCallback,
37
+ useContext,
38
+ useEffect,
39
+ useMemo,
40
+ useState,
41
+ type AnchorHTMLAttributes,
42
+ type ButtonHTMLAttributes,
43
+ type ComponentProps,
44
+ type HTMLAttributes,
45
+ } from 'react';
46
+ import { cva, type VariantProps } from 'class-variance-authority';
47
+ import { cn } from './internal/cn.js';
48
+ import { Button } from './Button.js';
49
+ import { Sheet, SheetContent } from './Sheet.js';
50
+ import { Separator } from './Separator.js';
51
+ import { Skeleton } from './Skeleton.js';
52
+ import { Tooltip } from './Tooltip.js';
53
+ import { Input } from './Input.js';
54
+
55
+ type SidebarSide = 'left' | 'right';
56
+ type SidebarVariant = 'sidebar' | 'floating' | 'inset';
57
+ type SidebarCollapsible = 'offcanvas' | 'icon' | 'none';
58
+ type SidebarPosition = 'contained' | 'fixed';
59
+
60
+ /* ── Inline icon (avoids a lucide-react dep on the ui package) ───── */
61
+
62
+ function PanelLeftIcon() {
63
+ return (
64
+ <svg
65
+ aria-hidden="true"
66
+ xmlns="http://www.w3.org/2000/svg"
67
+ viewBox="0 0 24 24"
68
+ fill="none"
69
+ stroke="currentColor"
70
+ strokeWidth={2}
71
+ strokeLinecap="round"
72
+ strokeLinejoin="round"
73
+ className="h-4 w-4"
74
+ >
75
+ <rect width="18" height="18" x="3" y="3" rx="2" />
76
+ <path d="M9 3v18" />
77
+ </svg>
78
+ );
79
+ }
80
+
81
+ function PanelRightIcon() {
82
+ return (
83
+ <svg
84
+ aria-hidden="true"
85
+ xmlns="http://www.w3.org/2000/svg"
86
+ viewBox="0 0 24 24"
87
+ fill="none"
88
+ stroke="currentColor"
89
+ strokeWidth={2}
90
+ strokeLinecap="round"
91
+ strokeLinejoin="round"
92
+ className="h-4 w-4"
93
+ >
94
+ <rect width="18" height="18" x="3" y="3" rx="2" />
95
+ <path d="M15 3v18" />
96
+ </svg>
97
+ );
98
+ }
99
+
100
+ /* ── Constants ─────────────────────────────────────────────────────── */
101
+
102
+ const SIDEBAR_COOKIE_NAME = 'sidebar_state';
103
+ const SIDEBAR_COOKIE_MAX_AGE = 60 * 60 * 24 * 7; // 7 days
104
+ const SIDEBAR_WIDTH = '16rem';
105
+ const SIDEBAR_WIDTH_ICON = '3rem';
106
+ const SIDEBAR_WIDTH_MOBILE = '18rem';
107
+ const SIDEBAR_KEYBOARD_SHORTCUT = 'b';
108
+ const SIDEBAR_MOBILE_BREAKPOINT = 768;
109
+
110
+ /* ── useIsMobile (inline) ──────────────────────────────────────────── */
111
+
112
+ function useIsMobile(breakpoint: number) {
113
+ const [isMobile, setIsMobile] = useState(false);
114
+
115
+ useEffect(() => {
116
+ if (typeof window.matchMedia !== 'function') {
117
+ return;
118
+ }
119
+
120
+ const mql = window.matchMedia(`(max-width: ${breakpoint}px)`);
121
+ const onChange = () => setIsMobile(mql.matches);
122
+ onChange();
123
+ mql.addEventListener('change', onChange);
124
+ return () => mql.removeEventListener('change', onChange);
125
+ }, [breakpoint]);
126
+
127
+ return isMobile;
128
+ }
129
+
130
+ /* ── Context ───────────────────────────────────────────────────────── */
131
+
132
+ interface SidebarContextValue {
133
+ state: 'expanded' | 'collapsed';
134
+ open: boolean;
135
+ setOpen: (open: boolean | ((prev: boolean) => boolean)) => void;
136
+ openMobile: boolean;
137
+ setOpenMobile: (open: boolean | ((prev: boolean) => boolean)) => void;
138
+ isMobile: boolean;
139
+ side: SidebarSide;
140
+ variant: SidebarVariant;
141
+ collapsible: SidebarCollapsible;
142
+ position: SidebarPosition;
143
+ toggleSidebar: () => void;
144
+ }
145
+
146
+ const SidebarContext = createContext<SidebarContextValue | null>(null);
147
+
148
+ export function useSidebar() {
149
+ const ctx = useContext(SidebarContext);
150
+ if (!ctx) {
151
+ throw new Error('useSidebar must be used within a <SidebarProvider>.');
152
+ }
153
+ return ctx;
154
+ }
155
+
156
+ /* ── SidebarProvider ───────────────────────────────────────────────── */
157
+
158
+ export interface SidebarProviderProps extends HTMLAttributes<HTMLDivElement> {
159
+ defaultOpen?: boolean;
160
+ open?: boolean;
161
+ onOpenChange?: (open: boolean) => void;
162
+ /** Initial mobile Sheet open state. Useful for examples and forced mobile previews. */
163
+ defaultOpenMobile?: boolean;
164
+ /** Controlled mobile Sheet open state. */
165
+ openMobile?: boolean;
166
+ /** Called when mobile Sheet open state changes. */
167
+ onOpenMobileChange?: (open: boolean) => void;
168
+ side?: SidebarSide;
169
+ variant?: SidebarVariant;
170
+ collapsible?: SidebarCollapsible;
171
+ position?: SidebarPosition;
172
+ /** Force mobile behavior for previews/tests. When omitted, matchMedia decides. */
173
+ mobile?: boolean;
174
+ /** Breakpoint in px where the sidebar switches to mobile Sheet mode. */
175
+ mobileBreakpoint?: number;
176
+ /** Expanded desktop width. */
177
+ width?: string;
178
+ /** Collapsed icon-rail width. */
179
+ iconWidth?: string;
180
+ /** Mobile Sheet width. */
181
+ mobileWidth?: string;
182
+ }
183
+
184
+ export const SidebarProvider = forwardRef<HTMLDivElement, SidebarProviderProps>(
185
+ function SidebarProvider(
186
+ {
187
+ defaultOpen = true,
188
+ open: openProp,
189
+ onOpenChange: setOpenProp,
190
+ defaultOpenMobile = false,
191
+ openMobile: openMobileProp,
192
+ onOpenMobileChange: setOpenMobileProp,
193
+ side = 'left',
194
+ variant = 'sidebar',
195
+ collapsible = 'offcanvas',
196
+ position = 'contained',
197
+ mobile,
198
+ mobileBreakpoint = SIDEBAR_MOBILE_BREAKPOINT,
199
+ width = SIDEBAR_WIDTH,
200
+ iconWidth = SIDEBAR_WIDTH_ICON,
201
+ mobileWidth = SIDEBAR_WIDTH_MOBILE,
202
+ className,
203
+ style,
204
+ children,
205
+ ...props
206
+ },
207
+ ref,
208
+ ) {
209
+ const detectedMobile = useIsMobile(mobileBreakpoint);
210
+ const isMobile = mobile ?? detectedMobile;
211
+ const [_openMobile, _setOpenMobile] = useState(defaultOpenMobile);
212
+
213
+ // Start from props so server and initial client render match.
214
+ const [_open, _setOpen] = useState(defaultOpen);
215
+
216
+ const open = openProp ?? _open;
217
+ const openMobile = openMobileProp ?? _openMobile;
218
+
219
+ useEffect(() => {
220
+ if (openProp !== undefined) return;
221
+
222
+ const cookie = document.cookie
223
+ .split('; ')
224
+ .find((row) => row.startsWith(`${SIDEBAR_COOKIE_NAME}=`));
225
+ if (!cookie) return;
226
+
227
+ const nextOpen = cookie.split('=')[1] === 'true';
228
+ let cancelled = false;
229
+ queueMicrotask(() => {
230
+ if (!cancelled) {
231
+ _setOpen(nextOpen);
232
+ }
233
+ });
234
+
235
+ return () => {
236
+ cancelled = true;
237
+ };
238
+ }, [openProp]);
239
+
240
+ const setOpen = useCallback(
241
+ (value: boolean | ((prev: boolean) => boolean)) => {
242
+ const next = typeof value === 'function' ? value(open) : value;
243
+ if (setOpenProp) {
244
+ setOpenProp(next);
245
+ } else {
246
+ _setOpen(next);
247
+ }
248
+ if (typeof document !== 'undefined') {
249
+ document.cookie = `${SIDEBAR_COOKIE_NAME}=${next}; path=/; max-age=${SIDEBAR_COOKIE_MAX_AGE}`;
250
+ }
251
+ },
252
+ [setOpenProp, open],
253
+ );
254
+
255
+ const setOpenMobile = useCallback(
256
+ (value: boolean | ((prev: boolean) => boolean)) => {
257
+ const next = typeof value === 'function' ? value(openMobile) : value;
258
+ if (setOpenMobileProp) {
259
+ setOpenMobileProp(next);
260
+ } else {
261
+ _setOpenMobile(next);
262
+ }
263
+ },
264
+ [openMobile, setOpenMobileProp],
265
+ );
266
+
267
+ const toggleSidebar = useCallback(() => {
268
+ if (collapsible === 'none') return;
269
+
270
+ if (isMobile) {
271
+ setOpenMobile((prev) => !prev);
272
+ } else {
273
+ setOpen((prev) => !prev);
274
+ }
275
+ }, [collapsible, isMobile, setOpen]);
276
+
277
+ // Keyboard shortcut: Ctrl+B / Cmd+B
278
+ useEffect(() => {
279
+ const handleKeyDown = (e: KeyboardEvent) => {
280
+ if (e.key === SIDEBAR_KEYBOARD_SHORTCUT && (e.metaKey || e.ctrlKey)) {
281
+ e.preventDefault();
282
+ toggleSidebar();
283
+ }
284
+ };
285
+ window.addEventListener('keydown', handleKeyDown);
286
+ return () => window.removeEventListener('keydown', handleKeyDown);
287
+ }, [toggleSidebar]);
288
+
289
+ const state = open ? 'expanded' : 'collapsed';
290
+
291
+ const value = useMemo<SidebarContextValue>(
292
+ () => ({
293
+ state,
294
+ open,
295
+ setOpen,
296
+ isMobile,
297
+ openMobile,
298
+ setOpenMobile,
299
+ side,
300
+ variant,
301
+ collapsible,
302
+ position,
303
+ toggleSidebar,
304
+ }),
305
+ [
306
+ state,
307
+ open,
308
+ setOpen,
309
+ isMobile,
310
+ openMobile,
311
+ setOpenMobile,
312
+ side,
313
+ variant,
314
+ collapsible,
315
+ position,
316
+ toggleSidebar,
317
+ ],
318
+ );
319
+
320
+ return (
321
+ <SidebarContext.Provider value={value}>
322
+ <div
323
+ ref={ref}
324
+ style={
325
+ {
326
+ '--sidebar-width': width,
327
+ '--sidebar-width-icon': iconWidth,
328
+ '--sidebar-width-mobile': mobileWidth,
329
+ ...style,
330
+ } as React.CSSProperties
331
+ }
332
+ className={cn(
333
+ 'group/sidebar-wrapper flex min-h-svh w-full',
334
+ side === 'right' && 'flex-row-reverse',
335
+ variant === 'inset' && 'bg-sidebar',
336
+ className,
337
+ )}
338
+ data-sidebar="provider"
339
+ data-state={state}
340
+ data-collapsible={state === 'collapsed' ? collapsible : ''}
341
+ data-variant={variant}
342
+ data-side={side}
343
+ data-position={position}
344
+ {...props}
345
+ >
346
+ {children}
347
+ </div>
348
+ </SidebarContext.Provider>
349
+ );
350
+ },
351
+ );
352
+
353
+ /* ── Sidebar ───────────────────────────────────────────────────────── */
354
+
355
+ export interface SidebarProps extends HTMLAttributes<HTMLElement> {
356
+ side?: SidebarSide;
357
+ variant?: SidebarVariant;
358
+ collapsible?: SidebarCollapsible;
359
+ position?: SidebarPosition;
360
+ }
361
+
362
+ export const Sidebar = forwardRef<HTMLElement, SidebarProps>(function Sidebar(
363
+ { side, variant, collapsible, position, className, children, ...props },
364
+ ref,
365
+ ) {
366
+ const context = useSidebar();
367
+ const { isMobile, state, openMobile, setOpenMobile } = context;
368
+ const currentSide = side ?? context.side;
369
+ const currentVariant = variant ?? context.variant;
370
+ const currentCollapsible = collapsible ?? context.collapsible;
371
+ const currentPosition = position ?? context.position;
372
+ const isCollapsed = state === 'collapsed';
373
+ const isFloating = currentVariant === 'floating' || currentVariant === 'inset';
374
+ const isOffcanvasCollapsed = isCollapsed && currentCollapsible === 'offcanvas';
375
+ const isIconCollapsed = isCollapsed && currentCollapsible === 'icon';
376
+ const sidebarEdgeBorder = currentSide === 'right'
377
+ ? 'border-l border-sidebar-border'
378
+ : 'border-r border-sidebar-border';
379
+
380
+ if (currentCollapsible === 'none') {
381
+ return (
382
+ <nav
383
+ ref={ref}
384
+ aria-label={props['aria-label'] ?? 'Sidebar'}
385
+ data-sidebar="sidebar"
386
+ data-state={state}
387
+ data-collapsible=""
388
+ data-variant={currentVariant}
389
+ data-side={currentSide}
390
+ data-position={currentPosition}
391
+ className={cn(
392
+ 'flex h-full w-(--sidebar-width) flex-col bg-sidebar text-sidebar-foreground',
393
+ isFloating ? 'rounded-lg border border-sidebar-border shadow' : sidebarEdgeBorder,
394
+ className,
395
+ )}
396
+ {...props}
397
+ >
398
+ {children}
399
+ </nav>
400
+ );
401
+ }
402
+
403
+ if (isMobile) {
404
+ return (
405
+ <Sheet open={openMobile} onOpenChange={setOpenMobile}>
406
+ <SheetContent
407
+ data-sidebar="sidebar"
408
+ data-mobile="true"
409
+ className={cn(
410
+ 'w-(--sidebar-width-mobile) bg-sidebar p-0 text-sidebar-foreground [&>button]:hidden',
411
+ className,
412
+ )}
413
+ side={currentSide}
414
+ {...props}
415
+ >
416
+ <nav aria-label={props['aria-label'] ?? 'Sidebar'} className="flex h-full w-full flex-col">
417
+ {children}
418
+ </nav>
419
+ </SheetContent>
420
+ </Sheet>
421
+ );
422
+ }
423
+
424
+ if (currentPosition === 'contained') {
425
+ return (
426
+ <div
427
+ data-sidebar="sidebar-container"
428
+ className={cn(
429
+ 'group peer relative hidden h-full shrink-0 overflow-hidden text-sidebar-foreground transition-[width] duration-200 ease-linear md:flex',
430
+ isOffcanvasCollapsed
431
+ ? 'w-0'
432
+ : isIconCollapsed
433
+ ? isFloating
434
+ ? 'w-[calc(var(--sidebar-width-icon)+theme(spacing.4))]'
435
+ : 'w-(--sidebar-width-icon)'
436
+ : 'w-(--sidebar-width)',
437
+ isFloating && !isOffcanvasCollapsed && 'p-2',
438
+ className,
439
+ )}
440
+ data-state={state}
441
+ data-collapsible={isCollapsed ? currentCollapsible : ''}
442
+ data-variant={currentVariant}
443
+ data-side={currentSide}
444
+ data-position={currentPosition}
445
+ >
446
+ <nav
447
+ ref={ref}
448
+ aria-label={props['aria-label'] ?? 'Sidebar'}
449
+ data-sidebar="sidebar"
450
+ className={cn(
451
+ 'flex h-full w-full min-w-0 flex-col bg-sidebar',
452
+ isFloating ? 'rounded-lg border border-sidebar-border shadow' : sidebarEdgeBorder,
453
+ )}
454
+ {...props}
455
+ >
456
+ {children}
457
+ </nav>
458
+ </div>
459
+ );
460
+ }
461
+
462
+ return (
463
+ <div
464
+ data-sidebar="sidebar-container"
465
+ className="group peer hidden md:block text-sidebar-foreground"
466
+ data-state={state}
467
+ data-collapsible={isCollapsed ? currentCollapsible : ''}
468
+ data-variant={currentVariant}
469
+ data-side={currentSide}
470
+ data-position={currentPosition}
471
+ >
472
+ {/* Gap element — occupies space so the main content shifts */}
473
+ <div
474
+ className={cn(
475
+ 'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',
476
+ 'group-data-[collapsible=offcanvas]:w-0',
477
+ 'group-data-[side=right]:rotate-180',
478
+ isFloating
479
+ ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+theme(spacing.4))]'
480
+ : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
481
+ )}
482
+ />
483
+ <div
484
+ className={cn(
485
+ 'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex',
486
+ currentSide === 'left'
487
+ ? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
488
+ : 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
489
+ isFloating
490
+ ? 'p-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+theme(spacing.4)+2px)]'
491
+ : cn(
492
+ 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
493
+ 'border-sidebar-border',
494
+ currentSide === 'right' ? 'group-data-[variant=sidebar]:border-l' : 'group-data-[variant=sidebar]:border-r',
495
+ ),
496
+ className,
497
+ )}
498
+ {...props}
499
+ >
500
+ <nav
501
+ ref={ref}
502
+ aria-label={props['aria-label'] ?? 'Sidebar'}
503
+ data-sidebar="sidebar"
504
+ className={cn(
505
+ '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',
506
+ )}
507
+ >
508
+ {children}
509
+ </nav>
510
+ </div>
511
+ </div>
512
+ );
513
+ });
514
+
515
+ /* ── SidebarTrigger ────────────────────────────────────────────────── */
516
+
517
+ export const SidebarTrigger = forwardRef<
518
+ HTMLButtonElement,
519
+ ComponentProps<typeof Button>
520
+ >(function SidebarTrigger({ className, disabled, onClick, ...props }, ref) {
521
+ const { isMobile, open, openMobile, collapsible, side, toggleSidebar } = useSidebar();
522
+ const expanded = collapsible === 'none' ? true : isMobile ? openMobile : open;
523
+ const isDisabled = disabled || collapsible === 'none';
524
+
525
+ return (
526
+ <Button
527
+ ref={ref}
528
+ data-sidebar="trigger"
529
+ aria-expanded={expanded}
530
+ aria-disabled={isDisabled || undefined}
531
+ disabled={isDisabled}
532
+ variant="ghost"
533
+ size="icon"
534
+ className={cn('size-7', className)}
535
+ onClick={(e) => {
536
+ onClick?.(e);
537
+ if (collapsible === 'none') return;
538
+ toggleSidebar();
539
+ }}
540
+ {...props}
541
+ >
542
+ {side === 'right' ? <PanelRightIcon /> : <PanelLeftIcon />}
543
+ <span className="sr-only">Toggle Sidebar</span>
544
+ </Button>
545
+ );
546
+ });
547
+
548
+ /* ── SidebarRail ───────────────────────────────────────────────────── */
549
+
550
+ export const SidebarRail = forwardRef<HTMLButtonElement, HTMLAttributes<HTMLButtonElement>>(
551
+ function SidebarRail({ className, ...props }, ref) {
552
+ const { toggleSidebar } = useSidebar();
553
+
554
+ return (
555
+ <button
556
+ ref={ref}
557
+ type="button"
558
+ data-sidebar="rail"
559
+ aria-label="Toggle Sidebar"
560
+ tabIndex={-1}
561
+ onClick={toggleSidebar}
562
+ title="Toggle Sidebar"
563
+ className={cn(
564
+ 'absolute inset-y-0 z-20 hidden w-4 transition-all ease-linear after:absolute after:inset-y-0 after:left-1/2 after:w-[2px] group-data-[side=left]:-right-4 group-data-[side=left]:-translate-x-1/2 group-data-[side=right]:-left-4 group-data-[side=right]:translate-x-1/2 sm:flex',
565
+ 'hover:after:bg-sidebar-border',
566
+ '[[data-side=left]_&]:cursor-w-resize [[data-side=right]_&]:cursor-e-resize',
567
+ '[[data-side=left][data-state=collapsed]_&]:cursor-e-resize [[data-side=right][data-state=collapsed]_&]:cursor-w-resize',
568
+ 'group-data-[collapsible=offcanvas]:after:left-full group-data-[collapsible=offcanvas]:hover:bg-sidebar',
569
+ '[[data-side=left][data-collapsible=offcanvas]_&]:-right-2 [[data-side=left][data-collapsible=offcanvas]_&]:translate-x-0',
570
+ '[[data-side=right][data-collapsible=offcanvas]_&]:-left-2 [[data-side=right][data-collapsible=offcanvas]_&]:translate-x-0',
571
+ className,
572
+ )}
573
+ {...props}
574
+ />
575
+ );
576
+ },
577
+ );
578
+
579
+ /* ── SidebarInset ──────────────────────────────────────────────────── */
580
+
581
+ export const SidebarInset = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
582
+ function SidebarInset({ className, ...props }, ref) {
583
+ return (
584
+ <main
585
+ ref={ref}
586
+ className={cn(
587
+ 'relative flex min-h-svh flex-1 flex-col bg-background',
588
+ 'peer-data-[variant=inset]:min-h-[calc(100svh-theme(spacing.4))] md:peer-data-[variant=inset]:m-2 md:peer-data-[side=left]:peer-data-[variant=inset]:ml-0 md:peer-data-[side=right]:peer-data-[variant=inset]:mr-0 md:peer-data-[side=left]:peer-data-[state=collapsed]:peer-data-[variant=inset]:ml-2 md:peer-data-[side=right]:peer-data-[state=collapsed]:peer-data-[variant=inset]:mr-2 md:peer-data-[variant=inset]:rounded-xl md:peer-data-[variant=inset]:shadow',
589
+ className,
590
+ )}
591
+ {...props}
592
+ />
593
+ );
594
+ },
595
+ );
596
+
597
+ /* ── SidebarInput ──────────────────────────────────────────────────── */
598
+
599
+ export const SidebarInput = forwardRef<
600
+ HTMLInputElement,
601
+ ComponentProps<typeof Input>
602
+ >(function SidebarInput({ className, ...props }, ref) {
603
+ return (
604
+ <Input
605
+ ref={ref}
606
+ data-sidebar="input"
607
+ className={cn(
608
+ 'h-8 w-full bg-background shadow-none focus-within:ring-2 focus-within:ring-sidebar-ring',
609
+ className,
610
+ )}
611
+ {...props}
612
+ />
613
+ );
614
+ });
615
+
616
+ /* ── Layout sections ───────────────────────────────────────────────── */
617
+
618
+ export const SidebarHeader = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
619
+ function SidebarHeader({ className, ...props }, ref) {
620
+ return (
621
+ <div
622
+ ref={ref}
623
+ data-sidebar="header"
624
+ className={cn('flex flex-col gap-2 p-2', className)}
625
+ {...props}
626
+ />
627
+ );
628
+ },
629
+ );
630
+
631
+ export const SidebarFooter = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
632
+ function SidebarFooter({ className, ...props }, ref) {
633
+ return (
634
+ <div
635
+ ref={ref}
636
+ data-sidebar="footer"
637
+ className={cn('flex flex-col gap-2 p-2', className)}
638
+ {...props}
639
+ />
640
+ );
641
+ },
642
+ );
643
+
644
+ export const SidebarContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
645
+ function SidebarContent({ className, ...props }, ref) {
646
+ return (
647
+ <div
648
+ ref={ref}
649
+ data-sidebar="content"
650
+ className={cn(
651
+ 'flex min-h-0 flex-1 flex-col gap-2 overflow-auto group-data-[collapsible=icon]:overflow-hidden',
652
+ className,
653
+ )}
654
+ {...props}
655
+ />
656
+ );
657
+ },
658
+ );
659
+
660
+ /* ── SidebarSeparator ──────────────────────────────────────────────── */
661
+
662
+ export const SidebarSeparator = forwardRef<
663
+ HTMLDivElement,
664
+ ComponentProps<typeof Separator>
665
+ >(function SidebarSeparator({ className, ...props }, ref) {
666
+ return (
667
+ <Separator
668
+ ref={ref}
669
+ data-sidebar="separator"
670
+ className={cn('mx-2 w-auto bg-sidebar-border', className)}
671
+ {...props}
672
+ />
673
+ );
674
+ });
675
+
676
+ /* ── Group ─────────────────────────────────────────────────────────── */
677
+
678
+ export const SidebarGroup = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
679
+ function SidebarGroup({ className, ...props }, ref) {
680
+ return (
681
+ <div
682
+ ref={ref}
683
+ data-sidebar="group"
684
+ className={cn('relative flex w-full min-w-0 flex-col p-2', className)}
685
+ {...props}
686
+ />
687
+ );
688
+ },
689
+ );
690
+
691
+ export const SidebarGroupLabel = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement> & { asChild?: boolean }>(
692
+ function SidebarGroupLabel({ className, asChild: _asChild, ...props }, ref) {
693
+ return (
694
+ <div
695
+ ref={ref}
696
+ data-sidebar="group-label"
697
+ className={cn(
698
+ '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',
699
+ 'group-data-[collapsible=icon]:-mt-8 group-data-[collapsible=icon]:opacity-0',
700
+ className,
701
+ )}
702
+ {...props}
703
+ />
704
+ );
705
+ },
706
+ );
707
+
708
+ export const SidebarGroupAction = forwardRef<HTMLButtonElement, ButtonHTMLAttributes<HTMLButtonElement> & { asChild?: boolean }>(
709
+ function SidebarGroupAction({ className, asChild: _asChild, ...props }, ref) {
710
+ return (
711
+ <button
712
+ ref={ref}
713
+ type="button"
714
+ data-sidebar="group-action"
715
+ className={cn(
716
+ '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',
717
+ 'after:absolute after:-inset-2 after:md:hidden',
718
+ 'group-data-[collapsible=icon]:hidden',
719
+ className,
720
+ )}
721
+ {...props}
722
+ />
723
+ );
724
+ },
725
+ );
726
+
727
+ export const SidebarGroupContent = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
728
+ function SidebarGroupContent({ className, ...props }, ref) {
729
+ return (
730
+ <div
731
+ ref={ref}
732
+ data-sidebar="group-content"
733
+ className={cn('w-full text-sm', className)}
734
+ {...props}
735
+ />
736
+ );
737
+ },
738
+ );
739
+
740
+ /* ── Menu ──────────────────────────────────────────────────────────── */
741
+
742
+ export const SidebarMenu = forwardRef<HTMLUListElement, HTMLAttributes<HTMLUListElement>>(
743
+ function SidebarMenu({ className, ...props }, ref) {
744
+ return (
745
+ <ul
746
+ ref={ref}
747
+ data-sidebar="menu"
748
+ className={cn('flex w-full min-w-0 flex-col gap-1', className)}
749
+ {...props}
750
+ />
751
+ );
752
+ },
753
+ );
754
+
755
+ export const SidebarMenuItem = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(
756
+ function SidebarMenuItem({ className, ...props }, ref) {
757
+ return (
758
+ <li
759
+ ref={ref}
760
+ data-sidebar="menu-item"
761
+ className={cn('group/menu-item relative', className)}
762
+ {...props}
763
+ />
764
+ );
765
+ },
766
+ );
767
+
768
+ /* ── SidebarMenuButton ─────────────────────────────────────────────── */
769
+
770
+ export const sidebarMenuButtonVariants = cva(
771
+ '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',
772
+ {
773
+ variants: {
774
+ variant: {
775
+ default: 'hover:bg-sidebar-accent hover:text-sidebar-accent-foreground',
776
+ outline:
777
+ 'bg-background shadow-[0_0_0_1px_hsl(var(--sidebar-border))] hover:bg-sidebar-accent hover:text-sidebar-accent-foreground hover:shadow-[0_0_0_1px_hsl(var(--sidebar-accent))]',
778
+ },
779
+ size: {
780
+ default: 'h-8 text-sm',
781
+ sm: 'h-7 text-xs',
782
+ lg: 'h-12 text-sm group-data-[collapsible=icon]:p-0!',
783
+ },
784
+ },
785
+ defaultVariants: {
786
+ variant: 'default',
787
+ size: 'default',
788
+ },
789
+ },
790
+ );
791
+
792
+ export interface SidebarMenuButtonProps
793
+ extends ButtonHTMLAttributes<HTMLButtonElement>,
794
+ VariantProps<typeof sidebarMenuButtonVariants> {
795
+ asChild?: boolean;
796
+ isActive?: boolean;
797
+ tooltip?: string | ComponentProps<typeof Tooltip>;
798
+ }
799
+
800
+ export const SidebarMenuButton = forwardRef<HTMLButtonElement, SidebarMenuButtonProps>(
801
+ function SidebarMenuButton(
802
+ { asChild: _asChild, isActive = false, variant, size, tooltip, className, ...props },
803
+ ref,
804
+ ) {
805
+ useSidebar();
806
+
807
+ const button = (
808
+ <button
809
+ ref={ref}
810
+ type="button"
811
+ data-sidebar="menu-button"
812
+ data-size={size}
813
+ data-active={isActive}
814
+ className={cn(sidebarMenuButtonVariants({ variant, size }), className)}
815
+ {...props}
816
+ />
817
+ );
818
+
819
+ if (!tooltip) return button;
820
+
821
+ const tooltipProps: ComponentProps<typeof Tooltip> =
822
+ typeof tooltip === 'string' ? { content: tooltip } : tooltip;
823
+
824
+ return (
825
+ <Tooltip {...tooltipProps} side="right">
826
+ {button}
827
+ </Tooltip>
828
+ );
829
+ },
830
+ );
831
+
832
+ /* ── SidebarMenuAction ─────────────────────────────────────────────── */
833
+
834
+ export const SidebarMenuAction = forwardRef<
835
+ HTMLButtonElement,
836
+ ButtonHTMLAttributes<HTMLButtonElement> & { asChild?: boolean; showOnHover?: boolean }
837
+ >(function SidebarMenuAction({ className, asChild: _asChild, showOnHover = false, ...props }, ref) {
838
+ return (
839
+ <button
840
+ ref={ref}
841
+ type="button"
842
+ data-sidebar="menu-action"
843
+ className={cn(
844
+ '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',
845
+ 'after:absolute after:-inset-2 after:md:hidden',
846
+ 'group-data-[collapsible=icon]:hidden',
847
+ showOnHover &&
848
+ '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',
849
+ className,
850
+ )}
851
+ {...props}
852
+ />
853
+ );
854
+ });
855
+
856
+ /* ── SidebarMenuBadge ──────────────────────────────────────────────── */
857
+
858
+ export const SidebarMenuBadge = forwardRef<HTMLDivElement, HTMLAttributes<HTMLDivElement>>(
859
+ function SidebarMenuBadge({ className, ...props }, ref) {
860
+ return (
861
+ <div
862
+ ref={ref}
863
+ data-sidebar="menu-badge"
864
+ className={cn(
865
+ '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',
866
+ 'peer-hover/menu-button:text-sidebar-accent-foreground peer-data-[active=true]/menu-button:text-sidebar-accent-foreground',
867
+ 'group-data-[collapsible=icon]:hidden',
868
+ className,
869
+ )}
870
+ {...props}
871
+ />
872
+ );
873
+ },
874
+ );
875
+
876
+ /* ── SidebarMenuSkeleton ───────────────────────────────────────────── */
877
+
878
+ export interface SidebarMenuSkeletonProps extends HTMLAttributes<HTMLDivElement> {
879
+ showIcon?: boolean;
880
+ }
881
+
882
+ export const SidebarMenuSkeleton = forwardRef<HTMLDivElement, SidebarMenuSkeletonProps>(
883
+ function SidebarMenuSkeleton({ className, showIcon = false, ...props }, ref) {
884
+ // Fixed skeleton width — visual variety comes from multiple instances
885
+ const width = '70%';
886
+
887
+ return (
888
+ <div
889
+ ref={ref}
890
+ data-sidebar="menu-skeleton"
891
+ className={cn('flex h-8 items-center gap-2 rounded-md px-2', className)}
892
+ {...props}
893
+ >
894
+ {showIcon && <Skeleton className="size-4 rounded-md" data-sidebar="menu-skeleton-icon" />}
895
+ <Skeleton
896
+ className="h-4 max-w-(--skeleton-width) flex-1"
897
+ data-sidebar="menu-skeleton-text"
898
+ style={{ '--skeleton-width': width } as React.CSSProperties}
899
+ />
900
+ </div>
901
+ );
902
+ },
903
+ );
904
+
905
+ /* ── Sub-menu ──────────────────────────────────────────────────────── */
906
+
907
+ export const SidebarMenuSub = forwardRef<HTMLUListElement, HTMLAttributes<HTMLUListElement>>(
908
+ function SidebarMenuSub({ className, ...props }, ref) {
909
+ return (
910
+ <ul
911
+ ref={ref}
912
+ data-sidebar="menu-sub"
913
+ className={cn(
914
+ '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',
915
+ 'group-data-[collapsible=icon]:hidden',
916
+ className,
917
+ )}
918
+ {...props}
919
+ />
920
+ );
921
+ },
922
+ );
923
+
924
+ export const SidebarMenuSubItem = forwardRef<HTMLLIElement, HTMLAttributes<HTMLLIElement>>(
925
+ function SidebarMenuSubItem({ ...props }, ref) {
926
+ return <li ref={ref} {...props} />;
927
+ },
928
+ );
929
+
930
+ export interface SidebarMenuSubButtonProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
931
+ asChild?: boolean;
932
+ size?: 'sm' | 'md';
933
+ isActive?: boolean;
934
+ }
935
+
936
+ export const SidebarMenuSubButton = forwardRef<HTMLAnchorElement, SidebarMenuSubButtonProps>(
937
+ function SidebarMenuSubButton({ asChild: _asChild, size = 'md', isActive, className, ...props }, ref) {
938
+ return (
939
+ <a
940
+ ref={ref}
941
+ data-sidebar="menu-sub-button"
942
+ data-size={size}
943
+ data-active={isActive}
944
+ className={cn(
945
+ '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',
946
+ 'data-[active=true]:bg-sidebar-accent data-[active=true]:text-sidebar-accent-foreground',
947
+ size === 'sm' && 'text-xs',
948
+ size === 'md' && 'text-sm',
949
+ 'group-data-[collapsible=icon]:hidden',
950
+ className,
951
+ )}
952
+ {...props}
953
+ />
954
+ );
955
+ },
956
+ );