@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.
- package/CHANGELOG.md +125 -8
- package/README.md +1 -1
- package/accordion/item/AccordionItem.d.ts +4 -0
- package/accordion/item/AccordionItem.js +5 -4
- package/accordion/panel/AccordionPanel.js +29 -51
- package/accordion/root/AccordionRoot.js +5 -6
- package/accordion/trigger/AccordionTrigger.js +3 -4
- package/alert-dialog/handle.d.ts +14 -1
- package/alert-dialog/handle.js +22 -5
- package/alert-dialog/index.d.ts +1 -1
- package/alert-dialog/index.parts.d.ts +2 -3
- package/alert-dialog/index.parts.js +4 -5
- package/alert-dialog/root/AlertDialogRoot.d.ts +7 -7
- package/alert-dialog/root/AlertDialogRoot.js +2 -56
- package/alert-dialog/trigger/AlertDialogTrigger.d.ts +25 -0
- package/alert-dialog/trigger/AlertDialogTrigger.js +15 -0
- package/alert-dialog/trigger/AlertDialogTriggerDataAttributes.d.ts +10 -0
- package/alert-dialog/trigger/AlertDialogTriggerDataAttributes.js +18 -0
- package/autocomplete/root/AutocompleteRoot.js +9 -10
- package/avatar/image/AvatarImage.js +4 -4
- package/checkbox/indicator/CheckboxIndicator.js +2 -2
- package/checkbox/root/CheckboxRoot.js +49 -11
- package/checkbox-group/CheckboxGroup.js +1 -5
- package/collapsible/panel/CollapsiblePanel.js +29 -51
- package/collapsible/panel/useCollapsiblePanel.d.ts +9 -23
- package/collapsible/panel/useCollapsiblePanel.js +308 -268
- package/collapsible/root/CollapsibleRoot.d.ts +1 -1
- package/collapsible/root/CollapsibleRootContext.d.ts +0 -2
- package/collapsible/root/useCollapsibleRoot.d.ts +0 -27
- package/collapsible/root/useCollapsibleRoot.js +2 -64
- package/collapsible/trigger/CollapsibleTrigger.js +5 -6
- package/combobox/arrow/ComboboxArrow.js +1 -1
- package/combobox/backdrop/ComboboxBackdrop.js +1 -1
- package/combobox/chip/ComboboxChip.js +7 -2
- package/combobox/clear/ComboboxClear.d.ts +4 -0
- package/combobox/clear/ComboboxClear.js +1 -0
- package/combobox/clear/ComboboxClearDataAttributes.d.ts +4 -0
- package/combobox/clear/ComboboxClearDataAttributes.js +4 -0
- package/combobox/icon/ComboboxIcon.js +1 -1
- package/combobox/input/ComboboxInput.js +15 -6
- package/combobox/item/ComboboxItem.js +8 -14
- package/combobox/item-indicator/ComboboxItemIndicator.js +1 -2
- package/combobox/root/AriaCombobox.js +61 -28
- package/combobox/store.d.ts +4 -8
- package/combobox/store.js +2 -1
- package/combobox/utils/ComboboxInternalDismissButton.js +2 -3
- package/csp-provider/CSPProvider.js +1 -1
- package/dialog/close/DialogClose.js +6 -6
- package/dialog/popup/DialogPopup.js +9 -4
- package/dialog/root/DialogRoot.d.ts +1 -2
- package/dialog/root/DialogRoot.js +3 -73
- package/dialog/root/DialogRootContext.d.ts +1 -0
- package/dialog/root/DialogRootContext.js +3 -1
- package/dialog/root/useDialogRoot.d.ts +12 -4
- package/dialog/root/useDialogRoot.js +27 -25
- package/dialog/root/useRenderDialogRoot.d.ts +4 -0
- package/dialog/root/useRenderDialogRoot.js +96 -0
- package/dialog/store/DialogHandle.d.ts +1 -1
- package/dialog/store/DialogHandle.js +2 -2
- package/dialog/store/DialogStore.d.ts +88 -1
- package/dialog/store/DialogStore.js +12 -17
- package/dialog/trigger/DialogTrigger.d.ts +1 -1
- package/dialog/trigger/DialogTrigger.js +11 -4
- package/dialog/viewport/DialogViewport.js +4 -3
- package/drawer/popup/DrawerPopup.js +13 -9
- package/drawer/root/DrawerRoot.js +11 -11
- package/drawer/root/DrawerRootContext.d.ts +1 -1
- package/drawer/swipe-area/DrawerSwipeArea.js +6 -5
- package/drawer/viewport/DrawerViewport.js +13 -14
- package/esm/accordion/item/AccordionItem.d.ts +4 -0
- package/esm/accordion/item/AccordionItem.js +5 -4
- package/esm/accordion/panel/AccordionPanel.js +29 -51
- package/esm/accordion/root/AccordionRoot.js +5 -6
- package/esm/accordion/trigger/AccordionTrigger.js +4 -5
- package/esm/alert-dialog/handle.d.ts +14 -1
- package/esm/alert-dialog/handle.js +20 -5
- package/esm/alert-dialog/index.d.ts +1 -1
- package/esm/alert-dialog/index.parts.d.ts +2 -3
- package/esm/alert-dialog/index.parts.js +2 -3
- package/esm/alert-dialog/root/AlertDialogRoot.d.ts +7 -7
- package/esm/alert-dialog/root/AlertDialogRoot.js +2 -55
- package/esm/alert-dialog/trigger/AlertDialogTrigger.d.ts +25 -0
- package/esm/alert-dialog/trigger/AlertDialogTrigger.js +10 -0
- package/esm/alert-dialog/trigger/AlertDialogTriggerDataAttributes.d.ts +10 -0
- package/esm/alert-dialog/trigger/AlertDialogTriggerDataAttributes.js +12 -0
- package/esm/autocomplete/root/AutocompleteRoot.js +9 -10
- package/esm/avatar/image/AvatarImage.js +4 -4
- package/esm/checkbox/indicator/CheckboxIndicator.js +2 -2
- package/esm/checkbox/root/CheckboxRoot.js +49 -11
- package/esm/checkbox-group/CheckboxGroup.js +1 -5
- package/esm/collapsible/panel/CollapsiblePanel.js +29 -51
- package/esm/collapsible/panel/useCollapsiblePanel.d.ts +9 -23
- package/esm/collapsible/panel/useCollapsiblePanel.js +309 -269
- package/esm/collapsible/root/CollapsibleRoot.d.ts +1 -1
- package/esm/collapsible/root/CollapsibleRootContext.d.ts +0 -2
- package/esm/collapsible/root/useCollapsibleRoot.d.ts +0 -27
- package/esm/collapsible/root/useCollapsibleRoot.js +2 -64
- package/esm/collapsible/trigger/CollapsibleTrigger.js +5 -6
- package/esm/combobox/arrow/ComboboxArrow.js +1 -1
- package/esm/combobox/backdrop/ComboboxBackdrop.js +1 -1
- package/esm/combobox/chip/ComboboxChip.js +7 -2
- package/esm/combobox/clear/ComboboxClear.d.ts +4 -0
- package/esm/combobox/clear/ComboboxClear.js +1 -0
- package/esm/combobox/clear/ComboboxClearDataAttributes.d.ts +4 -0
- package/esm/combobox/clear/ComboboxClearDataAttributes.js +4 -0
- package/esm/combobox/icon/ComboboxIcon.js +1 -1
- package/esm/combobox/input/ComboboxInput.js +16 -7
- package/esm/combobox/item/ComboboxItem.js +8 -14
- package/esm/combobox/item-indicator/ComboboxItemIndicator.js +1 -2
- package/esm/combobox/root/AriaCombobox.js +62 -29
- package/esm/combobox/store.d.ts +4 -8
- package/esm/combobox/store.js +2 -1
- package/esm/combobox/utils/ComboboxInternalDismissButton.js +2 -3
- package/esm/csp-provider/CSPProvider.js +1 -1
- package/esm/dialog/close/DialogClose.js +6 -6
- package/esm/dialog/popup/DialogPopup.js +9 -4
- package/esm/dialog/root/DialogRoot.d.ts +1 -2
- package/esm/dialog/root/DialogRoot.js +4 -72
- package/esm/dialog/root/DialogRootContext.d.ts +1 -0
- package/esm/dialog/root/DialogRootContext.js +2 -0
- package/esm/dialog/root/useDialogRoot.d.ts +12 -4
- package/esm/dialog/root/useDialogRoot.js +28 -27
- package/esm/dialog/root/useRenderDialogRoot.d.ts +4 -0
- package/esm/dialog/root/useRenderDialogRoot.js +90 -0
- package/esm/dialog/store/DialogHandle.d.ts +1 -1
- package/esm/dialog/store/DialogHandle.js +2 -2
- package/esm/dialog/store/DialogStore.d.ts +88 -1
- package/esm/dialog/store/DialogStore.js +13 -18
- package/esm/dialog/trigger/DialogTrigger.d.ts +1 -1
- package/esm/dialog/trigger/DialogTrigger.js +12 -5
- package/esm/dialog/viewport/DialogViewport.js +4 -3
- package/esm/drawer/popup/DrawerPopup.js +14 -9
- package/esm/drawer/root/DrawerRoot.js +11 -11
- package/esm/drawer/root/DrawerRootContext.d.ts +1 -1
- package/esm/drawer/swipe-area/DrawerSwipeArea.js +6 -5
- package/esm/drawer/viewport/DrawerViewport.js +13 -14
- package/esm/field/control/FieldControl.js +2 -6
- package/esm/field/item/FieldItem.js +1 -4
- package/esm/field/root/FieldRoot.js +11 -3
- package/esm/field/root/useFieldValidation.d.ts +1 -0
- package/esm/field/root/useFieldValidation.js +23 -20
- package/esm/field/utils/getCombinedFieldValidityData.d.ts +1 -1
- package/esm/field/validity/FieldValidity.d.ts +1 -1
- package/esm/floating-ui-react/components/FloatingDelayGroup.js +3 -3
- package/esm/floating-ui-react/components/FloatingFocusManager.d.ts +1 -1
- package/esm/floating-ui-react/components/FloatingFocusManager.js +20 -8
- package/esm/floating-ui-react/components/FloatingPortal.js +3 -3
- package/esm/floating-ui-react/hooks/useClick.js +83 -74
- package/esm/floating-ui-react/hooks/useClientPoint.js +29 -20
- package/esm/floating-ui-react/hooks/useDismiss.d.ts +1 -1
- package/esm/floating-ui-react/hooks/useDismiss.js +82 -93
- package/esm/floating-ui-react/hooks/useFloating.js +37 -32
- package/esm/floating-ui-react/hooks/useFloatingRootContext.d.ts +1 -1
- package/esm/floating-ui-react/hooks/useFloatingRootContext.js +2 -2
- package/esm/floating-ui-react/hooks/useFocus.js +84 -81
- package/esm/floating-ui-react/hooks/useHover.js +72 -76
- package/esm/floating-ui-react/hooks/useHoverFloatingInteraction.js +49 -44
- package/esm/floating-ui-react/hooks/useHoverInteractionSharedState.js +1 -1
- package/esm/floating-ui-react/hooks/useHoverReferenceInteraction.d.ts +7 -2
- package/esm/floating-ui-react/hooks/useHoverReferenceInteraction.js +44 -39
- package/esm/floating-ui-react/hooks/useHoverShared.d.ts +2 -1
- package/esm/floating-ui-react/hooks/useHoverShared.js +4 -0
- package/esm/floating-ui-react/hooks/useListNavigation.d.ts +1 -3
- package/esm/floating-ui-react/hooks/useListNavigation.js +83 -74
- package/esm/floating-ui-react/hooks/useSyncedFloatingRootContext.d.ts +9 -6
- package/esm/floating-ui-react/hooks/useSyncedFloatingRootContext.js +25 -20
- package/esm/floating-ui-react/hooks/useTypeahead.d.ts +2 -2
- package/esm/floating-ui-react/hooks/useTypeahead.js +33 -52
- package/esm/floating-ui-react/index.d.ts +0 -2
- package/esm/floating-ui-react/index.js +0 -2
- package/esm/floating-ui-react/types.d.ts +2 -7
- package/esm/floating-ui-react/utils/composite.js +2 -0
- package/esm/floating-ui-react/utils/enqueueFocus.d.ts +1 -1
- package/esm/floating-ui-react/utils/enqueueFocus.js +10 -7
- package/esm/floating-ui-react/utils/getEmptyRootContext.js +1 -1
- package/esm/form/Form.js +2 -2
- package/esm/index.js +1 -1
- package/esm/internals/composite/composite.d.ts +0 -1
- package/esm/internals/composite/composite.js +1 -2
- package/esm/internals/composite/root/useCompositeRoot.js +2 -2
- package/esm/internals/createBaseUIEventDetails.d.ts +2 -0
- package/esm/internals/csp-context/index.d.ts +2 -0
- package/esm/internals/csp-context/index.js +1 -0
- package/esm/internals/field-register-control/index.d.ts +0 -1
- package/esm/internals/field-register-control/useFieldControlRegistration.d.ts +2 -1
- package/esm/internals/field-register-control/useFieldControlRegistration.js +11 -14
- package/esm/internals/field-register-control/useRegisterFieldControl.d.ts +1 -4
- package/esm/internals/field-register-control/useRegisterFieldControl.js +6 -11
- package/esm/internals/field-root-context/FieldRootContext.d.ts +1 -0
- package/esm/internals/field-root-context/FieldRootContext.js +3 -2
- package/esm/internals/form-context/FormContext.d.ts +5 -1
- package/esm/internals/reason-parts.d.ts +2 -0
- package/esm/internals/reason-parts.js +2 -0
- package/esm/internals/types.d.ts +1 -0
- package/esm/internals/use-button/useButton.js +4 -4
- package/esm/internals/usePressAndHold.js +2 -2
- package/esm/internals/useRenderElement.js +2 -0
- package/esm/menu/arrow/MenuArrow.js +1 -1
- package/esm/menu/backdrop/MenuBackdrop.js +1 -1
- package/esm/menu/checkbox-item/MenuCheckboxItem.js +5 -7
- package/esm/menu/group/MenuGroup.js +1 -4
- package/esm/menu/group/MenuGroupContext.d.ts +1 -3
- package/esm/menu/group/MenuGroupContext.js +1 -1
- package/esm/menu/group-label/MenuGroupLabel.js +4 -6
- package/esm/menu/link-item/MenuLinkItem.js +2 -2
- package/esm/menu/popup/MenuPopup.js +5 -5
- package/esm/menu/radio-group/MenuRadioGroup.js +11 -5
- package/esm/menu/radio-item/MenuRadioItem.js +5 -7
- package/esm/menu/root/MenuRoot.js +63 -68
- package/esm/menu/store/MenuHandle.js +1 -1
- package/esm/menu/store/MenuStore.d.ts +87 -0
- package/esm/menu/submenu-trigger/MenuSubmenuTrigger.js +8 -5
- package/esm/menu/trigger/MenuTrigger.js +13 -10
- package/esm/menu/viewport/MenuViewport.d.ts +2 -2
- package/esm/menu/viewport/MenuViewport.js +2 -2
- package/esm/navigation-menu/arrow/NavigationMenuArrow.js +1 -1
- package/esm/navigation-menu/backdrop/NavigationMenuBackdrop.js +1 -1
- package/esm/navigation-menu/content/NavigationMenuContent.js +8 -5
- package/esm/navigation-menu/icon/NavigationMenuIcon.js +1 -1
- package/esm/navigation-menu/item/NavigationMenuItem.js +2 -2
- package/esm/navigation-menu/list/NavigationMenuList.js +1 -1
- package/esm/navigation-menu/popup/NavigationMenuPopup.js +2 -2
- package/esm/navigation-menu/root/NavigationMenuRoot.js +1 -3
- package/esm/navigation-menu/trigger/NavigationMenuTrigger.js +24 -17
- package/esm/navigation-menu/utils/isOutsideMenuEvent.d.ts +0 -1
- package/esm/navigation-menu/utils/isOutsideMenuEvent.js +1 -5
- package/esm/navigation-menu/viewport/NavigationMenuViewport.js +2 -3
- package/esm/number-field/input/NumberFieldInput.js +3 -5
- package/esm/number-field/root/NumberFieldRoot.js +5 -2
- package/esm/number-field/scrub-area/NumberFieldScrubArea.js +7 -3
- package/esm/otp-field/input/OTPFieldInput.js +43 -29
- package/esm/otp-field/root/OTPFieldRoot.d.ts +17 -8
- package/esm/otp-field/root/OTPFieldRoot.js +33 -33
- package/esm/otp-field/root/OTPFieldRootContext.d.ts +1 -1
- package/esm/otp-field/utils/otp.d.ts +5 -4
- package/esm/otp-field/utils/otp.js +23 -12
- package/esm/popover/arrow/PopoverArrow.js +1 -1
- package/esm/popover/backdrop/PopoverBackdrop.js +1 -1
- package/esm/popover/close/PopoverClose.js +2 -2
- package/esm/popover/description/PopoverDescription.js +1 -7
- package/esm/popover/popup/PopoverPopup.d.ts +1 -1
- package/esm/popover/popup/PopoverPopup.js +16 -10
- package/esm/popover/popup/PopoverPopupDataAttributes.d.ts +1 -1
- package/esm/popover/popup/PopoverPopupDataAttributes.js +1 -1
- package/esm/popover/positioner/PopoverPositioner.js +5 -5
- package/esm/popover/root/PopoverRoot.d.ts +1 -1
- package/esm/popover/root/PopoverRoot.js +42 -47
- package/esm/popover/store/PopoverHandle.js +1 -1
- package/esm/popover/store/PopoverStore.d.ts +91 -4
- package/esm/popover/store/PopoverStore.js +17 -18
- package/esm/popover/title/PopoverTitle.js +1 -7
- package/esm/popover/trigger/PopoverTrigger.js +24 -17
- package/esm/popover/viewport/PopoverViewport.d.ts +3 -3
- package/esm/popover/viewport/PopoverViewport.js +2 -2
- package/esm/popover/viewport/PopoverViewportDataAttributes.d.ts +1 -1
- package/esm/popover/viewport/PopoverViewportDataAttributes.js +1 -1
- package/esm/preview-card/positioner/PreviewCardPositioner.js +11 -1
- package/esm/preview-card/root/PreviewCardRoot.d.ts +1 -1
- package/esm/preview-card/root/PreviewCardRoot.js +32 -22
- package/esm/preview-card/store/PreviewCardHandle.js +1 -1
- package/esm/preview-card/store/PreviewCardStore.d.ts +90 -2
- package/esm/preview-card/store/PreviewCardStore.js +19 -31
- package/esm/preview-card/trigger/PreviewCardTrigger.js +6 -3
- package/esm/preview-card/viewport/PreviewCardViewport.d.ts +2 -2
- package/esm/preview-card/viewport/PreviewCardViewport.js +2 -2
- package/esm/preview-card/viewport/PreviewCardViewportDataAttributes.d.ts +2 -2
- package/esm/preview-card/viewport/PreviewCardViewportDataAttributes.js +2 -2
- package/esm/progress/indicator/ProgressIndicator.js +6 -11
- package/esm/progress/root/ProgressRoot.d.ts +1 -1
- package/esm/radio/root/RadioRoot.js +7 -3
- package/esm/radio-group/RadioGroup.js +4 -11
- package/esm/radio-group/RadioGroupContext.d.ts +0 -1
- package/esm/scroll-area/content/ScrollAreaContent.js +4 -4
- package/esm/scroll-area/root/ScrollAreaRoot.js +1 -1
- package/esm/scroll-area/scrollbar/ScrollAreaScrollbar.js +16 -20
- package/esm/scroll-area/viewport/ScrollAreaViewport.js +6 -10
- package/esm/select/arrow/SelectArrow.js +1 -1
- package/esm/select/backdrop/SelectBackdrop.js +1 -1
- package/esm/select/group/SelectGroup.js +1 -1
- package/esm/select/group-label/SelectGroupLabel.js +2 -2
- package/esm/select/icon/SelectIcon.js +1 -1
- package/esm/select/item/SelectItem.js +46 -32
- package/esm/select/item/SelectItemContext.d.ts +1 -1
- package/esm/select/item-indicator/SelectItemIndicator.js +1 -2
- package/esm/select/item-text/SelectItemText.js +9 -6
- package/esm/select/list/SelectList.js +1 -1
- package/esm/select/popup/SelectPopup.js +8 -3
- package/esm/select/positioner/SelectPositioner.js +3 -0
- package/esm/select/root/SelectRoot.js +46 -40
- package/esm/select/root/SelectRootContext.d.ts +4 -5
- package/esm/select/store.d.ts +3 -0
- package/esm/select/store.js +1 -0
- package/esm/select/trigger/SelectTrigger.d.ts +5 -0
- package/esm/select/trigger/SelectTrigger.js +19 -33
- package/esm/select/trigger/SelectTriggerDataAttributes.d.ts +5 -0
- package/esm/select/trigger/SelectTriggerDataAttributes.js +5 -0
- package/esm/slider/control/SliderControl.js +10 -12
- package/esm/slider/root/SliderRoot.js +1 -4
- package/esm/slider/thumb/SliderThumb.js +32 -30
- package/esm/slider/value/SliderValue.js +7 -15
- package/esm/switch/root/SwitchRoot.js +10 -10
- package/esm/switch/thumb/SwitchThumb.js +1 -9
- package/esm/tabs/indicator/TabsIndicator.js +14 -19
- package/esm/tabs/list/TabsList.js +4 -10
- package/esm/tabs/list/TabsListContext.d.ts +2 -1
- package/esm/tabs/panel/TabsPanel.js +1 -1
- package/esm/tabs/root/TabsRoot.d.ts +16 -1
- package/esm/tabs/root/TabsRoot.js +73 -25
- package/esm/tabs/root/TabsRootContext.d.ts +0 -2
- package/esm/toast/provider/ToastProvider.js +1 -1
- package/esm/toast/root/ToastRoot.d.ts +1 -1
- package/esm/toast/root/ToastRoot.js +108 -131
- package/esm/toast/root/ToastRootDataAttributes.d.ts +1 -1
- package/esm/toast/root/ToastRootDataAttributes.js +1 -1
- package/esm/toast/store.d.ts +9 -1
- package/esm/toast/store.js +19 -13
- package/esm/toast/useToastManager.d.ts +1 -1
- package/esm/toast/viewport/ToastViewport.js +1 -1
- package/esm/toggle/Toggle.js +5 -9
- package/esm/toggle-group/ToggleGroup.d.ts +2 -2
- package/esm/toggle-group/ToggleGroup.js +6 -13
- package/esm/toolbar/link/ToolbarLink.d.ts +1 -1
- package/esm/toolbar/link/ToolbarLink.js +1 -2
- package/esm/tooltip/arrow/TooltipArrow.js +3 -3
- package/esm/tooltip/popup/TooltipPopup.js +5 -4
- package/esm/tooltip/root/TooltipRoot.js +35 -26
- package/esm/tooltip/store/TooltipHandle.js +1 -1
- package/esm/tooltip/store/TooltipStore.d.ts +90 -2
- package/esm/tooltip/store/TooltipStore.js +18 -31
- package/esm/tooltip/trigger/TooltipTrigger.js +151 -20
- package/esm/tooltip/viewport/TooltipViewport.d.ts +2 -2
- package/esm/tooltip/viewport/TooltipViewport.js +2 -2
- package/esm/tooltip/viewport/TooltipViewportDataAttributes.d.ts +1 -1
- package/esm/tooltip/viewport/TooltipViewportDataAttributes.js +1 -1
- package/esm/unstable-use-media-query/index.js +1 -1
- package/esm/utils/popups/index.d.ts +1 -0
- package/esm/utils/popups/index.js +1 -0
- package/esm/utils/popups/inlineRect.d.ts +15 -0
- package/esm/utils/popups/inlineRect.js +191 -0
- package/esm/utils/popups/popupStoreUtils.d.ts +28 -10
- package/esm/utils/popups/popupStoreUtils.js +105 -20
- package/esm/utils/popups/popupTriggerMap.js +2 -0
- package/esm/utils/popups/store.d.ts +15 -2
- package/esm/utils/popups/store.js +38 -2
- package/esm/utils/popups/useTriggerFocusGuards.js +4 -5
- package/esm/utils/useAnchorPositioning.d.ts +5 -0
- package/esm/utils/useAnchorPositioning.js +12 -9
- package/esm/utils/useOpenInteractionType.d.ts +4 -0
- package/esm/utils/useOpenInteractionType.js +23 -18
- package/field/control/FieldControl.js +2 -6
- package/field/item/FieldItem.js +1 -4
- package/field/root/FieldRoot.js +11 -3
- package/field/root/useFieldValidation.d.ts +1 -0
- package/field/root/useFieldValidation.js +23 -20
- package/field/utils/getCombinedFieldValidityData.d.ts +1 -1
- package/field/validity/FieldValidity.d.ts +1 -1
- package/floating-ui-react/components/FloatingDelayGroup.js +3 -3
- package/floating-ui-react/components/FloatingFocusManager.d.ts +1 -1
- package/floating-ui-react/components/FloatingFocusManager.js +20 -8
- package/floating-ui-react/components/FloatingPortal.js +3 -3
- package/floating-ui-react/hooks/useClick.js +82 -73
- package/floating-ui-react/hooks/useClientPoint.js +29 -20
- package/floating-ui-react/hooks/useDismiss.d.ts +1 -1
- package/floating-ui-react/hooks/useDismiss.js +82 -92
- package/floating-ui-react/hooks/useFloating.js +36 -32
- package/floating-ui-react/hooks/useFloatingRootContext.d.ts +1 -1
- package/floating-ui-react/hooks/useFloatingRootContext.js +2 -2
- package/floating-ui-react/hooks/useFocus.js +84 -81
- package/floating-ui-react/hooks/useHover.js +74 -78
- package/floating-ui-react/hooks/useHoverFloatingInteraction.js +48 -43
- package/floating-ui-react/hooks/useHoverInteractionSharedState.js +1 -1
- package/floating-ui-react/hooks/useHoverReferenceInteraction.d.ts +7 -2
- package/floating-ui-react/hooks/useHoverReferenceInteraction.js +43 -38
- package/floating-ui-react/hooks/useHoverShared.d.ts +2 -1
- package/floating-ui-react/hooks/useHoverShared.js +11 -0
- package/floating-ui-react/hooks/useListNavigation.d.ts +1 -3
- package/floating-ui-react/hooks/useListNavigation.js +83 -74
- package/floating-ui-react/hooks/useSyncedFloatingRootContext.d.ts +9 -6
- package/floating-ui-react/hooks/useSyncedFloatingRootContext.js +26 -20
- package/floating-ui-react/hooks/useTypeahead.d.ts +2 -2
- package/floating-ui-react/hooks/useTypeahead.js +33 -52
- package/floating-ui-react/index.d.ts +0 -2
- package/floating-ui-react/index.js +0 -14
- package/floating-ui-react/types.d.ts +2 -7
- package/floating-ui-react/utils/composite.js +2 -0
- package/floating-ui-react/utils/enqueueFocus.d.ts +1 -1
- package/floating-ui-react/utils/enqueueFocus.js +10 -7
- package/floating-ui-react/utils/getEmptyRootContext.js +1 -1
- package/form/Form.js +2 -2
- package/index.js +1 -1
- package/internals/composite/composite.d.ts +0 -1
- package/internals/composite/composite.js +2 -3
- package/internals/composite/root/useCompositeRoot.js +1 -1
- package/internals/createBaseUIEventDetails.d.ts +2 -0
- package/internals/csp-context/index.d.ts +2 -0
- package/internals/csp-context/index.js +18 -0
- package/internals/field-register-control/index.d.ts +0 -1
- package/internals/field-register-control/useFieldControlRegistration.d.ts +2 -1
- package/internals/field-register-control/useFieldControlRegistration.js +11 -14
- package/internals/field-register-control/useRegisterFieldControl.d.ts +1 -4
- package/internals/field-register-control/useRegisterFieldControl.js +6 -11
- package/internals/field-root-context/FieldRootContext.d.ts +1 -0
- package/internals/field-root-context/FieldRootContext.js +4 -3
- package/internals/form-context/FormContext.d.ts +5 -1
- package/internals/reason-parts.d.ts +2 -0
- package/internals/reason-parts.js +3 -1
- package/internals/types.d.ts +1 -0
- package/internals/use-button/useButton.js +4 -4
- package/internals/usePressAndHold.js +2 -2
- package/internals/useRenderElement.js +2 -0
- package/menu/arrow/MenuArrow.js +1 -1
- package/menu/backdrop/MenuBackdrop.js +1 -1
- package/menu/checkbox-item/MenuCheckboxItem.js +5 -7
- package/menu/group/MenuGroup.js +1 -4
- package/menu/group/MenuGroupContext.d.ts +1 -3
- package/menu/group/MenuGroupContext.js +1 -1
- package/menu/group-label/MenuGroupLabel.js +4 -6
- package/menu/link-item/MenuLinkItem.js +2 -2
- package/menu/popup/MenuPopup.js +5 -5
- package/menu/radio-group/MenuRadioGroup.js +11 -5
- package/menu/radio-item/MenuRadioItem.js +5 -7
- package/menu/root/MenuRoot.js +60 -65
- package/menu/store/MenuHandle.js +1 -1
- package/menu/store/MenuStore.d.ts +87 -0
- package/menu/submenu-trigger/MenuSubmenuTrigger.js +7 -4
- package/menu/trigger/MenuTrigger.js +12 -9
- package/menu/viewport/MenuViewport.d.ts +2 -2
- package/menu/viewport/MenuViewport.js +2 -2
- package/navigation-menu/arrow/NavigationMenuArrow.js +1 -1
- package/navigation-menu/backdrop/NavigationMenuBackdrop.js +1 -1
- package/navigation-menu/content/NavigationMenuContent.js +8 -5
- package/navigation-menu/icon/NavigationMenuIcon.js +1 -1
- package/navigation-menu/item/NavigationMenuItem.js +2 -2
- package/navigation-menu/list/NavigationMenuList.js +1 -1
- package/navigation-menu/popup/NavigationMenuPopup.js +2 -2
- package/navigation-menu/root/NavigationMenuRoot.js +1 -3
- package/navigation-menu/trigger/NavigationMenuTrigger.js +23 -16
- package/navigation-menu/utils/isOutsideMenuEvent.d.ts +0 -1
- package/navigation-menu/utils/isOutsideMenuEvent.js +1 -5
- package/navigation-menu/viewport/NavigationMenuViewport.js +2 -3
- package/number-field/input/NumberFieldInput.js +3 -5
- package/number-field/root/NumberFieldRoot.js +5 -2
- package/number-field/scrub-area/NumberFieldScrubArea.js +7 -3
- package/otp-field/input/OTPFieldInput.js +42 -28
- package/otp-field/root/OTPFieldRoot.d.ts +17 -8
- package/otp-field/root/OTPFieldRoot.js +32 -32
- package/otp-field/root/OTPFieldRootContext.d.ts +1 -1
- package/otp-field/utils/otp.d.ts +5 -4
- package/otp-field/utils/otp.js +24 -12
- package/package.json +331 -317
- package/popover/arrow/PopoverArrow.js +1 -1
- package/popover/backdrop/PopoverBackdrop.js +1 -1
- package/popover/close/PopoverClose.js +2 -2
- package/popover/description/PopoverDescription.js +1 -7
- package/popover/popup/PopoverPopup.d.ts +1 -1
- package/popover/popup/PopoverPopup.js +16 -10
- package/popover/popup/PopoverPopupDataAttributes.d.ts +1 -1
- package/popover/popup/PopoverPopupDataAttributes.js +1 -1
- package/popover/positioner/PopoverPositioner.js +5 -5
- package/popover/root/PopoverRoot.d.ts +1 -1
- package/popover/root/PopoverRoot.js +39 -44
- package/popover/store/PopoverHandle.js +1 -1
- package/popover/store/PopoverStore.d.ts +91 -4
- package/popover/store/PopoverStore.js +16 -19
- package/popover/title/PopoverTitle.js +1 -7
- package/popover/trigger/PopoverTrigger.js +23 -16
- package/popover/viewport/PopoverViewport.d.ts +3 -3
- package/popover/viewport/PopoverViewport.js +2 -2
- package/popover/viewport/PopoverViewportDataAttributes.d.ts +1 -1
- package/popover/viewport/PopoverViewportDataAttributes.js +1 -1
- package/preview-card/positioner/PreviewCardPositioner.js +11 -1
- package/preview-card/root/PreviewCardRoot.d.ts +1 -1
- package/preview-card/root/PreviewCardRoot.js +30 -20
- package/preview-card/store/PreviewCardHandle.js +1 -1
- package/preview-card/store/PreviewCardStore.d.ts +90 -2
- package/preview-card/store/PreviewCardStore.js +18 -30
- package/preview-card/trigger/PreviewCardTrigger.js +5 -2
- package/preview-card/viewport/PreviewCardViewport.d.ts +2 -2
- package/preview-card/viewport/PreviewCardViewport.js +2 -2
- package/preview-card/viewport/PreviewCardViewportDataAttributes.d.ts +2 -2
- package/preview-card/viewport/PreviewCardViewportDataAttributes.js +2 -2
- package/progress/indicator/ProgressIndicator.js +6 -11
- package/progress/root/ProgressRoot.d.ts +1 -1
- package/radio/root/RadioRoot.js +7 -3
- package/radio-group/RadioGroup.js +4 -11
- package/radio-group/RadioGroupContext.d.ts +0 -1
- package/scroll-area/content/ScrollAreaContent.js +4 -4
- package/scroll-area/root/ScrollAreaRoot.js +1 -1
- package/scroll-area/scrollbar/ScrollAreaScrollbar.js +16 -20
- package/scroll-area/viewport/ScrollAreaViewport.js +6 -10
- package/select/arrow/SelectArrow.js +1 -1
- package/select/backdrop/SelectBackdrop.js +1 -1
- package/select/group/SelectGroup.js +1 -1
- package/select/group-label/SelectGroupLabel.js +2 -2
- package/select/icon/SelectIcon.js +1 -1
- package/select/item/SelectItem.js +46 -32
- package/select/item/SelectItemContext.d.ts +1 -1
- package/select/item-indicator/SelectItemIndicator.js +1 -2
- package/select/item-text/SelectItemText.js +9 -6
- package/select/list/SelectList.js +1 -1
- package/select/popup/SelectPopup.js +8 -3
- package/select/positioner/SelectPositioner.js +3 -0
- package/select/root/SelectRoot.js +45 -39
- package/select/root/SelectRootContext.d.ts +4 -5
- package/select/store.d.ts +3 -0
- package/select/store.js +1 -0
- package/select/trigger/SelectTrigger.d.ts +5 -0
- package/select/trigger/SelectTrigger.js +19 -33
- package/select/trigger/SelectTriggerDataAttributes.d.ts +5 -0
- package/select/trigger/SelectTriggerDataAttributes.js +5 -0
- package/slider/control/SliderControl.js +9 -11
- package/slider/root/SliderRoot.js +1 -4
- package/slider/thumb/SliderThumb.js +32 -30
- package/slider/value/SliderValue.js +7 -15
- package/switch/root/SwitchRoot.js +10 -10
- package/switch/thumb/SwitchThumb.js +1 -9
- package/tabs/indicator/TabsIndicator.js +14 -19
- package/tabs/list/TabsList.js +4 -10
- package/tabs/list/TabsListContext.d.ts +2 -1
- package/tabs/panel/TabsPanel.js +1 -1
- package/tabs/root/TabsRoot.d.ts +16 -1
- package/tabs/root/TabsRoot.js +71 -24
- package/tabs/root/TabsRootContext.d.ts +0 -2
- package/toast/provider/ToastProvider.js +1 -1
- package/toast/root/ToastRoot.d.ts +1 -1
- package/toast/root/ToastRoot.js +110 -133
- package/toast/root/ToastRootDataAttributes.d.ts +1 -1
- package/toast/root/ToastRootDataAttributes.js +1 -1
- package/toast/store.d.ts +9 -1
- package/toast/store.js +18 -12
- package/toast/useToastManager.d.ts +1 -1
- package/toast/viewport/ToastViewport.js +1 -1
- package/toggle/Toggle.js +5 -9
- package/toggle-group/ToggleGroup.d.ts +2 -2
- package/toggle-group/ToggleGroup.js +6 -13
- package/toolbar/link/ToolbarLink.d.ts +1 -1
- package/toolbar/link/ToolbarLink.js +1 -2
- package/tooltip/arrow/TooltipArrow.js +3 -3
- package/tooltip/popup/TooltipPopup.js +5 -4
- package/tooltip/root/TooltipRoot.js +32 -23
- package/tooltip/store/TooltipHandle.js +1 -1
- package/tooltip/store/TooltipStore.d.ts +90 -2
- package/tooltip/store/TooltipStore.js +17 -30
- package/tooltip/trigger/TooltipTrigger.js +152 -20
- package/tooltip/viewport/TooltipViewport.d.ts +2 -2
- package/tooltip/viewport/TooltipViewport.js +2 -2
- package/tooltip/viewport/TooltipViewportDataAttributes.d.ts +1 -1
- package/tooltip/viewport/TooltipViewportDataAttributes.js +1 -1
- package/unstable-use-media-query/index.js +1 -1
- package/utils/popups/index.d.ts +1 -0
- package/utils/popups/index.js +11 -0
- package/utils/popups/inlineRect.d.ts +15 -0
- package/utils/popups/inlineRect.js +198 -0
- package/utils/popups/popupStoreUtils.d.ts +28 -10
- package/utils/popups/popupStoreUtils.js +110 -20
- package/utils/popups/popupTriggerMap.js +2 -0
- package/utils/popups/store.d.ts +15 -2
- package/utils/popups/store.js +39 -2
- package/utils/popups/useTriggerFocusGuards.js +4 -5
- package/utils/useAnchorPositioning.d.ts +5 -0
- package/utils/useAnchorPositioning.js +12 -9
- package/utils/useOpenInteractionType.d.ts +4 -0
- package/utils/useOpenInteractionType.js +24 -17
- package/checkbox-group/index.parts.d.ts +0 -1
- package/checkbox-group/index.parts.js +0 -12
- package/esm/checkbox-group/index.parts.d.ts +0 -1
- package/esm/checkbox-group/index.parts.js +0 -1
- package/esm/floating-ui-react/hooks/useInteractions.d.ts +0 -20
- package/esm/floating-ui-react/hooks/useInteractions.js +0 -88
- package/esm/floating-ui-react/hooks/useRole.d.ts +0 -17
- package/esm/floating-ui-react/hooks/useRole.js +0 -113
- package/floating-ui-react/hooks/useInteractions.d.ts +0 -20
- package/floating-ui-react/hooks/useInteractions.js +0 -95
- package/floating-ui-react/hooks/useRole.d.ts +0 -17
- package/floating-ui-react/hooks/useRole.js +0 -120
- /package/{csp-provider → esm/internals/csp-context}/CSPContext.d.ts +0 -0
- /package/esm/{csp-provider → internals/csp-context}/CSPContext.js +0 -0
- /package/{esm/csp-provider → internals/csp-context}/CSPContext.d.ts +0 -0
- /package/{csp-provider → internals/csp-context}/CSPContext.js +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { getWindow, isElement, isHTMLElement } from '@floating-ui/utils/dom';
|
|
5
4
|
import { addEventListener } from '@base-ui/utils/addEventListener';
|
|
6
|
-
import { mergeCleanups } from '@base-ui/utils/mergeCleanups';
|
|
7
5
|
import { isMac, isSafari } from '@base-ui/utils/detectBrowser';
|
|
8
|
-
import {
|
|
6
|
+
import { mergeCleanups } from '@base-ui/utils/mergeCleanups';
|
|
9
7
|
import { ownerDocument } from '@base-ui/utils/owner';
|
|
8
|
+
import { useTimeout } from '@base-ui/utils/useTimeout';
|
|
9
|
+
import { getWindow, isElement, isHTMLElement } from '@floating-ui/utils/dom';
|
|
10
|
+
import { createAttribute } from "../utils/createAttribute.js";
|
|
10
11
|
import { activeElement, contains, getTarget, isTargetInsideEnabledTrigger, isTypeableElement, matchesFocusVisible } from "../utils/element.js";
|
|
11
12
|
import { createChangeEventDetails } from "../../internals/createBaseUIEventDetails.js";
|
|
12
13
|
import { REASONS } from "../../internals/reasons.js";
|
|
13
|
-
import { createAttribute } from "../utils/createAttribute.js";
|
|
14
14
|
const isMacSafari = isMac && isSafari;
|
|
15
15
|
/**
|
|
16
16
|
* Opens the floating element while the reference element has focus, like CSS
|
|
@@ -18,20 +18,20 @@ const isMacSafari = isMac && isSafari;
|
|
|
18
18
|
* @see https://floating-ui.com/docs/useFocus
|
|
19
19
|
*/
|
|
20
20
|
export function useFocus(context, props = {}) {
|
|
21
|
+
const {
|
|
22
|
+
enabled = true,
|
|
23
|
+
delay
|
|
24
|
+
} = props;
|
|
21
25
|
const store = 'rootStore' in context ? context.rootStore : context;
|
|
22
26
|
const {
|
|
23
27
|
events,
|
|
24
28
|
dataRef
|
|
25
29
|
} = store.context;
|
|
26
|
-
const {
|
|
27
|
-
enabled = true,
|
|
28
|
-
delay
|
|
29
|
-
} = props;
|
|
30
30
|
const blockFocusRef = React.useRef(false);
|
|
31
31
|
// Track which reference should be blocked from re-opening after Escape/press dismissal.
|
|
32
32
|
const blockedReferenceRef = React.useRef(null);
|
|
33
|
-
const timeout = useTimeout();
|
|
34
33
|
const keyboardModalityRef = React.useRef(true);
|
|
34
|
+
const timeout = useTimeout();
|
|
35
35
|
React.useEffect(() => {
|
|
36
36
|
const domReference = store.select('domReferenceElement');
|
|
37
37
|
if (!enabled) {
|
|
@@ -74,91 +74,94 @@ export function useFocus(context, props = {}) {
|
|
|
74
74
|
events.off('openchange', onOpenChangeLocal);
|
|
75
75
|
};
|
|
76
76
|
}, [events, enabled, store]);
|
|
77
|
-
const reference = React.useMemo(() =>
|
|
78
|
-
|
|
77
|
+
const reference = React.useMemo(() => {
|
|
78
|
+
function resetBlockedFocus() {
|
|
79
79
|
blockFocusRef.current = false;
|
|
80
80
|
blockedReferenceRef.current = null;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
onMouseLeave() {
|
|
84
|
+
resetBlockedFocus();
|
|
85
|
+
},
|
|
86
|
+
onFocus(event) {
|
|
87
|
+
const focusTarget = event.currentTarget;
|
|
88
|
+
if (blockFocusRef.current) {
|
|
89
|
+
if (blockedReferenceRef.current === focusTarget) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
resetBlockedFocus();
|
|
87
93
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
if (!
|
|
94
|
+
const target = getTarget(event.nativeEvent);
|
|
95
|
+
if (isElement(target)) {
|
|
96
|
+
// Safari fails to match `:focus-visible` if focus was initially
|
|
97
|
+
// outside the document.
|
|
98
|
+
if (isMacSafari && !event.relatedTarget) {
|
|
99
|
+
if (!keyboardModalityRef.current && !isTypeableElement(target)) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
} else if (!matchesFocusVisible(target)) {
|
|
97
103
|
return;
|
|
98
104
|
}
|
|
99
|
-
} else if (!matchesFocusVisible(target)) {
|
|
100
|
-
return;
|
|
101
105
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
store.setOpen(true, createChangeEventDetails(REASONS.triggerFocus, nativeEvent, currentTarget));
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
timeout.start(delayValue, () => {
|
|
114
|
-
if (blockFocusRef.current) {
|
|
106
|
+
const movedFromOtherEnabledTrigger = isTargetInsideEnabledTrigger(event.relatedTarget, store.context.triggerElements);
|
|
107
|
+
const {
|
|
108
|
+
nativeEvent,
|
|
109
|
+
currentTarget
|
|
110
|
+
} = event;
|
|
111
|
+
const delayValue = typeof delay === 'function' ? delay() : delay;
|
|
112
|
+
if (store.select('open') && movedFromOtherEnabledTrigger || delayValue === 0 || delayValue === undefined) {
|
|
113
|
+
store.setOpen(true, createChangeEventDetails(REASONS.triggerFocus, nativeEvent, currentTarget));
|
|
115
114
|
return;
|
|
116
115
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
116
|
+
timeout.start(delayValue, () => {
|
|
117
|
+
if (blockFocusRef.current) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
store.setOpen(true, createChangeEventDetails(REASONS.triggerFocus, nativeEvent, currentTarget));
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
onBlur(event) {
|
|
124
|
+
resetBlockedFocus();
|
|
125
|
+
const relatedTarget = event.relatedTarget;
|
|
126
|
+
const nativeEvent = event.nativeEvent;
|
|
125
127
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
128
|
+
// Hit the non-modal focus management portal guard. Focus will be
|
|
129
|
+
// moved into the floating element immediately after.
|
|
130
|
+
const movedToFocusGuard = isElement(relatedTarget) && relatedTarget.hasAttribute(createAttribute('focus-guard')) && relatedTarget.getAttribute('data-type') === 'outside';
|
|
129
131
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
// Wait for the window blur listener to fire.
|
|
133
|
+
timeout.start(0, () => {
|
|
134
|
+
const domReference = store.select('domReferenceElement');
|
|
135
|
+
const activeEl = activeElement(ownerDocument(domReference));
|
|
134
136
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
// Focus left the page, keep it open.
|
|
138
|
+
if (!relatedTarget && activeEl === domReference) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
139
141
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
142
|
+
// When focusing the reference element (e.g. regular click), then
|
|
143
|
+
// clicking into the floating element, prevent it from hiding.
|
|
144
|
+
// Note: it must be focusable, e.g. `tabindex="-1"`.
|
|
145
|
+
// We can not rely on relatedTarget to point to the correct element
|
|
146
|
+
// as it will only point to the shadow host of the newly focused element
|
|
147
|
+
// and not the element that actually has received focus if it is located
|
|
148
|
+
// inside a shadow root.
|
|
149
|
+
if (contains(dataRef.current.floatingContext?.refs.floating.current, activeEl) || contains(domReference, activeEl) || movedToFocusGuard) {
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
150
152
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
153
|
+
// If the next focused element is one of the triggers, do not close
|
|
154
|
+
// the floating element. The focus handler of that trigger will
|
|
155
|
+
// handle the open state.
|
|
156
|
+
const nextFocusedElement = relatedTarget ?? activeEl;
|
|
157
|
+
if (isTargetInsideEnabledTrigger(nextFocusedElement, store.context.triggerElements)) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
store.setOpen(false, createChangeEventDetails(REASONS.triggerFocus, nativeEvent));
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
}, [dataRef, delay, store, timeout]);
|
|
162
165
|
return React.useMemo(() => enabled ? {
|
|
163
166
|
reference,
|
|
164
167
|
trigger: reference
|
|
@@ -1,25 +1,31 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { isElement } from '@floating-ui/utils/dom';
|
|
5
4
|
import { addEventListener } from '@base-ui/utils/addEventListener';
|
|
6
5
|
import { mergeCleanups } from '@base-ui/utils/mergeCleanups';
|
|
7
|
-
import { useTimeout } from '@base-ui/utils/useTimeout';
|
|
8
|
-
import { useValueAsRef } from '@base-ui/utils/useValueAsRef';
|
|
9
|
-
import { useStableCallback } from '@base-ui/utils/useStableCallback';
|
|
10
6
|
import { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect';
|
|
11
7
|
import { ownerDocument } from '@base-ui/utils/owner';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
8
|
+
import { useStableCallback } from '@base-ui/utils/useStableCallback';
|
|
9
|
+
import { useTimeout } from '@base-ui/utils/useTimeout';
|
|
10
|
+
import { useValueAsRef } from '@base-ui/utils/useValueAsRef';
|
|
11
|
+
import { isElement } from '@floating-ui/utils/dom';
|
|
14
12
|
import { createChangeEventDetails } from "../../internals/createBaseUIEventDetails.js";
|
|
15
13
|
import { REASONS } from "../../internals/reasons.js";
|
|
16
|
-
import {
|
|
14
|
+
import { useFloatingParentNodeId, useFloatingTree } from "../components/FloatingTree.js";
|
|
15
|
+
import { contains, getTarget, isInteractiveElement } from "../utils/element.js";
|
|
16
|
+
import { getDelay, getRestMs, isClickLikeOpenEvent as isClickLikeOpenEventShared, isHoverOpenEvent } from "./useHoverShared.js";
|
|
17
17
|
/**
|
|
18
18
|
* Opens the floating element while hovering over the reference element, like
|
|
19
19
|
* CSS `:hover`.
|
|
20
20
|
* @see https://floating-ui.com/docs/useHover
|
|
21
21
|
*/
|
|
22
22
|
export function useHover(context, props = {}) {
|
|
23
|
+
const {
|
|
24
|
+
delay = 0,
|
|
25
|
+
handleClose = null,
|
|
26
|
+
restMs = 0,
|
|
27
|
+
move = true
|
|
28
|
+
} = props;
|
|
23
29
|
const store = 'rootStore' in context ? context.rootStore : context;
|
|
24
30
|
const open = store.useState('open');
|
|
25
31
|
const floatingElement = store.useState('floatingElement');
|
|
@@ -28,12 +34,6 @@ export function useHover(context, props = {}) {
|
|
|
28
34
|
dataRef,
|
|
29
35
|
events
|
|
30
36
|
} = store.context;
|
|
31
|
-
const {
|
|
32
|
-
delay = 0,
|
|
33
|
-
handleClose = null,
|
|
34
|
-
restMs = 0,
|
|
35
|
-
move = true
|
|
36
|
-
} = props;
|
|
37
37
|
const tree = useFloatingTree();
|
|
38
38
|
const parentId = useFloatingParentNodeId();
|
|
39
39
|
const handleCloseRef = useValueAsRef(handleClose);
|
|
@@ -41,22 +41,29 @@ export function useHover(context, props = {}) {
|
|
|
41
41
|
const restMsRef = useValueAsRef(restMs);
|
|
42
42
|
const pointerTypeRef = React.useRef(undefined);
|
|
43
43
|
const interactedInsideRef = React.useRef(false);
|
|
44
|
-
const timeout = useTimeout();
|
|
45
44
|
const handlerRef = React.useRef(undefined);
|
|
46
|
-
const restTimeout = useTimeout();
|
|
47
45
|
const blockMouseMoveRef = React.useRef(true);
|
|
48
46
|
const performedPointerEventsMutationRef = React.useRef(false);
|
|
49
47
|
const unbindMouseMoveRef = React.useRef(() => {});
|
|
50
48
|
const restTimeoutPendingRef = React.useRef(false);
|
|
49
|
+
const timeout = useTimeout();
|
|
50
|
+
const restTimeout = useTimeout();
|
|
51
51
|
const isHoverOpen = useStableCallback(() => {
|
|
52
|
-
|
|
53
|
-
return type?.includes('mouse') && type !== 'mousedown';
|
|
52
|
+
return isHoverOpenEvent(dataRef.current.openEvent?.type);
|
|
54
53
|
});
|
|
55
54
|
const isClickLikeOpenEvent = useStableCallback(() => {
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
return isClickLikeOpenEventShared(dataRef.current.openEvent?.type, interactedInsideRef.current);
|
|
56
|
+
});
|
|
57
|
+
const cleanupMouseMoveHandler = useStableCallback(() => {
|
|
58
|
+
unbindMouseMoveRef.current();
|
|
59
|
+
handlerRef.current = undefined;
|
|
60
|
+
});
|
|
61
|
+
const clearPointerEvents = useStableCallback(() => {
|
|
62
|
+
if (performedPointerEventsMutationRef.current) {
|
|
63
|
+
const body = ownerDocument(floatingElement).body;
|
|
64
|
+
body.style.pointerEvents = '';
|
|
65
|
+
performedPointerEventsMutationRef.current = false;
|
|
58
66
|
}
|
|
59
|
-
return dataRef.current.openEvent ? ['click', 'mousedown'].includes(dataRef.current.openEvent.type) : false;
|
|
60
67
|
});
|
|
61
68
|
|
|
62
69
|
// When closing before opening, clear the delay timeouts to cancel it
|
|
@@ -93,39 +100,40 @@ export function useHover(context, props = {}) {
|
|
|
93
100
|
const html = ownerDocument(floatingElement).documentElement;
|
|
94
101
|
return addEventListener(html, 'mouseleave', onLeave);
|
|
95
102
|
}, [floatingElement, open, store, handleCloseRef, isHoverOpen, isClickLikeOpenEvent]);
|
|
96
|
-
const closeWithDelay = React.useCallback((event, runElseBranch = true) => {
|
|
97
|
-
const closeDelay = getDelay(delayRef.current, 'close', pointerTypeRef.current);
|
|
98
|
-
if (closeDelay && !handlerRef.current) {
|
|
99
|
-
timeout.start(closeDelay, () => store.setOpen(false, createChangeEventDetails(REASONS.triggerHover, event)));
|
|
100
|
-
} else if (runElseBranch) {
|
|
101
|
-
timeout.clear();
|
|
102
|
-
store.setOpen(false, createChangeEventDetails(REASONS.triggerHover, event));
|
|
103
|
-
}
|
|
104
|
-
}, [delayRef, store, timeout]);
|
|
105
|
-
const cleanupMouseMoveHandler = useStableCallback(() => {
|
|
106
|
-
unbindMouseMoveRef.current();
|
|
107
|
-
handlerRef.current = undefined;
|
|
108
|
-
});
|
|
109
|
-
const clearPointerEvents = useStableCallback(() => {
|
|
110
|
-
if (performedPointerEventsMutationRef.current) {
|
|
111
|
-
const body = ownerDocument(floatingElement).body;
|
|
112
|
-
body.style.pointerEvents = '';
|
|
113
|
-
performedPointerEventsMutationRef.current = false;
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
const handleInteractInside = useStableCallback(event => {
|
|
117
|
-
const target = getTarget(event);
|
|
118
|
-
if (!isInteractiveElement(target)) {
|
|
119
|
-
interactedInsideRef.current = false;
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
interactedInsideRef.current = true;
|
|
123
|
-
});
|
|
124
103
|
|
|
125
104
|
// Registering the mouse events on the reference directly to bypass React's
|
|
126
105
|
// delegation system. If the cursor was on a disabled element and then entered
|
|
127
106
|
// the reference (no gap), `mouseenter` doesn't fire in the delegation system.
|
|
128
107
|
React.useEffect(() => {
|
|
108
|
+
function closeWithDelay(event, runElseBranch = true) {
|
|
109
|
+
const closeDelay = getDelay(delayRef.current, 'close', pointerTypeRef.current);
|
|
110
|
+
if (closeDelay && !handlerRef.current) {
|
|
111
|
+
timeout.start(closeDelay, () => store.setOpen(false, createChangeEventDetails(REASONS.triggerHover, event)));
|
|
112
|
+
} else if (runElseBranch) {
|
|
113
|
+
timeout.clear();
|
|
114
|
+
store.setOpen(false, createChangeEventDetails(REASONS.triggerHover, event));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function handleInteractInside(event) {
|
|
118
|
+
const target = getTarget(event);
|
|
119
|
+
if (!isInteractiveElement(target)) {
|
|
120
|
+
interactedInsideRef.current = false;
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
interactedInsideRef.current = true;
|
|
124
|
+
}
|
|
125
|
+
function getHandleCloseHandler(event, onClose) {
|
|
126
|
+
if (!handleCloseRef.current || !dataRef.current.floatingContext) {
|
|
127
|
+
return null;
|
|
128
|
+
}
|
|
129
|
+
return handleCloseRef.current({
|
|
130
|
+
...dataRef.current.floatingContext,
|
|
131
|
+
tree,
|
|
132
|
+
x: event.clientX,
|
|
133
|
+
y: event.clientY,
|
|
134
|
+
onClose
|
|
135
|
+
});
|
|
136
|
+
}
|
|
129
137
|
function onReferenceMouseEnter(event) {
|
|
130
138
|
timeout.clear();
|
|
131
139
|
blockMouseMoveRef.current = false;
|
|
@@ -161,25 +169,19 @@ export function useHover(context, props = {}) {
|
|
|
161
169
|
// as it will be moved.
|
|
162
170
|
return;
|
|
163
171
|
}
|
|
164
|
-
|
|
172
|
+
const handler = getHandleCloseHandler(event, () => {
|
|
173
|
+
clearPointerEvents();
|
|
174
|
+
cleanupMouseMoveHandler();
|
|
175
|
+
if (!isClickLikeOpenEvent()) {
|
|
176
|
+
closeWithDelay(event, true);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
if (handler) {
|
|
165
180
|
// Prevent clearing `onScrollMouseLeave` timeout.
|
|
166
181
|
if (!open) {
|
|
167
182
|
timeout.clear();
|
|
168
183
|
}
|
|
169
|
-
handlerRef.current =
|
|
170
|
-
...dataRef.current.floatingContext,
|
|
171
|
-
tree,
|
|
172
|
-
x: event.clientX,
|
|
173
|
-
y: event.clientY,
|
|
174
|
-
onClose() {
|
|
175
|
-
clearPointerEvents();
|
|
176
|
-
cleanupMouseMoveHandler();
|
|
177
|
-
if (!isClickLikeOpenEvent()) {
|
|
178
|
-
closeWithDelay(event, true);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
const handler = handlerRef.current;
|
|
184
|
+
handlerRef.current = handler;
|
|
183
185
|
unbindMouseMoveRef.current = addEventListener(doc, 'mousemove', handler);
|
|
184
186
|
return;
|
|
185
187
|
}
|
|
@@ -206,19 +208,13 @@ export function useHover(context, props = {}) {
|
|
|
206
208
|
// as it will be moved.
|
|
207
209
|
return;
|
|
208
210
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
onClose() {
|
|
215
|
-
clearPointerEvents();
|
|
216
|
-
cleanupMouseMoveHandler();
|
|
217
|
-
if (!isClickLikeOpenEvent()) {
|
|
218
|
-
closeWithDelay(event);
|
|
219
|
-
}
|
|
211
|
+
getHandleCloseHandler(event, () => {
|
|
212
|
+
clearPointerEvents();
|
|
213
|
+
cleanupMouseMoveHandler();
|
|
214
|
+
if (!isClickLikeOpenEvent()) {
|
|
215
|
+
closeWithDelay(event);
|
|
220
216
|
}
|
|
221
|
-
})(event);
|
|
217
|
+
})?.(event);
|
|
222
218
|
}
|
|
223
219
|
function onFloatingMouseEnter() {
|
|
224
220
|
timeout.clear();
|
|
@@ -237,7 +233,7 @@ export function useHover(context, props = {}) {
|
|
|
237
233
|
}), addEventListener(trigger, 'mouseenter', onReferenceMouseEnter), addEventListener(trigger, 'mouseleave', onReferenceMouseLeave), floating && addEventListener(floating, 'mouseleave', onScrollMouseLeave), floating && addEventListener(floating, 'mouseenter', onFloatingMouseEnter), floating && addEventListener(floating, 'mouseleave', onFloatingMouseLeave), floating && addEventListener(floating, 'pointerdown', handleInteractInside, true));
|
|
238
234
|
}
|
|
239
235
|
return undefined;
|
|
240
|
-
}, [move, domReferenceElement, floatingElement, store,
|
|
236
|
+
}, [move, domReferenceElement, floatingElement, store, cleanupMouseMoveHandler, clearPointerEvents, open, tree, delayRef, handleCloseRef, dataRef, isClickLikeOpenEvent, restMsRef, timeout, restTimeout]);
|
|
241
237
|
|
|
242
238
|
// Block pointer-events of every element other than the reference and floating
|
|
243
239
|
// while the floating element is open and has a `handleClose` handler. Also
|
|
@@ -1,24 +1,29 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { isElement } from '@floating-ui/utils/dom';
|
|
5
4
|
import { addEventListener } from '@base-ui/utils/addEventListener';
|
|
6
5
|
import { mergeCleanups } from '@base-ui/utils/mergeCleanups';
|
|
7
|
-
import { useStableCallback } from '@base-ui/utils/useStableCallback';
|
|
8
6
|
import { useIsoLayoutEffect } from '@base-ui/utils/useIsoLayoutEffect';
|
|
9
|
-
import { useTimeout } from '@base-ui/utils/useTimeout';
|
|
10
7
|
import { ownerDocument } from '@base-ui/utils/owner';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
8
|
+
import { useStableCallback } from '@base-ui/utils/useStableCallback';
|
|
9
|
+
import { useTimeout } from '@base-ui/utils/useTimeout';
|
|
10
|
+
import { isElement } from '@floating-ui/utils/dom';
|
|
13
11
|
import { createChangeEventDetails } from "../../internals/createBaseUIEventDetails.js";
|
|
14
12
|
import { REASONS } from "../../internals/reasons.js";
|
|
15
13
|
import { useFloatingParentNodeId, useFloatingTree } from "../components/FloatingTree.js";
|
|
14
|
+
import { contains, getTarget } from "../utils/element.js";
|
|
15
|
+
import { getNodeChildren } from "../utils/nodes.js";
|
|
16
16
|
import { applySafePolygonPointerEventsMutation, clearSafePolygonPointerEventsMutation, isInteractiveElement, useHoverInteractionSharedState } from "./useHoverInteractionSharedState.js";
|
|
17
|
-
import { getDelay, isClickLikeOpenEvent as isClickLikeOpenEventShared } from "./useHoverShared.js";
|
|
17
|
+
import { getDelay, isClickLikeOpenEvent as isClickLikeOpenEventShared, isHoverOpenEvent, isInsideEnabledTrigger } from "./useHoverShared.js";
|
|
18
18
|
/**
|
|
19
19
|
* Provides hover interactions that should be attached to the floating element.
|
|
20
20
|
*/
|
|
21
21
|
export function useHoverFloatingInteraction(context, parameters = {}) {
|
|
22
|
+
const {
|
|
23
|
+
enabled = true,
|
|
24
|
+
closeDelay: closeDelayProp = 0,
|
|
25
|
+
nodeId: nodeIdProp
|
|
26
|
+
} = parameters;
|
|
22
27
|
const store = 'rootStore' in context ? context.rootStore : context;
|
|
23
28
|
const open = store.useState('open');
|
|
24
29
|
const floatingElement = store.useState('floatingElement');
|
|
@@ -26,48 +31,19 @@ export function useHoverFloatingInteraction(context, parameters = {}) {
|
|
|
26
31
|
const {
|
|
27
32
|
dataRef
|
|
28
33
|
} = store.context;
|
|
29
|
-
const {
|
|
30
|
-
enabled = true,
|
|
31
|
-
closeDelay: closeDelayProp = 0,
|
|
32
|
-
nodeId: nodeIdProp
|
|
33
|
-
} = parameters;
|
|
34
|
-
const instance = useHoverInteractionSharedState(store);
|
|
35
34
|
const tree = useFloatingTree();
|
|
36
35
|
const parentId = useFloatingParentNodeId();
|
|
36
|
+
const instance = useHoverInteractionSharedState(store);
|
|
37
|
+
const childClosedTimeout = useTimeout();
|
|
37
38
|
const isClickLikeOpenEvent = useStableCallback(() => {
|
|
38
39
|
return isClickLikeOpenEventShared(dataRef.current.openEvent?.type, instance.interactedInside);
|
|
39
40
|
});
|
|
40
41
|
const isHoverOpen = useStableCallback(() => {
|
|
41
|
-
|
|
42
|
-
return type?.includes('mouse') && type !== 'mousedown';
|
|
43
|
-
});
|
|
44
|
-
const isRelatedTargetInsideEnabledTrigger = useStableCallback(target => {
|
|
45
|
-
return isTargetInsideEnabledTrigger(target, store.context.triggerElements);
|
|
42
|
+
return isHoverOpenEvent(dataRef.current.openEvent?.type);
|
|
46
43
|
});
|
|
47
|
-
const closeWithDelay = React.useCallback(event => {
|
|
48
|
-
const closeDelay = getDelay(closeDelayProp, 'close', instance.pointerType);
|
|
49
|
-
const close = () => {
|
|
50
|
-
store.setOpen(false, createChangeEventDetails(REASONS.triggerHover, event));
|
|
51
|
-
tree?.events.emit('floating.closed', event);
|
|
52
|
-
};
|
|
53
|
-
if (closeDelay) {
|
|
54
|
-
instance.openChangeTimeout.start(closeDelay, close);
|
|
55
|
-
} else {
|
|
56
|
-
instance.openChangeTimeout.clear();
|
|
57
|
-
close();
|
|
58
|
-
}
|
|
59
|
-
}, [closeDelayProp, store, instance, tree]);
|
|
60
44
|
const clearPointerEvents = useStableCallback(() => {
|
|
61
45
|
clearSafePolygonPointerEventsMutation(instance);
|
|
62
46
|
});
|
|
63
|
-
const handleInteractInside = useStableCallback(event => {
|
|
64
|
-
const target = getTarget(event);
|
|
65
|
-
if (!isInteractiveElement(target)) {
|
|
66
|
-
instance.interactedInside = false;
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
instance.interactedInside = target?.closest('[aria-haspopup]') != null;
|
|
70
|
-
});
|
|
71
47
|
useIsoLayoutEffect(() => {
|
|
72
48
|
if (!open) {
|
|
73
49
|
instance.pointerType = undefined;
|
|
@@ -91,7 +67,13 @@ export function useHoverFloatingInteraction(context, parameters = {}) {
|
|
|
91
67
|
if (parentFloating) {
|
|
92
68
|
parentFloating.style.pointerEvents = '';
|
|
93
69
|
}
|
|
94
|
-
|
|
70
|
+
|
|
71
|
+
// A keep-mounted submenu can appear in the tree before it opens, so a
|
|
72
|
+
// cached scope or parent lookup may resolve to the submenu itself. That
|
|
73
|
+
// would not shield sibling items in the parent menu.
|
|
74
|
+
const cachedScopeElement = instance.pointerEventsScopeElement !== floatingEl ? instance.pointerEventsScopeElement : null;
|
|
75
|
+
const parentScopeElement = parentFloating !== floatingEl ? parentFloating : null;
|
|
76
|
+
const scopeElement = instance.handleCloseOptions?.getScope?.() ?? cachedScopeElement ?? parentScopeElement ?? ref.closest('[data-rootownerid]') ?? doc.body;
|
|
95
77
|
applySafePolygonPointerEventsMutation(instance, {
|
|
96
78
|
scopeElement,
|
|
97
79
|
referenceElement: ref,
|
|
@@ -103,11 +85,34 @@ export function useHoverFloatingInteraction(context, parameters = {}) {
|
|
|
103
85
|
}
|
|
104
86
|
return undefined;
|
|
105
87
|
}, [enabled, open, domReferenceElement, floatingElement, instance, isHoverOpen, tree, parentId, clearPointerEvents]);
|
|
106
|
-
const childClosedTimeout = useTimeout();
|
|
107
88
|
React.useEffect(() => {
|
|
108
89
|
if (!enabled) {
|
|
109
90
|
return undefined;
|
|
110
91
|
}
|
|
92
|
+
function hasParentChildren() {
|
|
93
|
+
return !!(tree && parentId && getNodeChildren(tree.nodesRef.current, parentId).length > 0);
|
|
94
|
+
}
|
|
95
|
+
function closeWithDelay(event) {
|
|
96
|
+
const closeDelay = getDelay(closeDelayProp, 'close', instance.pointerType);
|
|
97
|
+
const close = () => {
|
|
98
|
+
store.setOpen(false, createChangeEventDetails(REASONS.triggerHover, event));
|
|
99
|
+
tree?.events.emit('floating.closed', event);
|
|
100
|
+
};
|
|
101
|
+
if (closeDelay) {
|
|
102
|
+
instance.openChangeTimeout.start(closeDelay, close);
|
|
103
|
+
} else {
|
|
104
|
+
instance.openChangeTimeout.clear();
|
|
105
|
+
close();
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function handleInteractInside(event) {
|
|
109
|
+
const target = getTarget(event);
|
|
110
|
+
if (!isInteractiveElement(target)) {
|
|
111
|
+
instance.interactedInside = false;
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
instance.interactedInside = target?.closest('[aria-haspopup]') != null;
|
|
115
|
+
}
|
|
111
116
|
function onFloatingMouseEnter() {
|
|
112
117
|
instance.openChangeTimeout.clear();
|
|
113
118
|
childClosedTimeout.clear();
|
|
@@ -115,11 +120,11 @@ export function useHoverFloatingInteraction(context, parameters = {}) {
|
|
|
115
120
|
clearPointerEvents();
|
|
116
121
|
}
|
|
117
122
|
function onFloatingMouseLeave(event) {
|
|
118
|
-
if (
|
|
123
|
+
if (hasParentChildren() && tree) {
|
|
119
124
|
tree.events.on('floating.closed', onNodeClosed);
|
|
120
125
|
return;
|
|
121
126
|
}
|
|
122
|
-
if (
|
|
127
|
+
if (isInsideEnabledTrigger(event.relatedTarget, store.context.triggerElements)) {
|
|
123
128
|
// If the mouse is leaving the reference element to another trigger, don't explicitly close the popup
|
|
124
129
|
// as it will be moved.
|
|
125
130
|
return;
|
|
@@ -142,7 +147,7 @@ export function useHoverFloatingInteraction(context, parameters = {}) {
|
|
|
142
147
|
}
|
|
143
148
|
}
|
|
144
149
|
function onNodeClosed(event) {
|
|
145
|
-
if (!tree || !parentId ||
|
|
150
|
+
if (!tree || !parentId || hasParentChildren()) {
|
|
146
151
|
return;
|
|
147
152
|
}
|
|
148
153
|
// Allow the mouseenter event to fire in case child was closed because mouse moved into parent.
|
|
@@ -156,5 +161,5 @@ export function useHoverFloatingInteraction(context, parameters = {}) {
|
|
|
156
161
|
return mergeCleanups(floating && addEventListener(floating, 'mouseenter', onFloatingMouseEnter), floating && addEventListener(floating, 'mouseleave', onFloatingMouseLeave), floating && addEventListener(floating, 'pointerdown', handleInteractInside, true), () => {
|
|
157
162
|
tree?.events.off('floating.closed', onNodeClosed);
|
|
158
163
|
});
|
|
159
|
-
}, [enabled, floatingElement, store, dataRef, nodeIdProp, isClickLikeOpenEvent,
|
|
164
|
+
}, [enabled, floatingElement, store, dataRef, closeDelayProp, nodeIdProp, isClickLikeOpenEvent, clearPointerEvents, instance, tree, parentId, childClosedTimeout]);
|
|
160
165
|
}
|
|
@@ -69,8 +69,8 @@ export function applySafePolygonPointerEventsMutation(instance, options) {
|
|
|
69
69
|
floatingElement.style.pointerEvents = 'auto';
|
|
70
70
|
}
|
|
71
71
|
export function useHoverInteractionSharedState(store) {
|
|
72
|
-
const instance = useRefWithInit(HoverInteraction.create).current;
|
|
73
72
|
const data = store.context.dataRef.current;
|
|
73
|
+
const instance = useRefWithInit(() => data.hoverInteractionState ?? HoverInteraction.create()).current;
|
|
74
74
|
if (!data.hoverInteractionState) {
|
|
75
75
|
data.hoverInteractionState = instance;
|
|
76
76
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import
|
|
2
|
+
import { HTMLProps } from "../../internals/types.js";
|
|
3
3
|
import type { FloatingTreeStore } from "../components/FloatingTreeStore.js";
|
|
4
|
+
import type { Delay, FloatingContext, FloatingRootContext } from "../types.js";
|
|
4
5
|
import type { HandleClose, HandleCloseContextBase } from "./useHoverShared.js";
|
|
5
|
-
import { HTMLProps } from "../../internals/types.js";
|
|
6
6
|
export interface UseHoverReferenceInteractionProps {
|
|
7
7
|
enabled?: boolean | undefined;
|
|
8
8
|
handleClose?: HandleClose | null | undefined;
|
|
@@ -21,6 +21,11 @@ export interface UseHoverReferenceInteractionProps {
|
|
|
21
21
|
triggerElementRef?: Readonly<React.RefObject<Element | null>> | undefined;
|
|
22
22
|
getHandleCloseContext?: (() => HandleCloseContextBase | null) | undefined;
|
|
23
23
|
isClosing?: (() => boolean) | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Called before each hover-driven open attempt (immediate, delayed, and rest-ms
|
|
26
|
+
* paths). Return `false` to veto; any other return value permits the open.
|
|
27
|
+
*/
|
|
28
|
+
shouldOpen?: (() => boolean) | undefined;
|
|
24
29
|
}
|
|
25
30
|
/**
|
|
26
31
|
* Provides hover interactions that should be attached to reference or trigger
|