reka-ui 2.9.9 → 2.10.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 (470) hide show
  1. package/dist/AlertDialog/AlertDialogContent.cjs +2 -1
  2. package/dist/AlertDialog/AlertDialogContent.cjs.map +1 -1
  3. package/dist/AlertDialog/AlertDialogContent.js +2 -1
  4. package/dist/AlertDialog/AlertDialogContent.js.map +1 -1
  5. package/dist/AlertDialog/AlertDialogRoot.cjs +4 -0
  6. package/dist/AlertDialog/AlertDialogRoot.cjs.map +1 -1
  7. package/dist/AlertDialog/AlertDialogRoot.js +4 -0
  8. package/dist/AlertDialog/AlertDialogRoot.js.map +1 -1
  9. package/dist/Checkbox/CheckboxRoot.cjs +27 -18
  10. package/dist/Checkbox/CheckboxRoot.cjs.map +1 -1
  11. package/dist/Checkbox/CheckboxRoot.js +28 -19
  12. package/dist/Checkbox/CheckboxRoot.js.map +1 -1
  13. package/dist/Collection/Collection.cjs +2 -1
  14. package/dist/Collection/Collection.cjs.map +1 -1
  15. package/dist/Collection/Collection.js +2 -1
  16. package/dist/Collection/Collection.js.map +1 -1
  17. package/dist/Combobox/ComboboxContent.cjs +8 -0
  18. package/dist/Combobox/ComboboxContent.cjs.map +1 -1
  19. package/dist/Combobox/ComboboxContent.js +8 -0
  20. package/dist/Combobox/ComboboxContent.js.map +1 -1
  21. package/dist/Combobox/ComboboxContentImpl.cjs +18 -2
  22. package/dist/Combobox/ComboboxContentImpl.cjs.map +1 -1
  23. package/dist/Combobox/ComboboxContentImpl.js +18 -2
  24. package/dist/Combobox/ComboboxContentImpl.js.map +1 -1
  25. package/dist/Combobox/ComboboxItem.cjs +11 -2
  26. package/dist/Combobox/ComboboxItem.cjs.map +1 -1
  27. package/dist/Combobox/ComboboxItem.js +12 -3
  28. package/dist/Combobox/ComboboxItem.js.map +1 -1
  29. package/dist/ConfigProvider/ConfigProvider.cjs +7 -1
  30. package/dist/ConfigProvider/ConfigProvider.cjs.map +1 -1
  31. package/dist/ConfigProvider/ConfigProvider.js +7 -1
  32. package/dist/ConfigProvider/ConfigProvider.js.map +1 -1
  33. package/dist/ContextMenu/ContextMenuContent.cjs +4 -0
  34. package/dist/ContextMenu/ContextMenuContent.cjs.map +1 -1
  35. package/dist/ContextMenu/ContextMenuContent.js +4 -0
  36. package/dist/ContextMenu/ContextMenuContent.js.map +1 -1
  37. package/dist/ContextMenu/ContextMenuSubContent.cjs +4 -0
  38. package/dist/ContextMenu/ContextMenuSubContent.cjs.map +1 -1
  39. package/dist/ContextMenu/ContextMenuSubContent.js +4 -0
  40. package/dist/ContextMenu/ContextMenuSubContent.js.map +1 -1
  41. package/dist/DateField/DateFieldInput.cjs +3 -1
  42. package/dist/DateField/DateFieldInput.cjs.map +1 -1
  43. package/dist/DateField/DateFieldInput.js +3 -1
  44. package/dist/DateField/DateFieldInput.js.map +1 -1
  45. package/dist/DateField/DateFieldRoot.cjs +7 -1
  46. package/dist/DateField/DateFieldRoot.cjs.map +1 -1
  47. package/dist/DateField/DateFieldRoot.js +7 -1
  48. package/dist/DateField/DateFieldRoot.js.map +1 -1
  49. package/dist/DatePicker/DatePickerContent.cjs +8 -0
  50. package/dist/DatePicker/DatePickerContent.cjs.map +1 -1
  51. package/dist/DatePicker/DatePickerContent.js +8 -0
  52. package/dist/DatePicker/DatePickerContent.js.map +1 -1
  53. package/dist/DatePicker/DatePickerRoot.cjs +4 -0
  54. package/dist/DatePicker/DatePickerRoot.cjs.map +1 -1
  55. package/dist/DatePicker/DatePickerRoot.js +4 -0
  56. package/dist/DatePicker/DatePickerRoot.js.map +1 -1
  57. package/dist/DateRangePicker/DateRangePickerContent.cjs +8 -0
  58. package/dist/DateRangePicker/DateRangePickerContent.cjs.map +1 -1
  59. package/dist/DateRangePicker/DateRangePickerContent.js +8 -0
  60. package/dist/DateRangePicker/DateRangePickerContent.js.map +1 -1
  61. package/dist/Dialog/DialogContent.cjs +16 -10
  62. package/dist/Dialog/DialogContent.cjs.map +1 -1
  63. package/dist/Dialog/DialogContent.js +17 -11
  64. package/dist/Dialog/DialogContent.js.map +1 -1
  65. package/dist/Dialog/DialogContentImpl.cjs +8 -1
  66. package/dist/Dialog/DialogContentImpl.cjs.map +1 -1
  67. package/dist/Dialog/DialogContentImpl.js +8 -1
  68. package/dist/Dialog/DialogContentImpl.js.map +1 -1
  69. package/dist/Dialog/DialogContentModal.cjs +23 -5
  70. package/dist/Dialog/DialogContentModal.cjs.map +1 -1
  71. package/dist/Dialog/DialogContentModal.js +24 -6
  72. package/dist/Dialog/DialogContentModal.js.map +1 -1
  73. package/dist/Dialog/DialogContentNonModal.cjs +18 -2
  74. package/dist/Dialog/DialogContentNonModal.cjs.map +1 -1
  75. package/dist/Dialog/DialogContentNonModal.js +19 -3
  76. package/dist/Dialog/DialogContentNonModal.js.map +1 -1
  77. package/dist/Dialog/DialogOverlay.cjs +12 -6
  78. package/dist/Dialog/DialogOverlay.cjs.map +1 -1
  79. package/dist/Dialog/DialogOverlay.js +13 -7
  80. package/dist/Dialog/DialogOverlay.js.map +1 -1
  81. package/dist/Dialog/DialogOverlayImpl.cjs +8 -1
  82. package/dist/Dialog/DialogOverlayImpl.cjs.map +1 -1
  83. package/dist/Dialog/DialogOverlayImpl.js +9 -2
  84. package/dist/Dialog/DialogOverlayImpl.js.map +1 -1
  85. package/dist/Dialog/DialogRoot.cjs +7 -1
  86. package/dist/Dialog/DialogRoot.cjs.map +1 -1
  87. package/dist/Dialog/DialogRoot.js +7 -1
  88. package/dist/Dialog/DialogRoot.js.map +1 -1
  89. package/dist/DismissableLayer/DismissableLayer.cjs +27 -10
  90. package/dist/DismissableLayer/DismissableLayer.cjs.map +1 -1
  91. package/dist/DismissableLayer/DismissableLayer.js +28 -11
  92. package/dist/DismissableLayer/DismissableLayer.js.map +1 -1
  93. package/dist/Drawer/DrawerClose.cjs +48 -0
  94. package/dist/Drawer/DrawerClose.cjs.map +1 -0
  95. package/dist/Drawer/DrawerClose.js +42 -0
  96. package/dist/Drawer/DrawerClose.js.map +1 -0
  97. package/dist/Drawer/DrawerContent.cjs +139 -0
  98. package/dist/Drawer/DrawerContent.cjs.map +1 -0
  99. package/dist/Drawer/DrawerContent.js +133 -0
  100. package/dist/Drawer/DrawerContent.js.map +1 -0
  101. package/dist/Drawer/DrawerContentImpl.cjs +298 -0
  102. package/dist/Drawer/DrawerContentImpl.cjs.map +1 -0
  103. package/dist/Drawer/DrawerContentImpl.js +292 -0
  104. package/dist/Drawer/DrawerContentImpl.js.map +1 -0
  105. package/dist/Drawer/DrawerDescription.cjs +45 -0
  106. package/dist/Drawer/DrawerDescription.cjs.map +1 -0
  107. package/dist/Drawer/DrawerDescription.js +39 -0
  108. package/dist/Drawer/DrawerDescription.js.map +1 -0
  109. package/dist/Drawer/DrawerHandle.cjs +48 -0
  110. package/dist/Drawer/DrawerHandle.cjs.map +1 -0
  111. package/dist/Drawer/DrawerHandle.js +42 -0
  112. package/dist/Drawer/DrawerHandle.js.map +1 -0
  113. package/dist/Drawer/DrawerIndent.cjs +78 -0
  114. package/dist/Drawer/DrawerIndent.cjs.map +1 -0
  115. package/dist/Drawer/DrawerIndent.js +72 -0
  116. package/dist/Drawer/DrawerIndent.js.map +1 -0
  117. package/dist/Drawer/DrawerIndentBackground.cjs +49 -0
  118. package/dist/Drawer/DrawerIndentBackground.cjs.map +1 -0
  119. package/dist/Drawer/DrawerIndentBackground.js +43 -0
  120. package/dist/Drawer/DrawerIndentBackground.js.map +1 -0
  121. package/dist/Drawer/DrawerOverlay.cjs +66 -0
  122. package/dist/Drawer/DrawerOverlay.cjs.map +1 -0
  123. package/dist/Drawer/DrawerOverlay.js +60 -0
  124. package/dist/Drawer/DrawerOverlay.js.map +1 -0
  125. package/dist/Drawer/DrawerOverlayImpl.cjs +69 -0
  126. package/dist/Drawer/DrawerOverlayImpl.cjs.map +1 -0
  127. package/dist/Drawer/DrawerOverlayImpl.js +63 -0
  128. package/dist/Drawer/DrawerOverlayImpl.js.map +1 -0
  129. package/dist/Drawer/DrawerPortal.cjs +47 -0
  130. package/dist/Drawer/DrawerPortal.cjs.map +1 -0
  131. package/dist/Drawer/DrawerPortal.js +41 -0
  132. package/dist/Drawer/DrawerPortal.js.map +1 -0
  133. package/dist/Drawer/DrawerProvider.cjs +80 -0
  134. package/dist/Drawer/DrawerProvider.cjs.map +1 -0
  135. package/dist/Drawer/DrawerProvider.js +68 -0
  136. package/dist/Drawer/DrawerProvider.js.map +1 -0
  137. package/dist/Drawer/DrawerRoot.cjs +197 -0
  138. package/dist/Drawer/DrawerRoot.cjs.map +1 -0
  139. package/dist/Drawer/DrawerRoot.js +185 -0
  140. package/dist/Drawer/DrawerRoot.js.map +1 -0
  141. package/dist/Drawer/DrawerSwipeArea.cjs +87 -0
  142. package/dist/Drawer/DrawerSwipeArea.cjs.map +1 -0
  143. package/dist/Drawer/DrawerSwipeArea.js +81 -0
  144. package/dist/Drawer/DrawerSwipeArea.js.map +1 -0
  145. package/dist/Drawer/DrawerTitle.cjs +45 -0
  146. package/dist/Drawer/DrawerTitle.cjs.map +1 -0
  147. package/dist/Drawer/DrawerTitle.js +39 -0
  148. package/dist/Drawer/DrawerTitle.js.map +1 -0
  149. package/dist/Drawer/DrawerTrigger.cjs +64 -0
  150. package/dist/Drawer/DrawerTrigger.cjs.map +1 -0
  151. package/dist/Drawer/DrawerTrigger.js +58 -0
  152. package/dist/Drawer/DrawerTrigger.js.map +1 -0
  153. package/dist/Drawer/DrawerViewport.cjs +49 -0
  154. package/dist/Drawer/DrawerViewport.cjs.map +1 -0
  155. package/dist/Drawer/DrawerViewport.js +43 -0
  156. package/dist/Drawer/DrawerViewport.js.map +1 -0
  157. package/dist/Drawer/utils.cjs +185 -0
  158. package/dist/Drawer/utils.cjs.map +1 -0
  159. package/dist/Drawer/utils.js +149 -0
  160. package/dist/Drawer/utils.js.map +1 -0
  161. package/dist/DropdownMenu/DropdownMenuContent.cjs +4 -0
  162. package/dist/DropdownMenu/DropdownMenuContent.cjs.map +1 -1
  163. package/dist/DropdownMenu/DropdownMenuContent.js +4 -0
  164. package/dist/DropdownMenu/DropdownMenuContent.js.map +1 -1
  165. package/dist/DropdownMenu/DropdownMenuSubContent.cjs +4 -0
  166. package/dist/DropdownMenu/DropdownMenuSubContent.cjs.map +1 -1
  167. package/dist/DropdownMenu/DropdownMenuSubContent.js +4 -0
  168. package/dist/DropdownMenu/DropdownMenuSubContent.js.map +1 -1
  169. package/dist/FocusScope/FocusScope.cjs +31 -11
  170. package/dist/FocusScope/FocusScope.cjs.map +1 -1
  171. package/dist/FocusScope/FocusScope.js +32 -12
  172. package/dist/FocusScope/FocusScope.js.map +1 -1
  173. package/dist/HoverCard/HoverCardContent.cjs +8 -0
  174. package/dist/HoverCard/HoverCardContent.cjs.map +1 -1
  175. package/dist/HoverCard/HoverCardContent.js +8 -0
  176. package/dist/HoverCard/HoverCardContent.js.map +1 -1
  177. package/dist/HoverCard/HoverCardContentImpl.cjs +8 -0
  178. package/dist/HoverCard/HoverCardContentImpl.cjs.map +1 -1
  179. package/dist/HoverCard/HoverCardContentImpl.js +8 -0
  180. package/dist/HoverCard/HoverCardContentImpl.js.map +1 -1
  181. package/dist/HoverCard/HoverCardRoot.cjs +9 -2
  182. package/dist/HoverCard/HoverCardRoot.cjs.map +1 -1
  183. package/dist/HoverCard/HoverCardRoot.js +9 -2
  184. package/dist/HoverCard/HoverCardRoot.js.map +1 -1
  185. package/dist/HoverCard/HoverCardTrigger.cjs +6 -0
  186. package/dist/HoverCard/HoverCardTrigger.cjs.map +1 -1
  187. package/dist/HoverCard/HoverCardTrigger.js +6 -0
  188. package/dist/HoverCard/HoverCardTrigger.js.map +1 -1
  189. package/dist/Listbox/ListboxRoot.cjs +4 -1
  190. package/dist/Listbox/ListboxRoot.cjs.map +1 -1
  191. package/dist/Listbox/ListboxRoot.js +4 -1
  192. package/dist/Listbox/ListboxRoot.js.map +1 -1
  193. package/dist/Listbox/ListboxVirtualizer.cjs +7 -3
  194. package/dist/Listbox/ListboxVirtualizer.cjs.map +1 -1
  195. package/dist/Listbox/ListboxVirtualizer.js +7 -3
  196. package/dist/Listbox/ListboxVirtualizer.js.map +1 -1
  197. package/dist/Menu/MenuContent.cjs +4 -0
  198. package/dist/Menu/MenuContent.cjs.map +1 -1
  199. package/dist/Menu/MenuContent.js +4 -0
  200. package/dist/Menu/MenuContent.js.map +1 -1
  201. package/dist/Menu/MenuContentImpl.cjs +4 -0
  202. package/dist/Menu/MenuContentImpl.cjs.map +1 -1
  203. package/dist/Menu/MenuContentImpl.js +4 -0
  204. package/dist/Menu/MenuContentImpl.js.map +1 -1
  205. package/dist/Menu/MenuRootContentModal.cjs +4 -0
  206. package/dist/Menu/MenuRootContentModal.cjs.map +1 -1
  207. package/dist/Menu/MenuRootContentModal.js +4 -0
  208. package/dist/Menu/MenuRootContentModal.js.map +1 -1
  209. package/dist/Menu/MenuRootContentNonModal.cjs +4 -0
  210. package/dist/Menu/MenuRootContentNonModal.cjs.map +1 -1
  211. package/dist/Menu/MenuRootContentNonModal.js +4 -0
  212. package/dist/Menu/MenuRootContentNonModal.js.map +1 -1
  213. package/dist/Menu/MenuSubContent.cjs +4 -0
  214. package/dist/Menu/MenuSubContent.cjs.map +1 -1
  215. package/dist/Menu/MenuSubContent.js +4 -0
  216. package/dist/Menu/MenuSubContent.js.map +1 -1
  217. package/dist/Menubar/MenubarContent.cjs +4 -0
  218. package/dist/Menubar/MenubarContent.cjs.map +1 -1
  219. package/dist/Menubar/MenubarContent.js +4 -0
  220. package/dist/Menubar/MenubarContent.js.map +1 -1
  221. package/dist/Menubar/MenubarSubContent.cjs +4 -0
  222. package/dist/Menubar/MenubarSubContent.cjs.map +1 -1
  223. package/dist/Menubar/MenubarSubContent.js +4 -0
  224. package/dist/Menubar/MenubarSubContent.js.map +1 -1
  225. package/dist/Popover/PopoverContent.cjs +8 -0
  226. package/dist/Popover/PopoverContent.cjs.map +1 -1
  227. package/dist/Popover/PopoverContent.js +8 -0
  228. package/dist/Popover/PopoverContent.js.map +1 -1
  229. package/dist/Popover/PopoverContentImpl.cjs +8 -0
  230. package/dist/Popover/PopoverContentImpl.cjs.map +1 -1
  231. package/dist/Popover/PopoverContentImpl.js +8 -0
  232. package/dist/Popover/PopoverContentImpl.js.map +1 -1
  233. package/dist/Popover/PopoverContentModal.cjs +8 -0
  234. package/dist/Popover/PopoverContentModal.cjs.map +1 -1
  235. package/dist/Popover/PopoverContentModal.js +8 -0
  236. package/dist/Popover/PopoverContentModal.js.map +1 -1
  237. package/dist/Popover/PopoverContentNonModal.cjs +8 -0
  238. package/dist/Popover/PopoverContentNonModal.cjs.map +1 -1
  239. package/dist/Popover/PopoverContentNonModal.js +8 -0
  240. package/dist/Popover/PopoverContentNonModal.js.map +1 -1
  241. package/dist/Popper/PopperContent.cjs +49 -6
  242. package/dist/Popper/PopperContent.cjs.map +1 -1
  243. package/dist/Popper/PopperContent.js +50 -7
  244. package/dist/Popper/PopperContent.js.map +1 -1
  245. package/dist/Popper/utils.cjs +10 -5
  246. package/dist/Popper/utils.cjs.map +1 -1
  247. package/dist/Popper/utils.js +10 -5
  248. package/dist/Popper/utils.js.map +1 -1
  249. package/dist/RadioGroup/Radio.cjs +27 -22
  250. package/dist/RadioGroup/Radio.cjs.map +1 -1
  251. package/dist/RadioGroup/Radio.js +28 -23
  252. package/dist/RadioGroup/Radio.js.map +1 -1
  253. package/dist/Rating/RatingItem.cjs +66 -0
  254. package/dist/Rating/RatingItem.cjs.map +1 -0
  255. package/dist/Rating/RatingItem.js +54 -0
  256. package/dist/Rating/RatingItem.js.map +1 -0
  257. package/dist/Rating/RatingItemIndicator.cjs +89 -0
  258. package/dist/Rating/RatingItemIndicator.cjs.map +1 -0
  259. package/dist/Rating/RatingItemIndicator.js +83 -0
  260. package/dist/Rating/RatingItemIndicator.js.map +1 -0
  261. package/dist/Rating/RatingRoot.cjs +136 -0
  262. package/dist/Rating/RatingRoot.cjs.map +1 -0
  263. package/dist/Rating/RatingRoot.js +124 -0
  264. package/dist/Rating/RatingRoot.js.map +1 -0
  265. package/dist/RovingFocus/RovingFocusItem.cjs +5 -0
  266. package/dist/RovingFocus/RovingFocusItem.cjs.map +1 -1
  267. package/dist/RovingFocus/RovingFocusItem.js +6 -1
  268. package/dist/RovingFocus/RovingFocusItem.js.map +1 -1
  269. package/dist/Select/SelectContent.cjs +8 -0
  270. package/dist/Select/SelectContent.cjs.map +1 -1
  271. package/dist/Select/SelectContent.js +8 -0
  272. package/dist/Select/SelectContent.js.map +1 -1
  273. package/dist/Select/SelectContentImpl.cjs +8 -0
  274. package/dist/Select/SelectContentImpl.cjs.map +1 -1
  275. package/dist/Select/SelectContentImpl.js +8 -0
  276. package/dist/Select/SelectContentImpl.js.map +1 -1
  277. package/dist/Select/SelectPopperPosition.cjs +8 -0
  278. package/dist/Select/SelectPopperPosition.cjs.map +1 -1
  279. package/dist/Select/SelectPopperPosition.js +8 -0
  280. package/dist/Select/SelectPopperPosition.js.map +1 -1
  281. package/dist/Select/SelectRoot.cjs +10 -5
  282. package/dist/Select/SelectRoot.cjs.map +1 -1
  283. package/dist/Select/SelectRoot.js +10 -5
  284. package/dist/Select/SelectRoot.js.map +1 -1
  285. package/dist/Select/SelectTrigger.cjs +25 -14
  286. package/dist/Select/SelectTrigger.cjs.map +1 -1
  287. package/dist/Select/SelectTrigger.js +25 -14
  288. package/dist/Select/SelectTrigger.js.map +1 -1
  289. package/dist/Switch/SwitchRoot.cjs +25 -18
  290. package/dist/Switch/SwitchRoot.cjs.map +1 -1
  291. package/dist/Switch/SwitchRoot.js +26 -19
  292. package/dist/Switch/SwitchRoot.js.map +1 -1
  293. package/dist/Tabs/TabsIndicator.cjs +4 -0
  294. package/dist/Tabs/TabsIndicator.cjs.map +1 -1
  295. package/dist/Tabs/TabsIndicator.js +4 -0
  296. package/dist/Tabs/TabsIndicator.js.map +1 -1
  297. package/dist/Teleport/Teleport.cjs +6 -3
  298. package/dist/Teleport/Teleport.cjs.map +1 -1
  299. package/dist/Teleport/Teleport.js +7 -4
  300. package/dist/Teleport/Teleport.js.map +1 -1
  301. package/dist/Toggle/Toggle.cjs +21 -16
  302. package/dist/Toggle/Toggle.cjs.map +1 -1
  303. package/dist/Toggle/Toggle.js +22 -17
  304. package/dist/Toggle/Toggle.js.map +1 -1
  305. package/dist/Toolbar/ToolbarToggleItem.cjs +5 -2
  306. package/dist/Toolbar/ToolbarToggleItem.cjs.map +1 -1
  307. package/dist/Toolbar/ToolbarToggleItem.js +5 -2
  308. package/dist/Toolbar/ToolbarToggleItem.js.map +1 -1
  309. package/dist/Tree/TreeItem.cjs +18 -2
  310. package/dist/Tree/TreeItem.cjs.map +1 -1
  311. package/dist/Tree/TreeItem.js +18 -2
  312. package/dist/Tree/TreeItem.js.map +1 -1
  313. package/dist/Tree/TreeVirtualizer.cjs +2 -1
  314. package/dist/Tree/TreeVirtualizer.cjs.map +1 -1
  315. package/dist/Tree/TreeVirtualizer.js +2 -1
  316. package/dist/Tree/TreeVirtualizer.js.map +1 -1
  317. package/dist/VisuallyHidden/VisuallyHidden.cjs +1 -1
  318. package/dist/VisuallyHidden/VisuallyHidden.cjs.map +1 -1
  319. package/dist/VisuallyHidden/VisuallyHidden.js +1 -1
  320. package/dist/VisuallyHidden/VisuallyHidden.js.map +1 -1
  321. package/dist/composables/useDrawerSnapPoints.cjs +130 -0
  322. package/dist/composables/useDrawerSnapPoints.cjs.map +1 -0
  323. package/dist/composables/useDrawerSnapPoints.js +124 -0
  324. package/dist/composables/useDrawerSnapPoints.js.map +1 -0
  325. package/dist/composables/useSwipeDismiss.cjs +397 -0
  326. package/dist/composables/useSwipeDismiss.cjs.map +1 -0
  327. package/dist/composables/useSwipeDismiss.js +391 -0
  328. package/dist/composables/useSwipeDismiss.js.map +1 -0
  329. package/dist/constant/components.cjs +20 -0
  330. package/dist/constant/components.cjs.map +1 -1
  331. package/dist/constant/components.js +20 -0
  332. package/dist/constant/components.js.map +1 -1
  333. package/dist/constant.d.cts +2 -0
  334. package/dist/constant.d.cts.map +1 -1
  335. package/dist/constant.d.ts +2 -0
  336. package/dist/constant.d.ts.map +1 -1
  337. package/dist/date/utils.cjs +1 -1
  338. package/dist/date/utils.cjs.map +1 -1
  339. package/dist/date/utils.js +1 -1
  340. package/dist/date/utils.js.map +1 -1
  341. package/dist/index.cjs +45 -1
  342. package/dist/index.d.cts +2 -2
  343. package/dist/index.d.ts +2 -2
  344. package/dist/index.js +24 -2
  345. package/dist/index2.d.cts.map +1 -1
  346. package/dist/index3.d.cts +68 -29
  347. package/dist/index3.d.cts.map +1 -1
  348. package/dist/index3.d.ts +68 -29
  349. package/dist/index3.d.ts.map +1 -1
  350. package/dist/index4.d.cts +1648 -1190
  351. package/dist/index4.d.cts.map +1 -1
  352. package/dist/index4.d.ts +1660 -1202
  353. package/dist/index4.d.ts.map +1 -1
  354. package/dist/internal.cjs +1 -1
  355. package/dist/internal.d.cts +3 -3
  356. package/dist/internal.d.ts +3 -3
  357. package/dist/internal.js +1 -1
  358. package/dist/namespaced/index.cjs +22 -0
  359. package/dist/namespaced/index.d.cts +22 -2
  360. package/dist/namespaced/index.d.mts +22 -2
  361. package/dist/namespaced/index.mjs +22 -2
  362. package/dist/nuxt/index.d.cts +2 -1
  363. package/dist/nuxt/index.d.mts +2 -1
  364. package/dist/resolver/index.d.cts +2 -1
  365. package/dist/resolver/index.d.mts +2 -1
  366. package/dist/shared/useEmitAsProps.cjs +5 -0
  367. package/dist/shared/useEmitAsProps.cjs.map +1 -1
  368. package/dist/shared/useEmitAsProps.js +5 -0
  369. package/dist/shared/useEmitAsProps.js.map +1 -1
  370. package/dist/shared/useForwardPropsEmits.cjs +0 -12
  371. package/dist/shared/useForwardPropsEmits.cjs.map +1 -1
  372. package/dist/shared/useForwardPropsEmits.js +0 -12
  373. package/dist/shared/useForwardPropsEmits.js.map +1 -1
  374. package/dist/shared/useForwardScopeId.cjs +34 -0
  375. package/dist/shared/useForwardScopeId.cjs.map +1 -0
  376. package/dist/shared/useForwardScopeId.js +28 -0
  377. package/dist/shared/useForwardScopeId.js.map +1 -0
  378. package/dist/shared/useId.cjs +7 -8
  379. package/dist/shared/useId.cjs.map +1 -1
  380. package/dist/shared/useId.js +7 -8
  381. package/dist/shared/useId.js.map +1 -1
  382. package/dist/shared/useSize.cjs +6 -2
  383. package/dist/shared/useSize.cjs.map +1 -1
  384. package/dist/shared/useSize.js +7 -3
  385. package/dist/shared/useSize.js.map +1 -1
  386. package/dist/shared.cjs +2 -2
  387. package/dist/shared.d.cts +2 -2
  388. package/dist/shared.d.ts +2 -2
  389. package/dist/shared.js +2 -2
  390. package/dist/utils/style.cjs +1 -1
  391. package/dist/utils/style.cjs.map +1 -1
  392. package/dist/utils/style.js +1 -1
  393. package/dist/utils/style.js.map +1 -1
  394. package/package.json +7 -5
  395. package/src/AlertDialog/AlertDialogContent.vue +6 -1
  396. package/src/Checkbox/CheckboxRoot.vue +28 -16
  397. package/src/Collection/Collection.ts +2 -1
  398. package/src/Combobox/ComboboxContentImpl.vue +20 -4
  399. package/src/Combobox/ComboboxItem.vue +1 -0
  400. package/src/ConfigProvider/ConfigProvider.vue +11 -1
  401. package/src/DateField/DateFieldInput.vue +6 -1
  402. package/src/DateField/DateFieldRoot.vue +6 -1
  403. package/src/Dialog/DialogContent.vue +16 -2
  404. package/src/Dialog/DialogContentImpl.vue +9 -2
  405. package/src/Dialog/DialogContentModal.vue +23 -4
  406. package/src/Dialog/DialogContentNonModal.vue +21 -3
  407. package/src/Dialog/DialogOverlay.vue +4 -0
  408. package/src/Dialog/DialogOverlayImpl.vue +7 -2
  409. package/src/Dialog/DialogRoot.vue +10 -1
  410. package/src/DismissableLayer/DismissableLayer.vue +75 -23
  411. package/src/Drawer/DrawerClose.vue +25 -0
  412. package/src/Drawer/DrawerContent.vue +98 -0
  413. package/src/Drawer/DrawerContentImpl.vue +386 -0
  414. package/src/Drawer/DrawerDescription.vue +24 -0
  415. package/src/Drawer/DrawerHandle.vue +25 -0
  416. package/src/Drawer/DrawerIndent.vue +61 -0
  417. package/src/Drawer/DrawerIndentBackground.vue +26 -0
  418. package/src/Drawer/DrawerOverlay.vue +42 -0
  419. package/src/Drawer/DrawerOverlayImpl.vue +54 -0
  420. package/src/Drawer/DrawerPortal.vue +17 -0
  421. package/src/Drawer/DrawerProvider.vue +87 -0
  422. package/src/Drawer/DrawerRoot.vue +244 -0
  423. package/src/Drawer/DrawerSwipeArea.vue +73 -0
  424. package/src/Drawer/DrawerTitle.vue +24 -0
  425. package/src/Drawer/DrawerTrigger.vue +44 -0
  426. package/src/Drawer/DrawerViewport.vue +34 -0
  427. package/src/Drawer/composables/useDrawerSnapPoints.ts +200 -0
  428. package/src/Drawer/composables/useSwipeDismiss.ts +557 -0
  429. package/src/Drawer/index.ts +74 -0
  430. package/src/Drawer/utils.ts +205 -0
  431. package/src/FocusScope/FocusScope.vue +76 -19
  432. package/src/HoverCard/HoverCardRoot.vue +7 -1
  433. package/src/HoverCard/HoverCardTrigger.vue +11 -0
  434. package/src/Listbox/ListboxRoot.vue +7 -4
  435. package/src/Listbox/ListboxVirtualizer.vue +19 -3
  436. package/src/Popper/PopperContent.vue +45 -4
  437. package/src/Popper/utils.ts +17 -7
  438. package/src/RadioGroup/Radio.vue +22 -14
  439. package/src/Rating/RatingItem.vue +1 -0
  440. package/src/Rating/RatingItemIndicator.vue +3 -2
  441. package/src/Rating/RatingRoot.vue +6 -3
  442. package/src/Rating/index.ts +3 -3
  443. package/src/RovingFocus/RovingFocusItem.vue +12 -1
  444. package/src/Select/SelectRoot.vue +4 -1
  445. package/src/Select/SelectTrigger.vue +49 -33
  446. package/src/Splitter/utils/style.ts +1 -1
  447. package/src/Switch/SwitchRoot.vue +20 -12
  448. package/src/Tabs/TabsIndicator.vue +5 -0
  449. package/src/Teleport/Teleport.vue +8 -4
  450. package/src/Toggle/Toggle.vue +18 -9
  451. package/src/Toolbar/ToolbarToggleItem.vue +4 -1
  452. package/src/Tree/TreeItem.vue +18 -0
  453. package/src/Tree/TreeRoot.vue +2 -2
  454. package/src/Tree/TreeVirtualizer.vue +3 -1
  455. package/src/VisuallyHidden/VisuallyHidden.vue +1 -1
  456. package/src/index.ts +2 -0
  457. package/src/shared/date/utils.ts +1 -1
  458. package/src/shared/index.ts +2 -2
  459. package/src/shared/useEmitAsProps.test-d.ts +77 -0
  460. package/src/shared/useEmitAsProps.ts +83 -4
  461. package/src/shared/useForwardProps.ts +1 -1
  462. package/src/shared/useForwardPropsEmits.ts +17 -2
  463. package/src/shared/useForwardScopeId.ts +26 -0
  464. package/src/shared/useId.ts +14 -6
  465. package/src/shared/useSize.ts +9 -4
  466. package/dist/shared/trap-focus.cjs +0 -35
  467. package/dist/shared/trap-focus.cjs.map +0 -1
  468. package/dist/shared/trap-focus.js +0 -30
  469. package/dist/shared/trap-focus.js.map +0 -1
  470. package/src/shared/trap-focus.ts +0 -43
