@arolariu/components 0.5.0 → 1.1.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 (972) hide show
  1. package/{changelog.md → CHANGELOG.md} +82 -0
  2. package/CONTRIBUTING.md +344 -265
  3. package/DEBUGGING.md +185 -103
  4. package/EXAMPLES.md +2976 -341
  5. package/{readme.md → README.md} +306 -203
  6. package/dist/components/ui/accordion.d.ts +157 -5
  7. package/dist/components/ui/accordion.d.ts.map +1 -1
  8. package/dist/components/ui/accordion.js +100 -22
  9. package/dist/components/ui/accordion.js.map +1 -1
  10. package/dist/components/ui/accordion.module.js +12 -0
  11. package/dist/components/ui/accordion.module.js.map +1 -0
  12. package/dist/components/ui/accordion_module.css +72 -0
  13. package/dist/components/ui/accordion_module.css.map +1 -0
  14. package/dist/components/ui/alert-dialog.d.ts +309 -18
  15. package/dist/components/ui/alert-dialog.d.ts.map +1 -1
  16. package/dist/components/ui/alert-dialog.js +149 -52
  17. package/dist/components/ui/alert-dialog.js.map +1 -1
  18. package/dist/components/ui/alert-dialog.module.js +13 -0
  19. package/dist/components/ui/alert-dialog.module.js.map +1 -0
  20. package/dist/components/ui/alert-dialog_module.css +89 -0
  21. package/dist/components/ui/alert-dialog_module.css.map +1 -0
  22. package/dist/components/ui/alert.d.ts +109 -6
  23. package/dist/components/ui/alert.d.ts.map +1 -1
  24. package/dist/components/ui/alert.js +12 -21
  25. package/dist/components/ui/alert.js.map +1 -1
  26. package/dist/components/ui/alert.module.js +11 -0
  27. package/dist/components/ui/alert.module.js.map +1 -0
  28. package/dist/components/ui/alert_module.css +59 -0
  29. package/dist/components/ui/alert_module.css.map +1 -0
  30. package/dist/components/ui/aspect-ratio.d.ts +24 -2
  31. package/dist/components/ui/aspect-ratio.d.ts.map +1 -1
  32. package/dist/components/ui/aspect-ratio.js +14 -3
  33. package/dist/components/ui/aspect-ratio.js.map +1 -1
  34. package/dist/components/ui/aspect-ratio.module.js +7 -0
  35. package/dist/components/ui/aspect-ratio.module.js.map +1 -0
  36. package/dist/components/ui/aspect-ratio_module.css +10 -0
  37. package/dist/components/ui/aspect-ratio_module.css.map +1 -0
  38. package/dist/components/ui/async-boundary.js +17 -0
  39. package/dist/components/ui/async-boundary.js.map +1 -0
  40. package/dist/components/ui/avatar.d.ts +88 -4
  41. package/dist/components/ui/avatar.d.ts.map +1 -1
  42. package/dist/components/ui/avatar.js +52 -20
  43. package/dist/components/ui/avatar.js.map +1 -1
  44. package/dist/components/ui/avatar.module.js +9 -0
  45. package/dist/components/ui/avatar.module.js.map +1 -0
  46. package/dist/components/ui/avatar_module.css +35 -0
  47. package/dist/components/ui/avatar_module.css.map +1 -0
  48. package/dist/components/ui/background-beams.d.ts +21 -3
  49. package/dist/components/ui/background-beams.d.ts.map +1 -1
  50. package/dist/components/ui/background-beams.js +22 -11
  51. package/dist/components/ui/background-beams.js.map +1 -1
  52. package/dist/components/ui/background-beams.module.js +8 -0
  53. package/dist/components/ui/background-beams.module.js.map +1 -0
  54. package/dist/components/ui/background-beams_module.css +22 -0
  55. package/dist/components/ui/background-beams_module.css.map +1 -0
  56. package/dist/components/ui/badge.d.ts +79 -6
  57. package/dist/components/ui/badge.d.ts.map +1 -1
  58. package/dist/components/ui/badge.js +19 -23
  59. package/dist/components/ui/badge.js.map +1 -1
  60. package/dist/components/ui/badge.module.js +11 -0
  61. package/dist/components/ui/badge.module.js.map +1 -0
  62. package/dist/components/ui/badge_module.css +63 -0
  63. package/dist/components/ui/badge_module.css.map +1 -0
  64. package/dist/components/ui/breadcrumb.d.ts +158 -13
  65. package/dist/components/ui/breadcrumb.d.ts.map +1 -1
  66. package/dist/components/ui/breadcrumb.js +39 -30
  67. package/dist/components/ui/breadcrumb.js.map +1 -1
  68. package/dist/components/ui/breadcrumb.module.js +14 -0
  69. package/dist/components/ui/breadcrumb.module.js.map +1 -0
  70. package/dist/components/ui/breadcrumb_module.css +90 -0
  71. package/dist/components/ui/breadcrumb_module.css.map +1 -0
  72. package/dist/components/ui/bubble-background.d.ts +38 -10
  73. package/dist/components/ui/bubble-background.d.ts.map +1 -1
  74. package/dist/components/ui/bubble-background.js +33 -35
  75. package/dist/components/ui/bubble-background.js.map +1 -1
  76. package/dist/components/ui/bubble-background.module.js +20 -0
  77. package/dist/components/ui/bubble-background.module.js.map +1 -0
  78. package/dist/components/ui/bubble-background_module.css +99 -0
  79. package/dist/components/ui/bubble-background_module.css.map +1 -0
  80. package/dist/components/ui/button-group.d.ts +88 -8
  81. package/dist/components/ui/button-group.d.ts.map +1 -1
  82. package/dist/components/ui/button-group.js +35 -32
  83. package/dist/components/ui/button-group.js.map +1 -1
  84. package/dist/components/ui/button-group.module.js +11 -0
  85. package/dist/components/ui/button-group.module.js.map +1 -0
  86. package/dist/components/ui/button-group_module.css +79 -0
  87. package/dist/components/ui/button-group_module.css.map +1 -0
  88. package/dist/components/ui/button.d.ts +82 -7
  89. package/dist/components/ui/button.d.ts.map +1 -1
  90. package/dist/components/ui/button.js +69 -34
  91. package/dist/components/ui/button.js.map +1 -1
  92. package/dist/components/ui/button.module.js +17 -0
  93. package/dist/components/ui/button.module.js.map +1 -0
  94. package/dist/components/ui/button_module.css +137 -0
  95. package/dist/components/ui/button_module.css.map +1 -0
  96. package/dist/components/ui/calendar.d.ts +36 -5
  97. package/dist/components/ui/calendar.d.ts.map +1 -1
  98. package/dist/components/ui/calendar.js +75 -64
  99. package/dist/components/ui/calendar.js.map +1 -1
  100. package/dist/components/ui/calendar.module.js +35 -0
  101. package/dist/components/ui/calendar.module.js.map +1 -0
  102. package/dist/components/ui/calendar_module.css +245 -0
  103. package/dist/components/ui/calendar_module.css.map +1 -0
  104. package/dist/components/ui/card-skeleton.js +41 -0
  105. package/dist/components/ui/card-skeleton.js.map +1 -0
  106. package/dist/components/ui/card-skeleton.module.js +15 -0
  107. package/dist/components/ui/card-skeleton.module.js.map +1 -0
  108. package/dist/components/ui/card-skeleton_module.css +54 -0
  109. package/dist/components/ui/card-skeleton_module.css.map +1 -0
  110. package/dist/components/ui/card.d.ts +162 -7
  111. package/dist/components/ui/card.d.ts.map +1 -1
  112. package/dist/components/ui/card.js +13 -13
  113. package/dist/components/ui/card.js.map +1 -1
  114. package/dist/components/ui/card.module.js +13 -0
  115. package/dist/components/ui/card.module.js.map +1 -0
  116. package/dist/components/ui/card_module.css +43 -0
  117. package/dist/components/ui/card_module.css.map +1 -0
  118. package/dist/components/ui/carousel.d.ts +127 -3
  119. package/dist/components/ui/carousel.d.ts.map +1 -1
  120. package/dist/components/ui/carousel.js +63 -36
  121. package/dist/components/ui/carousel.js.map +1 -1
  122. package/dist/components/ui/carousel.module.js +17 -0
  123. package/dist/components/ui/carousel.module.js.map +1 -0
  124. package/dist/components/ui/carousel_module.css +82 -0
  125. package/dist/components/ui/carousel_module.css.map +1 -0
  126. package/dist/components/ui/chart.d.ts +323 -13
  127. package/dist/components/ui/chart.d.ts.map +1 -1
  128. package/dist/components/ui/chart.js +224 -53
  129. package/dist/components/ui/chart.js.map +1 -1
  130. package/dist/components/ui/chart.module.js +27 -0
  131. package/dist/components/ui/chart.module.js.map +1 -0
  132. package/dist/components/ui/chart_module.css +159 -0
  133. package/dist/components/ui/chart_module.css.map +1 -0
  134. package/dist/components/ui/checkbox-group.d.ts +27 -0
  135. package/dist/components/ui/checkbox-group.d.ts.map +1 -0
  136. package/dist/components/ui/checkbox-group.js +26 -0
  137. package/dist/components/ui/checkbox-group.js.map +1 -0
  138. package/dist/components/ui/checkbox-group.module.js +7 -0
  139. package/dist/components/ui/checkbox-group.module.js.map +1 -0
  140. package/dist/components/ui/checkbox-group_module.css +11 -0
  141. package/dist/components/ui/checkbox-group_module.css.map +1 -0
  142. package/dist/components/ui/checkbox.d.ts +35 -2
  143. package/dist/components/ui/checkbox.d.ts.map +1 -1
  144. package/dist/components/ui/checkbox.js +40 -12
  145. package/dist/components/ui/checkbox.js.map +1 -1
  146. package/dist/components/ui/checkbox.module.js +8 -0
  147. package/dist/components/ui/checkbox.module.js.map +1 -0
  148. package/dist/components/ui/checkbox_module.css +45 -0
  149. package/dist/components/ui/checkbox_module.css.map +1 -0
  150. package/dist/components/ui/collapsible.d.ts +87 -3
  151. package/dist/components/ui/collapsible.d.ts.map +1 -1
  152. package/dist/components/ui/collapsible.js +46 -32
  153. package/dist/components/ui/collapsible.js.map +1 -1
  154. package/dist/components/ui/collapsible.module.js +8 -0
  155. package/dist/components/ui/collapsible.module.js.map +1 -0
  156. package/dist/components/ui/collapsible_module.css +26 -0
  157. package/dist/components/ui/collapsible_module.css.map +1 -0
  158. package/dist/components/ui/combobox.d.ts +335 -0
  159. package/dist/components/ui/combobox.d.ts.map +1 -0
  160. package/dist/components/ui/combobox.js +206 -0
  161. package/dist/components/ui/combobox.js.map +1 -0
  162. package/dist/components/ui/combobox.module.js +23 -0
  163. package/dist/components/ui/combobox.module.js.map +1 -0
  164. package/dist/components/ui/combobox_module.css +142 -0
  165. package/dist/components/ui/combobox_module.css.map +1 -0
  166. package/dist/components/ui/command.d.ts +284 -51
  167. package/dist/components/ui/command.d.ts.map +1 -1
  168. package/dist/components/ui/command.js +396 -51
  169. package/dist/components/ui/command.js.map +1 -1
  170. package/dist/components/ui/command.module.js +20 -0
  171. package/dist/components/ui/command.module.js.map +1 -0
  172. package/dist/components/ui/command_module.css +194 -0
  173. package/dist/components/ui/command_module.css.map +1 -0
  174. package/dist/components/ui/context-menu.d.ts +414 -21
  175. package/dist/components/ui/context-menu.d.ts.map +1 -1
  176. package/dist/components/ui/context-menu.js +190 -68
  177. package/dist/components/ui/context-menu.js.map +1 -1
  178. package/dist/components/ui/context-menu.module.js +19 -0
  179. package/dist/components/ui/context-menu.module.js.map +1 -0
  180. package/dist/components/ui/context-menu_module.css +114 -0
  181. package/dist/components/ui/context-menu_module.css.map +1 -0
  182. package/dist/components/ui/copy-button.d.ts +41 -0
  183. package/dist/components/ui/copy-button.d.ts.map +1 -0
  184. package/dist/components/ui/copy-button.js +51 -0
  185. package/dist/components/ui/copy-button.js.map +1 -0
  186. package/dist/components/ui/copy-button.module.js +8 -0
  187. package/dist/components/ui/copy-button.module.js.map +1 -0
  188. package/dist/components/ui/copy-button_module.css +37 -0
  189. package/dist/components/ui/copy-button_module.css.map +1 -0
  190. package/dist/components/ui/counting-number.d.ts +28 -2
  191. package/dist/components/ui/counting-number.d.ts.map +1 -1
  192. package/dist/components/ui/counting-number.js +31 -27
  193. package/dist/components/ui/counting-number.js.map +1 -1
  194. package/dist/components/ui/counting-number.module.js +7 -0
  195. package/dist/components/ui/counting-number.module.js.map +1 -0
  196. package/dist/components/ui/counting-number_module.css +7 -0
  197. package/dist/components/ui/counting-number_module.css.map +1 -0
  198. package/dist/components/ui/dialog.d.ts +287 -17
  199. package/dist/components/ui/dialog.d.ts.map +1 -1
  200. package/dist/components/ui/dialog.js +129 -52
  201. package/dist/components/ui/dialog.js.map +1 -1
  202. package/dist/components/ui/dialog.module.js +13 -0
  203. package/dist/components/ui/dialog.module.js.map +1 -0
  204. package/dist/components/ui/dialog_module.css +114 -0
  205. package/dist/components/ui/dialog_module.css.map +1 -0
  206. package/dist/components/ui/dot-background.d.ts +25 -35
  207. package/dist/components/ui/dot-background.d.ts.map +1 -1
  208. package/dist/components/ui/dot-background.js +31 -22
  209. package/dist/components/ui/dot-background.js.map +1 -1
  210. package/dist/components/ui/dot-background.module.js +8 -0
  211. package/dist/components/ui/dot-background.module.js.map +1 -0
  212. package/dist/components/ui/dot-background_module.css +15 -0
  213. package/dist/components/ui/dot-background_module.css.map +1 -0
  214. package/dist/components/ui/drawer.d.ts +287 -18
  215. package/dist/components/ui/drawer.d.ts.map +1 -1
  216. package/dist/components/ui/drawer.js +117 -40
  217. package/dist/components/ui/drawer.js.map +1 -1
  218. package/dist/components/ui/drawer.module.js +14 -0
  219. package/dist/components/ui/drawer.module.js.map +1 -0
  220. package/dist/components/ui/drawer_module.css +86 -0
  221. package/dist/components/ui/drawer_module.css.map +1 -0
  222. package/dist/components/ui/dropdown-menu.d.ts +414 -21
  223. package/dist/components/ui/dropdown-menu.d.ts.map +1 -1
  224. package/dist/components/ui/dropdown-menu.js +189 -68
  225. package/dist/components/ui/dropdown-menu.js.map +1 -1
  226. package/dist/components/ui/dropdown-menu.module.js +19 -0
  227. package/dist/components/ui/dropdown-menu.module.js.map +1 -0
  228. package/dist/components/ui/dropdown-menu_module.css +114 -0
  229. package/dist/components/ui/dropdown-menu_module.css.map +1 -0
  230. package/dist/components/ui/dropdrawer.d.ts +307 -17
  231. package/dist/components/ui/dropdrawer.d.ts.map +1 -1
  232. package/dist/components/ui/dropdrawer.js +438 -166
  233. package/dist/components/ui/dropdrawer.js.map +1 -1
  234. package/dist/components/ui/dropdrawer.module.js +43 -0
  235. package/dist/components/ui/dropdrawer.module.js.map +1 -0
  236. package/dist/components/ui/dropdrawer_module.css +307 -0
  237. package/dist/components/ui/dropdrawer_module.css.map +1 -0
  238. package/dist/components/ui/empty.d.ts +129 -10
  239. package/dist/components/ui/empty.d.ts.map +1 -1
  240. package/dist/components/ui/empty.js +32 -47
  241. package/dist/components/ui/empty.js.map +1 -1
  242. package/dist/components/ui/empty.module.js +13 -0
  243. package/dist/components/ui/empty.module.js.map +1 -0
  244. package/dist/components/ui/empty_module.css +85 -0
  245. package/dist/components/ui/empty_module.css.map +1 -0
  246. package/dist/components/ui/error-boundary.js +61 -0
  247. package/dist/components/ui/error-boundary.js.map +1 -0
  248. package/dist/components/ui/error-boundary.module.js +10 -0
  249. package/dist/components/ui/error-boundary.module.js.map +1 -0
  250. package/dist/components/ui/error-boundary_module.css +41 -0
  251. package/dist/components/ui/error-boundary_module.css.map +1 -0
  252. package/dist/components/ui/field.d.ts +222 -23
  253. package/dist/components/ui/field.d.ts.map +1 -1
  254. package/dist/components/ui/field.js +76 -86
  255. package/dist/components/ui/field.js.map +1 -1
  256. package/dist/components/ui/field.module.js +24 -0
  257. package/dist/components/ui/field.module.js.map +1 -0
  258. package/dist/components/ui/field_module.css +185 -0
  259. package/dist/components/ui/field_module.css.map +1 -0
  260. package/dist/components/ui/fireworks-background.d.ts +27 -3
  261. package/dist/components/ui/fireworks-background.d.ts.map +1 -1
  262. package/dist/components/ui/fireworks-background.js +36 -35
  263. package/dist/components/ui/fireworks-background.js.map +1 -1
  264. package/dist/components/ui/fireworks-background.module.js +8 -0
  265. package/dist/components/ui/fireworks-background.module.js.map +1 -0
  266. package/dist/components/ui/fireworks-background_module.css +17 -0
  267. package/dist/components/ui/fireworks-background_module.css.map +1 -0
  268. package/dist/components/ui/flip-button.d.ts +27 -3
  269. package/dist/components/ui/flip-button.d.ts.map +1 -1
  270. package/dist/components/ui/flip-button.js +27 -17
  271. package/dist/components/ui/flip-button.js.map +1 -1
  272. package/dist/components/ui/flip-button.module.js +11 -0
  273. package/dist/components/ui/flip-button.module.js.map +1 -0
  274. package/dist/components/ui/flip-button_module.css +47 -0
  275. package/dist/components/ui/flip-button_module.css.map +1 -0
  276. package/dist/components/ui/focus-scope.js +70 -0
  277. package/dist/components/ui/focus-scope.js.map +1 -0
  278. package/dist/components/ui/focus-scope.module.js +7 -0
  279. package/dist/components/ui/focus-scope.module.js.map +1 -0
  280. package/dist/components/ui/focus-scope_module.css +6 -0
  281. package/dist/components/ui/focus-scope_module.css.map +1 -0
  282. package/dist/components/ui/form-skeleton.js +32 -0
  283. package/dist/components/ui/form-skeleton.js.map +1 -0
  284. package/dist/components/ui/form-skeleton.module.js +11 -0
  285. package/dist/components/ui/form-skeleton.module.js.map +1 -0
  286. package/dist/components/ui/form-skeleton_module.css +30 -0
  287. package/dist/components/ui/form-skeleton_module.css.map +1 -0
  288. package/dist/components/ui/form.d.ts +143 -13
  289. package/dist/components/ui/form.d.ts.map +1 -1
  290. package/dist/components/ui/form.js +55 -21
  291. package/dist/components/ui/form.js.map +1 -1
  292. package/dist/components/ui/form.module.js +10 -0
  293. package/dist/components/ui/form.module.js.map +1 -0
  294. package/dist/components/ui/form_module.css +22 -0
  295. package/dist/components/ui/form_module.css.map +1 -0
  296. package/dist/components/ui/gradient-background.d.ts +21 -3
  297. package/dist/components/ui/gradient-background.d.ts.map +1 -1
  298. package/dist/components/ui/gradient-background.js +8 -4
  299. package/dist/components/ui/gradient-background.js.map +1 -1
  300. package/dist/components/ui/gradient-background.module.js +7 -0
  301. package/dist/components/ui/gradient-background.module.js.map +1 -0
  302. package/dist/components/ui/gradient-background_module.css +9 -0
  303. package/dist/components/ui/gradient-background_module.css.map +1 -0
  304. package/dist/components/ui/gradient-text.d.ts +23 -2
  305. package/dist/components/ui/gradient-text.d.ts.map +1 -1
  306. package/dist/components/ui/gradient-text.js +8 -6
  307. package/dist/components/ui/gradient-text.js.map +1 -1
  308. package/dist/components/ui/gradient-text.module.js +9 -0
  309. package/dist/components/ui/gradient-text.module.js.map +1 -0
  310. package/dist/components/ui/gradient-text_module.css +24 -0
  311. package/dist/components/ui/gradient-text_module.css.map +1 -0
  312. package/dist/components/ui/highlight-text.d.ts +24 -2
  313. package/dist/components/ui/highlight-text.d.ts.map +1 -1
  314. package/dist/components/ui/highlight-text.js +7 -10
  315. package/dist/components/ui/highlight-text.js.map +1 -1
  316. package/dist/components/ui/highlight-text.module.js +7 -0
  317. package/dist/components/ui/highlight-text.module.js.map +1 -0
  318. package/dist/components/ui/highlight-text_module.css +16 -0
  319. package/dist/components/ui/highlight-text_module.css.map +1 -0
  320. package/dist/components/ui/hole-background.d.ts +23 -2
  321. package/dist/components/ui/hole-background.d.ts.map +1 -1
  322. package/dist/components/ui/hole-background.js +155 -118
  323. package/dist/components/ui/hole-background.js.map +1 -1
  324. package/dist/components/ui/hole-background.module.js +10 -0
  325. package/dist/components/ui/hole-background.module.js.map +1 -0
  326. package/dist/components/ui/hole-background_module.css +85 -0
  327. package/dist/components/ui/hole-background_module.css.map +1 -0
  328. package/dist/components/ui/hover-card.d.ts +85 -4
  329. package/dist/components/ui/hover-card.d.ts.map +1 -1
  330. package/dist/components/ui/hover-card.js +52 -10
  331. package/dist/components/ui/hover-card.js.map +1 -1
  332. package/dist/components/ui/hover-card.module.js +8 -0
  333. package/dist/components/ui/hover-card.module.js.map +1 -0
  334. package/dist/components/ui/hover-card_module.css +23 -0
  335. package/dist/components/ui/hover-card_module.css.map +1 -0
  336. package/dist/components/ui/input-group.d.ts +132 -13
  337. package/dist/components/ui/input-group.d.ts.map +1 -1
  338. package/dist/components/ui/input-group.js +62 -66
  339. package/dist/components/ui/input-group.js.map +1 -1
  340. package/dist/components/ui/input-group.module.js +20 -0
  341. package/dist/components/ui/input-group.module.js.map +1 -0
  342. package/dist/components/ui/input-group_module.css +150 -0
  343. package/dist/components/ui/input-group_module.css.map +1 -0
  344. package/dist/components/ui/input-otp.d.ts +110 -30
  345. package/dist/components/ui/input-otp.d.ts.map +1 -1
  346. package/dist/components/ui/input-otp.js +24 -15
  347. package/dist/components/ui/input-otp.js.map +1 -1
  348. package/dist/components/ui/input-otp.module.js +17 -0
  349. package/dist/components/ui/input-otp.module.js.map +1 -0
  350. package/dist/components/ui/input-otp_module.css +89 -0
  351. package/dist/components/ui/input-otp_module.css.map +1 -0
  352. package/dist/components/ui/input.d.ts +31 -1
  353. package/dist/components/ui/input.d.ts.map +1 -1
  354. package/dist/components/ui/input.js +21 -8
  355. package/dist/components/ui/input.js.map +1 -1
  356. package/dist/components/ui/input.module.js +7 -0
  357. package/dist/components/ui/input.module.js.map +1 -0
  358. package/dist/components/ui/input_module.css +40 -0
  359. package/dist/components/ui/input_module.css.map +1 -0
  360. package/dist/components/ui/item.d.ts +221 -19
  361. package/dist/components/ui/item.d.ts.map +1 -1
  362. package/dist/components/ui/item.js +66 -90
  363. package/dist/components/ui/item.js.map +1 -1
  364. package/dist/components/ui/item.module.js +22 -0
  365. package/dist/components/ui/item.module.js.map +1 -0
  366. package/dist/components/ui/item_module.css +143 -0
  367. package/dist/components/ui/item_module.css.map +1 -0
  368. package/dist/components/ui/kbd.d.ts +43 -2
  369. package/dist/components/ui/kbd.d.ts.map +1 -1
  370. package/dist/components/ui/kbd.js +12 -12
  371. package/dist/components/ui/kbd.js.map +1 -1
  372. package/dist/components/ui/kbd.module.js +8 -0
  373. package/dist/components/ui/kbd.module.js.map +1 -0
  374. package/dist/components/ui/kbd_module.css +35 -0
  375. package/dist/components/ui/kbd_module.css.map +1 -0
  376. package/dist/components/ui/label.d.ts +30 -3
  377. package/dist/components/ui/label.d.ts.map +1 -1
  378. package/dist/components/ui/label.js +7 -8
  379. package/dist/components/ui/label.js.map +1 -1
  380. package/dist/components/ui/label.module.js +7 -0
  381. package/dist/components/ui/label.module.js.map +1 -0
  382. package/dist/components/ui/label_module.css +17 -0
  383. package/dist/components/ui/label_module.css.map +1 -0
  384. package/dist/components/ui/list-skeleton.js +35 -0
  385. package/dist/components/ui/list-skeleton.js.map +1 -0
  386. package/dist/components/ui/list-skeleton.module.js +12 -0
  387. package/dist/components/ui/list-skeleton.module.js.map +1 -0
  388. package/dist/components/ui/list-skeleton_module.css +39 -0
  389. package/dist/components/ui/list-skeleton_module.css.map +1 -0
  390. package/dist/components/ui/loading-overlay.js +21 -0
  391. package/dist/components/ui/loading-overlay.js.map +1 -0
  392. package/dist/components/ui/loading-overlay.module.js +9 -0
  393. package/dist/components/ui/loading-overlay.module.js.map +1 -0
  394. package/dist/components/ui/loading-overlay_module.css +22 -0
  395. package/dist/components/ui/loading-overlay_module.css.map +1 -0
  396. package/dist/components/ui/menubar.d.ts +420 -22
  397. package/dist/components/ui/menubar.d.ts.map +1 -1
  398. package/dist/components/ui/menubar.js +199 -100
  399. package/dist/components/ui/menubar.js.map +1 -1
  400. package/dist/components/ui/menubar.module.js +21 -0
  401. package/dist/components/ui/menubar.module.js.map +1 -0
  402. package/dist/components/ui/menubar_module.css +145 -0
  403. package/dist/components/ui/menubar_module.css.map +1 -0
  404. package/dist/components/ui/meter.d.ts +85 -0
  405. package/dist/components/ui/meter.d.ts.map +1 -0
  406. package/dist/components/ui/meter.js +75 -0
  407. package/dist/components/ui/meter.js.map +1 -0
  408. package/dist/components/ui/meter.module.js +10 -0
  409. package/dist/components/ui/meter.module.js.map +1 -0
  410. package/dist/components/ui/meter_module.css +31 -0
  411. package/dist/components/ui/meter_module.css.map +1 -0
  412. package/dist/components/ui/navigation-menu.d.ts +233 -11
  413. package/dist/components/ui/navigation-menu.d.ts.map +1 -1
  414. package/dist/components/ui/navigation-menu.js +138 -49
  415. package/dist/components/ui/navigation-menu.js.map +1 -1
  416. package/dist/components/ui/navigation-menu.module.js +18 -0
  417. package/dist/components/ui/navigation-menu.module.js.map +1 -0
  418. package/dist/components/ui/navigation-menu_module.css +112 -0
  419. package/dist/components/ui/navigation-menu_module.css.map +1 -0
  420. package/dist/components/ui/number-field.d.ts +138 -0
  421. package/dist/components/ui/number-field.d.ts.map +1 -0
  422. package/dist/components/ui/number-field.js +111 -0
  423. package/dist/components/ui/number-field.js.map +1 -0
  424. package/dist/components/ui/number-field.module.js +15 -0
  425. package/dist/components/ui/number-field.module.js.map +1 -0
  426. package/dist/components/ui/number-field_module.css +125 -0
  427. package/dist/components/ui/number-field_module.css.map +1 -0
  428. package/dist/components/ui/pagination.d.ts +150 -24
  429. package/dist/components/ui/pagination.d.ts.map +1 -1
  430. package/dist/components/ui/pagination.js +41 -38
  431. package/dist/components/ui/pagination.js.map +1 -1
  432. package/dist/components/ui/pagination.module.js +14 -0
  433. package/dist/components/ui/pagination.module.js.map +1 -0
  434. package/dist/components/ui/pagination_module.css +66 -0
  435. package/dist/components/ui/pagination_module.css.map +1 -0
  436. package/dist/components/ui/popover.d.ts +133 -5
  437. package/dist/components/ui/popover.d.ts.map +1 -1
  438. package/dist/components/ui/popover.js +68 -14
  439. package/dist/components/ui/popover.js.map +1 -1
  440. package/dist/components/ui/popover.module.js +9 -0
  441. package/dist/components/ui/popover.module.js.map +1 -0
  442. package/dist/components/ui/popover_module.css +28 -0
  443. package/dist/components/ui/popover_module.css.map +1 -0
  444. package/dist/components/ui/progress.d.ts +31 -2
  445. package/dist/components/ui/progress.d.ts.map +1 -1
  446. package/dist/components/ui/progress.js +22 -13
  447. package/dist/components/ui/progress.js.map +1 -1
  448. package/dist/components/ui/progress.module.js +8 -0
  449. package/dist/components/ui/progress.module.js.map +1 -0
  450. package/dist/components/ui/progress_module.css +20 -0
  451. package/dist/components/ui/progress_module.css.map +1 -0
  452. package/dist/components/ui/radio-group.d.ts +42 -3
  453. package/dist/components/ui/radio-group.d.ts.map +1 -1
  454. package/dist/components/ui/radio-group.js +38 -16
  455. package/dist/components/ui/radio-group.js.map +1 -1
  456. package/dist/components/ui/radio-group.module.js +10 -0
  457. package/dist/components/ui/radio-group.module.js.map +1 -0
  458. package/dist/components/ui/radio-group_module.css +44 -0
  459. package/dist/components/ui/radio-group_module.css.map +1 -0
  460. package/dist/components/ui/resizable.d.ts +78 -5
  461. package/dist/components/ui/resizable.d.ts.map +1 -1
  462. package/dist/components/ui/resizable.js +23 -13
  463. package/dist/components/ui/resizable.js.map +1 -1
  464. package/dist/components/ui/resizable.module.js +10 -0
  465. package/dist/components/ui/resizable.module.js.map +1 -0
  466. package/dist/components/ui/resizable_module.css +70 -0
  467. package/dist/components/ui/resizable_module.css.map +1 -0
  468. package/dist/components/ui/ripple-button.d.ts +23 -2
  469. package/dist/components/ui/ripple-button.d.ts.map +1 -1
  470. package/dist/components/ui/ripple-button.js +26 -11
  471. package/dist/components/ui/ripple-button.js.map +1 -1
  472. package/dist/components/ui/ripple-button.module.js +9 -0
  473. package/dist/components/ui/ripple-button.module.js.map +1 -0
  474. package/dist/components/ui/ripple-button_module.css +38 -0
  475. package/dist/components/ui/ripple-button_module.css.map +1 -0
  476. package/dist/components/ui/scratcher.d.ts +26 -3
  477. package/dist/components/ui/scratcher.d.ts.map +1 -1
  478. package/dist/components/ui/scratcher.js +89 -90
  479. package/dist/components/ui/scratcher.js.map +1 -1
  480. package/dist/components/ui/scratcher.module.js +8 -0
  481. package/dist/components/ui/scratcher.module.js.map +1 -0
  482. package/dist/components/ui/scratcher_module.css +13 -0
  483. package/dist/components/ui/scratcher_module.css.map +1 -0
  484. package/dist/components/ui/scroll-area.d.ts +44 -3
  485. package/dist/components/ui/scroll-area.d.ts.map +1 -1
  486. package/dist/components/ui/scroll-area.js +44 -19
  487. package/dist/components/ui/scroll-area.js.map +1 -1
  488. package/dist/components/ui/scroll-area.module.js +14 -0
  489. package/dist/components/ui/scroll-area.module.js.map +1 -0
  490. package/dist/components/ui/scroll-area_module.css +51 -0
  491. package/dist/components/ui/scroll-area_module.css.map +1 -0
  492. package/dist/components/ui/select.d.ts +269 -11
  493. package/dist/components/ui/select.d.ts.map +1 -1
  494. package/dist/components/ui/select.js +152 -67
  495. package/dist/components/ui/select.js.map +1 -1
  496. package/dist/components/ui/select.module.js +20 -0
  497. package/dist/components/ui/select.module.js.map +1 -0
  498. package/dist/components/ui/select_module.css +134 -0
  499. package/dist/components/ui/select_module.css.map +1 -0
  500. package/dist/components/ui/separator.d.ts +33 -2
  501. package/dist/components/ui/separator.d.ts.map +1 -1
  502. package/dist/components/ui/separator.js +20 -9
  503. package/dist/components/ui/separator.js.map +1 -1
  504. package/dist/components/ui/separator.module.js +9 -0
  505. package/dist/components/ui/separator.module.js.map +1 -0
  506. package/dist/components/ui/separator_module.css +17 -0
  507. package/dist/components/ui/separator_module.css.map +1 -0
  508. package/dist/components/ui/sheet.d.ts +297 -23
  509. package/dist/components/ui/sheet.d.ts.map +1 -1
  510. package/dist/components/ui/sheet.js +121 -63
  511. package/dist/components/ui/sheet.js.map +1 -1
  512. package/dist/components/ui/sheet.module.js +18 -0
  513. package/dist/components/ui/sheet.module.js.map +1 -0
  514. package/dist/components/ui/sheet_module.css +136 -0
  515. package/dist/components/ui/sheet_module.css.map +1 -0
  516. package/dist/components/ui/sidebar.d.ts +491 -23
  517. package/dist/components/ui/sidebar.d.ts.map +1 -1
  518. package/dist/components/ui/sidebar.js +214 -143
  519. package/dist/components/ui/sidebar.js.map +1 -1
  520. package/dist/components/ui/sidebar.module.js +50 -0
  521. package/dist/components/ui/sidebar.module.js.map +1 -0
  522. package/dist/components/ui/sidebar_module.css +569 -0
  523. package/dist/components/ui/sidebar_module.css.map +1 -0
  524. package/dist/components/ui/skeleton.d.ts +30 -1
  525. package/dist/components/ui/skeleton.d.ts.map +1 -1
  526. package/dist/components/ui/skeleton.js +7 -7
  527. package/dist/components/ui/skeleton.js.map +1 -1
  528. package/dist/components/ui/skeleton.module.js +8 -0
  529. package/dist/components/ui/skeleton.module.js.map +1 -0
  530. package/dist/components/ui/skeleton_module.css +18 -0
  531. package/dist/components/ui/skeleton_module.css.map +1 -0
  532. package/dist/components/ui/slider.d.ts +48 -2
  533. package/dist/components/ui/slider.d.ts.map +1 -1
  534. package/dist/components/ui/slider.js +44 -17
  535. package/dist/components/ui/slider.js.map +1 -1
  536. package/dist/components/ui/slider.module.js +11 -0
  537. package/dist/components/ui/slider.module.js.map +1 -0
  538. package/dist/components/ui/slider_module.css +55 -0
  539. package/dist/components/ui/slider_module.css.map +1 -0
  540. package/dist/components/ui/sonner.d.ts +138 -4
  541. package/dist/components/ui/sonner.d.ts.map +1 -1
  542. package/dist/components/ui/sonner.js +450 -17
  543. package/dist/components/ui/sonner.js.map +1 -1
  544. package/dist/components/ui/sonner.module.js +34 -0
  545. package/dist/components/ui/sonner.module.js.map +1 -0
  546. package/dist/components/ui/sonner_module.css +233 -0
  547. package/dist/components/ui/sonner_module.css.map +1 -0
  548. package/dist/components/ui/spinner.d.ts +20 -1
  549. package/dist/components/ui/spinner.d.ts.map +1 -1
  550. package/dist/components/ui/spinner.js +29 -11
  551. package/dist/components/ui/spinner.js.map +1 -1
  552. package/dist/components/ui/spinner.module.js +10 -0
  553. package/dist/components/ui/spinner.module.js.map +1 -0
  554. package/dist/components/ui/spinner_module.css +28 -0
  555. package/dist/components/ui/spinner_module.css.map +1 -0
  556. package/dist/components/ui/stepper.d.ts +48 -0
  557. package/dist/components/ui/stepper.d.ts.map +1 -0
  558. package/dist/components/ui/stepper.js +41 -0
  559. package/dist/components/ui/stepper.js.map +1 -0
  560. package/dist/components/ui/stepper.module.js +12 -0
  561. package/dist/components/ui/stepper.module.js.map +1 -0
  562. package/dist/components/ui/stepper_module.css +75 -0
  563. package/dist/components/ui/stepper_module.css.map +1 -0
  564. package/dist/components/ui/switch.d.ts +29 -2
  565. package/dist/components/ui/switch.d.ts.map +1 -1
  566. package/dist/components/ui/switch.js +21 -9
  567. package/dist/components/ui/switch.js.map +1 -1
  568. package/dist/components/ui/switch.module.js +8 -0
  569. package/dist/components/ui/switch.module.js.map +1 -0
  570. package/dist/components/ui/switch_module.css +45 -0
  571. package/dist/components/ui/switch_module.css.map +1 -0
  572. package/dist/components/ui/table-skeleton.js +34 -0
  573. package/dist/components/ui/table-skeleton.js.map +1 -0
  574. package/dist/components/ui/table-skeleton.module.js +11 -0
  575. package/dist/components/ui/table-skeleton.module.js.map +1 -0
  576. package/dist/components/ui/table-skeleton_module.css +32 -0
  577. package/dist/components/ui/table-skeleton_module.css.map +1 -0
  578. package/dist/components/ui/table.d.ts +170 -8
  579. package/dist/components/ui/table.d.ts.map +1 -1
  580. package/dist/components/ui/table.js +17 -17
  581. package/dist/components/ui/table.js.map +1 -1
  582. package/dist/components/ui/table.module.js +15 -0
  583. package/dist/components/ui/table.module.js.map +1 -0
  584. package/dist/components/ui/table_module.css +71 -0
  585. package/dist/components/ui/table_module.css.map +1 -0
  586. package/dist/components/ui/tabs.d.ts +114 -5
  587. package/dist/components/ui/tabs.d.ts.map +1 -1
  588. package/dist/components/ui/tabs.js +71 -20
  589. package/dist/components/ui/tabs.js.map +1 -1
  590. package/dist/components/ui/tabs.module.js +10 -0
  591. package/dist/components/ui/tabs.module.js.map +1 -0
  592. package/dist/components/ui/tabs_module.css +89 -0
  593. package/dist/components/ui/tabs_module.css.map +1 -0
  594. package/dist/components/ui/textarea.d.ts +24 -1
  595. package/dist/components/ui/textarea.d.ts.map +1 -1
  596. package/dist/components/ui/textarea.js +2 -2
  597. package/dist/components/ui/textarea.js.map +1 -1
  598. package/dist/components/ui/textarea.module.js +7 -0
  599. package/dist/components/ui/textarea.module.js.map +1 -0
  600. package/dist/components/ui/textarea_module.css +33 -0
  601. package/dist/components/ui/textarea_module.css.map +1 -0
  602. package/dist/components/ui/timeline.d.ts +111 -0
  603. package/dist/components/ui/timeline.d.ts.map +1 -0
  604. package/dist/components/ui/timeline.js +34 -0
  605. package/dist/components/ui/timeline.js.map +1 -0
  606. package/dist/components/ui/timeline.module.js +10 -0
  607. package/dist/components/ui/timeline.module.js.map +1 -0
  608. package/dist/components/ui/timeline_module.css +47 -0
  609. package/dist/components/ui/timeline_module.css.map +1 -0
  610. package/dist/components/ui/toggle-group.d.ts +75 -10
  611. package/dist/components/ui/toggle-group.d.ts.map +1 -1
  612. package/dist/components/ui/toggle-group.js +32 -21
  613. package/dist/components/ui/toggle-group.js.map +1 -1
  614. package/dist/components/ui/toggle-group.module.js +7 -0
  615. package/dist/components/ui/toggle-group.module.js.map +1 -0
  616. package/dist/components/ui/toggle-group_module.css +8 -0
  617. package/dist/components/ui/toggle-group_module.css.map +1 -0
  618. package/dist/components/ui/toggle.d.ts +60 -11
  619. package/dist/components/ui/toggle.d.ts.map +1 -1
  620. package/dist/components/ui/toggle.js +29 -29
  621. package/dist/components/ui/toggle.js.map +1 -1
  622. package/dist/components/ui/toggle.module.js +12 -0
  623. package/dist/components/ui/toggle.module.js.map +1 -0
  624. package/dist/components/ui/toggle_module.css +62 -0
  625. package/dist/components/ui/toggle_module.css.map +1 -0
  626. package/dist/components/ui/toolbar.d.ts +107 -0
  627. package/dist/components/ui/toolbar.d.ts.map +1 -0
  628. package/dist/components/ui/toolbar.js +90 -0
  629. package/dist/components/ui/toolbar.js.map +1 -0
  630. package/dist/components/ui/toolbar.module.js +12 -0
  631. package/dist/components/ui/toolbar.module.js.map +1 -0
  632. package/dist/components/ui/toolbar_module.css +115 -0
  633. package/dist/components/ui/toolbar_module.css.map +1 -0
  634. package/dist/components/ui/tooltip.d.ts +119 -5
  635. package/dist/components/ui/tooltip.d.ts.map +1 -1
  636. package/dist/components/ui/tooltip.js +48 -13
  637. package/dist/components/ui/tooltip.js.map +1 -1
  638. package/dist/components/ui/tooltip.module.js +9 -0
  639. package/dist/components/ui/tooltip.module.js.map +1 -0
  640. package/dist/components/ui/tooltip_module.css +35 -0
  641. package/dist/components/ui/tooltip_module.css.map +1 -0
  642. package/dist/components/ui/typewriter.d.ts +48 -13
  643. package/dist/components/ui/typewriter.d.ts.map +1 -1
  644. package/dist/components/ui/typewriter.js +46 -49
  645. package/dist/components/ui/typewriter.js.map +1 -1
  646. package/dist/components/ui/typewriter.module.js +16 -0
  647. package/dist/components/ui/typewriter.module.js.map +1 -0
  648. package/dist/components/ui/typewriter_module.css +102 -0
  649. package/dist/components/ui/typewriter_module.css.map +1 -0
  650. package/dist/components/ui/visually-hidden.d.ts +38 -0
  651. package/dist/components/ui/visually-hidden.d.ts.map +1 -0
  652. package/dist/components/ui/visually-hidden.js +13 -0
  653. package/dist/components/ui/visually-hidden.js.map +1 -0
  654. package/dist/components/ui/visually-hidden.module.js +7 -0
  655. package/dist/components/ui/visually-hidden.module.js.map +1 -0
  656. package/dist/components/ui/visually-hidden_module.css +14 -0
  657. package/dist/components/ui/visually-hidden_module.css.map +1 -0
  658. package/dist/hooks/useAnnounce.js +46 -0
  659. package/dist/hooks/useAnnounce.js.map +1 -0
  660. package/dist/hooks/useBreakpoint.d.ts +17 -0
  661. package/dist/hooks/useBreakpoint.d.ts.map +1 -0
  662. package/dist/hooks/useBreakpoint.js +16 -0
  663. package/dist/hooks/useBreakpoint.js.map +1 -0
  664. package/dist/hooks/useClipboard.d.ts +77 -0
  665. package/dist/hooks/useClipboard.d.ts.map +1 -0
  666. package/dist/hooks/useClipboard.js +42 -0
  667. package/dist/hooks/useClipboard.js.map +1 -0
  668. package/dist/hooks/useColorScheme.d.ts +14 -0
  669. package/dist/hooks/useColorScheme.d.ts.map +1 -0
  670. package/dist/hooks/useColorScheme.js +9 -0
  671. package/dist/hooks/useColorScheme.js.map +1 -0
  672. package/dist/hooks/useControllableState.d.ts +54 -0
  673. package/dist/hooks/useControllableState.d.ts.map +1 -0
  674. package/dist/hooks/useControllableState.js +29 -0
  675. package/dist/hooks/useControllableState.js.map +1 -0
  676. package/dist/hooks/useDebounce.d.ts +33 -0
  677. package/dist/hooks/useDebounce.d.ts.map +1 -0
  678. package/dist/hooks/useDebounce.js +20 -0
  679. package/dist/hooks/useDebounce.js.map +1 -0
  680. package/dist/hooks/useEventCallback.d.ts +34 -0
  681. package/dist/hooks/useEventCallback.d.ts.map +1 -0
  682. package/dist/hooks/useEventCallback.js +12 -0
  683. package/dist/hooks/useEventCallback.js.map +1 -0
  684. package/dist/hooks/useFocusManager.js +51 -0
  685. package/dist/hooks/useFocusManager.js.map +1 -0
  686. package/dist/hooks/useFocusVisible.d.ts +50 -0
  687. package/dist/hooks/useFocusVisible.d.ts.map +1 -0
  688. package/dist/hooks/useFocusVisible.js +35 -0
  689. package/dist/hooks/useFocusVisible.js.map +1 -0
  690. package/dist/hooks/useId.d.ts +30 -0
  691. package/dist/hooks/useId.d.ts.map +1 -0
  692. package/dist/hooks/useId.js +9 -0
  693. package/dist/hooks/useId.js.map +1 -0
  694. package/dist/hooks/useIntersectionObserver.d.ts +51 -0
  695. package/dist/hooks/useIntersectionObserver.d.ts.map +1 -0
  696. package/dist/hooks/useIntersectionObserver.js +25 -0
  697. package/dist/hooks/useIntersectionObserver.js.map +1 -0
  698. package/dist/hooks/useInterval.d.ts +55 -0
  699. package/dist/hooks/useInterval.d.ts.map +1 -0
  700. package/dist/hooks/useInterval.js +24 -0
  701. package/dist/hooks/useInterval.js.map +1 -0
  702. package/dist/hooks/useIsMobile.d.ts +5 -11
  703. package/dist/hooks/useIsMobile.d.ts.map +1 -1
  704. package/dist/hooks/useIsMobile.js +2 -13
  705. package/dist/hooks/useIsMobile.js.map +1 -1
  706. package/dist/hooks/useLocalStorage.d.ts +43 -0
  707. package/dist/hooks/useLocalStorage.d.ts.map +1 -0
  708. package/dist/hooks/useLocalStorage.js +53 -0
  709. package/dist/hooks/useLocalStorage.js.map +1 -0
  710. package/dist/hooks/useMediaQuery.d.ts +14 -0
  711. package/dist/hooks/useMediaQuery.d.ts.map +1 -0
  712. package/dist/hooks/useMediaQuery.js +20 -0
  713. package/dist/hooks/useMediaQuery.js.map +1 -0
  714. package/dist/hooks/useMergedRefs.d.ts +27 -0
  715. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  716. package/dist/hooks/useMergedRefs.js +11 -0
  717. package/dist/hooks/useMergedRefs.js.map +1 -0
  718. package/dist/hooks/useOnClickOutside.d.ts +32 -0
  719. package/dist/hooks/useOnClickOutside.d.ts.map +1 -0
  720. package/dist/hooks/useOnClickOutside.js +23 -0
  721. package/dist/hooks/useOnClickOutside.js.map +1 -0
  722. package/dist/hooks/usePrefersContrast.d.ts +19 -0
  723. package/dist/hooks/usePrefersContrast.d.ts.map +1 -0
  724. package/dist/hooks/usePrefersContrast.js +8 -0
  725. package/dist/hooks/usePrefersContrast.js.map +1 -0
  726. package/dist/hooks/usePrevious.d.ts +33 -0
  727. package/dist/hooks/usePrevious.d.ts.map +1 -0
  728. package/dist/hooks/usePrevious.js +14 -0
  729. package/dist/hooks/usePrevious.js.map +1 -0
  730. package/dist/hooks/useReducedMotion.d.ts +19 -0
  731. package/dist/hooks/useReducedMotion.d.ts.map +1 -0
  732. package/dist/hooks/useReducedMotion.js +2 -0
  733. package/dist/hooks/useThrottle.d.ts +37 -0
  734. package/dist/hooks/useThrottle.d.ts.map +1 -0
  735. package/dist/hooks/useThrottle.js +34 -0
  736. package/dist/hooks/useThrottle.js.map +1 -0
  737. package/dist/hooks/useTimeout.d.ts +28 -0
  738. package/dist/hooks/useTimeout.d.ts.map +1 -0
  739. package/dist/hooks/useTimeout.js +24 -0
  740. package/dist/hooks/useTimeout.js.map +1 -0
  741. package/dist/index.css +104 -5363
  742. package/dist/index.css.map +1 -1
  743. package/dist/index.d.ts +52 -8
  744. package/dist/index.d.ts.map +1 -1
  745. package/dist/index.js +103 -72
  746. package/dist/lib/utilities.d.ts +5 -5
  747. package/dist/lib/utilities.d.ts.map +1 -1
  748. package/dist/lib/utilities.js +1 -2
  749. package/dist/lib/utilities.js.map +1 -1
  750. package/dist/motion/Collapse.js +19 -0
  751. package/dist/motion/Collapse.js.map +1 -0
  752. package/dist/motion/Collapse.module.js +8 -0
  753. package/dist/motion/Collapse.module.js.map +1 -0
  754. package/dist/motion/Collapse_module.css +25 -0
  755. package/dist/motion/Collapse_module.css.map +1 -0
  756. package/dist/motion/Presence.js +14 -0
  757. package/dist/motion/Presence.js.map +1 -0
  758. package/dist/motion/index.js +5 -0
  759. package/dist/motion/presets.js +117 -0
  760. package/dist/motion/presets.js.map +1 -0
  761. package/dist/motion/tokens.js +41 -0
  762. package/dist/motion/tokens.js.map +1 -0
  763. package/dist/rslib-runtime.js +39 -0
  764. package/dist/rslib-runtime.js.map +1 -0
  765. package/package.json +233 -67
  766. package/src/components/ui/accordion.module.css +70 -0
  767. package/src/components/ui/accordion.tsx +278 -44
  768. package/src/components/ui/alert-dialog.module.css +87 -0
  769. package/src/components/ui/alert-dialog.tsx +481 -99
  770. package/src/components/ui/alert.module.css +57 -0
  771. package/src/components/ui/alert.tsx +136 -43
  772. package/src/components/ui/aspect-ratio.module.css +7 -0
  773. package/src/components/ui/aspect-ratio.tsx +38 -3
  774. package/src/components/ui/async-boundary.tsx +56 -0
  775. package/src/components/ui/avatar.module.css +31 -0
  776. package/src/components/ui/avatar.tsx +149 -36
  777. package/src/components/ui/background-beams.module.css +20 -0
  778. package/src/components/ui/background-beams.tsx +173 -134
  779. package/src/components/ui/badge.module.css +60 -0
  780. package/src/components/ui/badge.tsx +100 -32
  781. package/src/components/ui/breadcrumb.module.css +87 -0
  782. package/src/components/ui/breadcrumb.tsx +256 -74
  783. package/src/components/ui/bubble-background.module.css +97 -0
  784. package/src/components/ui/bubble-background.tsx +92 -52
  785. package/src/components/ui/button-group.module.css +76 -0
  786. package/src/components/ui/button-group.tsx +135 -46
  787. package/src/components/ui/button.module.css +138 -0
  788. package/src/components/ui/button.tsx +159 -41
  789. package/src/components/ui/calendar.module.css +250 -0
  790. package/src/components/ui/calendar.tsx +135 -111
  791. package/src/components/ui/card-skeleton.module.css +50 -0
  792. package/src/components/ui/card-skeleton.tsx +69 -0
  793. package/src/components/ui/card.module.css +41 -0
  794. package/src/components/ui/card.tsx +175 -22
  795. package/src/components/ui/carousel.module.css +80 -0
  796. package/src/components/ui/carousel.tsx +186 -43
  797. package/src/components/ui/chart.module.css +164 -0
  798. package/src/components/ui/chart.tsx +447 -102
  799. package/src/components/ui/checkbox-group.module.css +8 -0
  800. package/src/components/ui/checkbox-group.tsx +53 -0
  801. package/src/components/ui/checkbox.module.css +43 -0
  802. package/src/components/ui/checkbox.tsx +81 -19
  803. package/src/components/ui/collapsible.module.css +24 -0
  804. package/src/components/ui/collapsible.tsx +140 -3
  805. package/src/components/ui/combobox.module.css +158 -0
  806. package/src/components/ui/combobox.tsx +569 -0
  807. package/src/components/ui/command.module.css +193 -0
  808. package/src/components/ui/command.tsx +893 -114
  809. package/src/components/ui/context-menu.module.css +113 -0
  810. package/src/components/ui/context-menu.tsx +619 -157
  811. package/src/components/ui/copy-button.module.css +34 -0
  812. package/src/components/ui/copy-button.tsx +116 -0
  813. package/src/components/ui/counting-number.module.css +4 -0
  814. package/src/components/ui/counting-number.tsx +69 -31
  815. package/src/components/ui/dialog.module.css +113 -0
  816. package/src/components/ui/dialog.tsx +427 -81
  817. package/src/components/ui/dot-background.module.css +12 -0
  818. package/src/components/ui/dot-background.tsx +134 -126
  819. package/src/components/ui/drawer.module.css +85 -0
  820. package/src/components/ui/drawer.tsx +410 -80
  821. package/src/components/ui/dropdown-menu.module.css +113 -0
  822. package/src/components/ui/dropdown-menu.tsx +619 -159
  823. package/src/components/ui/dropdrawer.module.css +322 -0
  824. package/src/components/ui/dropdrawer.tsx +870 -400
  825. package/src/components/ui/empty.module.css +84 -0
  826. package/src/components/ui/empty.tsx +176 -52
  827. package/src/components/ui/error-boundary.module.css +36 -0
  828. package/src/components/ui/error-boundary.tsx +127 -0
  829. package/src/components/ui/field.module.css +179 -0
  830. package/src/components/ui/field.tsx +345 -139
  831. package/src/components/ui/fireworks-background.module.css +13 -0
  832. package/src/components/ui/fireworks-background.tsx +89 -51
  833. package/src/components/ui/flip-button.module.css +44 -0
  834. package/src/components/ui/flip-button.tsx +59 -28
  835. package/src/components/ui/focus-scope.module.css +3 -0
  836. package/src/components/ui/focus-scope.tsx +160 -0
  837. package/src/components/ui/form-skeleton.module.css +28 -0
  838. package/src/components/ui/form-skeleton.tsx +62 -0
  839. package/src/components/ui/form.module.css +20 -0
  840. package/src/components/ui/form.tsx +244 -33
  841. package/src/components/ui/gradient-background.module.css +6 -0
  842. package/src/components/ui/gradient-background.tsx +27 -5
  843. package/src/components/ui/gradient-text.module.css +23 -0
  844. package/src/components/ui/gradient-text.tsx +36 -9
  845. package/src/components/ui/highlight-text.module.css +14 -0
  846. package/src/components/ui/highlight-text.tsx +37 -15
  847. package/src/components/ui/hole-background.module.css +84 -0
  848. package/src/components/ui/hole-background.tsx +290 -162
  849. package/src/components/ui/hover-card.module.css +21 -0
  850. package/src/components/ui/hover-card.tsx +142 -21
  851. package/src/components/ui/input-group.module.css +148 -0
  852. package/src/components/ui/input-group.tsx +222 -98
  853. package/src/components/ui/input-otp.module.css +92 -0
  854. package/src/components/ui/input-otp.tsx +159 -33
  855. package/src/components/ui/input.module.css +37 -0
  856. package/src/components/ui/input.tsx +56 -14
  857. package/src/components/ui/item.module.css +143 -0
  858. package/src/components/ui/item.tsx +331 -104
  859. package/src/components/ui/kbd.module.css +31 -0
  860. package/src/components/ui/kbd.tsx +60 -17
  861. package/src/components/ui/label.module.css +13 -0
  862. package/src/components/ui/label.tsx +38 -14
  863. package/src/components/ui/list-skeleton.module.css +35 -0
  864. package/src/components/ui/list-skeleton.tsx +70 -0
  865. package/src/components/ui/loading-overlay.module.css +19 -0
  866. package/src/components/ui/loading-overlay.tsx +72 -0
  867. package/src/components/ui/menubar.module.css +144 -0
  868. package/src/components/ui/menubar.tsx +604 -192
  869. package/src/components/ui/meter.module.css +32 -0
  870. package/src/components/ui/meter.tsx +169 -0
  871. package/src/components/ui/navigation-menu.module.css +110 -0
  872. package/src/components/ui/navigation-menu.tsx +381 -99
  873. package/src/components/ui/number-field.module.css +126 -0
  874. package/src/components/ui/number-field.tsx +247 -0
  875. package/src/components/ui/pagination.module.css +64 -0
  876. package/src/components/ui/pagination.tsx +250 -72
  877. package/src/components/ui/popover.module.css +26 -0
  878. package/src/components/ui/popover.tsx +207 -25
  879. package/src/components/ui/progress.module.css +15 -0
  880. package/src/components/ui/progress.tsx +54 -16
  881. package/src/components/ui/radio-group.module.css +41 -0
  882. package/src/components/ui/radio-group.tsx +88 -34
  883. package/src/components/ui/resizable.module.css +67 -0
  884. package/src/components/ui/resizable.tsx +106 -26
  885. package/src/components/ui/ripple-button.module.css +35 -0
  886. package/src/components/ui/ripple-button.tsx +55 -21
  887. package/src/components/ui/scratcher.module.css +9 -0
  888. package/src/components/ui/scratcher.tsx +134 -108
  889. package/src/components/ui/scroll-area.module.css +47 -0
  890. package/src/components/ui/scroll-area.tsx +93 -34
  891. package/src/components/ui/select.module.css +131 -0
  892. package/src/components/ui/select.tsx +435 -124
  893. package/src/components/ui/separator.module.css +14 -0
  894. package/src/components/ui/separator.tsx +60 -18
  895. package/src/components/ui/sheet.module.css +138 -0
  896. package/src/components/ui/sheet.tsx +427 -95
  897. package/src/components/ui/sidebar.module.css +594 -0
  898. package/src/components/ui/sidebar.tsx +900 -425
  899. package/src/components/ui/skeleton.module.css +14 -0
  900. package/src/components/ui/skeleton.tsx +39 -9
  901. package/src/components/ui/slider.module.css +48 -0
  902. package/src/components/ui/slider.tsx +89 -16
  903. package/src/components/ui/sonner.module.css +246 -0
  904. package/src/components/ui/sonner.tsx +777 -25
  905. package/src/components/ui/spinner.module.css +25 -0
  906. package/src/components/ui/spinner.tsx +51 -12
  907. package/src/components/ui/stepper.module.css +72 -0
  908. package/src/components/ui/stepper.tsx +95 -0
  909. package/src/components/ui/switch.module.css +42 -0
  910. package/src/components/ui/switch.tsx +53 -20
  911. package/src/components/ui/table-skeleton.module.css +29 -0
  912. package/src/components/ui/table-skeleton.tsx +79 -0
  913. package/src/components/ui/table.module.css +66 -0
  914. package/src/components/ui/table.tsx +235 -61
  915. package/src/components/ui/tabs.module.css +89 -0
  916. package/src/components/ui/tabs.tsx +192 -45
  917. package/src/components/ui/textarea.module.css +30 -0
  918. package/src/components/ui/textarea.tsx +30 -10
  919. package/src/components/ui/timeline.module.css +43 -0
  920. package/src/components/ui/timeline.tsx +153 -0
  921. package/src/components/ui/toggle-group.module.css +5 -0
  922. package/src/components/ui/toggle-group.tsx +115 -32
  923. package/src/components/ui/toggle.module.css +57 -0
  924. package/src/components/ui/toggle.tsx +89 -33
  925. package/src/components/ui/toolbar.module.css +112 -0
  926. package/src/components/ui/toolbar.tsx +209 -0
  927. package/src/components/ui/tooltip.module.css +39 -0
  928. package/src/components/ui/tooltip.tsx +181 -24
  929. package/src/components/ui/typewriter.module.css +101 -0
  930. package/src/components/ui/typewriter.tsx +130 -128
  931. package/src/components/ui/visually-hidden.module.css +11 -0
  932. package/src/components/ui/visually-hidden.tsx +50 -0
  933. package/src/css-modules.d.ts +9 -0
  934. package/src/hooks/useAnnounce.tsx +73 -0
  935. package/src/hooks/useBreakpoint.tsx +41 -0
  936. package/src/hooks/useClipboard.tsx +137 -0
  937. package/src/hooks/useColorScheme.tsx +23 -0
  938. package/src/hooks/useControllableState.tsx +81 -0
  939. package/src/hooks/useDebounce.tsx +50 -0
  940. package/src/hooks/useEventCallback.tsx +47 -0
  941. package/src/hooks/useFocusManager.tsx +89 -0
  942. package/src/hooks/useFocusVisible.tsx +88 -0
  943. package/src/hooks/useId.tsx +36 -0
  944. package/src/hooks/useIntersectionObserver.tsx +81 -0
  945. package/src/hooks/useInterval.tsx +80 -0
  946. package/src/hooks/useIsMobile.tsx +7 -28
  947. package/src/hooks/useLocalStorage.tsx +111 -0
  948. package/src/hooks/useMediaQuery.tsx +34 -0
  949. package/src/hooks/useMergedRefs.tsx +48 -0
  950. package/src/hooks/useOnClickOutside.tsx +55 -0
  951. package/src/hooks/usePrefersContrast.tsx +24 -0
  952. package/src/hooks/usePrevious.tsx +44 -0
  953. package/src/hooks/useReducedMotion.tsx +20 -0
  954. package/src/hooks/useThrottle.tsx +78 -0
  955. package/src/hooks/useTimeout.tsx +51 -0
  956. package/src/index.css +127 -65
  957. package/src/index.ts +219 -18
  958. package/src/lib/utilities.ts +8 -7
  959. package/src/motion/Collapse.module.css +22 -0
  960. package/src/motion/Collapse.tsx +52 -0
  961. package/src/motion/Presence.tsx +44 -0
  962. package/src/motion/index.ts +13 -0
  963. package/src/motion/presets.ts +77 -0
  964. package/src/motion/tokens.ts +37 -0
  965. package/src/stories/DesignPrinciples.mdx +48 -0
  966. package/src/stories/GettingStarted.mdx +92 -0
  967. package/src/stories/Welcome.mdx +44 -0
  968. package/src/hooks/useIsMobile.test.tsx +0 -96
  969. package/src/hooks/useWindowSize.test.tsx +0 -57
  970. package/src/index.test.ts +0 -537
  971. package/src/lib/color-conversion-utilities.test.ts +0 -225
  972. package/src/lib/utilities.test.ts +0 -37
