@base-ui/react 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (579) hide show
  1. package/CHANGELOG.md +125 -8
  2. package/README.md +1 -1
  3. package/accordion/item/AccordionItem.d.ts +4 -0
  4. package/accordion/item/AccordionItem.js +5 -4
  5. package/accordion/panel/AccordionPanel.js +29 -51
  6. package/accordion/root/AccordionRoot.js +5 -6
  7. package/accordion/trigger/AccordionTrigger.js +3 -4
  8. package/alert-dialog/handle.d.ts +14 -1
  9. package/alert-dialog/handle.js +22 -5
  10. package/alert-dialog/index.d.ts +1 -1
  11. package/alert-dialog/index.parts.d.ts +2 -3
  12. package/alert-dialog/index.parts.js +4 -5
  13. package/alert-dialog/root/AlertDialogRoot.d.ts +7 -7
  14. package/alert-dialog/root/AlertDialogRoot.js +2 -56
  15. package/alert-dialog/trigger/AlertDialogTrigger.d.ts +25 -0
  16. package/alert-dialog/trigger/AlertDialogTrigger.js +15 -0
  17. package/alert-dialog/trigger/AlertDialogTriggerDataAttributes.d.ts +10 -0
  18. package/alert-dialog/trigger/AlertDialogTriggerDataAttributes.js +18 -0
  19. package/autocomplete/root/AutocompleteRoot.js +9 -10
  20. package/avatar/image/AvatarImage.js +4 -4
  21. package/checkbox/indicator/CheckboxIndicator.js +2 -2
  22. package/checkbox/root/CheckboxRoot.js +49 -11
  23. package/checkbox-group/CheckboxGroup.js +1 -5
  24. package/collapsible/panel/CollapsiblePanel.js +29 -51
  25. package/collapsible/panel/useCollapsiblePanel.d.ts +9 -23
  26. package/collapsible/panel/useCollapsiblePanel.js +308 -268
  27. package/collapsible/root/CollapsibleRoot.d.ts +1 -1
  28. package/collapsible/root/CollapsibleRootContext.d.ts +0 -2
  29. package/collapsible/root/useCollapsibleRoot.d.ts +0 -27
  30. package/collapsible/root/useCollapsibleRoot.js +2 -64
  31. package/collapsible/trigger/CollapsibleTrigger.js +5 -6
  32. package/combobox/arrow/ComboboxArrow.js +1 -1
  33. package/combobox/backdrop/ComboboxBackdrop.js +1 -1
  34. package/combobox/chip/ComboboxChip.js +7 -2
  35. package/combobox/clear/ComboboxClear.d.ts +4 -0
  36. package/combobox/clear/ComboboxClear.js +1 -0
  37. package/combobox/clear/ComboboxClearDataAttributes.d.ts +4 -0
  38. package/combobox/clear/ComboboxClearDataAttributes.js +4 -0
  39. package/combobox/icon/ComboboxIcon.js +1 -1
  40. package/combobox/input/ComboboxInput.js +15 -6
  41. package/combobox/item/ComboboxItem.js +8 -14
  42. package/combobox/item-indicator/ComboboxItemIndicator.js +1 -2
  43. package/combobox/root/AriaCombobox.js +61 -28
  44. package/combobox/store.d.ts +4 -8
  45. package/combobox/store.js +2 -1
  46. package/combobox/utils/ComboboxInternalDismissButton.js +2 -3
  47. package/csp-provider/CSPProvider.js +1 -1
  48. package/dialog/close/DialogClose.js +6 -6
  49. package/dialog/popup/DialogPopup.js +9 -4
  50. package/dialog/root/DialogRoot.d.ts +1 -2
  51. package/dialog/root/DialogRoot.js +3 -73
  52. package/dialog/root/DialogRootContext.d.ts +1 -0
  53. package/dialog/root/DialogRootContext.js +3 -1
  54. package/dialog/root/useDialogRoot.d.ts +12 -4
  55. package/dialog/root/useDialogRoot.js +27 -25
  56. package/dialog/root/useRenderDialogRoot.d.ts +4 -0
  57. package/dialog/root/useRenderDialogRoot.js +96 -0
  58. package/dialog/store/DialogHandle.d.ts +1 -1
  59. package/dialog/store/DialogHandle.js +2 -2
  60. package/dialog/store/DialogStore.d.ts +88 -1
  61. package/dialog/store/DialogStore.js +12 -17
  62. package/dialog/trigger/DialogTrigger.d.ts +1 -1
  63. package/dialog/trigger/DialogTrigger.js +11 -4
  64. package/dialog/viewport/DialogViewport.js +4 -3
  65. package/drawer/popup/DrawerPopup.js +13 -9
  66. package/drawer/root/DrawerRoot.js +11 -11
  67. package/drawer/root/DrawerRootContext.d.ts +1 -1
  68. package/drawer/swipe-area/DrawerSwipeArea.js +6 -5
  69. package/drawer/viewport/DrawerViewport.js +13 -14
  70. package/esm/accordion/item/AccordionItem.d.ts +4 -0
  71. package/esm/accordion/item/AccordionItem.js +5 -4
  72. package/esm/accordion/panel/AccordionPanel.js +29 -51
  73. package/esm/accordion/root/AccordionRoot.js +5 -6
  74. package/esm/accordion/trigger/AccordionTrigger.js +4 -5
  75. package/esm/alert-dialog/handle.d.ts +14 -1
  76. package/esm/alert-dialog/handle.js +20 -5
  77. package/esm/alert-dialog/index.d.ts +1 -1
  78. package/esm/alert-dialog/index.parts.d.ts +2 -3
  79. package/esm/alert-dialog/index.parts.js +2 -3
  80. package/esm/alert-dialog/root/AlertDialogRoot.d.ts +7 -7
  81. package/esm/alert-dialog/root/AlertDialogRoot.js +2 -55
  82. package/esm/alert-dialog/trigger/AlertDialogTrigger.d.ts +25 -0
  83. package/esm/alert-dialog/trigger/AlertDialogTrigger.js +10 -0
  84. package/esm/alert-dialog/trigger/AlertDialogTriggerDataAttributes.d.ts +10 -0
  85. package/esm/alert-dialog/trigger/AlertDialogTriggerDataAttributes.js +12 -0
  86. package/esm/autocomplete/root/AutocompleteRoot.js +9 -10
  87. package/esm/avatar/image/AvatarImage.js +4 -4
  88. package/esm/checkbox/indicator/CheckboxIndicator.js +2 -2
  89. package/esm/checkbox/root/CheckboxRoot.js +49 -11
  90. package/esm/checkbox-group/CheckboxGroup.js +1 -5
  91. package/esm/collapsible/panel/CollapsiblePanel.js +29 -51
  92. package/esm/collapsible/panel/useCollapsiblePanel.d.ts +9 -23
  93. package/esm/collapsible/panel/useCollapsiblePanel.js +309 -269
  94. package/esm/collapsible/root/CollapsibleRoot.d.ts +1 -1
  95. package/esm/collapsible/root/CollapsibleRootContext.d.ts +0 -2
  96. package/esm/collapsible/root/useCollapsibleRoot.d.ts +0 -27
  97. package/esm/collapsible/root/useCollapsibleRoot.js +2 -64
  98. package/esm/collapsible/trigger/CollapsibleTrigger.js +5 -6
  99. package/esm/combobox/arrow/ComboboxArrow.js +1 -1
  100. package/esm/combobox/backdrop/ComboboxBackdrop.js +1 -1
  101. package/esm/combobox/chip/ComboboxChip.js +7 -2
  102. package/esm/combobox/clear/ComboboxClear.d.ts +4 -0
  103. package/esm/combobox/clear/ComboboxClear.js +1 -0
  104. package/esm/combobox/clear/ComboboxClearDataAttributes.d.ts +4 -0
  105. package/esm/combobox/clear/ComboboxClearDataAttributes.js +4 -0
  106. package/esm/combobox/icon/ComboboxIcon.js +1 -1
  107. package/esm/combobox/input/ComboboxInput.js +16 -7
  108. package/esm/combobox/item/ComboboxItem.js +8 -14
  109. package/esm/combobox/item-indicator/ComboboxItemIndicator.js +1 -2
  110. package/esm/combobox/root/AriaCombobox.js +62 -29
  111. package/esm/combobox/store.d.ts +4 -8
  112. package/esm/combobox/store.js +2 -1
  113. package/esm/combobox/utils/ComboboxInternalDismissButton.js +2 -3
  114. package/esm/csp-provider/CSPProvider.js +1 -1
  115. package/esm/dialog/close/DialogClose.js +6 -6
  116. package/esm/dialog/popup/DialogPopup.js +9 -4
  117. package/esm/dialog/root/DialogRoot.d.ts +1 -2
  118. package/esm/dialog/root/DialogRoot.js +4 -72
  119. package/esm/dialog/root/DialogRootContext.d.ts +1 -0
  120. package/esm/dialog/root/DialogRootContext.js +2 -0
  121. package/esm/dialog/root/useDialogRoot.d.ts +12 -4
  122. package/esm/dialog/root/useDialogRoot.js +28 -27
  123. package/esm/dialog/root/useRenderDialogRoot.d.ts +4 -0
  124. package/esm/dialog/root/useRenderDialogRoot.js +90 -0
  125. package/esm/dialog/store/DialogHandle.d.ts +1 -1
  126. package/esm/dialog/store/DialogHandle.js +2 -2
  127. package/esm/dialog/store/DialogStore.d.ts +88 -1
  128. package/esm/dialog/store/DialogStore.js +13 -18
  129. package/esm/dialog/trigger/DialogTrigger.d.ts +1 -1
  130. package/esm/dialog/trigger/DialogTrigger.js +12 -5
  131. package/esm/dialog/viewport/DialogViewport.js +4 -3
  132. package/esm/drawer/popup/DrawerPopup.js +14 -9
  133. package/esm/drawer/root/DrawerRoot.js +11 -11
  134. package/esm/drawer/root/DrawerRootContext.d.ts +1 -1
  135. package/esm/drawer/swipe-area/DrawerSwipeArea.js +6 -5
  136. package/esm/drawer/viewport/DrawerViewport.js +13 -14
  137. package/esm/field/control/FieldControl.js +2 -6
  138. package/esm/field/item/FieldItem.js +1 -4
  139. package/esm/field/root/FieldRoot.js +11 -3
  140. package/esm/field/root/useFieldValidation.d.ts +1 -0
  141. package/esm/field/root/useFieldValidation.js +23 -20
  142. package/esm/field/utils/getCombinedFieldValidityData.d.ts +1 -1
  143. package/esm/field/validity/FieldValidity.d.ts +1 -1
  144. package/esm/floating-ui-react/components/FloatingDelayGroup.js +3 -3
  145. package/esm/floating-ui-react/components/FloatingFocusManager.d.ts +1 -1
  146. package/esm/floating-ui-react/components/FloatingFocusManager.js +20 -8
  147. package/esm/floating-ui-react/components/FloatingPortal.js +3 -3
  148. package/esm/floating-ui-react/hooks/useClick.js +83 -74
  149. package/esm/floating-ui-react/hooks/useClientPoint.js +29 -20
  150. package/esm/floating-ui-react/hooks/useDismiss.d.ts +1 -1
  151. package/esm/floating-ui-react/hooks/useDismiss.js +82 -93
  152. package/esm/floating-ui-react/hooks/useFloating.js +37 -32
  153. package/esm/floating-ui-react/hooks/useFloatingRootContext.d.ts +1 -1
  154. package/esm/floating-ui-react/hooks/useFloatingRootContext.js +2 -2
  155. package/esm/floating-ui-react/hooks/useFocus.js +84 -81
  156. package/esm/floating-ui-react/hooks/useHover.js +72 -76
  157. package/esm/floating-ui-react/hooks/useHoverFloatingInteraction.js +49 -44
  158. package/esm/floating-ui-react/hooks/useHoverInteractionSharedState.js +1 -1
  159. package/esm/floating-ui-react/hooks/useHoverReferenceInteraction.d.ts +7 -2
  160. package/esm/floating-ui-react/hooks/useHoverReferenceInteraction.js +44 -39
  161. package/esm/floating-ui-react/hooks/useHoverShared.d.ts +2 -1
  162. package/esm/floating-ui-react/hooks/useHoverShared.js +4 -0
  163. package/esm/floating-ui-react/hooks/useListNavigation.d.ts +1 -3
  164. package/esm/floating-ui-react/hooks/useListNavigation.js +83 -74
  165. package/esm/floating-ui-react/hooks/useSyncedFloatingRootContext.d.ts +9 -6
  166. package/esm/floating-ui-react/hooks/useSyncedFloatingRootContext.js +25 -20
  167. package/esm/floating-ui-react/hooks/useTypeahead.d.ts +2 -2
  168. package/esm/floating-ui-react/hooks/useTypeahead.js +33 -52
  169. package/esm/floating-ui-react/index.d.ts +0 -2
  170. package/esm/floating-ui-react/index.js +0 -2
  171. package/esm/floating-ui-react/types.d.ts +2 -7
  172. package/esm/floating-ui-react/utils/composite.js +2 -0
  173. package/esm/floating-ui-react/utils/enqueueFocus.d.ts +1 -1
  174. package/esm/floating-ui-react/utils/enqueueFocus.js +10 -7
  175. package/esm/floating-ui-react/utils/getEmptyRootContext.js +1 -1
  176. package/esm/form/Form.js +2 -2
  177. package/esm/index.js +1 -1
  178. package/esm/internals/composite/composite.d.ts +0 -1
  179. package/esm/internals/composite/composite.js +1 -2
  180. package/esm/internals/composite/root/useCompositeRoot.js +2 -2
  181. package/esm/internals/createBaseUIEventDetails.d.ts +2 -0
  182. package/esm/internals/csp-context/index.d.ts +2 -0
  183. package/esm/internals/csp-context/index.js +1 -0
  184. package/esm/internals/field-register-control/index.d.ts +0 -1
  185. package/esm/internals/field-register-control/useFieldControlRegistration.d.ts +2 -1
  186. package/esm/internals/field-register-control/useFieldControlRegistration.js +11 -14
  187. package/esm/internals/field-register-control/useRegisterFieldControl.d.ts +1 -4
  188. package/esm/internals/field-register-control/useRegisterFieldControl.js +6 -11
  189. package/esm/internals/field-root-context/FieldRootContext.d.ts +1 -0
  190. package/esm/internals/field-root-context/FieldRootContext.js +3 -2
  191. package/esm/internals/form-context/FormContext.d.ts +5 -1
  192. package/esm/internals/reason-parts.d.ts +2 -0
  193. package/esm/internals/reason-parts.js +2 -0
  194. package/esm/internals/types.d.ts +1 -0
  195. package/esm/internals/use-button/useButton.js +4 -4
  196. package/esm/internals/usePressAndHold.js +2 -2
  197. package/esm/internals/useRenderElement.js +2 -0
  198. package/esm/menu/arrow/MenuArrow.js +1 -1
  199. package/esm/menu/backdrop/MenuBackdrop.js +1 -1
  200. package/esm/menu/checkbox-item/MenuCheckboxItem.js +5 -7
  201. package/esm/menu/group/MenuGroup.js +1 -4
  202. package/esm/menu/group/MenuGroupContext.d.ts +1 -3
  203. package/esm/menu/group/MenuGroupContext.js +1 -1
  204. package/esm/menu/group-label/MenuGroupLabel.js +4 -6
  205. package/esm/menu/link-item/MenuLinkItem.js +2 -2
  206. package/esm/menu/popup/MenuPopup.js +5 -5
  207. package/esm/menu/radio-group/MenuRadioGroup.js +11 -5
  208. package/esm/menu/radio-item/MenuRadioItem.js +5 -7
  209. package/esm/menu/root/MenuRoot.js +63 -68
  210. package/esm/menu/store/MenuHandle.js +1 -1
  211. package/esm/menu/store/MenuStore.d.ts +87 -0
  212. package/esm/menu/submenu-trigger/MenuSubmenuTrigger.js +8 -5
  213. package/esm/menu/trigger/MenuTrigger.js +13 -10
  214. package/esm/menu/viewport/MenuViewport.d.ts +2 -2
  215. package/esm/menu/viewport/MenuViewport.js +2 -2
  216. package/esm/navigation-menu/arrow/NavigationMenuArrow.js +1 -1
  217. package/esm/navigation-menu/backdrop/NavigationMenuBackdrop.js +1 -1
  218. package/esm/navigation-menu/content/NavigationMenuContent.js +8 -5
  219. package/esm/navigation-menu/icon/NavigationMenuIcon.js +1 -1
  220. package/esm/navigation-menu/item/NavigationMenuItem.js +2 -2
  221. package/esm/navigation-menu/list/NavigationMenuList.js +1 -1
  222. package/esm/navigation-menu/popup/NavigationMenuPopup.js +2 -2
  223. package/esm/navigation-menu/root/NavigationMenuRoot.js +1 -3
  224. package/esm/navigation-menu/trigger/NavigationMenuTrigger.js +24 -17
  225. package/esm/navigation-menu/utils/isOutsideMenuEvent.d.ts +0 -1
  226. package/esm/navigation-menu/utils/isOutsideMenuEvent.js +1 -5
  227. package/esm/navigation-menu/viewport/NavigationMenuViewport.js +2 -3
  228. package/esm/number-field/input/NumberFieldInput.js +3 -5
  229. package/esm/number-field/root/NumberFieldRoot.js +5 -2
  230. package/esm/number-field/scrub-area/NumberFieldScrubArea.js +7 -3
  231. package/esm/otp-field/input/OTPFieldInput.js +43 -29
  232. package/esm/otp-field/root/OTPFieldRoot.d.ts +17 -8
  233. package/esm/otp-field/root/OTPFieldRoot.js +33 -33
  234. package/esm/otp-field/root/OTPFieldRootContext.d.ts +1 -1
  235. package/esm/otp-field/utils/otp.d.ts +5 -4
  236. package/esm/otp-field/utils/otp.js +23 -12
  237. package/esm/popover/arrow/PopoverArrow.js +1 -1
  238. package/esm/popover/backdrop/PopoverBackdrop.js +1 -1
  239. package/esm/popover/close/PopoverClose.js +2 -2
  240. package/esm/popover/description/PopoverDescription.js +1 -7
  241. package/esm/popover/popup/PopoverPopup.d.ts +1 -1
  242. package/esm/popover/popup/PopoverPopup.js +16 -10
  243. package/esm/popover/popup/PopoverPopupDataAttributes.d.ts +1 -1
  244. package/esm/popover/popup/PopoverPopupDataAttributes.js +1 -1
  245. package/esm/popover/positioner/PopoverPositioner.js +5 -5
  246. package/esm/popover/root/PopoverRoot.d.ts +1 -1
  247. package/esm/popover/root/PopoverRoot.js +42 -47
  248. package/esm/popover/store/PopoverHandle.js +1 -1
  249. package/esm/popover/store/PopoverStore.d.ts +91 -4
  250. package/esm/popover/store/PopoverStore.js +17 -18
  251. package/esm/popover/title/PopoverTitle.js +1 -7
  252. package/esm/popover/trigger/PopoverTrigger.js +24 -17
  253. package/esm/popover/viewport/PopoverViewport.d.ts +3 -3
  254. package/esm/popover/viewport/PopoverViewport.js +2 -2
  255. package/esm/popover/viewport/PopoverViewportDataAttributes.d.ts +1 -1
  256. package/esm/popover/viewport/PopoverViewportDataAttributes.js +1 -1
  257. package/esm/preview-card/positioner/PreviewCardPositioner.js +11 -1
  258. package/esm/preview-card/root/PreviewCardRoot.d.ts +1 -1
  259. package/esm/preview-card/root/PreviewCardRoot.js +32 -22
  260. package/esm/preview-card/store/PreviewCardHandle.js +1 -1
  261. package/esm/preview-card/store/PreviewCardStore.d.ts +90 -2
  262. package/esm/preview-card/store/PreviewCardStore.js +19 -31
  263. package/esm/preview-card/trigger/PreviewCardTrigger.js +6 -3
  264. package/esm/preview-card/viewport/PreviewCardViewport.d.ts +2 -2
  265. package/esm/preview-card/viewport/PreviewCardViewport.js +2 -2
  266. package/esm/preview-card/viewport/PreviewCardViewportDataAttributes.d.ts +2 -2
  267. package/esm/preview-card/viewport/PreviewCardViewportDataAttributes.js +2 -2
  268. package/esm/progress/indicator/ProgressIndicator.js +6 -11
  269. package/esm/progress/root/ProgressRoot.d.ts +1 -1
  270. package/esm/radio/root/RadioRoot.js +7 -3
  271. package/esm/radio-group/RadioGroup.js +4 -11
  272. package/esm/radio-group/RadioGroupContext.d.ts +0 -1
  273. package/esm/scroll-area/content/ScrollAreaContent.js +4 -4
  274. package/esm/scroll-area/root/ScrollAreaRoot.js +1 -1
  275. package/esm/scroll-area/scrollbar/ScrollAreaScrollbar.js +16 -20
  276. package/esm/scroll-area/viewport/ScrollAreaViewport.js +6 -10
  277. package/esm/select/arrow/SelectArrow.js +1 -1
  278. package/esm/select/backdrop/SelectBackdrop.js +1 -1
  279. package/esm/select/group/SelectGroup.js +1 -1
  280. package/esm/select/group-label/SelectGroupLabel.js +2 -2
  281. package/esm/select/icon/SelectIcon.js +1 -1
  282. package/esm/select/item/SelectItem.js +46 -32
  283. package/esm/select/item/SelectItemContext.d.ts +1 -1
  284. package/esm/select/item-indicator/SelectItemIndicator.js +1 -2
  285. package/esm/select/item-text/SelectItemText.js +9 -6
  286. package/esm/select/list/SelectList.js +1 -1
  287. package/esm/select/popup/SelectPopup.js +8 -3
  288. package/esm/select/positioner/SelectPositioner.js +3 -0
  289. package/esm/select/root/SelectRoot.js +46 -40
  290. package/esm/select/root/SelectRootContext.d.ts +4 -5
  291. package/esm/select/store.d.ts +3 -0
  292. package/esm/select/store.js +1 -0
  293. package/esm/select/trigger/SelectTrigger.d.ts +5 -0
  294. package/esm/select/trigger/SelectTrigger.js +19 -33
  295. package/esm/select/trigger/SelectTriggerDataAttributes.d.ts +5 -0
  296. package/esm/select/trigger/SelectTriggerDataAttributes.js +5 -0
  297. package/esm/slider/control/SliderControl.js +10 -12
  298. package/esm/slider/root/SliderRoot.js +1 -4
  299. package/esm/slider/thumb/SliderThumb.js +32 -30
  300. package/esm/slider/value/SliderValue.js +7 -15
  301. package/esm/switch/root/SwitchRoot.js +10 -10
  302. package/esm/switch/thumb/SwitchThumb.js +1 -9
  303. package/esm/tabs/indicator/TabsIndicator.js +14 -19
  304. package/esm/tabs/list/TabsList.js +4 -10
  305. package/esm/tabs/list/TabsListContext.d.ts +2 -1
  306. package/esm/tabs/panel/TabsPanel.js +1 -1
  307. package/esm/tabs/root/TabsRoot.d.ts +16 -1
  308. package/esm/tabs/root/TabsRoot.js +73 -25
  309. package/esm/tabs/root/TabsRootContext.d.ts +0 -2
  310. package/esm/toast/provider/ToastProvider.js +1 -1
  311. package/esm/toast/root/ToastRoot.d.ts +1 -1
  312. package/esm/toast/root/ToastRoot.js +108 -131
  313. package/esm/toast/root/ToastRootDataAttributes.d.ts +1 -1
  314. package/esm/toast/root/ToastRootDataAttributes.js +1 -1
  315. package/esm/toast/store.d.ts +9 -1
  316. package/esm/toast/store.js +19 -13
  317. package/esm/toast/useToastManager.d.ts +1 -1
  318. package/esm/toast/viewport/ToastViewport.js +1 -1
  319. package/esm/toggle/Toggle.js +5 -9
  320. package/esm/toggle-group/ToggleGroup.d.ts +2 -2
  321. package/esm/toggle-group/ToggleGroup.js +6 -13
  322. package/esm/toolbar/link/ToolbarLink.d.ts +1 -1
  323. package/esm/toolbar/link/ToolbarLink.js +1 -2
  324. package/esm/tooltip/arrow/TooltipArrow.js +3 -3
  325. package/esm/tooltip/popup/TooltipPopup.js +5 -4
  326. package/esm/tooltip/root/TooltipRoot.js +35 -26
  327. package/esm/tooltip/store/TooltipHandle.js +1 -1
  328. package/esm/tooltip/store/TooltipStore.d.ts +90 -2
  329. package/esm/tooltip/store/TooltipStore.js +18 -31
  330. package/esm/tooltip/trigger/TooltipTrigger.js +151 -20
  331. package/esm/tooltip/viewport/TooltipViewport.d.ts +2 -2
  332. package/esm/tooltip/viewport/TooltipViewport.js +2 -2
  333. package/esm/tooltip/viewport/TooltipViewportDataAttributes.d.ts +1 -1
  334. package/esm/tooltip/viewport/TooltipViewportDataAttributes.js +1 -1
  335. package/esm/unstable-use-media-query/index.js +1 -1
  336. package/esm/utils/popups/index.d.ts +1 -0
  337. package/esm/utils/popups/index.js +1 -0
  338. package/esm/utils/popups/inlineRect.d.ts +15 -0
  339. package/esm/utils/popups/inlineRect.js +191 -0
  340. package/esm/utils/popups/popupStoreUtils.d.ts +28 -10
  341. package/esm/utils/popups/popupStoreUtils.js +105 -20
  342. package/esm/utils/popups/popupTriggerMap.js +2 -0
  343. package/esm/utils/popups/store.d.ts +15 -2
  344. package/esm/utils/popups/store.js +38 -2
  345. package/esm/utils/popups/useTriggerFocusGuards.js +4 -5
  346. package/esm/utils/useAnchorPositioning.d.ts +5 -0
  347. package/esm/utils/useAnchorPositioning.js +12 -9
  348. package/esm/utils/useOpenInteractionType.d.ts +4 -0
  349. package/esm/utils/useOpenInteractionType.js +23 -18
  350. package/field/control/FieldControl.js +2 -6
  351. package/field/item/FieldItem.js +1 -4
  352. package/field/root/FieldRoot.js +11 -3
  353. package/field/root/useFieldValidation.d.ts +1 -0
  354. package/field/root/useFieldValidation.js +23 -20
  355. package/field/utils/getCombinedFieldValidityData.d.ts +1 -1
  356. package/field/validity/FieldValidity.d.ts +1 -1
  357. package/floating-ui-react/components/FloatingDelayGroup.js +3 -3
  358. package/floating-ui-react/components/FloatingFocusManager.d.ts +1 -1
  359. package/floating-ui-react/components/FloatingFocusManager.js +20 -8
  360. package/floating-ui-react/components/FloatingPortal.js +3 -3
  361. package/floating-ui-react/hooks/useClick.js +82 -73
  362. package/floating-ui-react/hooks/useClientPoint.js +29 -20
  363. package/floating-ui-react/hooks/useDismiss.d.ts +1 -1
  364. package/floating-ui-react/hooks/useDismiss.js +82 -92
  365. package/floating-ui-react/hooks/useFloating.js +36 -32
  366. package/floating-ui-react/hooks/useFloatingRootContext.d.ts +1 -1
  367. package/floating-ui-react/hooks/useFloatingRootContext.js +2 -2
  368. package/floating-ui-react/hooks/useFocus.js +84 -81
  369. package/floating-ui-react/hooks/useHover.js +74 -78
  370. package/floating-ui-react/hooks/useHoverFloatingInteraction.js +48 -43
  371. package/floating-ui-react/hooks/useHoverInteractionSharedState.js +1 -1
  372. package/floating-ui-react/hooks/useHoverReferenceInteraction.d.ts +7 -2
  373. package/floating-ui-react/hooks/useHoverReferenceInteraction.js +43 -38
  374. package/floating-ui-react/hooks/useHoverShared.d.ts +2 -1
  375. package/floating-ui-react/hooks/useHoverShared.js +11 -0
  376. package/floating-ui-react/hooks/useListNavigation.d.ts +1 -3
  377. package/floating-ui-react/hooks/useListNavigation.js +83 -74
  378. package/floating-ui-react/hooks/useSyncedFloatingRootContext.d.ts +9 -6
  379. package/floating-ui-react/hooks/useSyncedFloatingRootContext.js +26 -20
  380. package/floating-ui-react/hooks/useTypeahead.d.ts +2 -2
  381. package/floating-ui-react/hooks/useTypeahead.js +33 -52
  382. package/floating-ui-react/index.d.ts +0 -2
  383. package/floating-ui-react/index.js +0 -14
  384. package/floating-ui-react/types.d.ts +2 -7
  385. package/floating-ui-react/utils/composite.js +2 -0
  386. package/floating-ui-react/utils/enqueueFocus.d.ts +1 -1
  387. package/floating-ui-react/utils/enqueueFocus.js +10 -7
  388. package/floating-ui-react/utils/getEmptyRootContext.js +1 -1
  389. package/form/Form.js +2 -2
  390. package/index.js +1 -1
  391. package/internals/composite/composite.d.ts +0 -1
  392. package/internals/composite/composite.js +2 -3
  393. package/internals/composite/root/useCompositeRoot.js +1 -1
  394. package/internals/createBaseUIEventDetails.d.ts +2 -0
  395. package/internals/csp-context/index.d.ts +2 -0
  396. package/internals/csp-context/index.js +18 -0
  397. package/internals/field-register-control/index.d.ts +0 -1
  398. package/internals/field-register-control/useFieldControlRegistration.d.ts +2 -1
  399. package/internals/field-register-control/useFieldControlRegistration.js +11 -14
  400. package/internals/field-register-control/useRegisterFieldControl.d.ts +1 -4
  401. package/internals/field-register-control/useRegisterFieldControl.js +6 -11
  402. package/internals/field-root-context/FieldRootContext.d.ts +1 -0
  403. package/internals/field-root-context/FieldRootContext.js +4 -3
  404. package/internals/form-context/FormContext.d.ts +5 -1
  405. package/internals/reason-parts.d.ts +2 -0
  406. package/internals/reason-parts.js +3 -1
  407. package/internals/types.d.ts +1 -0
  408. package/internals/use-button/useButton.js +4 -4
  409. package/internals/usePressAndHold.js +2 -2
  410. package/internals/useRenderElement.js +2 -0
  411. package/menu/arrow/MenuArrow.js +1 -1
  412. package/menu/backdrop/MenuBackdrop.js +1 -1
  413. package/menu/checkbox-item/MenuCheckboxItem.js +5 -7
  414. package/menu/group/MenuGroup.js +1 -4
  415. package/menu/group/MenuGroupContext.d.ts +1 -3
  416. package/menu/group/MenuGroupContext.js +1 -1
  417. package/menu/group-label/MenuGroupLabel.js +4 -6
  418. package/menu/link-item/MenuLinkItem.js +2 -2
  419. package/menu/popup/MenuPopup.js +5 -5
  420. package/menu/radio-group/MenuRadioGroup.js +11 -5
  421. package/menu/radio-item/MenuRadioItem.js +5 -7
  422. package/menu/root/MenuRoot.js +60 -65
  423. package/menu/store/MenuHandle.js +1 -1
  424. package/menu/store/MenuStore.d.ts +87 -0
  425. package/menu/submenu-trigger/MenuSubmenuTrigger.js +7 -4
  426. package/menu/trigger/MenuTrigger.js +12 -9
  427. package/menu/viewport/MenuViewport.d.ts +2 -2
  428. package/menu/viewport/MenuViewport.js +2 -2
  429. package/navigation-menu/arrow/NavigationMenuArrow.js +1 -1
  430. package/navigation-menu/backdrop/NavigationMenuBackdrop.js +1 -1
  431. package/navigation-menu/content/NavigationMenuContent.js +8 -5
  432. package/navigation-menu/icon/NavigationMenuIcon.js +1 -1
  433. package/navigation-menu/item/NavigationMenuItem.js +2 -2
  434. package/navigation-menu/list/NavigationMenuList.js +1 -1
  435. package/navigation-menu/popup/NavigationMenuPopup.js +2 -2
  436. package/navigation-menu/root/NavigationMenuRoot.js +1 -3
  437. package/navigation-menu/trigger/NavigationMenuTrigger.js +23 -16
  438. package/navigation-menu/utils/isOutsideMenuEvent.d.ts +0 -1
  439. package/navigation-menu/utils/isOutsideMenuEvent.js +1 -5
  440. package/navigation-menu/viewport/NavigationMenuViewport.js +2 -3
  441. package/number-field/input/NumberFieldInput.js +3 -5
  442. package/number-field/root/NumberFieldRoot.js +5 -2
  443. package/number-field/scrub-area/NumberFieldScrubArea.js +7 -3
  444. package/otp-field/input/OTPFieldInput.js +42 -28
  445. package/otp-field/root/OTPFieldRoot.d.ts +17 -8
  446. package/otp-field/root/OTPFieldRoot.js +32 -32
  447. package/otp-field/root/OTPFieldRootContext.d.ts +1 -1
  448. package/otp-field/utils/otp.d.ts +5 -4
  449. package/otp-field/utils/otp.js +24 -12
  450. package/package.json +331 -317
  451. package/popover/arrow/PopoverArrow.js +1 -1
  452. package/popover/backdrop/PopoverBackdrop.js +1 -1
  453. package/popover/close/PopoverClose.js +2 -2
  454. package/popover/description/PopoverDescription.js +1 -7
  455. package/popover/popup/PopoverPopup.d.ts +1 -1
  456. package/popover/popup/PopoverPopup.js +16 -10
  457. package/popover/popup/PopoverPopupDataAttributes.d.ts +1 -1
  458. package/popover/popup/PopoverPopupDataAttributes.js +1 -1
  459. package/popover/positioner/PopoverPositioner.js +5 -5
  460. package/popover/root/PopoverRoot.d.ts +1 -1
  461. package/popover/root/PopoverRoot.js +39 -44
  462. package/popover/store/PopoverHandle.js +1 -1
  463. package/popover/store/PopoverStore.d.ts +91 -4
  464. package/popover/store/PopoverStore.js +16 -19
  465. package/popover/title/PopoverTitle.js +1 -7
  466. package/popover/trigger/PopoverTrigger.js +23 -16
  467. package/popover/viewport/PopoverViewport.d.ts +3 -3
  468. package/popover/viewport/PopoverViewport.js +2 -2
  469. package/popover/viewport/PopoverViewportDataAttributes.d.ts +1 -1
  470. package/popover/viewport/PopoverViewportDataAttributes.js +1 -1
  471. package/preview-card/positioner/PreviewCardPositioner.js +11 -1
  472. package/preview-card/root/PreviewCardRoot.d.ts +1 -1
  473. package/preview-card/root/PreviewCardRoot.js +30 -20
  474. package/preview-card/store/PreviewCardHandle.js +1 -1
  475. package/preview-card/store/PreviewCardStore.d.ts +90 -2
  476. package/preview-card/store/PreviewCardStore.js +18 -30
  477. package/preview-card/trigger/PreviewCardTrigger.js +5 -2
  478. package/preview-card/viewport/PreviewCardViewport.d.ts +2 -2
  479. package/preview-card/viewport/PreviewCardViewport.js +2 -2
  480. package/preview-card/viewport/PreviewCardViewportDataAttributes.d.ts +2 -2
  481. package/preview-card/viewport/PreviewCardViewportDataAttributes.js +2 -2
  482. package/progress/indicator/ProgressIndicator.js +6 -11
  483. package/progress/root/ProgressRoot.d.ts +1 -1
  484. package/radio/root/RadioRoot.js +7 -3
  485. package/radio-group/RadioGroup.js +4 -11
  486. package/radio-group/RadioGroupContext.d.ts +0 -1
  487. package/scroll-area/content/ScrollAreaContent.js +4 -4
  488. package/scroll-area/root/ScrollAreaRoot.js +1 -1
  489. package/scroll-area/scrollbar/ScrollAreaScrollbar.js +16 -20
  490. package/scroll-area/viewport/ScrollAreaViewport.js +6 -10
  491. package/select/arrow/SelectArrow.js +1 -1
  492. package/select/backdrop/SelectBackdrop.js +1 -1
  493. package/select/group/SelectGroup.js +1 -1
  494. package/select/group-label/SelectGroupLabel.js +2 -2
  495. package/select/icon/SelectIcon.js +1 -1
  496. package/select/item/SelectItem.js +46 -32
  497. package/select/item/SelectItemContext.d.ts +1 -1
  498. package/select/item-indicator/SelectItemIndicator.js +1 -2
  499. package/select/item-text/SelectItemText.js +9 -6
  500. package/select/list/SelectList.js +1 -1
  501. package/select/popup/SelectPopup.js +8 -3
  502. package/select/positioner/SelectPositioner.js +3 -0
  503. package/select/root/SelectRoot.js +45 -39
  504. package/select/root/SelectRootContext.d.ts +4 -5
  505. package/select/store.d.ts +3 -0
  506. package/select/store.js +1 -0
  507. package/select/trigger/SelectTrigger.d.ts +5 -0
  508. package/select/trigger/SelectTrigger.js +19 -33
  509. package/select/trigger/SelectTriggerDataAttributes.d.ts +5 -0
  510. package/select/trigger/SelectTriggerDataAttributes.js +5 -0
  511. package/slider/control/SliderControl.js +9 -11
  512. package/slider/root/SliderRoot.js +1 -4
  513. package/slider/thumb/SliderThumb.js +32 -30
  514. package/slider/value/SliderValue.js +7 -15
  515. package/switch/root/SwitchRoot.js +10 -10
  516. package/switch/thumb/SwitchThumb.js +1 -9
  517. package/tabs/indicator/TabsIndicator.js +14 -19
  518. package/tabs/list/TabsList.js +4 -10
  519. package/tabs/list/TabsListContext.d.ts +2 -1
  520. package/tabs/panel/TabsPanel.js +1 -1
  521. package/tabs/root/TabsRoot.d.ts +16 -1
  522. package/tabs/root/TabsRoot.js +71 -24
  523. package/tabs/root/TabsRootContext.d.ts +0 -2
  524. package/toast/provider/ToastProvider.js +1 -1
  525. package/toast/root/ToastRoot.d.ts +1 -1
  526. package/toast/root/ToastRoot.js +110 -133
  527. package/toast/root/ToastRootDataAttributes.d.ts +1 -1
  528. package/toast/root/ToastRootDataAttributes.js +1 -1
  529. package/toast/store.d.ts +9 -1
  530. package/toast/store.js +18 -12
  531. package/toast/useToastManager.d.ts +1 -1
  532. package/toast/viewport/ToastViewport.js +1 -1
  533. package/toggle/Toggle.js +5 -9
  534. package/toggle-group/ToggleGroup.d.ts +2 -2
  535. package/toggle-group/ToggleGroup.js +6 -13
  536. package/toolbar/link/ToolbarLink.d.ts +1 -1
  537. package/toolbar/link/ToolbarLink.js +1 -2
  538. package/tooltip/arrow/TooltipArrow.js +3 -3
  539. package/tooltip/popup/TooltipPopup.js +5 -4
  540. package/tooltip/root/TooltipRoot.js +32 -23
  541. package/tooltip/store/TooltipHandle.js +1 -1
  542. package/tooltip/store/TooltipStore.d.ts +90 -2
  543. package/tooltip/store/TooltipStore.js +17 -30
  544. package/tooltip/trigger/TooltipTrigger.js +152 -20
  545. package/tooltip/viewport/TooltipViewport.d.ts +2 -2
  546. package/tooltip/viewport/TooltipViewport.js +2 -2
  547. package/tooltip/viewport/TooltipViewportDataAttributes.d.ts +1 -1
  548. package/tooltip/viewport/TooltipViewportDataAttributes.js +1 -1
  549. package/unstable-use-media-query/index.js +1 -1
  550. package/utils/popups/index.d.ts +1 -0
  551. package/utils/popups/index.js +11 -0
  552. package/utils/popups/inlineRect.d.ts +15 -0
  553. package/utils/popups/inlineRect.js +198 -0
  554. package/utils/popups/popupStoreUtils.d.ts +28 -10
  555. package/utils/popups/popupStoreUtils.js +110 -20
  556. package/utils/popups/popupTriggerMap.js +2 -0
  557. package/utils/popups/store.d.ts +15 -2
  558. package/utils/popups/store.js +39 -2
  559. package/utils/popups/useTriggerFocusGuards.js +4 -5
  560. package/utils/useAnchorPositioning.d.ts +5 -0
  561. package/utils/useAnchorPositioning.js +12 -9
  562. package/utils/useOpenInteractionType.d.ts +4 -0
  563. package/utils/useOpenInteractionType.js +24 -17
  564. package/checkbox-group/index.parts.d.ts +0 -1
  565. package/checkbox-group/index.parts.js +0 -12
  566. package/esm/checkbox-group/index.parts.d.ts +0 -1
  567. package/esm/checkbox-group/index.parts.js +0 -1
  568. package/esm/floating-ui-react/hooks/useInteractions.d.ts +0 -20
  569. package/esm/floating-ui-react/hooks/useInteractions.js +0 -88
  570. package/esm/floating-ui-react/hooks/useRole.d.ts +0 -17
  571. package/esm/floating-ui-react/hooks/useRole.js +0 -113
  572. package/floating-ui-react/hooks/useInteractions.d.ts +0 -20
  573. package/floating-ui-react/hooks/useInteractions.js +0 -95
  574. package/floating-ui-react/hooks/useRole.d.ts +0 -17
  575. package/floating-ui-react/hooks/useRole.js +0 -120
  576. /package/{csp-provider → esm/internals/csp-context}/CSPContext.d.ts +0 -0
  577. /package/esm/{csp-provider → internals/csp-context}/CSPContext.js +0 -0
  578. /package/{esm/csp-provider → internals/csp-context}/CSPContext.d.ts +0 -0
  579. /package/{csp-provider → internals/csp-context}/CSPContext.js +0 -0