@@ -0,0 +1,205 @@
1
+ // packages/core/src/Drawer/utils.ts
2
+
3
+ export type SwipeDirection = 'up' | 'down' | 'left' | 'right'
4
+ export type DrawerSnapPoint = number | string
5
+
6
+ export const DRAWER_CSS_VARS = {
7
+ swipeMovementX: '--drawer-swipe-movement-x',
8
+ swipeMovementY: '--drawer-swipe-movement-y',
9
+ snapPointOffset: '--drawer-snap-point-offset',
10
+ height: '--drawer-height',
11
+ frontmostHeight: '--drawer-frontmost-height',
12
+ swipeProgress: '--drawer-swipe-progress',
13
+ swipeStrength: '--drawer-swipe-strength',
14
+ nestedDrawers: '--nested-drawers',
15
+ } as const
16
+
17
+ export interface NestedSwipeProgressStore {
18
+ getSnapshot: () => number
19
+ subscribe: (listener: () => void) => () => void
20
+ }
21
+
22
+ export function createNestedSwipeProgressStore(): NestedSwipeProgressStore & {
23
+ set: (progress: number) => void
24
+ } {
25
+ let progress = 0
26
+ const listeners = new Set<() => void>()
27
+ return {
28
+ getSnapshot: () => progress,
29
+ subscribe(listener) {
30
+ listeners.add(listener)
31
+ return () => listeners.delete(listener)
32
+ },
33
+ set(next: number) {
34
+ if (next !== progress) {
35
+ progress = next
36
+ listeners.forEach(l => l())
37
+ }
38
+ },
39
+ }
40
+ }
41
+
42
+ export function getDisplacement(
43
+ direction: SwipeDirection,
44
+ deltaX: number,
45
+ deltaY: number,
46
+ ): number {
47
+ switch (direction) {
48
+ case 'up': return -deltaY
49
+ case 'down': return deltaY
50
+ case 'left': return -deltaX
51
+ case 'right': return deltaX
52
+ default: return 0
53
+ }
54
+ }
55
+
56
+ // BaseUI swipe release scalar constants (DrawerViewport.tsx:41-46)
57
+ const MIN_SWIPE_RELEASE_VELOCITY = 0.2
58
+ const MAX_SWIPE_RELEASE_VELOCITY = 4
59
+ const MIN_SWIPE_RELEASE_DURATION_MS = 80
60
+ const MAX_SWIPE_RELEASE_DURATION_MS = 360
61
+ const MIN_SWIPE_RELEASE_SCALAR = 0.1
62
+ const MAX_SWIPE_RELEASE_SCALAR = 1
63
+
64
+ function clamp(v: number, lo: number, hi: number): number {
65
+ return Math.max(lo, Math.min(hi, v))
66
+ }
67
+
68
+ /**
69
+ * Computes a 0.1 - 1.0 scalar for the `--drawer-swipe-strength` CSS var.
70
+ * Ported from BaseUI `DrawerViewport.tsx:resolveSwipeRelease` (lines 243-337).
71
+ *
72
+ * The scalar is derived from how much further the drawer still has to travel
73
+ * vs how fast the user flung it. A short remaining distance with high velocity
74
+ * → near-zero scalar (fast release). A long distance / low velocity → near-1
75
+ * (default release).
76
+ *
77
+ * Returns `null` when the formula is degenerate (no velocity, no distance, or
78
+ * moving in the wrong direction).
79
+ */
80
+ export function computeSwipeReleaseScalar(params: {
81
+ direction: SwipeDirection
82
+ size: number
83
+ axisDelta: number
84
+ snapPointOffset: number
85
+ releaseVelocity: number
86
+ }): number | null {
87
+ const { direction, size, axisDelta, snapPointOffset, releaseVelocity } = params
88
+ if (!Number.isFinite(size) || size <= 0)
89
+ return null
90
+
91
+ // Seed the translation with the active snap offset along the dismiss axis so
92
+ // horizontal drawers honor snap points too: down/right collapse toward
93
+ // positive translation, up/left toward negative.
94
+ let baseOffset = 0
95
+ if (direction === 'down' || direction === 'right')
96
+ baseOffset = snapPointOffset
97
+ else if (direction === 'up' || direction === 'left')
98
+ baseOffset = -snapPointOffset
99
+
100
+ const translation = baseOffset + axisDelta
101
+ const translationAlongDirection
102
+ = (direction === 'left' || direction === 'up') ? -translation : translation
103
+ const remainingDistance = Math.max(0, size - translationAlongDirection)
104
+ if (!Number.isFinite(remainingDistance) || remainingDistance <= 0)
105
+ return null
106
+
107
+ const directionalVelocity
108
+ = (direction === 'left' || direction === 'up') ? -releaseVelocity : releaseVelocity
109
+ if (!Number.isFinite(directionalVelocity) || directionalVelocity <= MIN_SWIPE_RELEASE_VELOCITY)
110
+ return null
111
+
112
+ const clampedVelocity = clamp(
113
+ directionalVelocity,
114
+ MIN_SWIPE_RELEASE_VELOCITY,
115
+ MAX_SWIPE_RELEASE_VELOCITY,
116
+ )
117
+ const durationMs = clamp(
118
+ remainingDistance / clampedVelocity,
119
+ MIN_SWIPE_RELEASE_DURATION_MS,
120
+ MAX_SWIPE_RELEASE_DURATION_MS,
121
+ )
122
+ if (!Number.isFinite(durationMs))
123
+ return null
124
+
125
+ const normalized
126
+ = (durationMs - MIN_SWIPE_RELEASE_DURATION_MS)
127
+ / (MAX_SWIPE_RELEASE_DURATION_MS - MIN_SWIPE_RELEASE_DURATION_MS)
128
+ const scalar = clamp(
129
+ MIN_SWIPE_RELEASE_SCALAR + normalized * (MAX_SWIPE_RELEASE_SCALAR - MIN_SWIPE_RELEASE_SCALAR),
130
+ MIN_SWIPE_RELEASE_SCALAR,
131
+ MAX_SWIPE_RELEASE_SCALAR,
132
+ )
133
+ if (!Number.isFinite(scalar) || scalar <= 0)
134
+ return null
135
+ return scalar
136
+ }
137
+
138
+ const MATRIX_RE = /matrix(?:3d)?\(([^)]+)\)/
139
+
140
+ export function getElementTransform(element: HTMLElement): {
141
+ x: number
142
+ y: number
143
+ scale: number
144
+ } {
145
+ const style = window.getComputedStyle(element)
146
+ const transform = style.transform
147
+ let x = 0
148
+ let y = 0
149
+ let scale = 1
150
+ if (transform && transform !== 'none') {
151
+ const matrix = transform.match(MATRIX_RE)
152
+ if (matrix) {
153
+ const v = matrix[1].split(', ').map(Number)
154
+ if (v.length === 6) {
155
+ x = v[4]
156
+ y = v[5]
157
+ scale = Math.sqrt(v[0] * v[0] + v[1] * v[1])
158
+ }
159
+ else if (v.length === 16) {
160
+ x = v[12]
161
+ y = v[13]
162
+ scale = v[0]
163
+ }
164
+ }
165
+ }
166
+ return { x, y, scale }
167
+ }
168
+
169
+ let drawerCssVarsRegistered = false
170
+
171
+ /**
172
+ * Removes CSS variable inheritance for high-frequency drawer swipe vars.
173
+ * Uses proper syntax types matching BaseUI:
174
+ * - Length vars (<length>) with initialValue '0px' for use in calc()/translateY()
175
+ * - Number vars (<number>) for opacity/strength scalars
176
+ */
177
+ export function registerDrawerCssProperties() {
178
+ if (drawerCssVarsRegistered || typeof CSS === 'undefined' || !CSS.registerProperty)
179
+ return
180
+
181
+ const lengthVars = [
182
+ DRAWER_CSS_VARS.swipeMovementX,
183
+ DRAWER_CSS_VARS.swipeMovementY,
184
+ DRAWER_CSS_VARS.snapPointOffset,
185
+ ]
186
+ for (const name of lengthVars) {
187
+ try {
188
+ CSS.registerProperty({ name, syntax: '<length>', inherits: false, initialValue: '0px' })
189
+ }
190
+ catch {}
191
+ }
192
+
193
+ const numberVars = [
194
+ { name: DRAWER_CSS_VARS.swipeProgress, initialValue: '0' },
195
+ { name: DRAWER_CSS_VARS.swipeStrength, initialValue: '1' },
196
+ ]
197
+ for (const { name, initialValue } of numberVars) {
198
+ try {
199
+ CSS.registerProperty({ name, syntax: '<number>', inherits: false, initialValue })
200
+ }
201
+ catch {}
202
+ }
203
+
204
+ drawerCssVarsRegistered = true
205
+ }
@@ -30,12 +30,22 @@ export interface FocusScopeProps extends PrimitiveProps {
30
30
  * @defaultValue false
31
31
  */
32
32
  trapped?: boolean
33
+
34
+ /**
35
+ * Whether the scope is currently visible. Lets a consumer keep the scope
36
+ * mounted but hidden (e.g. `display: none`) and still get correct auto-focus:
37
+ * the mount auto-focus is skipped while not present, and re-runs when it
38
+ * becomes present again. Defaults to `true` so consumers that mount the scope
39
+ * only while visible are unaffected.
40
+ * @defaultValue true
41
+ */
42
+ present?: boolean
33
43
  }