@@ -1,205 +1,569 @@
1
1
  "use client";
2
2
 
3
- /* eslint-disable */
3
+ /* eslint-disable react/no-children-prop, react-x/no-children-for-each, react-x/no-children-map, react-x/no-children-to-array, react-x/no-clone-element, sonarjs/function-return-type, sonarjs/no-identical-functions, sonarjs/no-unused-vars, max-lines, unicorn/no-array-callback-reference, unicorn/no-useless-undefined, unicorn/prefer-at, unicorn/prefer-dom-node-dataset, jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */
4
4
 
5
+ import {Drawer as BaseDrawer} from "@base-ui/react/drawer";
6
+ import {Menu as BaseMenu} from "@base-ui/react/menu";
7
+ import {mergeProps} from "@base-ui/react/merge-props";
8
+ import {useRender} from "@base-ui/react/use-render";
5
9
  import {ChevronLeftIcon, ChevronRightIcon} from "lucide-react";
6
- import {AnimatePresence, motion, Transition} from "motion/react";
10
+ import {AnimatePresence, motion, type Transition} from "motion/react";
7
11
  import * as React from "react";
8
12
 
9
- import {Drawer, DrawerClose, DrawerContent, DrawerFooter, DrawerHeader, DrawerTitle, DrawerTrigger} from "@/components/ui/drawer";
10
- import {
11
- DropdownMenu,
12
- DropdownMenuContent,
13
- DropdownMenuItem,
14
- DropdownMenuLabel,
15
- DropdownMenuSeparator,
16
- DropdownMenuSub,
17
- DropdownMenuSubContent,
18
- DropdownMenuSubTrigger,
19
- DropdownMenuTrigger,
20
- } from "@/components/ui/dropdown-menu";
21
13
  import {useIsMobile} from "@/hooks/useIsMobile";