@@ -5,9 +5,10 @@ import { fastComponent } from '@base-ui/utils/fastHooks';
5
5
  import { useOnFirstRender } from '@base-ui/utils/useOnFirstRender';
6
6
  import { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect';
7
7
  import { TooltipRootContext } from "./TooltipRootContext.js";
8
- import { useClientPoint, useDismiss, useInteractions } from "../../floating-ui-react/index.js";
8
+ import { useClientPoint, useDismiss } from "../../floating-ui-react/index.js";
9
9
  import { createChangeEventDetails } from "../../internals/createBaseUIEventDetails.js";
10
- import { useImplicitActiveTrigger, useOpenStateTransitions } from "../../utils/popups/index.js";
10
+ import { FOCUSABLE_POPUP_PROPS, useImplicitActiveTrigger, useOpenStateTransitions, usePopupInteractionProps } from "../../utils/popups/index.js";
11
+ import { mergeProps } from "../../merge-props/index.js";
11
12
  import { TooltipStore } from "../store/TooltipStore.js";
12
13
  import { REASONS } from "../../internals/reasons.js";
13
14
 
@@ -17,7 +18,7 @@ import { REASONS } from "../../internals/reasons.js";
17
18
  *
18
19
  * Documentation: [Base UI Tooltip](https://base-ui.com/react/components/tooltip)
19
20
  */
20
- import { jsx as _jsx } from "react/jsx-runtime";
21
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
21
22
  export const TooltipRoot = fastComponent(function TooltipRoot(props) {
22
23
  const {
23
24
  disabled = false,
@@ -56,23 +57,18 @@ export const TooltipRoot = fastComponent(function TooltipRoot(props) {
56
57
  const openState = store.useState('open');
57
58
  const open = !disabled && openState;
58
59
  const activeTriggerId = store.useState('activeTriggerId');
60
+ const mounted = store.useState('mounted');
59
61
  const payload = store.useState('payload');
60
62
  store.useSyncedValues({
61
63
  trackCursorAxis,
62
64
  disableHoverablePopup
63
65
  });
64
- useIsoLayoutEffect(() => {
65
- if (openState && disabled) {
66
- store.setOpen(false, createChangeEventDetails(REASONS.disabled));
67
- }
68
- }, [openState, disabled, store]);
69
66
  store.useSyncedValue('disabled', disabled);
70
67
  useImplicitActiveTrigger(store);
71
68
  const {
72
69
  forceUnmount,
73
70
  transitionStatus
74
71
  } = useOpenStateTransitions(open, store);
75
- const floatingRootContext = store.select('floatingRootContext');
76
72
  const isInstantPhase = store.useState('isInstantPhase');
77
73
  const instantType = store.useState('instantType');
78
74
  const lastOpenChangeReason = store.useState('lastOpenChangeReason');
@@ -83,6 +79,11 @@ export const TooltipRoot = fastComponent(function TooltipRoot(props) {
83
79
  // Otherwise, allow the animation to play. In particular, do not disable animations
84
80
  // during the 'ending' phase unless it's due to a sibling opening.
85
81
  const previousInstantTypeRef = React.useRef(null);
82
+ useIsoLayoutEffect(() => {
83
+ if (openState && disabled) {
84
+ store.setOpen(false, createChangeEventDetails(REASONS.disabled));
85
+ }
86
+ }, [openState, disabled, store]);
86
87
  useIsoLayoutEffect(() => {
87
88
  if (transitionStatus === 'ending' && lastOpenChangeReason === REASONS.none || transitionStatus !== 'ending' && isInstantPhase) {
88
89
  // Capture the current instant type so we can restore it later
@@ -111,6 +112,25 @@ export const TooltipRoot = fastComponent(function TooltipRoot(props) {
111
112
  unmount: forceUnmount,
112
113
  close: handleImperativeClose
113
114
  }), [forceUnmount, handleImperativeClose]);
115
+ const shouldRenderInteractions = open || mounted || !disabled && trackCursorAxis !== 'none';
116
+ return /*#__PURE__*/_jsxs(TooltipRootContext.Provider, {
117
+ value: store,
118
+ children: [shouldRenderInteractions && /*#__PURE__*/_jsx(TooltipInteractions, {
119
+ store: store,
120
+ disabled: disabled,
121
+ trackCursorAxis: trackCursorAxis
122
+ }), typeof children === 'function' ? children({
123
+ payload
124
+ }) : children]
125
+ });
126
+ });
127
+ if (process.env.NODE_ENV !== "production") TooltipRoot.displayName = "TooltipRoot";
128
+ function TooltipInteractions({
129
+ store,
130
+ disabled,
131
+ trackCursorAxis
132
+ }) {
133
+ const floatingRootContext = store.useState('floatingRootContext');
114
134
  const dismiss = useDismiss(floatingRootContext, {
115
135
  enabled: !disabled,
116
136
  referencePress: () => store.select('closeOnClick')
@@ -119,24 +139,13 @@ export const TooltipRoot = fastComponent(function TooltipRoot(props) {
119
139
  enabled: !disabled && trackCursorAxis !== 'none',
120
140
  axis: trackCursorAxis === 'none' ? undefined : trackCursorAxis
121
141
  });
122
- const {
123
- getReferenceProps,
124
- getFloatingProps,
125
- getTriggerProps
126
- } = useInteractions([dismiss, clientPoint]);
127
- const activeTriggerProps = React.useMemo(() => getReferenceProps(), [getReferenceProps]);
128
- const inactiveTriggerProps = React.useMemo(() => getTriggerProps(), [getTriggerProps]);
129
- const popupProps = React.useMemo(() => getFloatingProps(), [getFloatingProps]);
130
- store.useSyncedValues({
142
+ const activeTriggerProps = React.useMemo(() => mergeProps(clientPoint.reference, dismiss.reference), [clientPoint.reference, dismiss.reference]);
143
+ const inactiveTriggerProps = React.useMemo(() => mergeProps(clientPoint.trigger, dismiss.trigger), [clientPoint.trigger, dismiss.trigger]);
144
+ const popupProps = React.useMemo(() => mergeProps(FOCUSABLE_POPUP_PROPS, clientPoint.floating, dismiss.floating), [clientPoint.floating, dismiss.floating]);
145
+ usePopupInteractionProps(store, {
131
146
  activeTriggerProps,
132
147
  inactiveTriggerProps,
133
148
  popupProps
134
149
  });
135
- return /*#__PURE__*/_jsx(TooltipRootContext.Provider, {
136
- value: store,
137
- children: typeof children === 'function' ? children({
138
- payload
139
- }) : children
140
- });
141
- });
142
- if (process.env.NODE_ENV !== "production") TooltipRoot.displayName = "TooltipRoot";
150
+ return null;
151
+ }
@@ -43,7 +43,7 @@ export class TooltipHandle {
43
43
  * Indicates whether the tooltip is currently open.
44
44
  */
45
45
  get isOpen() {
46
- return this.store.state.open;
46
+ return this.store.select('open');
47
47
  }
48
48
  }
49
49
 
@@ -18,7 +18,7 @@ export type Context = PopupStoreContext<TooltipRoot.ChangeEventDetails> & {
18
18
  };
19
19
  declare const selectors: {
20
20
  disabled: (state: State<unknown>) => boolean;
21
- instantType: (state: State<unknown>) => "focus" | "delay" | "dismiss" | undefined;
21
+ instantType: (state: State<unknown>) => "delay" | "focus" | "dismiss" | undefined;
22
22
  isInstantPhase: (state: State<unknown>) => boolean;
23
23
  trackCursorAxis: (state: State<unknown>) => "none" | "both" | "x" | "y";
24
24
  disableHoverablePopup: (state: State<unknown>) => boolean;
@@ -32,6 +32,8 @@ declare const selectors: {
32
32
  mounted: boolean;
33
33
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
34
34
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
35
+ floatingId: string | undefined;
36
+ triggerCount: number;
35
37
  preventUnmountingOnClose: boolean;
36
38
  payload: unknown;
37
39
  activeTriggerId: string | null;
@@ -49,6 +51,8 @@ declare const selectors: {
49
51
  mounted: boolean;
50
52
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
51
53
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
54
+ floatingId: string | undefined;
55
+ triggerCount: number;
52
56
  preventUnmountingOnClose: boolean;
53
57
  payload: unknown;
54
58
  activeTriggerId: string | null;
@@ -66,6 +70,8 @@ declare const selectors: {
66
70
  mounted: boolean;
67
71
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
68
72
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
73
+ floatingId: string | undefined;
74
+ triggerCount: number;
69
75
  preventUnmountingOnClose: boolean;
70
76
  payload: unknown;
71
77
  activeTriggerId: string | null;
@@ -83,6 +89,8 @@ declare const selectors: {
83
89
  mounted: boolean;
84
90
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
85
91
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
92
+ floatingId: string | undefined;
93
+ triggerCount: number;
86
94
  preventUnmountingOnClose: boolean;
87
95
  payload: unknown;
88
96
  activeTriggerId: string | null;
@@ -94,12 +102,33 @@ declare const selectors: {
94
102
  inactiveTriggerProps: import("../../index.js").HTMLProps;
95
103
  popupProps: import("../../index.js").HTMLProps;
96
104
  }) => import("../../floating-ui-react/components/FloatingRootStore.js").FloatingRootStore;
105
+ triggerCount: (state: {
106
+ open: boolean;
107
+ readonly openProp: boolean | undefined;
108
+ mounted: boolean;
109
+ transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
110
+ floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
111
+ floatingId: string | undefined;
112
+ triggerCount: number;
113
+ preventUnmountingOnClose: boolean;
114
+ payload: unknown;
115
+ activeTriggerId: string | null;
116
+ activeTriggerElement: Element | null;
117
+ readonly triggerIdProp: string | null | undefined;
118
+ popupElement: HTMLElement | null;
119
+ positionerElement: HTMLElement | null;
120
+ activeTriggerProps: import("../../index.js").HTMLProps;
121
+ inactiveTriggerProps: import("../../index.js").HTMLProps;
122
+ popupProps: import("../../index.js").HTMLProps;
123
+ }) => number;
97
124
  preventUnmountingOnClose: (state: {
98
125
  open: boolean;
99
126
  readonly openProp: boolean | undefined;
100
127
  mounted: boolean;
101
128
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
102
129
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
130
+ floatingId: string | undefined;
131
+ triggerCount: number;
103
132
  preventUnmountingOnClose: boolean;
104
133
  payload: unknown;
105
134
  activeTriggerId: string | null;
@@ -117,6 +146,8 @@ declare const selectors: {
117
146
  mounted: boolean;
118
147
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
119
148
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
149
+ floatingId: string | undefined;
150
+ triggerCount: number;
120
151
  preventUnmountingOnClose: boolean;
121
152
  payload: unknown;
122
153
  activeTriggerId: string | null;
@@ -134,6 +165,8 @@ declare const selectors: {
134
165
  mounted: boolean;
135
166
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
136
167
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
168
+ floatingId: string | undefined;
169
+ triggerCount: number;
137
170
  preventUnmountingOnClose: boolean;
138
171
  payload: unknown;
139
172
  activeTriggerId: string | null;
@@ -151,6 +184,8 @@ declare const selectors: {
151
184
  mounted: boolean;
152
185
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
153
186
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
187
+ floatingId: string | undefined;
188
+ triggerCount: number;
154
189
  preventUnmountingOnClose: boolean;
155
190
  payload: unknown;
156
191
  activeTriggerId: string | null;
@@ -162,12 +197,33 @@ declare const selectors: {
162
197
  inactiveTriggerProps: import("../../index.js").HTMLProps;
163
198
  popupProps: import("../../index.js").HTMLProps;
164
199
  }) => Element | null;
200
+ popupId: (state: {
201
+ open: boolean;
202
+ readonly openProp: boolean | undefined;
203
+ mounted: boolean;
204
+ transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
205
+ floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
206
+ floatingId: string | undefined;
207
+ triggerCount: number;
208
+ preventUnmountingOnClose: boolean;
209
+ payload: unknown;
210
+ activeTriggerId: string | null;
211
+ activeTriggerElement: Element | null;
212
+ readonly triggerIdProp: string | null | undefined;
213
+ popupElement: HTMLElement | null;
214
+ positionerElement: HTMLElement | null;
215
+ activeTriggerProps: import("../../index.js").HTMLProps;
216
+ inactiveTriggerProps: import("../../index.js").HTMLProps;
217
+ popupProps: import("../../index.js").HTMLProps;
218
+ }) => string | undefined;
165
219
  isTriggerActive: (state: {
166
220
  open: boolean;
167
221
  readonly openProp: boolean | undefined;
168
222
  mounted: boolean;
169
223
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
170
224
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
225
+ floatingId: string | undefined;
226
+ triggerCount: number;
171
227
  preventUnmountingOnClose: boolean;
172
228
  payload: unknown;
173
229
  activeTriggerId: string | null;
@@ -185,6 +241,8 @@ declare const selectors: {
185
241
  mounted: boolean;
186
242
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
187
243
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
244
+ floatingId: string | undefined;
245
+ triggerCount: number;
188
246
  preventUnmountingOnClose: boolean;
189
247
  payload: unknown;
190
248
  activeTriggerId: string | null;
@@ -202,6 +260,8 @@ declare const selectors: {
202
260
  mounted: boolean;
203
261
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
204
262
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
263
+ floatingId: string | undefined;
264
+ triggerCount: number;
205
265
  preventUnmountingOnClose: boolean;
206
266
  payload: unknown;
207
267
  activeTriggerId: string | null;
@@ -219,6 +279,8 @@ declare const selectors: {
219
279
  mounted: boolean;
220
280
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
221
281
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
282
+ floatingId: string | undefined;
283
+ triggerCount: number;
222
284
  preventUnmountingOnClose: boolean;
223
285
  payload: unknown;
224
286
  activeTriggerId: string | null;
@@ -230,12 +292,33 @@ declare const selectors: {
230
292
  inactiveTriggerProps: import("../../index.js").HTMLProps;
231
293
  popupProps: import("../../index.js").HTMLProps;
232
294
  }, isActive: boolean) => import("../../index.js").HTMLProps;
295
+ triggerPopupId: (state: {
296
+ open: boolean;
297
+ readonly openProp: boolean | undefined;
298
+ mounted: boolean;
299
+ transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
300
+ floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
301
+ floatingId: string | undefined;
302
+ triggerCount: number;
303
+ preventUnmountingOnClose: boolean;
304
+ payload: unknown;
305
+ activeTriggerId: string | null;
306
+ activeTriggerElement: Element | null;
307
+ readonly triggerIdProp: string | null | undefined;
308
+ popupElement: HTMLElement | null;
309
+ positionerElement: HTMLElement | null;
310
+ activeTriggerProps: import("../../index.js").HTMLProps;
311
+ inactiveTriggerProps: import("../../index.js").HTMLProps;
312
+ popupProps: import("../../index.js").HTMLProps;
313
+ }, triggerId: string | undefined) => string | undefined;
233
314
  popupProps: (state: {
234
315
  open: boolean;
235
316
  readonly openProp: boolean | undefined;
236
317
  mounted: boolean;
237
318
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
238
319
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
320
+ floatingId: string | undefined;
321
+ triggerCount: number;
239
322
  preventUnmountingOnClose: boolean;
240
323
  payload: unknown;
241
324
  activeTriggerId: string | null;
@@ -253,6 +336,8 @@ declare const selectors: {
253
336
  mounted: boolean;
254
337
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
255
338
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
339
+ floatingId: string | undefined;
340
+ triggerCount: number;
256
341
  preventUnmountingOnClose: boolean;
257
342
  payload: unknown;
258
343
  activeTriggerId: string | null;
@@ -270,6 +355,8 @@ declare const selectors: {
270
355
  mounted: boolean;
271
356
  transitionStatus: import("../../internals/useTransitionStatus.js").TransitionStatus;
272
357
  floatingRootContext: import("../../floating-ui-react/index.js").FloatingRootContext;
358
+ floatingId: string | undefined;
359
+ triggerCount: number;
273
360
  preventUnmountingOnClose: boolean;
274
361
  payload: unknown;
275
362
  activeTriggerId: string | null;
@@ -283,8 +370,9 @@ declare const selectors: {
283
370
  }) => HTMLElement | null;
284
371
  };
285
372
  export declare class TooltipStore<Payload> extends ReactStore<Readonly<State<Payload>>, Context, typeof selectors> {
286
- constructor(initialState?: Partial<State<Payload>>);
373
+ constructor(initialState?: Partial<State<Payload>>, floatingId?: string | undefined, nested?: boolean);
287
374
  setOpen: (nextOpen: boolean, eventDetails: Omit<TooltipRoot.ChangeEventDetails, "preventUnmountOnClose">) => void;
375
+ cancelPendingOpen(event: MouseEvent | PointerEvent): void;
288
376
  static useStore<Payload>(externalStore: TooltipStore<Payload> | undefined, initialState?: Partial<State<Payload>>): TooltipStore<Payload>;
289
377
  }
290
378
  export {};
@@ -1,10 +1,9 @@
1
1
  import * as React from 'react';
2
2
  import * as ReactDOM from 'react-dom';
3
3
  import { createSelector, ReactStore } from '@base-ui/utils/store';
4
- import { useRefWithInit } from '@base-ui/utils/useRefWithInit';
5
- import { useSyncedFloatingRootContext } from "../../floating-ui-react/index.js";
4
+ import { createChangeEventDetails } from "../../internals/createBaseUIEventDetails.js";
6
5
  import { REASONS } from "../../internals/reasons.js";
7
- import { createInitialPopupStoreState, popupStoreSelectors, PopupTriggerMap } from "../../utils/popups/index.js";
6
+ import { createPopupFloatingRootContext, createInitialPopupStoreState, popupStoreSelectors, PopupTriggerMap, setOpenTriggerState, usePopupStore } from "../../utils/popups/index.js";
8
7
  const selectors = {
9
8
  ...popupStoreSelectors,
10
9
  disabled: createSelector(state => state.disabled),
@@ -18,15 +17,18 @@ const selectors = {
18
17
  hasViewport: createSelector(state => state.hasViewport)
19
18
  };
20
19
  export class TooltipStore extends ReactStore {
21
- constructor(initialState) {
22
- super({
20
+ constructor(initialState, floatingId, nested = false) {
21
+ const triggerElements = new PopupTriggerMap();
22
+ const state = {
23
23
  ...createInitialState(),
24
24
  ...initialState
25
- }, {
25
+ };
26
+ state.floatingRootContext = createPopupFloatingRootContext(triggerElements, floatingId, nested);
27
+ super(state, {
26
28
  popupRef: /*#__PURE__*/React.createRef(),
27
29
  onOpenChange: undefined,
28
30
  onOpenChangeComplete: undefined,
29
- triggerElements: new PopupTriggerMap()
31
+ triggerElements
30
32
  }, selectors);
31
33
  }
32
34
  setOpen = (nextOpen, eventDetails) => {
@@ -54,14 +56,7 @@ export class TooltipStore extends ReactStore {
54
56
  } else if (reason === REASONS.triggerHover) {
55
57
  updatedState.instantType = undefined;
56
58
  }
57
-
58
- // If a popup is closing, the `trigger` may be null.
59
- // We want to keep the previous value so that exit animations are played and focus is returned correctly.
60
- const newTriggerId = eventDetails.trigger?.id ?? null;
61
- if (newTriggerId || nextOpen) {
62
- updatedState.activeTriggerId = newTriggerId;
63
- updatedState.activeTriggerElement = eventDetails.trigger ?? null;
64
- }
59
+ setOpenTriggerState(updatedState, nextOpen, eventDetails.trigger);
65
60
  this.update(updatedState);
66
61
  };
67
62
  if (isHover) {
@@ -72,24 +67,16 @@ export class TooltipStore extends ReactStore {
72
67
  changeState();
73
68
  }
74
69
  };
75
- static useStore(externalStore, initialState) {
76
- // eslint-disable-next-line react-hooks/rules-of-hooks
77
- const internalStore = useRefWithInit(() => {
78
- return new TooltipStore(initialState);
79
- }).current;
80
- const store = externalStore ?? internalStore;
81
70
 
82
- // eslint-disable-next-line react-hooks/rules-of-hooks
83
- const floatingRootContext = useSyncedFloatingRootContext({
84
- popupStore: store,
85
- onOpenChange: store.setOpen
86
- });
71
+ // Used by trigger clicks to clear a delayed hover open without reporting a public open-state change.
72
+ cancelPendingOpen(event) {
73
+ this.state.floatingRootContext.dispatchOpenChange(false, createChangeEventDetails(REASONS.triggerPress, event));
74
+ }
75
+ static useStore(externalStore, initialState) {
76
+ /* eslint-disable react-hooks/rules-of-hooks */
77
+ const store = usePopupStore(externalStore, (floatingId, nested) => new TooltipStore(initialState, floatingId, nested)).store;
78
+ /* eslint-enable react-hooks/rules-of-hooks */
87
79
 
88
- // It's safe to set this here because when this code runs for the first time,
89
- // nothing has had a chance to subscribe to the `store` yet.
90
- // For subsequent renders, the `floatingRootContext` reference remains the same,
91
- // so it's basically a no-op.
92
- store.state.floatingRootContext = floatingRootContext;
93
80
  return store;
94
81
  }
95
82
  }
@@ -2,7 +2,10 @@
2
2
 
3
3
  import _formatErrorMessage from "@base-ui/utils/formatErrorMessage";
4
4
  import * as React from 'react';
5
+ import { isElement } from '@floating-ui/utils/dom';
5
6
  import { fastComponentRef } from '@base-ui/utils/fastHooks';
7
+ import { useTimeout } from '@base-ui/utils/useTimeout';
8
+ import { useValueAsRef } from '@base-ui/utils/useValueAsRef';
6
9
  import { useTooltipRootContext } from "../root/TooltipRootContext.js";
7
10
  import { triggerOpenStateMapping } from "../../utils/popupStateMapping.js";
8
11
  import { useRenderElement } from "../../internals/useRenderElement.js";
@@ -10,8 +13,46 @@ import { useTriggerDataForwarding } from "../../utils/popups/index.js";
10
13
  import { useBaseUiId } from "../../internals/useBaseUiId.js";
11
14
  import { useTooltipProviderContext } from "../provider/TooltipProviderContext.js";
12
15
  import { safePolygon, useDelayGroup, useFocus, useHoverReferenceInteraction } from "../../floating-ui-react/index.js";
16
+ import { contains } from "../../floating-ui-react/utils/element.js";
17
+ import { isMouseLikePointerType } from "../../floating-ui-react/utils/event.js";
18
+ import { createChangeEventDetails } from "../../internals/createBaseUIEventDetails.js";
19
+ import { REASONS } from "../../internals/reasons.js";
13
20
  import { TooltipTriggerDataAttributes } from "./TooltipTriggerDataAttributes.js";
21
+ import { useHoverInteractionSharedState } from "../../floating-ui-react/hooks/useHoverInteractionSharedState.js";
14
22
  import { OPEN_DELAY } from "../utils/constants.js";
23
+ const TOOLTIP_TRIGGER_IDENTIFIER = 'data-base-ui-tooltip-trigger';
24
+ function getTargetElement(event) {
25
+ if ('composedPath' in event) {
26
+ const path = event.composedPath();
27
+ for (let i = 0; i < path.length; i += 1) {
28
+ const element = path[i];
29
+ if (isElement(element)) {
30
+ return element;
31
+ }
32
+ }
33
+ }
34
+ const target = event.target;
35
+ if (isElement(target)) {
36
+ return target;
37
+ }
38
+ return null;
39
+ }
40
+ function closestEnabledTooltipTrigger(element) {
41
+ let current = element;
42
+ while (current) {
43
+ if (current.hasAttribute(TOOLTIP_TRIGGER_IDENTIFIER)) {
44
+ return current;
45
+ }
46
+ const parentElement = current.parentElement;
47
+ if (parentElement) {
48
+ current = parentElement;
49
+ continue;
50
+ }
51
+ const root = current.getRootNode();
52
+ current = 'host' in root && isElement(root.host) ? root.host : null;
53
+ }
54
+ return null;
55
+ }
15
56
 
16
57
  /**
17
58
  * An element to attach the tooltip to.
@@ -21,8 +62,9 @@ import { OPEN_DELAY } from "../utils/constants.js";
21
62
  */
22
63
  export const TooltipTrigger = fastComponentRef(function TooltipTrigger(componentProps, forwardedRef) {
23
64
  const {
24
- className,
25
65
  render,
66
+ className,
67
+ style,
26
68
  handle,
27
69
  payload,
28
70
  disabled: disabledProp,
@@ -30,7 +72,6 @@ export const TooltipTrigger = fastComponentRef(function TooltipTrigger(component
30
72
  closeOnClick = true,
31
73
  closeDelay,
32
74
  id: idProp,
33
- style,
34
75
  ...elementProps
35
76
  } = componentProps;
36
77
  const rootContext = useTooltipRootContext(true);
@@ -61,29 +102,55 @@ export const TooltipTrigger = fastComponentRef(function TooltipTrigger(component
61
102
  } = useDelayGroup(floatingRootContext, {
62
103
  open: isOpenedByThisTrigger
63
104
  });
105
+ const hoverInteraction = useHoverInteractionSharedState(floatingRootContext);
64
106
  store.useSyncedValue('isInstantPhase', isInstantPhase);
65
107
  const rootDisabled = store.useState('disabled');
66
108
  const disabled = disabledProp ?? rootDisabled;
109
+ const disabledRef = useValueAsRef(disabled);
67
110
  const trackCursorAxis = store.useState('trackCursorAxis');
68
111
  const disableHoverablePopup = store.useState('disableHoverablePopup');
112
+ const isNestedTriggerHoveredRef = React.useRef(false);
113
+ const nestedTriggerOpenTimeout = useTimeout();
114
+ // Local copy so it can be cleared on mouseLeave without resetting the hover hook's own pointerType.
115
+ const pointerTypeRef = React.useRef(undefined);
116
+ function getOpenDelay() {
117
+ const providerDelay = providerContext?.delay;
118
+ const groupOpenValue = typeof delayRef.current === 'object' ? delayRef.current.open : undefined;
119
+ let computedOpenDelay = delayWithDefault;
120
+ if (hasProvider) {
121
+ if (groupOpenValue !== 0) {
122
+ computedOpenDelay = delay ?? providerDelay ?? delayWithDefault;
123
+ } else {
124
+ computedOpenDelay = 0;
125
+ }
126
+ }
127
+ return computedOpenDelay;
128
+ }
129
+ function isEnabledNestedTriggerTarget(target) {
130
+ const triggerEl = triggerElementRef.current;
131
+ if (!triggerEl || !target) {
132
+ return false;
133
+ }
134
+ const nearestTrigger = closestEnabledTooltipTrigger(target);
135
+ return nearestTrigger !== null && nearestTrigger !== triggerEl && contains(triggerEl, nearestTrigger);
136
+ }
137
+ function detectNestedTriggerHover(target) {
138
+ const nestedTriggerHovered = isEnabledNestedTriggerTarget(target);
139
+ isNestedTriggerHoveredRef.current = nestedTriggerHovered;
140
+ if (nestedTriggerHovered) {
141
+ hoverInteraction.openChangeTimeout.clear();
142
+ hoverInteraction.restTimeout.clear();
143
+ hoverInteraction.restTimeoutPending = false;
144
+ nestedTriggerOpenTimeout.clear();
145
+ }
146
+ return nestedTriggerHovered;
147
+ }
69
148
  const hoverProps = useHoverReferenceInteraction(floatingRootContext, {
70
149
  enabled: !disabled,
71
150
  mouseOnly: true,
72
151
  move: false,
73
152
  handleClose: !disableHoverablePopup && trackCursorAxis !== 'both' ? safePolygon() : null,
74
- restMs() {
75
- const providerDelay = providerContext?.delay;
76
- const groupOpenValue = typeof delayRef.current === 'object' ? delayRef.current.open : undefined;
77
- let computedRestMs = delayWithDefault;
78
- if (hasProvider) {
79
- if (groupOpenValue !== 0) {
80
- computedRestMs = delay ?? providerDelay ?? delayWithDefault;
81
- } else {
82
- computedRestMs = 0;
83
- }
84
- }
85
- return computedRestMs;
86
- },
153
+ restMs: getOpenDelay,
87
154
  delay() {
88
155
  const closeValue = typeof delayRef.current === 'object' ? delayRef.current.close : undefined;
89
156
  let computedCloseDelay = closeDelayWithDefault;
@@ -96,24 +163,88 @@ export const TooltipTrigger = fastComponentRef(function TooltipTrigger(component
96
163
  },
97
164
  triggerElementRef,
98
165
  isActiveTrigger: isTriggerActive,
99
- isClosing: () => store.select('transitionStatus') === 'ending'
166
+ isClosing: () => store.select('transitionStatus') === 'ending',
167
+ shouldOpen() {
168
+ return !isNestedTriggerHoveredRef.current;
169
+ }
100
170
  });
101
171
  const focusProps = useFocus(floatingRootContext, {
102
172
  enabled: !disabled
103
173
  }).reference;
174
+ const handleNestedTriggerHover = event => {
175
+ const wasNestedTriggerHovered = isNestedTriggerHoveredRef.current;
176
+ const target = getTargetElement(event);
177
+ const nestedTriggerHovered = detectNestedTriggerHover(target);
178
+ const triggerEl = triggerElementRef.current;
179
+ const targetInsideTrigger = triggerEl && target && contains(triggerEl, target);
180
+
181
+ // Only close hover-opened parents. Focus/click-like opens remain owned by
182
+ // their original interaction and should not be clobbered by nested hover.
183
+ if (nestedTriggerHovered && store.select('open') && store.select('lastOpenChangeReason') === REASONS.triggerHover) {
184
+ store.setOpen(false, createChangeEventDetails(REASONS.triggerHover, event));
185
+ return;
186
+ }
187
+ if (wasNestedTriggerHovered && !nestedTriggerHovered && targetInsideTrigger && !disabledRef.current && !store.select('open') && triggerEl &&
188
+ // Match the hover hook's non-strict mouse fallback for mouse-only event sequences.
189
+ isMouseLikePointerType(pointerTypeRef.current)) {
190
+ const open = () => {
191
+ if (!isNestedTriggerHoveredRef.current && !disabledRef.current && !store.select('open')) {
192
+ store.setOpen(true, createChangeEventDetails(REASONS.triggerHover, event, triggerEl));
193
+ }
194
+ };
195
+ const openDelay = getOpenDelay();
196
+
197
+ // With `move: false`, the hover hook only listens to mouseenter/mouseleave
198
+ // on the parent trigger. Leaving a nested child for the parent area fires
199
+ // no event the hook can react to, so reopen locally.
200
+ if (openDelay === 0) {
201
+ nestedTriggerOpenTimeout.clear();
202
+ open();
203
+ } else {
204
+ nestedTriggerOpenTimeout.start(openDelay, open);
205
+ }
206
+ }
207
+ };
208
+ const rootTriggerProps = store.useState('triggerProps', isMountedByThisTrigger);
209
+ const shouldApplyRootTriggerProps = isMountedByThisTrigger || trackCursorAxis !== 'none';
104
210
  const state = {
105
211
  open: isOpenedByThisTrigger
106
212
  };
107
- const rootTriggerProps = store.useState('triggerProps', isMountedByThisTrigger);
108
213
  const element = useRenderElement('button', componentProps, {
109
214
  state,
110
215
  ref: [forwardedRef, registerTrigger, triggerElementRef],
111
- props: [hoverProps, focusProps, rootTriggerProps, {
112
- onPointerDown() {
216
+ props: [hoverProps, focusProps, shouldApplyRootTriggerProps ? rootTriggerProps : undefined, {
217
+ onMouseOver(event) {
218
+ handleNestedTriggerHover(event.nativeEvent);
219
+ },
220
+ onFocus(event) {
221
+ if (isEnabledNestedTriggerTarget(getTargetElement(event.nativeEvent))) {
222
+ event.preventBaseUIHandler();
223
+ }
224
+ },
225
+ onMouseLeave() {
226
+ isNestedTriggerHoveredRef.current = false;
227
+ nestedTriggerOpenTimeout.clear();
228
+ pointerTypeRef.current = undefined;
229
+ },
230
+ onPointerEnter(event) {
231
+ pointerTypeRef.current = event.pointerType;
232
+ },
233
+ onPointerDown(event) {
234
+ pointerTypeRef.current = event.pointerType;
113
235
  store.set('closeOnClick', closeOnClick);
236
+ if (closeOnClick && !store.select('open')) {
237
+ store.cancelPendingOpen(event.nativeEvent);
238
+ }
239
+ },
240
+ onClick(event) {
241
+ if (closeOnClick && !store.select('open')) {
242
+ store.cancelPendingOpen(event.nativeEvent);
243
+ }
114
244
  },
115
245
  id: thisTriggerId,
116
- [TooltipTriggerDataAttributes.triggerDisabled]: disabled ? '' : undefined
246
+ [TooltipTriggerDataAttributes.triggerDisabled]: disabled ? '' : undefined,
247
+ [TOOLTIP_TRIGGER_IDENTIFIER]: disabled ? undefined : ''
117
248
  }, elementProps],
118
249
  stateAttributesMapping: triggerOpenStateMapping
119
250
  });