34
44
  </script>
35
45
 
36
46
  <script setup lang="ts">
37
47
  import { isClient } from '@vueuse/shared'
38
- import { nextTick, reactive, ref, watchEffect } from 'vue'
48
+ import { nextTick, reactive, ref, watch, watchEffect } from 'vue'
39
49
  import { Primitive } from '@/Primitive'
40
50
  import { createFocusScopesStack } from './stack'
41
51
  import {
@@ -149,35 +159,51 @@ watchEffect((cleanupFn) => {
149
159
  })
150
160
  })
151
161
 
162
+ // Dispatch the mount auto-focus event and move focus to the first tabbable
163
+ // candidate (or the container as a fallback). Shared by the physical-mount path
164
+ // and the visibility path below so both behave identically. Consumers (e.g.
165
+ // Dialog's `openAutoFocus`) may `preventDefault()` to opt out of default focus.
166
+ function dispatchMountAutoFocus(container: HTMLElement, previouslyFocusedElement: HTMLElement | null) {
167
+ const mountEvent = new CustomEvent(AUTOFOCUS_ON_MOUNT, EVENT_OPTIONS)
168
+ const handleMountAutoFocus = (ev: Event) => emits('mountAutoFocus', ev)
169
+ container.addEventListener(AUTOFOCUS_ON_MOUNT, handleMountAutoFocus)
170
+ container.dispatchEvent(mountEvent)
171
+ container.removeEventListener(AUTOFOCUS_ON_MOUNT, handleMountAutoFocus)
172
+
173
+ if (!mountEvent.defaultPrevented) {
174
+ focusFirst(getTabbableCandidates(container), { select: true })
175
+ if (getActiveElement() === previouslyFocusedElement)
176
+ focus(container)
177
+ }
178
+ }
179
+
152
180
  watchEffect(async (cleanupFn) => {
153
181
  const container = currentElement.value
154
182
 
155
183
  await nextTick()
156
184
  if (!container)
157
185
  return
158
- focusScopesStack.add(focusScope)
186
+ // A scope that mounts hidden (`present: false`, e.g. a closed Dialog with
187
+ // `unmountOnHide: false`) must stay out of the scope stack: adding it would
188
+ // pause the currently active scope and break its focus trap. The `present`
189
+ // watcher below adds/removes it as it becomes visible.
190
+ if (props.present !== false)
191
+ focusScopesStack.add(focusScope)
159
192
  const previouslyFocusedElement = getActiveElement() as HTMLElement | null
160
193
  const hasFocusedCandidate = container.contains(previouslyFocusedElement)
161
194
 
162
- if (!hasFocusedCandidate) {
163
- const mountEvent = new CustomEvent(AUTOFOCUS_ON_MOUNT, EVENT_OPTIONS)
164
- container.addEventListener(AUTOFOCUS_ON_MOUNT, (ev: Event) =>
165
- emits('mountAutoFocus', ev))
166
- container.dispatchEvent(mountEvent)
167
-
168
- if (!mountEvent.defaultPrevented) {
169
- focusFirst(getTabbableCandidates(container), {
170
- select: true,
171
- })
172
- if (getActiveElement() === previouslyFocusedElement)
173
- focus(container)
174
- }
175
- }
195
+ // When force-mounted while closed (e.g. Dialog `unmountOnHide: false`), the
196
+ // consumer keeps the scope mounted but flags it as not present. Skip the
197
+ // mount auto-focus in that case, otherwise it fires `mountAutoFocus` and
198
+ // steals focus into a hidden scope. The `present` watcher below re-runs the
199
+ // auto-focus once the scope becomes present again.
200
+ // NOTE: `props.present` must stay read *after* the `await` above so this
201
+ // effect does not track it — re-running on `present` changes would dispatch
202
+ // the unmount auto-focus cleanup below on every close.
203
+ if (!hasFocusedCandidate && props.present !== false)
204
+ dispatchMountAutoFocus(container, previouslyFocusedElement)
176
205
 
177
206
  cleanupFn(() => {
178
- container.removeEventListener(AUTOFOCUS_ON_MOUNT, (ev: Event) =>
179
- emits('mountAutoFocus', ev))
180
-
181
207
  const unmountEvent = new CustomEvent(AUTOFOCUS_ON_UNMOUNT, EVENT_OPTIONS)
182
208
  const unmountEventHandler = (ev: Event) => {
183
209
  emits('unmountAutoFocus', ev)
@@ -202,6 +228,37 @@ watchEffect(async (cleanupFn) => {
202
228
  })
203
229
  })
204
230
 
231
+ // Force-mounted scopes (e.g. Dialog `unmountOnHide: false`) stay mounted across
232
+ // open/close and toggle `present` instead of unmounting, so mount/unmount-keyed
233
+ // behavior must be re-keyed on `present`: stack membership (which pauses other
234
+ // scopes' traps) and the mount auto-focus (which only fires on physical mount).
235
+ // Awaiting `nextTick` lets the consumer's visibility change (e.g. `v-show`)
236
+ // apply first, so the focus targets exist. Consumers that don't pass `present`
237
+ // never hit this — it stays `undefined`.
238
+ watch(() => props.present, async (present, prevPresent) => {
239
+ if (!isClient)
240
+ return
241
+
242
+ if (present === false && prevPresent === true) {
243
+ focusScopesStack.remove(focusScope)
244
+ return
245
+ }
246
+
247
+ if (present !== true || prevPresent !== false)
248
+ return
249
+
250
+ focusScopesStack.add(focusScope)
251
+
252
+ await nextTick()
253
+ const container = currentElement.value
254
+ if (!container)
255
+ return
256
+
257
+ const previouslyFocusedElement = getActiveElement() as HTMLElement | null
258
+ if (!container.contains(previouslyFocusedElement))
259
+ dispatchMountAutoFocus(container, previouslyFocusedElement)
260
+ })
261
+
205
262
  function handleKeyDown(event: KeyboardEvent) {
206
263
  if (!props.loop && !props.trapped)
207
264
  return
@@ -11,6 +11,8 @@ export interface HoverCardRootProps {
11
11
  openDelay?: number
12
12
  /** The duration from when the mouse leaves the trigger or content until the hover card closes. */
13
13
  closeDelay?: number
14
+ /** When `true`, tapping the trigger on touch devices toggles the hover card open/closed. By default touch interactions are ignored to match pointer hover semantics. */
15
+ enableTouch?: boolean
14
16
  }
15
17
  export type HoverCardRootEmits = {
16
18
  /** Event handler called when the open state of the hover card changes. */
@@ -27,6 +29,7 @@ export interface HoverCardRootContext {
27
29
  isPointerDownOnContentRef: Ref<boolean>
28
30
  isPointerInTransitRef: Ref<boolean>
29
31
  triggerElement: Ref<HTMLElement | undefined>
32
+ enableTouch: Ref<boolean>
30
33
  }
31
34
 
32
35
  export const [injectHoverCardRootContext, provideHoverCardRootContext]
@@ -43,6 +46,7 @@ const props = withDefaults(defineProps<HoverCardRootProps>(), {
43
46
  open: undefined,
44
47
  openDelay: 700,
45
48
  closeDelay: 300,
49
+ enableTouch: false,
46
50
  })
47
51
  const emit = defineEmits<HoverCardRootEmits>()
48
52
 
@@ -53,7 +57,7 @@ defineSlots<{
53
57
  }) => any
54
58
  }>()
55
59
 
56
- const { openDelay, closeDelay } = toRefs(props)
60
+ const { openDelay, closeDelay, enableTouch } = toRefs(props)
57
61
 
58
62
  useForwardExpose()
59
63
  const open = useVModel(props, 'open', emit, {
@@ -80,6 +84,7 @@ function handleClose() {
80
84
  }
81
85
 
82
86
  function handleDismiss() {
87
+ clearTimeout(openTimerRef.value)
83
88
  open.value = false
84
89
  }
85
90
 
@@ -95,6 +100,7 @@ provideHoverCardRootContext({
95
100
  isPointerDownOnContentRef,
96
101
  isPointerInTransitRef,
97
102
  triggerElement,
103
+ enableTouch,
98
104
  })
99
105
  </script>
100
106
 
@@ -25,6 +25,16 @@ function handleLeave() {
25
25
  }
26
26
  }, 0)
27
27
  }
28
+
29
+ function handleTouch(event: PointerEvent) {
30
+ if (!rootContext.enableTouch.value || event.pointerType !== 'touch')
31
+ return
32
+
33
+ if (rootContext.open.value)
34
+ rootContext.onDismiss()
35
+ else
36
+ rootContext.onOpenChange(true)
37
+ }
28
38
  </script>
29
39
 
30
40
  <template>
@@ -40,6 +50,7 @@ function handleLeave() {
40
50
  data-grace-area-trigger
41
51
  @pointerenter="excludeTouch(rootContext.onOpen)($event)"
42
52
  @pointerleave="excludeTouch(handleLeave)($event)"
53
+ @pointerup="handleTouch"
43
54
  @focus="rootContext.onOpen()"
44
55
  @blur="rootContext.onClose()"
45
56
  >
@@ -16,7 +16,7 @@ type ListboxRootContext<T> = {
16
16
  highlightOnHover: Ref<boolean>
17
17
  highlightedElement: Ref<HTMLElement | null>
18
18
  isVirtual: Ref<boolean>
19
- virtualFocusHook: EventHook<Event | null | undefined>
19
+ virtualFocusHook: EventHook<{ event?: Event, scroll: boolean }>
20
20
  virtualKeydownHook: EventHook<KeyboardEvent>
21
21
  virtualHighlightHook: EventHook<any>
22
22
  by?: string | ((a: T, b: T) => boolean)
@@ -150,7 +150,7 @@ const highlightedElement = ref<HTMLElement | null>(null)
150
150
  const previousElement = ref<HTMLElement | null>(null)
151
151
  const isVirtual = ref(false)
152
152
  const isComposing = ref(false)
153
- const virtualFocusHook = createEventHook<Event | null | undefined>()
153
+ const virtualFocusHook = createEventHook<{ event?: Event, scroll: boolean }>()
154
154
  const virtualKeydownHook = createEventHook<KeyboardEvent>()
155
155
  const virtualHighlightHook = createEventHook<T>()
156
156
 
@@ -333,8 +333,11 @@ async function highlightSelected(event?: Event, scroll = true) {
333
333
  return
334
334
  await nextTick()
335
335
  if (isVirtual.value) {
336
- // Trigger on nextTick for Virtualizer to be mounted
337
- virtualFocusHook.trigger(event)
336
+ // Trigger on nextTick for Virtualizer to be mounted.
337
+ // `scroll` is `false` on the initial mount highlight, so the virtualizer sets
338
+ // its roving-tabindex target without focusing/scrolling — otherwise a
339
+ // virtualized Listbox below the fold would pull the page to it on load.
340
+ virtualFocusHook.trigger({ event, scroll })
338
341
  }
339
342
  else {
340
343
  const collection = getCollectionItem()
@@ -104,7 +104,11 @@ const virtualizedItems = computed(() => virtualizer.value.getVirtualItems().map(
104
104
  }
105
105
  }))
106
106
 
107
- rootContext.virtualFocusHook.on((event) => {
107
+ rootContext.virtualFocusHook.on(({ event, scroll }) => {
108
+ // `scroll` is `false` only for the initial mount highlight. There we set the
109
+ // roving-tabindex target without focusing or scrolling, so a virtualized
110
+ // Listbox below the fold doesn't pull the page to it on load. User-driven
111
+ // highlights (keyboard, typeahead, select) keep scrolling as before.
108
112
  const index = props.options.findIndex((option) => {
109
113
  if (Array.isArray(rootContext.modelValue.value))
110
114
  return compare(option, rootContext.modelValue.value[0], rootContext.by)
@@ -114,19 +118,31 @@ rootContext.virtualFocusHook.on((event) => {
114
118
  if (index !== -1) {
115
119
  event?.preventDefault()
116
120
 
121
+ // Bringing the checked item into the (internal) scroll viewport is safe — it
122
+ // only scrolls the listbox container, never the page.
117
123
  virtualizer.value.scrollToIndex(index, { align: 'start' })
118
124
  requestAnimationFrame(() => {
119
125
  const item = queryCheckedElement(parentEl.value)
120
126
  if (item) {
121
- rootContext.changeHighlight(item)
127
+ rootContext.changeHighlight(item, scroll, scroll ? undefined : false)
122
128
  if (event)
123
129
  item?.focus()
124
130
  }
125
131
  })
126
132
  }
127
- else {
133
+ else if (scroll) {
128
134
  rootContext.highlightFirstItem()
129
135
  }
136
+ else {
137
+ // Mount highlight with no checked item: highlight the first enabled item only,
138
+ // mirroring the non-virtual path. `highlightFirstItem` is reserved for
139
+ // user-driven PageUp/Home navigation, which focuses and scrolls.
140
+ requestAnimationFrame(() => {
141
+ const item = getItems().find(i => i.ref.dataset.disabled !== '')?.ref
142
+ if (item)
143
+ rootContext.changeHighlight(item, false, false)
144
+ })
145
+ }
130
146
  })
131
147
 
132
148
  rootContext.virtualHighlightHook.on((value) => {
@@ -10,7 +10,8 @@ import type {
10
10
  Side,
11
11
  } from './utils'
12
12
  import type { PrimitiveProps } from '@/Primitive'
13
- import { createContext, useForwardExpose, useSize } from '@/shared'
13
+ import type { Direction } from '@/shared/types'
14
+ import { createContext, useDirection, useForwardExpose, useSize } from '@/shared'
14
15
 
15
16
  export const PopperContentPropsDefaultValue = {
16
17
  side: 'bottom' as Side,
@@ -32,6 +33,11 @@ export const PopperContentPropsDefaultValue = {
32
33
  }
33
34
 
34
35
  export interface PopperContentProps extends PrimitiveProps {
36
+ /**
37
+ * Reactive dependencies that should invalidate the memoized content subtree.
38
+ */
39
+ memoDependencies?: unknown[]
40
+
35
41
  /**
36
42
  * The preferred side of the trigger to render against when open.
37
43
  * Will be reversed when collisions occur and avoidCollisions
@@ -173,6 +179,11 @@ export interface PopperContentProps extends PrimitiveProps {
173
179
  * If provided, it will replace the default anchor element.
174
180
  */
175
181
  reference?: ReferenceElement
182
+
183
+ /**
184
+ * The reading direction of the popper content when applicable. <br> If omitted, inherits globally from `ConfigProvider` or assumes LTR (left-to-right) reading mode.
185
+ */
186
+ dir?: Direction
176
187
  }
177
188
 
178
189
  export interface PopperContentContext {
@@ -199,7 +210,6 @@ import {
199
210
  size,
200
211
  useFloating,
201
212
  } from '@floating-ui/vue'
202
- import { computedEager } from '@vueuse/core'
203
213
  import { computed, ref, watchEffect, watchPostEffect } from 'vue'
204
214
  import {
205
215
  Primitive,
@@ -224,6 +234,7 @@ const emits = defineEmits<{
224
234
 
225
235
  const rootContext = injectPopperRootContext()
226
236
  const { forwardRef, currentElement: contentElement } = useForwardExpose()
237
+ const dir = useDirection(computed(() => props.dir))
227
238
 
228
239
  const floatingRef = ref<HTMLElement>()
229
240
 
@@ -264,7 +275,7 @@ const flipOptions = computed(() => {
264
275
  }
265
276
  })
266
277
 
267
- const computedMiddleware = computedEager(() => {
278
+ const computedMiddleware = computed(() => {
268
279
  return [
269
280
  offset({
270
281
  mainAxis: props.sideOffset + arrowHeight.value,
@@ -317,6 +328,7 @@ const computedMiddleware = computedEager(() => {
317
328
  transformOrigin({
318
329
  arrowWidth: arrowWidth.value,
319
330
  arrowHeight: arrowHeight.value,
331
+ dir: dir.value,
320
332
  }),
321
333
  props.hideWhenDetached
322
334
  && hide({ strategy: 'referenceHidden', ...detectOverflowOptions.value }),
@@ -382,6 +394,7 @@ providePopperContentContext({
382
394
  <div
383
395
  ref="floatingRef"
384
396
  data-reka-popper-content-wrapper=""
397
+ :dir="dir"
385
398
  :style="{
386
399
  ...floatingStyles,
387
400
  transform: isPositioned ? floatingStyles.transform : 'translate(0, -200%)', // keep off the page when measuring
@@ -402,12 +415,40 @@ providePopperContentContext({
402
415
  }"
403
416
  >
404
417
  <Primitive
418
+ v-if="props.memoDependencies"
419
+ :ref="forwardRef"
420
+ v-memo="[
421
+ props.asChild,
422
+ props.as,
423
+ placedSide,
424
+ placedAlign,
425
+ isPositioned,
426
+ ...Object.values($attrs),
427
+ ...props.memoDependencies,
428
+ ]"
429
+ v-bind="$attrs"
430
+ :as-child="props.asChild"
431
+ :as="props.as"
432
+ :data-side="placedSide"
433
+ :data-align="placedAlign"
434
+ :style="{
435
+ // if the PopperContent hasn't been placed yet (not all measurements done)
436
+ // we prevent animations so that users's animation don't kick in too early referring wrong sides
437
+ animation: !isPositioned ? 'none' : undefined,
438
+ }"
439
+ >
440
+ <slot />
441
+ </Primitive>
442
+
443
+ <Primitive
444
+ v-else
405
445
  :ref="forwardRef"
406
446
  v-bind="$attrs"
407
447
  :as-child="props.asChild"
408
- :as="as"
448
+ :as="props.as"
409
449
  :data-side="placedSide"
410
450
  :data-align="placedAlign"
451
+ :dir="dir"
411
452
  :style="{
412
453
  // if the PopperContent hasn't been placed yet (not all measurements done)
413
454
  // we prevent animations so that users's animation don't kick in too early referring wrong sides
@@ -1,4 +1,5 @@
1
1
  import type { Middleware, Placement } from '@floating-ui/vue'
2
+ import type { Direction } from '@/shared/types'
2
3
 
3
4
  const SIDE_OPTIONS = ['top', 'right', 'bottom', 'left'] as const
4
5
  const ALIGN_OPTIONS = ['start', 'center', 'end'] as const
@@ -13,6 +14,7 @@ export function isNotNull<T>(value: T | null): value is T {
13
14
  export function transformOrigin(options: {
14
15
  arrowWidth: number
15
16
  arrowHeight: number
17
+ dir?: Direction
16
18
  }): Middleware {
17
19
  return {
18
20
  name: 'transformOrigin',
@@ -26,9 +28,17 @@ export function transformOrigin(options: {
26
28
  const arrowHeight = isArrowHidden ? 0 : options.arrowHeight
27
29
 
28
30
  const [placedSide, placedAlign] = getSideAndAlignFromPlacement(placement)
29
- const noArrowAlign = { start: '0%', center: '50%', end: '100%' }[
30
- placedAlign
31
- ]
31
+ const noArrowAlignX = {
32
+ start: options.dir === 'rtl' ? '100%' : '0%',
33
+ center: '50%',
34
+ end: options.dir === 'rtl' ? '0%' : '100%',
35
+ }[placedAlign]
36
+
37
+ const noArrowAlignY = {
38
+ start: '0%',
39
+ center: '50%',
40
+ end: '100%',
41
+ }[placedAlign]
32
42
 
33
43
  const arrowXCenter = (middlewareData.arrow?.x ?? 0) + arrowWidth / 2
34
44
  const arrowYCenter = (middlewareData.arrow?.y ?? 0) + arrowHeight / 2
@@ -37,20 +47,20 @@ export function transformOrigin(options: {
37
47
  let y = ''
38
48
 
39
49
  if (placedSide === 'bottom') {
40
- x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`
50
+ x = isArrowHidden ? noArrowAlignX : `${arrowXCenter}px`
41
51
  y = `${-arrowHeight}px`
42
52
  }
43
53
  else if (placedSide === 'top') {
44
- x = isArrowHidden ? noArrowAlign : `${arrowXCenter}px`
54
+ x = isArrowHidden ? noArrowAlignX : `${arrowXCenter}px`
45
55
  y = `${rects.floating.height + arrowHeight}px`
46
56
  }
47
57
  else if (placedSide === 'right') {
48
58
  x = `${-arrowHeight}px`
49
- y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`
59
+ y = isArrowHidden ? noArrowAlignY : `${arrowYCenter}px`
50
60
  }
51
61
  else if (placedSide === 'left') {
52
62
  x = `${rects.floating.width + arrowHeight}px`
53
- y = isArrowHidden ? noArrowAlign : `${arrowYCenter}px`
63
+ y = isArrowHidden ? noArrowAlignY : `${arrowYCenter}px`
54
64
  }
55
65
  return { data: { x, y } }
56
66
  },