22
14
  import {cn} from "@/lib/utilities";
15
+ import styles from "./dropdrawer.module.css";
23
16
 
24
- const DropDrawerContext = React.createContext<{isMobile: boolean}>({
25
- isMobile: false,
26
- });
17
+ const MOBILE_MENU_TITLE = "Menu";
18
+ const MOBILE_SUBMENU_TITLE = "Submenu";
19
+ const MOBILE_BACK_LABEL = "Go back";
20
+
21
+ interface DropDrawerContextValue {
22
+ isMobile: boolean;
23
+ }
27
24
 
28
- const useDropDrawerContext = () => {
25
+ const DropDrawerContext = React.createContext<DropDrawerContextValue | null>(null);
26
+
27
+ const useDropDrawerContext = (): DropDrawerContextValue => {
29
28
  const context = React.useContext(DropDrawerContext);
30
- if (!context) {
29
+
30
+ if (context === null) {
31
31
  throw new Error("DropDrawer components cannot be rendered outside the Context");
32
32
  }
33
+
33
34
  return context;
34
35
  };
35
36
 
36
- function DropDrawer({children, ...props}: React.ComponentProps<typeof Drawer> | React.ComponentProps<typeof DropdownMenu>) {
37
+ const Drawer = BaseDrawer.Root;
38
+ const DrawerPortal = BaseDrawer.Portal;
39
+
40
+ const DrawerTrigger = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<typeof BaseDrawer.Trigger> & {asChild?: boolean}>(
41
+ function DrawerTrigger(props, forwardedRef) {
42
+ const {asChild = false, children, className, render, ...otherProps} = props;
43
+ const renderProp = asChild && React.isValidElement(children) ? children : render;
44
+
45
+ return (
46
+ <BaseDrawer.Trigger
47
+ {...otherProps}
48
+ ref={forwardedRef}
49
+ render={useRender({
50
+ defaultTagName: "button",
51
+ render: renderProp as never,
52
+ props: mergeProps({className}, {}),
53
+ })}>
54
+ {renderProp ? undefined : children}
55
+ </BaseDrawer.Trigger>
56
+ );
57
+ },
58
+ );
59
+
60
+ function DrawerOverlay(props: Readonly<React.ComponentPropsWithRef<typeof BaseDrawer.Backdrop>>): React.ReactElement {
61
+ const {className, render, ...otherProps} = props;
62
+
63
+ return (
64
+ <BaseDrawer.Backdrop
65
+ {...otherProps}
66
+ render={useRender({
67
+ defaultTagName: "div",
68
+ render: render as never,
69
+ props: mergeProps({className: cn(styles.drawerOverlay, className)}, {}),
70
+ })}
71
+ />
72
+ );
73
+ }
74
+
75
+ const DrawerContent = React.forwardRef<HTMLDivElement, React.ComponentPropsWithRef<typeof BaseDrawer.Popup> & {children?: React.ReactNode}>(
76
+ function DrawerContent(props, forwardedRef) {
77
+ const {className, children, render, ...otherProps} = props;
78
+
79
+ return (
80
+ <DrawerPortal>
81
+ <DrawerOverlay />
82
+ <BaseDrawer.Viewport className={styles.drawerViewport}>
83
+ <BaseDrawer.Popup
84
+ {...otherProps}
85
+ ref={forwardedRef}
86
+ render={useRender({
87
+ defaultTagName: "div",
88
+ render: render as never,
89
+ props: mergeProps({className: cn(styles.drawerContent, className)}, {}),
90
+ })}>
91
+ <div className={styles.drawerHandle} />
92
+ <BaseDrawer.Content className={styles.drawerInnerContent}>{children}</BaseDrawer.Content>
93
+ </BaseDrawer.Popup>
94
+ </BaseDrawer.Viewport>
95
+ </DrawerPortal>
96
+ );
97
+ },
98
+ );
99
+
100
+ function DrawerHeader(
101
+ props: Readonly<React.ComponentPropsWithRef<"div"> & {render?: useRender.RenderProp<Record<string, never>>}>,
102
+ ): React.ReactElement {
103
+ const {className, children, render, ...otherProps} = props;
104
+
105
+ return useRender({
106
+ defaultTagName: "div",
107
+ render: render as never,
108
+ props: mergeProps({className: cn(styles.drawerHeader, className)}, otherProps, {children}),
109
+ });
110
+ }
111
+
112
+ function DrawerFooter(
113
+ props: Readonly<React.ComponentPropsWithRef<"div"> & {render?: useRender.RenderProp<Record<string, never>>}>,
114
+ ): React.ReactElement {
115
+ const {className, children, render, ...otherProps} = props;
116
+
117
+ return useRender({
118
+ defaultTagName: "div",
119
+ render: render as never,
120
+ props: mergeProps({className: cn(styles.drawerFooter, className)}, otherProps, {children}),
121
+ });
122
+ }
123
+
124
+ function DrawerTitle(props: Readonly<React.ComponentPropsWithRef<typeof BaseDrawer.Title>>): React.ReactElement {
125
+ const {className, children, render, ...otherProps} = props;
126
+
127
+ return (
128
+ <BaseDrawer.Title
129
+ {...otherProps}
130
+ render={useRender({
131
+ defaultTagName: "h2",
132
+ render: render as never,
133
+ props: mergeProps({className: cn(styles.drawerTitle, className)}, {}),
134
+ })}>
135
+ {children}
136
+ </BaseDrawer.Title>
137
+ );
138
+ }
139
+
140
+ const DropdownMenu = BaseMenu.Root;
141
+ const DropdownMenuSub = BaseMenu.SubmenuRoot;
142
+
143
+ const DropdownMenuTrigger = React.forwardRef<HTMLButtonElement, React.ComponentPropsWithRef<typeof BaseMenu.Trigger> & {asChild?: boolean}>(
144
+ function DropdownMenuTrigger(props, forwardedRef) {
145
+ const {asChild = false, children, className, render, ...otherProps} = props;
146
+ const renderProp = asChild && React.isValidElement(children) ? children : render;
147
+
148
+ return (
149
+ <BaseMenu.Trigger
150
+ {...otherProps}
151
+ ref={forwardedRef}
152
+ render={useRender({
153
+ defaultTagName: "button",
154
+ render: renderProp as never,
155
+ props: mergeProps({className}, {}),
156
+ })}>
157
+ {renderProp ? undefined : children}
158
+ </BaseMenu.Trigger>
159
+ );
160
+ },
161
+ );
162
+
163
+ const DropdownMenuContent = React.forwardRef<
164
+ HTMLDivElement,
165
+ React.ComponentPropsWithRef<typeof BaseMenu.Positioner> & {children?: React.ReactNode}
166
+ >(function DropdownMenuContent(props, forwardedRef) {
167
+ const {className, children, render, ...otherProps} = props;
168
+
169
+ return (
170
+ <BaseMenu.Portal>
171
+ <BaseMenu.Positioner
172
+ {...otherProps}
173
+ ref={forwardedRef}
174
+ render={useRender({
175
+ defaultTagName: "div",
176
+ props: mergeProps({className: styles.dropdownPositioner}, {}),
177
+ })}>
178
+ <BaseMenu.Popup
179
+ render={useRender({
180
+ defaultTagName: "div",
181
+ render: render as never,
182
+ props: mergeProps({className: cn(styles.dropdownContent, className)}, {}),
183
+ })}>
184
+ {children}
185
+ </BaseMenu.Popup>
186
+ </BaseMenu.Positioner>
187
+ </BaseMenu.Portal>
188
+ );
189
+ });
190
+
191
+ interface DropdownMenuItemProps extends React.ComponentPropsWithRef<typeof BaseMenu.Item> {
192
+ /** @deprecated Prefer Base UI's `render` prop. */
193
+ asChild?: boolean;
194
+ /**
195
+ * Whether to apply inset spacing to align with grouped menu content.
196
+ * @default false
197
+ */
198
+ inset?: boolean;
199
+ }
200
+
201
+ function DropdownMenuItem(props: Readonly<DropdownMenuItemProps>): React.ReactElement {
202
+ // eslint-disable-next-line sonarjs/deprecation -- backward-compatible asChild API
203
+ const {asChild = false, children, className, inset = false, render, ...otherProps} = props;
204
+ const renderProp = asChild && React.isValidElement(children) ? children : render;
205
+
206
+ return (
207
+ <BaseMenu.Item
208
+ {...otherProps}
209
+ render={useRender({
210
+ defaultTagName: "div",
211
+ render: renderProp as never,
212
+ props: mergeProps({className: cn(styles.desktopItem, inset && styles.inset, className)}, {}),
213
+ })}>
214
+ {renderProp ? undefined : children}
215
+ </BaseMenu.Item>
216
+ );
217
+ }
218
+
219
+ function DropdownMenuLabel(props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.GroupLabel>>): React.ReactElement {
220
+ const {className, children, render, ...otherProps} = props;
221
+
222
+ return (
223
+ <BaseMenu.GroupLabel
224
+ {...otherProps}
225
+ render={useRender({
226
+ defaultTagName: "div",
227
+ render: render as never,
228
+ props: mergeProps({className: cn(styles.desktopLabel, className)}, {}),
229
+ })}>
230
+ {children}
231
+ </BaseMenu.GroupLabel>
232
+ );
233
+ }
234
+
235
+ function DropdownMenuSeparator(props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.Separator>>): React.ReactElement {
236
+ const {className, render, ...otherProps} = props;
237
+
238
+ return (
239
+ <BaseMenu.Separator
240
+ {...otherProps}
241
+ render={useRender({
242
+ defaultTagName: "div",
243
+ render: render as never,
244
+ props: mergeProps({className: cn(styles.desktopSeparator, className)}, {}),
245
+ })}
246
+ />
247
+ );
248
+ }
249
+
250
+ function DropdownMenuSubTrigger(
251
+ props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.SubmenuTrigger> & {inset?: boolean}>,
252
+ ): React.ReactElement {
253
+ const {className, children, inset = false, render, ...otherProps} = props;
254
+
255
+ return (
256
+ <BaseMenu.SubmenuTrigger
257
+ {...otherProps}
258
+ render={useRender({
259
+ defaultTagName: "div",
260
+ render: render as never,
261
+ props: mergeProps({className: cn(styles.desktopSubTrigger, inset && styles.inset, className)}, {}),
262
+ })}>
263
+ {children}
264
+ <ChevronRightIcon className={styles.chevron} />
265
+ </BaseMenu.SubmenuTrigger>
266
+ );
267
+ }
268
+
269
+ function DropdownMenuSubContent(
270
+ props: Readonly<React.ComponentPropsWithRef<typeof BaseMenu.Positioner> & {children?: React.ReactNode}>,
271
+ ): React.ReactElement {
272
+ const {className, children, render, ...otherProps} = props;
273
+
274
+ return (
275
+ <BaseMenu.Positioner
276
+ {...otherProps}
277
+ render={useRender({
278
+ defaultTagName: "div",
279
+ props: mergeProps({className: styles.dropdownPositioner}, {}),
280
+ })}>
281
+ <BaseMenu.Popup
282
+ render={useRender({
283
+ defaultTagName: "div",
284
+ render: render as never,
285
+ props: mergeProps({className: cn(styles.dropdownSubContent, className)}, {}),
286
+ })}>
287
+ {children}
288
+ </BaseMenu.Popup>
289
+ </BaseMenu.Positioner>
290
+ );
291
+ }
292
+
293
+ type DropDrawerRootProps = React.ComponentProps<typeof Drawer> | React.ComponentProps<typeof DropdownMenu>;
294
+ type DropDrawerTriggerProps =
295
+ | React.ComponentPropsWithoutRef<typeof DrawerTrigger>
296
+ | React.ComponentPropsWithoutRef<typeof DropdownMenuTrigger>;
297
+ type DropDrawerContentProps =
298
+ | React.ComponentPropsWithoutRef<typeof DrawerContent>
299
+ | React.ComponentPropsWithoutRef<typeof DropdownMenuContent>;
300
+
301
+ interface MobileSubmenuDataAttributes {
302
+ "data-parent-submenu-id"?: string;
303
+ "data-parent-submenu"?: string;
304
+ "data-submenu-id"?: string;
305
+ }
306
+
307
+ interface SharedDropDrawerItemProps
308
+ extends Omit<React.ComponentPropsWithoutRef<typeof BaseMenu.Item>, "children" | "onClick" | "onSelect">, MobileSubmenuDataAttributes {
309
+ /**
310
+ * Item contents.
311
+ * @default undefined
312
+ */
313
+ children?: React.ReactNode;
314
+ /**
315
+ * Additional CSS classes merged with the item styles.
316
+ * @default undefined
317
+ */
318
+ className?: string;
319
+ /**
320
+ * Whether the desktop dropdown should close after the item is activated.
321
+ * @default undefined
322
+ */
323
+ closeOnClick?: boolean;
324
+ /**
325
+ * Optional trailing icon or affordance rendered alongside the item content.
326
+ * @default undefined
327
+ */
328
+ icon?: React.ReactNode;
329
+ /**
330
+ * Whether to apply inset spacing to align the item with grouped content.
331
+ * @default undefined
332
+ */
333
+ inset?: boolean;
334
+ /**
335
+ * Mouse click handler invoked when the item is activated.
336
+ * @default undefined
337
+ */
338
+ onClick?: React.MouseEventHandler<HTMLElement>;
339
+ /**
340
+ * Selection callback invoked with the native event when the item is activated.
341
+ * @default undefined
342
+ */
343
+ onSelect?: (event: Event) => void;
344
+ }
345
+
346
+ interface SubmenuContextType {
347
+ activeSubmenu: string | null;
348
+ navigateToSubmenu?: (id: string, title: string) => void;
349
+ registerSubmenuContent?: (id: string, content: ReadonlyArray<React.ReactNode>) => void;
350
+ setActiveSubmenu: (id: string | null) => void;
351
+ setSubmenuTitle: (title: string | null) => void;
352
+ submenuTitle: string | null;
353
+ }
354
+
355
+ const SubmenuContext = React.createContext<SubmenuContextType>({
356
+ activeSubmenu: null,
357
+ navigateToSubmenu: undefined,
358
+ registerSubmenuContent: undefined,
359
+ setActiveSubmenu: () => undefined,
360
+ setSubmenuTitle: () => undefined,
361
+ submenuTitle: null,
362
+ });
363
+
364
+ /**
365
+ * Provides a responsive dropdown-on-desktop, drawer-on-mobile navigation surface.
366
+ *
367
+ * @remarks
368
+ * - Renders either Base UI `Menu.Root` or `Drawer.Root` depending on viewport size
369
+ * - Built on Base UI Menu and Drawer primitives
370
+ *
371
+ * @example
372
+ * ```tsx
373
+ * <DropDrawer>
374
+ * <DropDrawerTrigger>Open menu</DropDrawerTrigger>
375
+ * <DropDrawerContent>
376
+ * <DropDrawerItem>Profile</DropDrawerItem>
377
+ * </DropDrawerContent>
378
+ * </DropDrawer>
379
+ * ```
380
+ *
381
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
382
+ */
383
+ function DropDrawer({children, ...props}: DropDrawerRootProps): React.JSX.Element {
37
384
  const isMobile = useIsMobile();
38
- const DropdownComponent = isMobile ? Drawer : DropdownMenu;
39
385
 
40
386
  return (
41
387
  <DropDrawerContext.Provider value={{isMobile}}>
42
- <DropdownComponent
43
- data-slot='drop-drawer'
44
- {...(isMobile && {autoFocus: true})}
45
- {...props}>
46
- {children}
47
- </DropdownComponent>
388
+ {isMobile ? (
389
+ <Drawer
390
+ data-slot='drop-drawer'
391
+ {...(props as React.ComponentProps<typeof Drawer>)}>
392
+ {children}
393
+ </Drawer>
394
+ ) : (
395
+ <DropdownMenu
396
+ data-slot='drop-drawer'
397
+ {...(props as React.ComponentProps<typeof DropdownMenu>)}>
398
+ {children}
399
+ </DropdownMenu>
400
+ )}
48
401
  </DropDrawerContext.Provider>
49
402
  );
50
403
  }
51
404
 
52
- function DropDrawerTrigger({
53
- className,
54
- children,
55
- ...props
56
- }: React.ComponentProps<typeof DrawerTrigger> | React.ComponentProps<typeof DropdownMenuTrigger>) {
405
+ /**
406
+ * Renders the control that opens the dropdown or drawer surface.
407
+ *
408
+ * @remarks
409
+ * - Renders either a Base UI menu trigger or drawer trigger
410
+ * - Built on Base UI Menu and Drawer primitives
411
+ *
412
+ * @example
413
+ * ```tsx
414
+ * <DropDrawerTrigger>Open menu</DropDrawerTrigger>
415
+ * ```
416
+ *
417
+ * @see {@link https://base-ui.com/react/components/drawer | Base UI Drawer Docs}
418
+ */
419
+ const DropDrawerTrigger = React.forwardRef<HTMLButtonElement, DropDrawerTriggerProps>(function DropDrawerTrigger(
420
+ {className, children, ...props},
421
+ forwardedRef,
422
+ ) {
57
423
  const {isMobile} = useDropDrawerContext();
58
- const TriggerComponent = isMobile ? DrawerTrigger : DropdownMenuTrigger;
59
424
 
60
- return (
61
- <TriggerComponent
425
+ return isMobile ? (
426
+ <DrawerTrigger
427
+ ref={forwardedRef}
62
428
  data-slot='drop-drawer-trigger'
63
429
  className={className}
64
- {...props}>
430
+ {...(props as React.ComponentProps<typeof DrawerTrigger>)}>
65
431
  {children}
66
- </TriggerComponent>
432
+ </DrawerTrigger>
433
+ ) : (
434
+ <DropdownMenuTrigger
435
+ ref={forwardedRef}
436
+ data-slot='drop-drawer-trigger'
437
+ className={className}
438
+ {...(props as React.ComponentProps<typeof DropdownMenuTrigger>)}>
439
+ {children}
440
+ </DropdownMenuTrigger>
67
441
  );
68
- }
442
+ });
69
443
 
70
- function DropDrawerContent({
71
- className,
72
- children,
73
- ...props
74
- }: React.ComponentProps<typeof DrawerContent> | React.ComponentProps<typeof DropdownMenuContent>) {
444
+ /**
445
+ * Renders the responsive dropdown or drawer content surface.
446
+ *
447
+ * @remarks
448
+ * - Renders a Base UI popup on desktop and drawer content on mobile
449
+ * - Built on Base UI Menu and Drawer primitives with animated mobile submenu navigation
450
+ *
451
+ * @example
452
+ * ```tsx
453
+ * <DropDrawerContent>
454
+ * <DropDrawerItem>Settings</DropDrawerItem>
455
+ * </DropDrawerContent>
456
+ * ```
457
+ *
458
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
459
+ */
460
+ const DropDrawerContent = React.forwardRef<HTMLDivElement, DropDrawerContentProps>(function DropDrawerContent(
461
+ {className, children, ...props},
462
+ forwardedRef,
463
+ ) {
75
464
  const {isMobile} = useDropDrawerContext();
76
465
  const [activeSubmenu, setActiveSubmenu] = React.useState<string | null>(null);
77
466
  const [submenuTitle, setSubmenuTitle] = React.useState<string | null>(null);
78
- const [submenuStack, setSubmenuStack] = React.useState<{id: string; title: string}[]>([]);
79
- // Add animation direction state
467
+ const [submenuStack, setSubmenuStack] = React.useState<ReadonlyArray<{id: string; title: string}>>([]);
80
468
  const [animationDirection, setAnimationDirection] = React.useState<"forward" | "backward">("forward");
469
+ const submenuContentRef = React.useRef(new Map<string, ReadonlyArray<React.ReactNode>>());
81
470
 
82
- // Create a ref to store submenu content by ID
83
- const submenuContentRef = React.useRef<Map<string, React.ReactNode[]>>(new Map());
471
+ React.useEffect(() => {
472
+ submenuContentRef.current.clear();
473
+ }, [children]);
84
474
 
85
- // Function to navigate to a submenu
86
- const navigateToSubmenu = React.useCallback((id: string, title: string) => {
87
- // Set animation direction to forward when navigating to a submenu
475
+ const navigateToSubmenu = React.useCallback((id: string, title: string): void => {
88
476
  setAnimationDirection("forward");
89
477
  setActiveSubmenu(id);
90
478
  setSubmenuTitle(title);
91
- setSubmenuStack((prev) => [...prev, {id, title}]);
479
+ setSubmenuStack((previousStack) => [...previousStack, {id, title}]);
92
480
  }, []);
93
481
 
94
- // Function to go back to previous menu
95
- const goBack = React.useCallback(() => {
96
- // Set animation direction to backward when going back
482
+ const goBack = React.useCallback((): void => {
97
483
  setAnimationDirection("backward");
98
484
 
99
485
  if (submenuStack.length <= 1) {
100
- // If we're at the first level, go back to main menu
101
486
  setActiveSubmenu(null);
102
487
  setSubmenuTitle(null);
103
488
  setSubmenuStack([]);
104
- } else {
105
- // Go back to previous submenu
106
- const newStack = [...submenuStack];
107
- newStack.pop(); // Remove current
108
- const previous = newStack[newStack.length - 1];
109
- setActiveSubmenu(previous.id);
110
- setSubmenuTitle(previous.title);
111
- setSubmenuStack(newStack);
489
+ return;
490
+ }
491
+
492
+ const newStack = [...submenuStack];
493
+ newStack.pop();
494
+ const previousSubmenu = newStack[newStack.length - 1];
495
+
496
+ if (!previousSubmenu) {
497
+ setActiveSubmenu(null);
498
+ setSubmenuTitle(null);
499
+ setSubmenuStack([]);
500
+ return;
112
501
  }
502
+
503
+ setActiveSubmenu(previousSubmenu.id);
504
+ setSubmenuTitle(previousSubmenu.title);
505
+ setSubmenuStack(newStack);
113
506
  }, [submenuStack]);
114
507
 
115
- // Function to register submenu content
116
- const registerSubmenuContent = React.useCallback((id: string, content: React.ReactNode[]) => {
508
+ const registerSubmenuContent = React.useCallback((id: string, content: ReadonlyArray<React.ReactNode>): void => {
117
509
  submenuContentRef.current.set(id, content);
118
510
  }, []);
119
511
 
120
- // Function to extract submenu content
121
- const extractSubmenuContent = React.useCallback((elements: React.ReactNode, targetId: string): React.ReactNode[] => {
122
- const result: React.ReactNode[] = [];
512
+ const extractSubmenuContent = React.useCallback((elements: React.ReactNode, targetId: string): ReadonlyArray<React.ReactNode> => {
513
+ const result: Array<React.ReactNode> = [];
123
514
 
124
- // Recursive function to search through all children
125
- const findSubmenuContent = (node: React.ReactNode) => {
126
- // Skip if not a valid element
127
- if (!React.isValidElement(node)) return;
515
+ const findSubmenuContent = (node: React.ReactNode): void => {
516
+ if (!React.isValidElement(node)) {
517
+ return;
518
+ }
128
519
 
129
- const element = node as React.ReactElement;
130
- // Use a more specific type to avoid 'any'
131
- const props = element.props as {
132
- id?: string;
520
+ const element = node as React.ReactElement<{
133
521
  "data-submenu-id"?: string;
134
522
  children?: React.ReactNode;
135
- };
523
+ id?: string;
524
+ }>;
136
525
 
137
- // Check if this is a DropDrawerSub
138
526
  if (element.type === DropDrawerSub) {
139
- // Get all possible ID values
140
- const elementId = props.id;
141
- const dataSubmenuId = props["data-submenu-id"];
527
+ const elementId = element.props.id;
528
+ const dataSubmenuId = element.props["data-submenu-id"];
142
529
 
143
- // If this is the submenu we're looking for
144
530
  if (elementId === targetId || dataSubmenuId === targetId) {
145
- // Find the SubContent within this Sub
146
- if (props.children) {
147
- React.Children.forEach(props.children, (child) => {
531
+ if (element.props.children) {
532
+ React.Children.forEach(element.props.children, (child) => {
148
533
  if (React.isValidElement(child) && child.type === DropDrawerSubContent) {
149
- // Add all children of the SubContent to the result
150
- const subContentProps = child.props as {
151
- children?: React.ReactNode;
152
- };
153
- if (subContentProps.children) {
154
- React.Children.forEach(subContentProps.children, (contentChild) => {
155
- result.push(contentChild);
156
- });
157
- }
534
+ const subContentElement = child as React.ReactElement<{children?: React.ReactNode}>;
535
+
536
+ React.Children.forEach(subContentElement.props.children, (contentChild) => {
537
+ result.push(contentChild);
538
+ });
158
539
  }
159
540
  });
160
541
  }
161
- return; // Found what we needed, no need to search deeper
542
+
543
+ return;
162
544
  }
163
545
  }
164
546
 
165
- // If this element has children, search through them
166
- if (props.children) {
167
- if (Array.isArray(props.children)) {
168
- props.children.forEach((child: React.ReactNode) => findSubmenuContent(child));
169
- } else {
170
- findSubmenuContent(props.children);
171
- }
547
+ if (element.props.children) {
548
+ React.Children.forEach(element.props.children, findSubmenuContent);
172
549
  }
173
550
  };
174
551
 
175
- // Start the search from the root elements
176
- if (Array.isArray(elements)) {
177
- elements.forEach((child) => findSubmenuContent(child));
178
- } else {
179
- findSubmenuContent(elements);
180
- }
181
-
552
+ React.Children.forEach(elements, findSubmenuContent);
182
553
  return result;
183
554
  }, []);
184
555
 
185
- // Get submenu content (either from cache or extract it)
186
556
  const getSubmenuContent = React.useCallback(
187
- (id: string) => {
188
- // Check if we have the content in our ref
189
- const cachedContent = submenuContentRef.current.get(id || "");
557
+ (id: string): ReadonlyArray<React.ReactNode> => {
558
+ const cachedContent = submenuContentRef.current.get(id);
559
+
190
560
  if (cachedContent && cachedContent.length > 0) {
191
561
  return cachedContent;
192
562
  }
193
563
 
194
- // If not in cache, extract it
195
564
  const submenuContent = extractSubmenuContent(children, id);
196
565
 
197
- if (submenuContent.length === 0) {
198
- return [];
199
- }
200
-
201
- // Store in cache for future use
202
- if (id) {
566
+ if (submenuContent.length > 0) {
203
567
  submenuContentRef.current.set(id, submenuContent);
204
568
  }
205
569
 
@@ -208,26 +572,24 @@ function DropDrawerContent({
208
572
  [children, extractSubmenuContent],
209
573
  );
210
574
 
211
- // Animation variants for Framer Motion
212
575
  const variants = {
213
- enter: (direction: "forward" | "backward") => ({
214
- x: direction === "forward" ? "100%" : "-100%",
215
- opacity: 0,
216
- }),
217
576
  center: {
218
- x: 0,
219
577
  opacity: 1,
578
+ x: 0,
220
579
  },
580
+ enter: (direction: "forward" | "backward") => ({
581
+ opacity: 0,
582
+ x: direction === "forward" ? "100%" : "-100%",
583
+ }),
221
584
  exit: (direction: "forward" | "backward") => ({
222
- x: direction === "forward" ? "-100%" : "100%",
223
585
  opacity: 0,
586
+ x: direction === "forward" ? "-100%" : "100%",
224
587
  }),
225
588
  };
226
589
 
227
- // Animation transition
228
590
  const transition = {
229
591
  duration: 0.3,
230
- ease: [0.25, 0.1, 0.25, 1.0], // cubic-bezier easing
592
+ ease: [0.25, 0.1, 0.25, 1],
231
593
  } satisfies Transition;
232
594
 
233
595
  if (isMobile) {
@@ -235,6 +597,8 @@ function DropDrawerContent({
235
597
  <SubmenuContext.Provider
236
598
  value={{
237
599
  activeSubmenu,
600
+ navigateToSubmenu,
601
+ registerSubmenuContent,
238
602
  setActiveSubmenu: (id) => {
239
603
  if (id === null) {
240
604
  setActiveSubmenu(null);
@@ -242,53 +606,53 @@ function DropDrawerContent({
242
606
  setSubmenuStack([]);
243
607
  }
244
608
  },
245
- submenuTitle,
246
609
  setSubmenuTitle,
247
- navigateToSubmenu,
248
- registerSubmenuContent,
610
+ submenuTitle,
249
611
  }}>
250
612
  <DrawerContent
613
+ ref={forwardedRef}
251
614
  data-slot='drop-drawer-content'
252
- className={cn("max-h-[90vh]", className)}
253
- {...props}>
615
+ className={cn(styles.mobileContent, className)}
616
+ {...(props as React.ComponentProps<typeof DrawerContent>)}>
254
617
  {activeSubmenu ? (
255
618
  <>
256
619
  <DrawerHeader>
257
- <div className='flex items-center gap-2'>
620
+ <div className={styles.mobileHeaderRow}>
258
621
  <button
622
+ type='button'
623
+ aria-label={MOBILE_BACK_LABEL}
259
624
  onClick={goBack}
260
- className='rounded-full p-1 hover:bg-neutral-100/50 dark:hover:bg-neutral-800/50'>
261
- <ChevronLeftIcon className='h-5 w-5' />
625
+ className={styles.backButton}>
626
+ <ChevronLeftIcon className={styles.chevron} />
262
627
  </button>
263
- <DrawerTitle>{submenuTitle || "Submenu"}</DrawerTitle>
628
+ <DrawerTitle>{submenuTitle || MOBILE_SUBMENU_TITLE}</DrawerTitle>
264
629
  </div>
265
630
  </DrawerHeader>
266
- <div className='relative max-h-[70vh] flex-1 overflow-y-auto'>
267
- {/* Use AnimatePresence to handle exit animations */}
631
+ <div className={styles.mobileViewport}>
268
632
  <AnimatePresence
269
633
  initial={false}
270
634
  mode='wait'
271
635
  custom={animationDirection}>
272
636
  <motion.div
273
- key={activeSubmenu || "main"}
637
+ key={activeSubmenu}
274
638
  custom={animationDirection}
275
639
  variants={variants}
276
640
  initial='enter'
277
641
  animate='center'
278
642
  exit='exit'
279
643
  transition={transition}
280
- className='h-full w-full space-y-1.5 pb-6'>
281
- {activeSubmenu ? getSubmenuContent(activeSubmenu) : children}
644
+ className={styles.mobileMotionPanel}>
645
+ {getSubmenuContent(activeSubmenu)}
282
646
  </motion.div>
283
647
  </AnimatePresence>
284
648
  </div>
285
649
  </>
286
650
  ) : (
287
651
  <>
288
- <DrawerHeader className='sr-only'>
289
- <DrawerTitle>Menu</DrawerTitle>
652
+ <DrawerHeader className={styles.screenReaderOnlyHeader}>
653
+ <DrawerTitle>{MOBILE_MENU_TITLE}</DrawerTitle>
290
654
  </DrawerHeader>
291
- <div className='max-h-[70vh] overflow-y-auto'>
655
+ <div className={styles.mobileMainViewport}>
292
656
  <AnimatePresence
293
657
  initial={false}
294
658
  mode='wait'
@@ -301,7 +665,7 @@ function DropDrawerContent({
301
665
  animate='center'
302
666
  exit='exit'
303
667
  transition={transition}
304
- className='w-full space-y-1.5 pb-6'>
668
+ className={styles.mobileMotionPanel}>
305
669
  {children}
306
670
  </motion.div>
307
671
  </AnimatePresence>
@@ -317,141 +681,203 @@ function DropDrawerContent({
317
681
  <SubmenuContext.Provider
318
682
  value={{
319
683
  activeSubmenu,
684
+ registerSubmenuContent,
320
685
  setActiveSubmenu,
321
- submenuTitle,
322
686
  setSubmenuTitle,
323
- registerSubmenuContent,
687
+ submenuTitle,
324
688
  }}>
325
689
  <DropdownMenuContent
690
+ ref={forwardedRef}
326
691
  data-slot='drop-drawer-content'
327
692
  align='end'
328
693
  sideOffset={4}
329
- className={cn("max-h-[var(--radix-dropdown-menu-content-available-height)] min-w-[220px] overflow-y-auto", className)}
330
- {...props}>
694
+ className={cn(styles.desktopContent, className)}
695
+ {...(props as React.ComponentProps<typeof DropdownMenuContent>)}>
331
696
  {children}
332
697
  </DropdownMenuContent>
333
698
  </SubmenuContext.Provider>
334
699
  );
335
- }
700
+ });
336
701
 
702
+ /**
703
+ * Renders an actionable item inside the drop drawer surface.
704
+ *
705
+ * @remarks
706
+ * - Renders a Base UI menu item on desktop and a keyboard-accessible `<div>` on mobile
707
+ * - Built on Base UI Menu and Drawer close primitives
708
+ *
709
+ * @example
710
+ * ```tsx
711
+ * <DropDrawerItem icon={<ChevronRightIcon />}>Account</DropDrawerItem>
712
+ * ```
713
+ *
714
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
715
+ */
337
716
  function DropDrawerItem({
338
717
  className,
339
718
  children,
340
- onSelect,
341
- onClick,
719
+ closeOnClick,
720
+ disabled,
342
721
  icon,
343
722
  inset,
344
- disabled,
723
+ onClick,
724
+ onSelect,
345
725
  ...props
346
- }: React.ComponentProps<typeof DropdownMenuItem> & {
347
- icon?: React.ReactNode;
348
- }) {
726
+ }: SharedDropDrawerItemProps): React.JSX.Element {
349
727
  const {isMobile} = useDropDrawerContext();
350
728
 
351
- // Define hooks outside of conditionals to follow React rules
352
- // Check if this item is inside a group by looking at parent elements
353
729
  const isInGroup = React.useCallback((element: HTMLElement | null): boolean => {
354
- if (!element) return false;
730
+ if (!element) {
731
+ return false;
732
+ }
355
733
 
356
- // Check if any parent has a data-drop-drawer-group attribute
357
734
  let parent = element.parentElement;
735
+
358
736
  while (parent) {
359
737
  if (parent.hasAttribute("data-drop-drawer-group")) {
360
738
  return true;
361
739
  }
740
+
362
741
  parent = parent.parentElement;
363
742
  }
743
+
364
744
  return false;
365
745
  }, []);
366
746
 
367
- // Create a ref to check if the item is in a group
368
747
  const itemRef = React.useRef<HTMLDivElement>(null);
369
748
  const [isInsideGroup, setIsInsideGroup] = React.useState(false);
370
749
 
371
750
  React.useEffect(() => {
372
- // Only run this effect in mobile mode
373
- if (!isMobile) return;
751
+ if (!isMobile) {
752
+ return;
753
+ }
374
754
 
375
- // Use a short timeout to ensure the DOM is fully rendered
376
- const timer = setTimeout(() => {
755
+ const timer = globalThis.window.setTimeout(() => {
377
756
  if (itemRef.current) {
378
757
  setIsInsideGroup(isInGroup(itemRef.current));
379
758
  }
380
759
  }, 0);
381
760
 
382
- return () => clearTimeout(timer);
761
+ return () => globalThis.window.clearTimeout(timer);
383
762
  }, [isInGroup, isMobile]);
384
763
 
764
+ const handleSelect = React.useCallback(
765
+ (event: Event): void => {
766
+ if (!disabled) {
767
+ onSelect?.(event);
768
+ }
769
+ },
770
+ [disabled, onSelect],
771
+ );
772
+
385
773
  if (isMobile) {
386
- const handleClick = (e: React.MouseEvent<HTMLDivElement>) => {
387
- if (disabled) return;
388
- if (onClick) onClick(e);
389
- if (onSelect) onSelect(e as unknown as Event);
774
+ const handleClick: React.MouseEventHandler<HTMLDivElement> = (event): void => {
775
+ if (disabled) {
776
+ return;
777
+ }
778
+
779
+ onClick?.(event);
780
+ handleSelect(event.nativeEvent);
781
+ };
782
+
783
+ const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event): void => {
784
+ if (event.key !== "Enter" && event.key !== " ") {
785
+ return;
786
+ }
787
+
788
+ event.preventDefault();
789
+ event.currentTarget.click();
390
790
  };
391
791
 
392
- // Only wrap in DrawerClose if it's not a submenu item
393
792
  const content = (
394
793
  <div
395
794
  ref={itemRef}
396
795
  data-slot='drop-drawer-item'
397
- data-inset={inset}
398
796
  data-disabled={disabled}
797
+ data-inset={inset}
798
+ role='menuitem'
799
+ tabIndex={disabled ? -1 : 0}
399
800
  className={cn(
400
- "flex cursor-pointer items-center justify-between px-4 py-4",
401
- // Only apply margin, background and rounded corners if not in a group
402
- !isInsideGroup && "mx-2 my-1.5 rounded-md bg-neutral-100 dark:bg-neutral-100 dark:bg-neutral-800 dark:dark:bg-neutral-800",
403
- // For items in a group, don't add background but add more padding
404
- isInsideGroup && "bg-transparent py-4",
405
- inset && "pl-8",
406
- disabled && "pointer-events-none opacity-50",
801
+ styles.mobileItem,
802
+ !isInsideGroup && styles.mobileStandaloneItem,
803
+ isInsideGroup && styles.mobileGroupedItem,
804
+ inset && styles.inset,
407
805
  className,
408
806
  )}
409
807
  onClick={handleClick}
808
+ onKeyDown={handleKeyDown}
410
809
  aria-disabled={disabled}
411
810
  {...props}>
412
- <div className='flex items-center gap-2'>{children}</div>
413
- {icon && <div className='flex-shrink-0'>{icon}</div>}
811
+ <div className={styles.itemChildren}>{children}</div>
812
+ {icon ? <div className={styles.itemIcon}>{icon}</div> : null}
414
813
  </div>
415
814
  );
416
815
 
417
- // Check if this is inside a submenu
418
- const isInSubmenu =
419
- (props as Record<string, unknown>)["data-parent-submenu-id"] || (props as Record<string, unknown>)["data-parent-submenu"];
816
+ const parentSubmenuId = props["data-parent-submenu-id"] ?? props["data-parent-submenu"];
420
817
 
421
- if (isInSubmenu) {
818
+ if (parentSubmenuId) {
422
819
  return content;
423
820
  }
424
821
 
425
- return <DrawerClose asChild>{content}</DrawerClose>;
822
+ return (
823
+ <BaseDrawer.Close
824
+ nativeButton={false}
825
+ render={content}
826
+ />
827
+ );
426
828
  }
427
829
 
830
+ const handleDesktopClick: React.MouseEventHandler<HTMLElement> = (event): void => {
831
+ if (disabled) {
832
+ return;
833
+ }
834
+
835
+ onClick?.(event);
836
+ handleSelect(event.nativeEvent);
837
+ };
838
+
428
839
  return (
429
840
  <DropdownMenuItem
430
841
  data-slot='drop-drawer-item'
431
842
  data-inset={inset}
432
- className={className}
433
- onSelect={onSelect}
434
- onClick={onClick as React.MouseEventHandler<HTMLDivElement>}
435
- inset={inset}
843
+ className={cn(styles.desktopItem, className)}
844
+ closeOnClick={closeOnClick}
436
845
  disabled={disabled}
846
+ inset={inset}
847
+ onClick={handleDesktopClick}
437
848
  {...props}>
438
- <div className='flex w-full items-center justify-between'>
439
- <div>{children}</div>
440
- {icon && <div>{icon}</div>}
849
+ <div className={styles.itemRow}>
850
+ <div className={styles.itemChildren}>{children}</div>
851
+ {icon ? <div className={styles.itemIcon}>{icon}</div> : null}
441
852
  </div>
442
853
  </DropdownMenuItem>
443
854
  );
444
855
  }
445
856
 
446
- function DropDrawerSeparator({className, ...props}: React.ComponentProps<typeof DropdownMenuSeparator>) {
857
+ /**
858
+ * Renders a visual separator between desktop drop drawer sections.
859
+ *
860
+ * @remarks
861
+ * - Renders a separator only in desktop dropdown mode
862
+ * - Built on Base UI Menu separator primitives
863
+ *
864
+ * @example
865
+ * ```tsx
866
+ * <DropDrawerSeparator />
867
+ * ```
868
+ *
869
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
870
+ */
871
+ function DropDrawerSeparator({
872
+ className,
873
+ ...props
874
+ }: React.ComponentPropsWithoutRef<typeof DropdownMenuSeparator>): React.JSX.Element | null {
447
875
  const {isMobile} = useDropDrawerContext();
448
876
 
449
- // For mobile, render a simple divider
450
877
  if (isMobile) {
451
878
  return null;
452
879
  }
453
880
 
454
- // For desktop, use the standard dropdown separator
455
881
  return (
456
882
  <DropdownMenuSeparator
457
883
  data-slot='drop-drawer-separator'
@@ -461,210 +887,211 @@ function DropDrawerSeparator({className, ...props}: React.ComponentProps<typeof
461
887
  );
462
888
  }
463
889
 
890
+ /**
891
+ * Renders a section label for the drop drawer surface.
892
+ *
893
+ * @remarks
894
+ * - Renders a drawer title on mobile and a menu label on desktop
895
+ * - Built on Base UI Drawer and Menu primitives
896
+ *
897
+ * @example
898
+ * ```tsx
899
+ * <DropDrawerLabel>Actions</DropDrawerLabel>
900
+ * ```
901
+ *
902
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
903
+ */
464
904
  function DropDrawerLabel({
465
905
  className,
466
906
  children,
467
907
  ...props
468
- }: React.ComponentProps<typeof DropdownMenuLabel> | React.ComponentProps<typeof DrawerTitle>) {
908
+ }: React.ComponentProps<typeof DropdownMenuLabel> | React.ComponentProps<typeof DrawerTitle>): React.JSX.Element {
469
909
  const {isMobile} = useDropDrawerContext();
470
910
 
471
- if (isMobile) {
472
- return (
473
- <DrawerHeader className='p-0'>
474
- <DrawerTitle
475
- data-slot='drop-drawer-label'
476
- className={cn("px-4 py-2 text-sm font-medium text-neutral-500 dark:text-neutral-400", className)}
477
- {...props}>
478
- {children}
479
- </DrawerTitle>
480
- </DrawerHeader>
481
- );
482
- }
483
-
484
- return (
911
+ return isMobile ? (
912
+ <DrawerHeader className={styles.mobileLabelWrapper}>
913
+ <DrawerTitle
914
+ data-slot='drop-drawer-label'
915
+ className={cn(styles.mobileLabel, className)}
916
+ {...(props as React.ComponentProps<typeof DrawerTitle>)}>
917
+ {children}
918
+ </DrawerTitle>
919
+ </DrawerHeader>
920
+ ) : (
485
921
  <DropdownMenuLabel
486
922
  data-slot='drop-drawer-label'
487
923
  className={className}
488
- {...props}>
924
+ {...(props as React.ComponentProps<typeof DropdownMenuLabel>)}>
489
925
  {children}
490
926
  </DropdownMenuLabel>
491
927
  );
492
928
  }
493
929
 
494
- function DropDrawerFooter({className, children, ...props}: React.ComponentProps<typeof DrawerFooter> | React.ComponentProps<"div">) {
930
+ /**
931
+ * Renders footer content aligned to the bottom of the responsive surface.
932
+ *
933
+ * @remarks
934
+ * - Renders a drawer footer on mobile and a styled `<div>` on desktop
935
+ * - Built on Base UI Drawer primitives for mobile layouts
936
+ *
937
+ * @example
938
+ * ```tsx
939
+ * <DropDrawerFooter>Signed in as Alex</DropDrawerFooter>
940
+ * ```
941
+ *
942
+ * @see {@link https://base-ui.com/react/components/drawer | Base UI Drawer Docs}
943
+ */
944
+ function DropDrawerFooter({
945
+ className,
946
+ children,
947
+ ...props
948
+ }: React.ComponentProps<typeof DrawerFooter> | React.ComponentProps<"div">): React.JSX.Element {
495
949
  const {isMobile} = useDropDrawerContext();
496
950
 
497
- if (isMobile) {
498
- return (
499
- <DrawerFooter
500
- data-slot='drop-drawer-footer'
501
- className={cn("p-4", className)}
502
- {...props}>
503
- {children}
504
- </DrawerFooter>
505
- );
506
- }
507
-
508
- // No direct equivalent in DropdownMenu, so we'll just render a div
509
- return (
951
+ return isMobile ? (
952
+ <DrawerFooter
953
+ data-slot='drop-drawer-footer'
954
+ className={cn(styles.mobileFooter, className)}
955
+ {...(props as React.ComponentProps<typeof DrawerFooter>)}>
956
+ {children}
957
+ </DrawerFooter>
958
+ ) : (
510
959
  <div
511
960
  data-slot='drop-drawer-footer'
512
- className={cn("p-2", className)}
961
+ className={cn(styles.desktopFooter, className)}
513
962
  {...props}>
514
963
  {children}
515
964
  </div>
516
965
  );
517
966
  }
518
967
 
519
- function DropDrawerGroup({
520
- className,
521
- children,
522
- ...props
523
- }: React.ComponentProps<"div"> & {
524
- children: React.ReactNode;
525
- }) {
968
+ /**
969
+ * Renders a grouped collection of drop drawer items.
970
+ *
971
+ * @remarks
972
+ * - Renders a Base UI menu group on desktop and a `<div role="group">` on mobile
973
+ * - Inserts mobile-only separators between adjacent children
974
+ *
975
+ * @example
976
+ * ```tsx
977
+ * <DropDrawerGroup>
978
+ * <DropDrawerItem>Profile</DropDrawerItem>
979
+ * <DropDrawerItem>Billing</DropDrawerItem>
980
+ * </DropDrawerGroup>
981
+ * ```
982
+ *
983
+ * @see {@link https://developer.mozilla.org/docs/Web/Accessibility/ARIA/Roles/group_role | ARIA Group Role}
984
+ */
985
+ function DropDrawerGroup({className, children, ...props}: React.ComponentProps<"div"> & {children: React.ReactNode}): React.JSX.Element {
526
986
  const {isMobile} = useDropDrawerContext();
527
987
 
528
- // Add separators between children on mobile
529
988
  const childrenWithSeparators = React.useMemo(() => {
530
- if (!isMobile) return children;
989
+ if (!isMobile) {
990
+ return children;
991
+ }
531
992
 
532
993
  const childArray = React.Children.toArray(children);
994
+ const filteredChildren = childArray.filter((child) => !(React.isValidElement(child) && child.type === DropDrawerSeparator));
533
995
 
534
- // Filter out any existing separators
535
- const filteredChildren = childArray.filter((child) => React.isValidElement(child) && child.type !== DropDrawerSeparator);
536
-
537
- // Add separators between items
538
996
  return filteredChildren.flatMap((child, index) => {
539
- if (index === filteredChildren.length - 1) return [child];
997
+ if (index === filteredChildren.length - 1) {
998
+ return [child];
999
+ }
1000
+
540
1001
  return [
541
1002
  child,
542
1003
  <div
543
1004
  key={`separator-${index}`}
544
- className='h-px bg-neutral-200 dark:bg-neutral-800'
1005
+ className={styles.mobileGroupSeparator}
545
1006
  aria-hidden='true'
546
1007
  />,
547
1008
  ];
548
1009
  });
549
1010
  }, [children, isMobile]);
550
1011
 
551
- if (isMobile) {
552
- return (
553
- <div
554
- data-drop-drawer-group
555
- data-slot='drop-drawer-group'
556
- role='group'
557
- className={cn(
558
- "mx-2 my-3 overflow-hidden rounded-xl bg-neutral-100 dark:bg-neutral-100 dark:bg-neutral-800 dark:dark:bg-neutral-800",
559
- className,
560
- )}
561
- {...props}>
562
- {childrenWithSeparators}
563
- </div>
564
- );
565
- }
566
-
567
- // On desktop, use a div with proper role and attributes
568
- return (
1012
+ return isMobile ? (
569
1013
  <div
570
1014
  data-drop-drawer-group
571
1015
  data-slot='drop-drawer-group'
572
1016
  role='group'
573
- className={className}
1017
+ className={cn(styles.mobileGroup, className)}
574
1018
  {...props}>
575
- {children}
1019
+ {childrenWithSeparators}
576
1020
  </div>
1021
+ ) : (
1022
+ <BaseMenu.Group
1023
+ data-drop-drawer-group
1024
+ data-slot='drop-drawer-group'
1025
+ className={className}
1026
+ {...(props as React.ComponentPropsWithoutRef<typeof BaseMenu.Group>)}>
1027
+ {children}
1028
+ </BaseMenu.Group>
577
1029
  );
578
1030
  }
579
1031
 
580
- // Context for managing submenu state on mobile
581
- interface SubmenuContextType {
582
- activeSubmenu: string | null;
583
- setActiveSubmenu: (id: string | null) => void;
584
- submenuTitle: string | null;
585
- setSubmenuTitle: (title: string | null) => void;
586
- navigateToSubmenu?: (id: string, title: string) => void;
587
- registerSubmenuContent?: (id: string, content: React.ReactNode[]) => void;
588
- }
589
-
590
- const SubmenuContext = React.createContext<SubmenuContextType>({
591
- activeSubmenu: null,
592
- setActiveSubmenu: () => {},
593
- submenuTitle: null,
594
- setSubmenuTitle: () => {},
595
- navigateToSubmenu: undefined,
596
- registerSubmenuContent: undefined,
597
- });
598
-
599
- // Submenu components
600
- // Counter for generating simple numeric IDs
601
- let submenuIdCounter = 0;
602
-
1032
+ /**
1033
+ * Renders a submenu root within the drop drawer surface.
1034
+ *
1035
+ * @remarks
1036
+ * - Renders a Base UI submenu on desktop and a mobile-aware container on small screens
1037
+ * - Registers submenu content for animated mobile drill-down navigation
1038
+ *
1039
+ * @example
1040
+ * ```tsx
1041
+ * <DropDrawerSub>
1042
+ * <DropDrawerSubTrigger>More</DropDrawerSubTrigger>
1043
+ * <DropDrawerSubContent>
1044
+ * <DropDrawerItem>Sub item</DropDrawerItem>
1045
+ * </DropDrawerSubContent>
1046
+ * </DropDrawerSub>
1047
+ * ```
1048
+ *
1049
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
1050
+ */
603
1051
  function DropDrawerSub({
604
1052
  children,
605
1053
  id,
606
1054
  ...props
607
- }: React.ComponentProps<typeof DropdownMenuSub> & {
608
- id?: string;
609
- }) {
1055
+ }: React.ComponentPropsWithoutRef<typeof DropdownMenuSub> & {children?: React.ReactNode; id?: string}): React.JSX.Element {
610
1056
  const {isMobile} = useDropDrawerContext();
611
1057
  const {registerSubmenuContent} = React.useContext(SubmenuContext);
612
-
613
- // Generate a simple numeric ID instead of using React.useId()
614
- const [generatedId] = React.useState(() => `submenu-${submenuIdCounter++}`);
1058
+ const generatedId = React.useId();
615
1059
  const submenuId = id || generatedId;
616
1060
 
617
- // Extract submenu content to register with parent
618
1061
  React.useEffect(() => {
619
- if (!registerSubmenuContent) return;
1062
+ if (!registerSubmenuContent) {
1063
+ return;
1064
+ }
1065
+
1066
+ const contentItems: Array<React.ReactNode> = [];
620
1067
 
621
- // Find the SubContent within this Sub
622
- const contentItems: React.ReactNode[] = [];
623
1068
  React.Children.forEach(children, (child) => {
624
1069
  if (React.isValidElement(child) && child.type === DropDrawerSubContent) {
625
- // Add all children of the SubContent to the result
626
- React.Children.forEach((child.props as {children?: React.ReactNode}).children, (contentChild) => {
1070
+ const childElement = child as React.ReactElement<{children?: React.ReactNode}>;
1071
+
1072
+ React.Children.forEach(childElement.props.children, (contentChild) => {
627
1073
  contentItems.push(contentChild);
628
1074
  });
629
1075
  }
630
1076
  });
631
1077
 
632
- // Register the content with the parent
633
1078
  if (contentItems.length > 0) {
634
1079
  registerSubmenuContent(submenuId, contentItems);
635
1080
  }
636
1081
  }, [children, registerSubmenuContent, submenuId]);
637
1082
 
638
1083
  if (isMobile) {
639
- // For mobile, we'll use the context to manage submenu state
640
- // Process children to pass the submenu ID to the trigger and content
641
1084
  const processedChildren = React.Children.map(children, (child) => {
642
- if (!React.isValidElement(child)) return child;
643
-
644
- if (child.type === DropDrawerSubTrigger) {
645
- return React.cloneElement(
646
- child as React.ReactElement,
647
- {
648
- ...(child.props as object),
649
- "data-parent-submenu-id": submenuId,
650
- "data-submenu-id": submenuId,
651
- // Use only data attributes, not custom props
652
- "data-parent-submenu": submenuId,
653
- } as React.HTMLAttributes<HTMLElement>,
654
- );
1085
+ if (!React.isValidElement(child)) {
1086
+ return child;
655
1087
  }
656
1088
 
657
- if (child.type === DropDrawerSubContent) {
658
- return React.cloneElement(
659
- child as React.ReactElement,
660
- {
661
- ...(child.props as object),
662
- "data-parent-submenu-id": submenuId,
663
- "data-submenu-id": submenuId,
664
- // Use only data attributes, not custom props
665
- "data-parent-submenu": submenuId,
666
- } as React.HTMLAttributes<HTMLElement>,
667
- );
1089
+ if (child.type === DropDrawerSubTrigger || child.type === DropDrawerSubContent) {
1090
+ return React.cloneElement(child as React.ReactElement<MobileSubmenuDataAttributes>, {
1091
+ "data-parent-submenu": submenuId,
1092
+ "data-parent-submenu-id": submenuId,
1093
+ "data-submenu-id": submenuId,
1094
+ });
668
1095
  }
669
1096
 
670
1097
  return child;
@@ -680,137 +1107,151 @@ function DropDrawerSub({
680
1107
  );
681
1108
  }
682
1109
 
683
- // For desktop, pass the generated ID to the DropdownMenuSub
684
1110
  return (
685
1111
  <DropdownMenuSub
686
1112
  data-slot='drop-drawer-sub'
687
1113
  data-submenu-id={submenuId}
688
- // Don't pass id to DropdownMenuSub as it doesn't accept this prop
689
1114
  {...props}>
690
1115
  {children}
691
1116
  </DropdownMenuSub>
692
1117
  );
693
1118
  }
694
1119
 
695
- function DropDrawerSubTrigger({
696
- className,
697
- inset,
698
- children,
699
- ...props
700
- }: React.ComponentProps<typeof DropdownMenuSubTrigger> & {
701
- icon?: React.ReactNode;
702
- }) {
1120
+ interface DropDrawerSubTriggerProps
1121
+ extends Omit<React.ComponentPropsWithoutRef<typeof DropdownMenuSubTrigger>, "children" | "onClick">, MobileSubmenuDataAttributes {
1122
+ /**
1123
+ * Trigger contents.
1124
+ * @default undefined
1125
+ */
1126
+ children?: React.ReactNode;
1127
+ /**
1128
+ * Additional CSS classes merged with the trigger styles.
1129
+ * @default undefined
1130
+ */
1131
+ className?: string;
1132
+ /**
1133
+ * Whether to apply inset spacing to align the trigger with grouped content.
1134
+ * @default undefined
1135
+ */
1136
+ inset?: boolean;
1137
+ /**
1138
+ * Mouse click handler invoked before submenu navigation occurs.
1139
+ * @default undefined
1140
+ */
1141
+ onClick?: React.MouseEventHandler<HTMLElement>;
1142
+ }
1143
+
1144
+ /**
1145
+ * Renders the trigger that opens a nested submenu.
1146
+ *
1147
+ * @remarks
1148
+ * - Renders a Base UI submenu trigger on desktop and a keyboard-accessible `<div>` on mobile
1149
+ * - Built on Base UI Menu submenu primitives
1150
+ *
1151
+ * @example
1152
+ * ```tsx
1153
+ * <DropDrawerSubTrigger>Advanced</DropDrawerSubTrigger>
1154
+ * ```
1155
+ *
1156
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
1157
+ */
1158
+ function DropDrawerSubTrigger({className, inset, children, onClick, ...props}: DropDrawerSubTriggerProps): React.JSX.Element {
703
1159
  const {isMobile} = useDropDrawerContext();
704
1160
  const {navigateToSubmenu} = React.useContext(SubmenuContext);
705
1161
 
706
- // Define hooks outside of conditionals to follow React rules
707
- // Check if this item is inside a group by looking at parent elements
708
1162
  const isInGroup = React.useCallback((element: HTMLElement | null): boolean => {
709
- if (!element) return false;
1163
+ if (!element) {
1164
+ return false;
1165
+ }
710
1166
 
711
- // Check if any parent has a data-drop-drawer-group attribute
712
1167
  let parent = element.parentElement;
1168
+
713
1169
  while (parent) {
714
1170
  if (parent.hasAttribute("data-drop-drawer-group")) {
715
1171
  return true;
716
1172
  }
1173
+
717
1174
  parent = parent.parentElement;
718
1175
  }
1176
+
719
1177
  return false;
720
1178
  }, []);
721
1179
 
722
- // Create a ref to check if the item is in a group
723
1180
  const itemRef = React.useRef<HTMLDivElement>(null);
724
1181
  const [isInsideGroup, setIsInsideGroup] = React.useState(false);
725
1182
 
726
1183
  React.useEffect(() => {
727
- // Only run this effect in mobile mode
728
- if (!isMobile) return;
1184
+ if (!isMobile) {
1185
+ return;
1186
+ }
729
1187
 
730
- // Use a short timeout to ensure the DOM is fully rendered
731
- const timer = setTimeout(() => {
1188
+ const timer = globalThis.window.setTimeout(() => {
732
1189
  if (itemRef.current) {
733
1190
  setIsInsideGroup(isInGroup(itemRef.current));
734
1191
  }
735
1192
  }, 0);
736
1193
 
737
- return () => clearTimeout(timer);
1194
+ return () => globalThis.window.clearTimeout(timer);
738
1195
  }, [isInGroup, isMobile]);
739
1196
 
740
1197
  if (isMobile) {
741
- // Find the parent submenu ID
742
- const handleClick = (e: React.MouseEvent) => {
743
- e.preventDefault();
744
- e.stopPropagation();
745
-
746
- // Get the closest parent with data-submenu-id attribute
747
- const element = e.currentTarget as HTMLElement;
1198
+ const navigate = (eventTarget: HTMLElement): void => {
748
1199
  let submenuId: string | null = null;
1200
+ const closestElement = eventTarget.closest("[data-submenu-id]");
1201
+ const closestId = closestElement?.getAttribute("data-submenu-id");
749
1202
 
750
- // First check if the element itself has the data attribute
751
- if (element.closest("[data-submenu-id]")) {
752
- const closestElement = element.closest("[data-submenu-id]");
753
- const id = closestElement?.getAttribute("data-submenu-id");
754
- if (id) {
755
- submenuId = id;
756
- }
1203
+ if (closestId) {
1204
+ submenuId = closestId;
757
1205
  }
758
1206
 
759
- // If not found, try props
760
1207
  if (!submenuId) {
761
- submenuId =
762
- ((props as Record<string, unknown>)["data-parent-submenu-id"] as string)
763
- || ((props as Record<string, unknown>)["data-parent-submenu"] as string);
1208
+ submenuId = props["data-parent-submenu-id"] ?? props["data-parent-submenu"] ?? null;
764
1209
  }
765
1210
 
766
1211
  if (!submenuId) {
767
1212
  return;
768
1213
  }
769
1214
 
770
- // Get the title
771
- const title = typeof children === "string" ? children : "Submenu";
1215
+ const title = typeof children === "string" ? children : MOBILE_SUBMENU_TITLE;
1216
+ navigateToSubmenu?.(submenuId, title);
1217
+ };
772
1218
 
773
- // Navigate to the submenu
774
- if (navigateToSubmenu) {
775
- navigateToSubmenu(submenuId, title);
776
- }
1219
+ const handleClick: React.MouseEventHandler<HTMLDivElement> = (event): void => {
1220
+ event.preventDefault();
1221
+ event.stopPropagation();
1222
+ onClick?.(event);
1223
+ navigate(event.currentTarget);
777
1224
  };
778
1225
 
779
- // Combine onClick handlers
780
- const combinedOnClick = (e: React.MouseEvent) => {
781
- // Call the original onClick if provided
782
- const typedProps = props as Record<string, unknown>;
783
- if (typedProps["onClick"]) {
784
- const originalOnClick = typedProps["onClick"] as React.MouseEventHandler<HTMLDivElement>;
785
- originalOnClick(e as React.MouseEvent<HTMLDivElement>);
1226
+ const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event): void => {
1227
+ if (event.key !== "Enter" && event.key !== " ") {
1228
+ return;
786
1229
  }
787
1230
 
788
- // Call our navigation handler
789
- handleClick(e);
1231
+ event.preventDefault();
1232
+ event.stopPropagation();
1233
+ event.currentTarget.click();
790
1234
  };
791
1235
 
792
- // Remove onClick from props to avoid duplicate handlers
793
- const {...restProps} = props as Record<string, unknown>;
794
-
795
- // Don't wrap in DrawerClose for submenu triggers
796
1236
  return (
797
1237
  <div
798
1238
  ref={itemRef}
799
1239
  data-slot='drop-drawer-sub-trigger'
800
1240
  data-inset={inset}
1241
+ role='menuitem'
1242
+ tabIndex={0}
801
1243
  className={cn(
802
- "flex cursor-pointer items-center justify-between px-4 py-4",
803
- // Only apply margin, background and rounded corners if not in a group
804
- !isInsideGroup && "mx-2 my-1.5 rounded-md bg-neutral-100 dark:bg-neutral-100 dark:bg-neutral-800 dark:dark:bg-neutral-800",
805
- // For items in a group, don't add background but add more padding
806
- isInsideGroup && "bg-transparent py-4",
807
- inset && "pl-8",
1244
+ styles.mobileItem,
1245
+ !isInsideGroup && styles.mobileStandaloneItem,
1246
+ isInsideGroup && styles.mobileGroupedItem,
1247
+ inset && styles.inset,
808
1248
  className,
809
1249
  )}
810
- onClick={combinedOnClick}
811
- {...restProps}>
812
- <div className='flex items-center gap-2'>{children}</div>
813
- <ChevronRightIcon className='h-5 w-5' />
1250
+ onClick={handleClick}
1251
+ onKeyDown={handleKeyDown}
1252
+ {...props}>
1253
+ <div className={styles.itemChildren}>{children}</div>
1254
+ <ChevronRightIcon className={styles.chevron} />
814
1255
  </div>
815
1256
  );
816
1257
  }
@@ -821,18 +1262,38 @@ function DropDrawerSubTrigger({
821
1262
  data-inset={inset}
822
1263
  className={className}
823
1264
  inset={inset}
1265
+ onClick={onClick}
824
1266
  {...props}>
825
1267
  {children}
826
1268
  </DropdownMenuSubTrigger>
827
1269
  );
828
1270
  }
829
1271
 
830
- function DropDrawerSubContent({className, sideOffset = 4, children, ...props}: React.ComponentProps<typeof DropdownMenuSubContent>) {
1272
+ /**
1273
+ * Renders the content region for a nested submenu.
1274
+ *
1275
+ * @remarks
1276
+ * - Renders only in desktop dropdown mode
1277
+ * - Built on Base UI Menu submenu popup primitives
1278
+ *
1279
+ * @example
1280
+ * ```tsx
1281
+ * <DropDrawerSubContent>
1282
+ * <DropDrawerItem>Details</DropDrawerItem>
1283
+ * </DropDrawerSubContent>
1284
+ * ```
1285
+ *
1286
+ * @see {@link https://base-ui.com/react/components/menu | Base UI Menu Docs}
1287
+ */
1288
+ function DropDrawerSubContent({
1289
+ className,
1290
+ sideOffset = 4,
1291
+ children,
1292
+ ...props
1293
+ }: React.ComponentProps<typeof DropdownMenuSubContent>): React.JSX.Element | null {
831
1294
  const {isMobile} = useDropDrawerContext();
832
1295
 
833
1296
  if (isMobile) {
834
- // For mobile, we don't render the content directly
835
- // It will be rendered by the DropDrawerContent component when active
836
1297
  return null;
837
1298
  }
838
1299
 
@@ -840,16 +1301,25 @@ function DropDrawerSubContent({className, sideOffset = 4, children, ...props}: R
840
1301
  <DropdownMenuSubContent
841
1302
  data-slot='drop-drawer-sub-content'
842
1303
  sideOffset={sideOffset}
843
- className={cn(
844
- "z-50 min-w-[8rem] overflow-hidden rounded-md border border-neutral-200 p-1 shadow-lg dark:border-neutral-800",
845
- className,
846
- )}
1304
+ className={cn(styles.dropdownSubContent, className)}
847
1305
  {...props}>
848
1306
  {children}
849
1307
  </DropdownMenuSubContent>
850
1308
  );
851
1309
  }
852
1310
 
1311
+ DropDrawer.displayName = "DropDrawer";
1312
+ DropDrawerTrigger.displayName = "DropDrawerTrigger";
1313
+ DropDrawerContent.displayName = "DropDrawerContent";
1314
+ DropDrawerItem.displayName = "DropDrawerItem";
1315
+ DropDrawerSeparator.displayName = "DropDrawerSeparator";
1316
+ DropDrawerLabel.displayName = "DropDrawerLabel";
1317
+ DropDrawerFooter.displayName = "DropDrawerFooter";
1318
+ DropDrawerGroup.displayName = "DropDrawerGroup";
1319
+ DropDrawerSub.displayName = "DropDrawerSub";
1320
+ DropDrawerSubTrigger.displayName = "DropDrawerSubTrigger";
1321
+ DropDrawerSubContent.displayName = "DropDrawerSubContent";
1322
+
853
1323
  export {
854
1324
  DropDrawer,
855
1325
  DropDrawerContent,