From 4e1bd0ede61d300996dbeb126ebfee0320f4d107 Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 15:26:51 +1100 Subject: [PATCH 01/10] [POC] Hide popup on anchorHidden --- .../src/popover/positioner/PopoverPositioner.tsx | 1 - .../popover/positioner/usePopoverPositioner.tsx | 15 ++++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/react/src/popover/positioner/PopoverPositioner.tsx b/packages/react/src/popover/positioner/PopoverPositioner.tsx index 0b8ded616d..8e8d0bed3b 100644 --- a/packages/react/src/popover/positioner/PopoverPositioner.tsx +++ b/packages/react/src/popover/positioner/PopoverPositioner.tsx @@ -46,7 +46,6 @@ const PopoverPositioner = React.forwardRef(function PopoverPositioner( floatingRootContext, positionMethod, mounted, - open, keepMounted, side, sideOffset, diff --git a/packages/react/src/popover/positioner/usePopoverPositioner.tsx b/packages/react/src/popover/positioner/usePopoverPositioner.tsx index 6d9456b5ec..0d599e9157 100644 --- a/packages/react/src/popover/positioner/usePopoverPositioner.tsx +++ b/packages/react/src/popover/positioner/usePopoverPositioner.tsx @@ -9,11 +9,14 @@ import { mergeReactProps } from '../../utils/mergeReactProps'; import { type Boundary, type Side, useAnchorPositioning } from '../../utils/useAnchorPositioning'; import type { GenericHTMLProps } from '../../utils/types'; import { InteractionType } from '../../utils/useEnhancedClickHandler'; +import { usePopoverRootContext } from '../root/PopoverRootContext'; export function usePopoverPositioner( params: usePopoverPositioner.Parameters, ): usePopoverPositioner.ReturnValue { - const { open = false, keepMounted = false, mounted } = params; + const { keepMounted = false, mounted } = params; + + const { open, setOpen } = usePopoverRootContext(); const { positionerStyles, @@ -26,6 +29,12 @@ export function usePopoverPositioner( positionerContext, } = useAnchorPositioning(params); + React.useEffect(() => { + if (open && anchorHidden) { + setOpen(false); + } + }, [open, anchorHidden, setOpen]); + const getPositionerProps: usePopoverPositioner.ReturnValue['getPositionerProps'] = React.useCallback( (externalProps = {}) => { @@ -149,10 +158,6 @@ export namespace usePopoverPositioner { * Whether the popover is mounted. */ mounted: boolean; - /** - * Whether the popover is currently open. - */ - open?: boolean; /** * The floating root context. */ From 4e973d05496f8716667ed4d79e3c3f31488876a1 Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 17:18:59 +1100 Subject: [PATCH 02/10] [POC] Anchored modality changes --- docs/reference/generated/menu-root.json | 2 +- docs/reference/generated/popover-root.json | 5 +++++ .../react/src/menu/backdrop/MenuBackdrop.tsx | 11 ++++++++++- .../react/src/menu/positioner/MenuPositioner.tsx | 4 +++- packages/react/src/menu/root/MenuRoot.tsx | 6 ++++-- packages/react/src/menu/root/useMenuRoot.ts | 9 +++++++-- .../src/popover/backdrop/PopoverBackdrop.tsx | 10 +++++++++- .../src/popover/positioner/PopoverPositioner.tsx | 4 +++- .../popover/positioner/usePopoverPositioner.tsx | 8 +------- packages/react/src/popover/root/PopoverRoot.tsx | 11 ++++++++++- .../react/src/popover/root/PopoverRootContext.ts | 3 +++ .../react/src/popover/root/usePopoverRoot.ts | 16 +++++++++++++++- .../react/src/select/backdrop/SelectBackdrop.tsx | 10 +++++++++- .../src/select/positioner/useSelectPositioner.ts | 4 +--- .../react/src/select/root/SelectRootContext.ts | 2 ++ packages/react/src/select/root/useSelectRoot.ts | 8 +++++++- 16 files changed, 90 insertions(+), 23 deletions(-) diff --git a/docs/reference/generated/menu-root.json b/docs/reference/generated/menu-root.json index aee7fbf47e..bd7770c797 100644 --- a/docs/reference/generated/menu-root.json +++ b/docs/reference/generated/menu-root.json @@ -23,7 +23,7 @@ "modal": { "type": "boolean", "default": "true", - "description": "Whether the menu should prevent outside clicks and lock page scroll when open." + "description": "Whether the menu should prevent interactivity of other elements\non the page when open and the anchor is visible." }, "disabled": { "type": "boolean", diff --git a/docs/reference/generated/popover-root.json b/docs/reference/generated/popover-root.json index 6b3efcddcc..37812728f0 100644 --- a/docs/reference/generated/popover-root.json +++ b/docs/reference/generated/popover-root.json @@ -15,6 +15,11 @@ "type": "(open, event, reason) => void", "description": "Event handler called when the popover is opened or closed." }, + "modal": { + "type": "boolean", + "default": "true", + "description": "Whether the popover should prevent interactivity of other elements\non the page when open and the anchor is visible." + }, "openOnHover": { "type": "boolean", "default": "false", diff --git a/packages/react/src/menu/backdrop/MenuBackdrop.tsx b/packages/react/src/menu/backdrop/MenuBackdrop.tsx index 7955ac1df8..d554b11e43 100644 --- a/packages/react/src/menu/backdrop/MenuBackdrop.tsx +++ b/packages/react/src/menu/backdrop/MenuBackdrop.tsx @@ -8,6 +8,7 @@ import { type CustomStyleHookMapping } from '../../utils/getStyleHookProps'; import { popupStateMapping as baseMapping } from '../../utils/popupStateMapping'; import type { TransitionStatus } from '../../utils/useTransitionStatus'; import { transitionStatusMapping } from '../../utils/styleHookMapping'; +import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; const customStyleHookMapping: CustomStyleHookMapping = { ...baseMapping, @@ -25,7 +26,15 @@ const MenuBackdrop = React.forwardRef(function MenuBackdrop( forwardedRef: React.ForwardedRef, ) { const { className, render, keepMounted = false, ...other } = props; - const { open, mounted, transitionStatus } = useMenuRootContext(); + + const { open, mounted, transitionStatus, setBackdropRendered } = useMenuRootContext(); + + useEnhancedEffect(() => { + setBackdropRendered(true); + return () => { + setBackdropRendered(false); + }; + }, [setBackdropRendered]); const state: MenuBackdrop.State = React.useMemo( () => ({ diff --git a/packages/react/src/menu/positioner/MenuPositioner.tsx b/packages/react/src/menu/positioner/MenuPositioner.tsx index 1552afa781..17f5a60e58 100644 --- a/packages/react/src/menu/positioner/MenuPositioner.tsx +++ b/packages/react/src/menu/positioner/MenuPositioner.tsx @@ -141,7 +141,9 @@ const MenuPositioner = React.forwardRef(function MenuPositioner( return ( - {mounted && modal && parentNodeId === null && } + {mounted && modal && parentNodeId === null && ( + + )} {renderElement()} diff --git a/packages/react/src/menu/root/MenuRoot.tsx b/packages/react/src/menu/root/MenuRoot.tsx index c56b0129e1..4d35fcf245 100644 --- a/packages/react/src/menu/root/MenuRoot.tsx +++ b/packages/react/src/menu/root/MenuRoot.tsx @@ -105,7 +105,8 @@ namespace MenuRoot { */ loop?: boolean; /** - * Whether the menu should prevent outside clicks and lock page scroll when open. + * Whether the menu should prevent interactivity of other elements + * on the page when open and the anchor is visible. * @default true */ modal?: boolean; @@ -191,7 +192,8 @@ MenuRoot.propTypes /* remove-proptypes */ = { */ loop: PropTypes.bool, /** - * Whether the menu should prevent outside clicks and lock page scroll when open. + * Whether the menu should prevent interactivity of other elements + * on the page when open and the anchor is visible. * @default true */ modal: PropTypes.bool, diff --git a/packages/react/src/menu/root/useMenuRoot.ts b/packages/react/src/menu/root/useMenuRoot.ts index 72d0e7008d..2c5f9d5637 100644 --- a/packages/react/src/menu/root/useMenuRoot.ts +++ b/packages/react/src/menu/root/useMenuRoot.ts @@ -49,6 +49,7 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret const positionerRef = React.useRef(null); const [hoverEnabled, setHoverEnabled] = React.useState(true); const [activeIndex, setActiveIndex] = React.useState(null); + const [backdropRendered, setBackdropRendered] = React.useState(false); const [open, setOpenUnwrapped] = useControlled({ controlled: openParam, @@ -66,7 +67,7 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret const { mounted, setMounted, transitionStatus } = useTransitionStatus(open); - useScrollLock(open && modal, triggerElement); + useScrollLock(open && modal && backdropRendered, triggerElement); const setOpen = useEventCallback((nextOpen: boolean, event?: Event) => { onOpenChange?.(nextOpen, event); @@ -191,6 +192,8 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret setPositionerElement, setTriggerElement, transitionStatus, + backdropRendered, + setBackdropRendered, }), [ activeIndex, @@ -205,7 +208,7 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret positionerRef, setOpen, transitionStatus, - setPositionerElement, + backdropRendered, ], ); } @@ -289,5 +292,7 @@ export namespace useMenuRoot { setTriggerElement: (element: HTMLElement | null) => void; transitionStatus: TransitionStatus; allowMouseUpTriggerRef: React.RefObject; + backdropRendered: boolean; + setBackdropRendered: (value: boolean) => void; } } diff --git a/packages/react/src/popover/backdrop/PopoverBackdrop.tsx b/packages/react/src/popover/backdrop/PopoverBackdrop.tsx index 0ebee86807..fc2ef4b193 100644 --- a/packages/react/src/popover/backdrop/PopoverBackdrop.tsx +++ b/packages/react/src/popover/backdrop/PopoverBackdrop.tsx @@ -8,6 +8,7 @@ import { type CustomStyleHookMapping } from '../../utils/getStyleHookProps'; import { popupStateMapping as baseMapping } from '../../utils/popupStateMapping'; import type { TransitionStatus } from '../../utils/useTransitionStatus'; import { transitionStatusMapping } from '../../utils/styleHookMapping'; +import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; const customStyleHookMapping: CustomStyleHookMapping = { ...baseMapping, @@ -26,7 +27,14 @@ const PopoverBackdrop = React.forwardRef(function PopoverBackdrop( ) { const { className, render, keepMounted = false, ...other } = props; - const { open, mounted, transitionStatus } = usePopoverRootContext(); + const { open, mounted, transitionStatus, setBackdropRendered } = usePopoverRootContext(); + + useEnhancedEffect(() => { + setBackdropRendered(true); + return () => { + setBackdropRendered(false); + }; + }, [setBackdropRendered]); const state: PopoverBackdrop.State = React.useMemo( () => ({ diff --git a/packages/react/src/popover/positioner/PopoverPositioner.tsx b/packages/react/src/popover/positioner/PopoverPositioner.tsx index 8e8d0bed3b..d755e7d8ae 100644 --- a/packages/react/src/popover/positioner/PopoverPositioner.tsx +++ b/packages/react/src/popover/positioner/PopoverPositioner.tsx @@ -10,6 +10,7 @@ import { HTMLElementType } from '../../utils/proptypes'; import type { BaseUIComponentProps } from '../../utils/types'; import type { Side, Align } from '../../utils/useAnchorPositioning'; import { popupStateMapping } from '../../utils/popupStateMapping'; +import { InternalBackdrop } from '../../utils/InternalBackdrop'; /** * Positions the popover against the trigger. @@ -38,7 +39,7 @@ const PopoverPositioner = React.forwardRef(function PopoverPositioner( ...otherProps } = props; - const { floatingRootContext, open, mounted, setPositionerElement, popupRef, openMethod } = + const { floatingRootContext, open, mounted, setPositionerElement, popupRef, openMethod, modal } = usePopoverRootContext(); const positioner = usePopoverPositioner({ @@ -88,6 +89,7 @@ const PopoverPositioner = React.forwardRef(function PopoverPositioner( return ( + {mounted && modal && } {renderElement()} ); diff --git a/packages/react/src/popover/positioner/usePopoverPositioner.tsx b/packages/react/src/popover/positioner/usePopoverPositioner.tsx index 0d599e9157..ffac3f9774 100644 --- a/packages/react/src/popover/positioner/usePopoverPositioner.tsx +++ b/packages/react/src/popover/positioner/usePopoverPositioner.tsx @@ -16,7 +16,7 @@ export function usePopoverPositioner( ): usePopoverPositioner.ReturnValue { const { keepMounted = false, mounted } = params; - const { open, setOpen } = usePopoverRootContext(); + const { open } = usePopoverRootContext(); const { positionerStyles, @@ -29,12 +29,6 @@ export function usePopoverPositioner( positionerContext, } = useAnchorPositioning(params); - React.useEffect(() => { - if (open && anchorHidden) { - setOpen(false); - } - }, [open, anchorHidden, setOpen]); - const getPositionerProps: usePopoverPositioner.ReturnValue['getPositionerProps'] = React.useCallback( (externalProps = {}) => { diff --git a/packages/react/src/popover/root/PopoverRoot.tsx b/packages/react/src/popover/root/PopoverRoot.tsx index 1feeb4dd2c..c570c7eece 100644 --- a/packages/react/src/popover/root/PopoverRoot.tsx +++ b/packages/react/src/popover/root/PopoverRoot.tsx @@ -13,7 +13,7 @@ import { PortalContext } from '../../portal/PortalContext'; * Documentation: [Base UI Popover](https://base-ui.com/react/components/popover) */ const PopoverRoot: React.FC = function PopoverRoot(props) { - const { openOnHover = false, delay, closeDelay = 0 } = props; + const { openOnHover = false, modal = true, delay, closeDelay = 0 } = props; const delayWithDefault = delay ?? OPEN_DELAY; @@ -39,6 +39,7 @@ const PopoverRoot: React.FC = function PopoverRoot(props) { openReason, } = usePopoverRoot({ openOnHover, + modal, delay: delayWithDefault, closeDelay, open: props.open, @@ -70,6 +71,7 @@ const PopoverRoot: React.FC = function PopoverRoot(props) { getRootTriggerProps, openMethod, openReason, + modal, }), [ openOnHover, @@ -94,6 +96,7 @@ const PopoverRoot: React.FC = function PopoverRoot(props) { getRootTriggerProps, openMethod, openReason, + modal, ], ); @@ -143,6 +146,12 @@ PopoverRoot.propTypes /* remove-proptypes */ = { * @default 300 */ delay: PropTypes.number, + /** + * Whether the popover should prevent interactivity of other elements + * on the page when open and the anchor is visible. + * @default true + */ + modal: PropTypes.bool, /** * Event handler called when the popover is opened or closed. */ diff --git a/packages/react/src/popover/root/PopoverRootContext.ts b/packages/react/src/popover/root/PopoverRootContext.ts index 63a47e91ac..953e630476 100644 --- a/packages/react/src/popover/root/PopoverRootContext.ts +++ b/packages/react/src/popover/root/PopoverRootContext.ts @@ -29,6 +29,9 @@ export interface PopoverRootContext { getRootPopupProps: (externalProps?: GenericHTMLProps) => GenericHTMLProps; openMethod: InteractionType | null; openReason: OpenChangeReason | null; + modal: boolean; + backdropRendered: boolean; + setBackdropRendered: React.Dispatch>; } export const PopoverRootContext = React.createContext(undefined); diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index 02ecfe22f5..ec87b3443f 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -24,6 +24,7 @@ import { type OpenChangeReason, } from '../../utils/translateOpenChangeReason'; import { useAfterExitAnimation } from '../../utils/useAfterExitAnimation'; +import { useScrollLock } from '../../utils/useScrollLock'; export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoot.ReturnValue { const { @@ -33,6 +34,7 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo delay, closeDelay, openOnHover = false, + modal, } = params; const delayWithDefault = delay ?? OPEN_DELAY; @@ -45,6 +47,7 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo const [positionerElement, setPositionerElement] = React.useState(null); const [openReason, setOpenReason] = React.useState(null); const [clickEnabled, setClickEnabled] = React.useState(true); + const [backdropRendered, setBackdropRendered] = React.useState(false); const popupRef = React.useRef(null); const clickEnabledTimeoutRef = React.useRef(-1); @@ -64,6 +67,8 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo const { mounted, setMounted, transitionStatus } = useTransitionStatus(open); + useScrollLock(open && modal && backdropRendered, triggerElement); + const setOpen = useEventCallback( (nextOpen: boolean, event?: Event, reason?: OpenChangeReason) => { onOpenChange(nextOpen, event, reason); @@ -129,7 +134,7 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo enabled: openOnHover, mouseOnly: true, move: false, - handleClose: safePolygon(), + handleClose: safePolygon({ blockPointerEvents: true }), restMs: computedRestMs, delay: { close: closeDelayWithDefault, @@ -171,6 +176,8 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo instantType, openMethod, openReason, + backdropRendered, + setBackdropRendered, }), [ mounted, @@ -188,6 +195,7 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo openMethod, triggerProps, openReason, + backdropRendered, ], ); } @@ -229,6 +237,12 @@ export namespace usePopoverRoot { * @default 0 */ closeDelay?: number; + /** + * Whether the popover should prevent interactivity of other elements + * on the page when open and the anchor is visible. + * @default true + */ + modal?: boolean; } export interface ReturnValue { diff --git a/packages/react/src/select/backdrop/SelectBackdrop.tsx b/packages/react/src/select/backdrop/SelectBackdrop.tsx index f45cf3f592..d85e4e982e 100644 --- a/packages/react/src/select/backdrop/SelectBackdrop.tsx +++ b/packages/react/src/select/backdrop/SelectBackdrop.tsx @@ -8,6 +8,7 @@ import { popupStateMapping } from '../../utils/popupStateMapping'; import type { CustomStyleHookMapping } from '../../utils/getStyleHookProps'; import type { TransitionStatus } from '../../utils/useTransitionStatus'; import { transitionStatusMapping } from '../../utils/styleHookMapping'; +import { useEnhancedEffect } from '@base-ui-components/react/utils'; const customStyleHookMapping: CustomStyleHookMapping = { ...popupStateMapping, @@ -26,7 +27,14 @@ const SelectBackdrop = React.forwardRef(function SelectBackdrop( ) { const { className, render, keepMounted = false, ...other } = props; - const { open, mounted, transitionStatus } = useSelectRootContext(); + const { open, mounted, transitionStatus, setBackdropRendered } = useSelectRootContext(); + + useEnhancedEffect(() => { + setBackdropRendered(true); + return () => { + setBackdropRendered(false); + }; + }, [setBackdropRendered]); const state: SelectBackdrop.State = React.useMemo( () => ({ open, transitionStatus }), diff --git a/packages/react/src/select/positioner/useSelectPositioner.ts b/packages/react/src/select/positioner/useSelectPositioner.ts index d672929ac6..f15e1c4628 100644 --- a/packages/react/src/select/positioner/useSelectPositioner.ts +++ b/packages/react/src/select/positioner/useSelectPositioner.ts @@ -15,9 +15,7 @@ import { useScrollLock } from '../../utils/useScrollLock'; export function useSelectPositioner( params: useSelectPositioner.Parameters, ): useSelectPositioner.ReturnValue { - const { open, alignItemToTrigger, mounted, triggerElement, modal } = useSelectRootContext(); - - useScrollLock((alignItemToTrigger || modal) && open, triggerElement); + const { open, alignItemToTrigger, mounted } = useSelectRootContext(); const { positionerStyles: enabledPositionerStyles, diff --git a/packages/react/src/select/root/SelectRootContext.ts b/packages/react/src/select/root/SelectRootContext.ts index 2c569abc4a..fd7b572910 100644 --- a/packages/react/src/select/root/SelectRootContext.ts +++ b/packages/react/src/select/root/SelectRootContext.ts @@ -51,6 +51,8 @@ export interface SelectRootContext { id: string | undefined; fieldControlValidation: ReturnType; modal: boolean; + backdropRendered: boolean; + setBackdropRendered: React.Dispatch>; } export const SelectRootContext = React.createContext(null); diff --git a/packages/react/src/select/root/useSelectRoot.ts b/packages/react/src/select/root/useSelectRoot.ts index ea66f29e15..c1b3fbbca5 100644 --- a/packages/react/src/select/root/useSelectRoot.ts +++ b/packages/react/src/select/root/useSelectRoot.ts @@ -12,7 +12,7 @@ import { useFieldControlValidation } from '../../field/control/useFieldControlVa import { useFieldRootContext } from '../../field/root/FieldRootContext'; import { useBaseUiId } from '../../utils/useBaseUiId'; import { useControlled } from '../../utils/useControlled'; -import { type TransitionStatus, useTransitionStatus } from '../../utils'; +import { type TransitionStatus, useScrollLock, useTransitionStatus } from '../../utils'; import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; import { useEventCallback } from '../../utils/useEventCallback'; import { warn } from '../../utils/warn'; @@ -80,11 +80,14 @@ export function useSelectRoot(params: useSelectRoot.Parameters): useSelect const [touchModality, setTouchModality] = React.useState(false); const [scrollUpArrowVisible, setScrollUpArrowVisible] = React.useState(false); const [scrollDownArrowVisible, setScrollDownArrowVisible] = React.useState(false); + const [backdropRendered, setBackdropRendered] = React.useState(false); const { mounted, setMounted, transitionStatus } = useTransitionStatus(open); const alignItemToTrigger = Boolean(mounted && controlledAlignItemToTrigger && !touchModality); + useScrollLock(open && (alignItemToTrigger || (modal && backdropRendered)), triggerElement); + if (!mounted && controlledAlignItemToTrigger !== alignItemToTriggerParam) { setcontrolledAlignItemToTrigger(alignItemToTriggerParam); } @@ -263,6 +266,8 @@ export function useSelectRoot(params: useSelectRoot.Parameters): useSelect transitionStatus, fieldControlValidation, modal, + backdropRendered, + setBackdropRendered, }), [ id, @@ -290,6 +295,7 @@ export function useSelectRoot(params: useSelectRoot.Parameters): useSelect transitionStatus, fieldControlValidation, modal, + backdropRendered, ], ); From 64c72d6c2c7f6f9c57177b9611108bc60112defc Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 17:24:14 +1100 Subject: [PATCH 03/10] Consistency --- docs/reference/generated/select-root.json | 2 +- packages/react/src/select/positioner/SelectPositioner.tsx | 2 +- packages/react/src/select/root/SelectRoot.tsx | 3 ++- packages/react/src/select/root/useSelectRoot.ts | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/reference/generated/select-root.json b/docs/reference/generated/select-root.json index 50fb8031c1..6a55af37d0 100644 --- a/docs/reference/generated/select-root.json +++ b/docs/reference/generated/select-root.json @@ -40,7 +40,7 @@ "modal": { "type": "boolean", "default": "true", - "description": "Whether the select should prevent outside clicks and lock page scroll when open." + "description": "Whether the select should prevent interactivity of other elements\non the page when open and the anchor is visible." }, "disabled": { "type": "boolean", diff --git a/packages/react/src/select/positioner/SelectPositioner.tsx b/packages/react/src/select/positioner/SelectPositioner.tsx index cb3a629092..78f1dc252e 100644 --- a/packages/react/src/select/positioner/SelectPositioner.tsx +++ b/packages/react/src/select/positioner/SelectPositioner.tsx @@ -84,7 +84,7 @@ const SelectPositioner = React.forwardRef(function SelectPositioner( return ( - {mounted && modal && } + {mounted && modal && } {renderElement()} diff --git a/packages/react/src/select/root/SelectRoot.tsx b/packages/react/src/select/root/SelectRoot.tsx index c7848d5f23..d516fc8c17 100644 --- a/packages/react/src/select/root/SelectRoot.tsx +++ b/packages/react/src/select/root/SelectRoot.tsx @@ -145,7 +145,8 @@ SelectRoot.propTypes /* remove-proptypes */ = { */ disabled: PropTypes.bool, /** - * Whether the select should prevent outside clicks and lock page scroll when open. + * Whether the select should prevent interactivity of other elements + * on the page when open and the anchor is visible. * @default true */ modal: PropTypes.bool, diff --git a/packages/react/src/select/root/useSelectRoot.ts b/packages/react/src/select/root/useSelectRoot.ts index c1b3fbbca5..09245ad6d0 100644 --- a/packages/react/src/select/root/useSelectRoot.ts +++ b/packages/react/src/select/root/useSelectRoot.ts @@ -383,7 +383,8 @@ export namespace useSelectRoot { */ transitionStatus?: TransitionStatus; /** - * Whether the select should prevent outside clicks and lock page scroll when open. + * Whether the select should prevent interactivity of other elements + * on the page when open and the anchor is visible. * @default true */ modal?: boolean; From 3bd71ac60732191225ff8fe690389831705ece4f Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 17:40:39 +1100 Subject: [PATCH 04/10] Popover fixes --- .../react/src/popover/root/PopoverRoot.tsx | 70 ++----------------- .../react/src/popover/root/usePopoverRoot.ts | 2 + 2 files changed, 6 insertions(+), 66 deletions(-) diff --git a/packages/react/src/popover/root/PopoverRoot.tsx b/packages/react/src/popover/root/PopoverRoot.tsx index c570c7eece..544c09c3f5 100644 --- a/packages/react/src/popover/root/PopoverRoot.tsx +++ b/packages/react/src/popover/root/PopoverRoot.tsx @@ -17,27 +17,7 @@ const PopoverRoot: React.FC = function PopoverRoot(props) { const delayWithDefault = delay ?? OPEN_DELAY; - const { - open, - setOpen, - mounted, - setMounted, - setTriggerElement, - positionerElement, - setPositionerElement, - popupRef, - instantType, - transitionStatus, - floatingRootContext, - getRootTriggerProps, - getRootPopupProps, - titleId, - setTitleId, - descriptionId, - setDescriptionId, - openMethod, - openReason, - } = usePopoverRoot({ + const popoverRoot = usePopoverRoot({ openOnHover, modal, delay: delayWithDefault, @@ -49,60 +29,18 @@ const PopoverRoot: React.FC = function PopoverRoot(props) { const contextValue: PopoverRootContext = React.useMemo( () => ({ + ...popoverRoot, openOnHover, delay: delayWithDefault, closeDelay, - open, - setOpen, - setTriggerElement, - positionerElement, - setPositionerElement, - popupRef, - mounted, - setMounted, - instantType, - transitionStatus, - titleId, - setTitleId, - descriptionId, - setDescriptionId, - floatingRootContext, - getRootPopupProps, - getRootTriggerProps, - openMethod, - openReason, modal, }), - [ - openOnHover, - delayWithDefault, - closeDelay, - open, - setOpen, - setTriggerElement, - positionerElement, - setPositionerElement, - popupRef, - mounted, - setMounted, - instantType, - transitionStatus, - titleId, - setTitleId, - descriptionId, - setDescriptionId, - floatingRootContext, - getRootPopupProps, - getRootTriggerProps, - openMethod, - openReason, - modal, - ], + [popoverRoot, openOnHover, delayWithDefault, closeDelay, open, modal], ); return ( - {props.children} + {props.children} ); }; diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index ec87b3443f..12a24e43ca 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -265,5 +265,7 @@ export namespace usePopoverRoot { popupRef: React.RefObject; openMethod: InteractionType | null; openReason: OpenChangeReason | null; + backdropRendered: boolean; + setBackdropRendered: React.Dispatch>; } } From 9e692da5b1f58badf81bafd5dac1584a3ffd7b7d Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 17:43:54 +1100 Subject: [PATCH 05/10] Satisfy duplications for now --- packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx | 2 ++ packages/react/src/menu/item/MenuItem.test.tsx | 2 ++ packages/react/src/menu/positioner/MenuPositioner.test.tsx | 2 ++ packages/react/src/menu/radio-item/MenuRadioItem.test.tsx | 2 ++ packages/react/src/menu/trigger/MenuTrigger.test.tsx | 2 ++ 5 files changed, 10 insertions(+) diff --git a/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx b/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx index d39bd9d53d..b94ce200d2 100644 --- a/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx +++ b/packages/react/src/menu/checkbox-item/MenuCheckboxItem.test.tsx @@ -29,6 +29,8 @@ const testRootContext: MenuRootContext = { modal: false, positionerRef: { current: null }, allowMouseUpTriggerRef: { current: false }, + backdropRendered: false, + setBackdropRendered: () => {}, }; describe('', () => { diff --git a/packages/react/src/menu/item/MenuItem.test.tsx b/packages/react/src/menu/item/MenuItem.test.tsx index d9fecfcee1..bd9c0e1fd8 100644 --- a/packages/react/src/menu/item/MenuItem.test.tsx +++ b/packages/react/src/menu/item/MenuItem.test.tsx @@ -29,6 +29,8 @@ const testRootContext: MenuRootContext = { modal: false, positionerRef: { current: null }, allowMouseUpTriggerRef: { current: false }, + backdropRendered: false, + setBackdropRendered: () => {}, }; describe('', () => { diff --git a/packages/react/src/menu/positioner/MenuPositioner.test.tsx b/packages/react/src/menu/positioner/MenuPositioner.test.tsx index 934fb73d2f..2cd5525229 100644 --- a/packages/react/src/menu/positioner/MenuPositioner.test.tsx +++ b/packages/react/src/menu/positioner/MenuPositioner.test.tsx @@ -29,6 +29,8 @@ const testRootContext: MenuRootContext = { modal: false, positionerRef: { current: null }, allowMouseUpTriggerRef: { current: false }, + backdropRendered: false, + setBackdropRendered: () => {}, }; describe('', () => { diff --git a/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx b/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx index 012555604d..ddc3a6e058 100644 --- a/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx +++ b/packages/react/src/menu/radio-item/MenuRadioItem.test.tsx @@ -30,6 +30,8 @@ const testRootContext: MenuRootContext = { modal: false, positionerRef: { current: null }, allowMouseUpTriggerRef: { current: false }, + backdropRendered: false, + setBackdropRendered: () => {}, }; const testRadioGroupContext = { diff --git a/packages/react/src/menu/trigger/MenuTrigger.test.tsx b/packages/react/src/menu/trigger/MenuTrigger.test.tsx index b994e047fd..c0f88dcfa4 100644 --- a/packages/react/src/menu/trigger/MenuTrigger.test.tsx +++ b/packages/react/src/menu/trigger/MenuTrigger.test.tsx @@ -29,6 +29,8 @@ const testRootContext: MenuRootContext = { modal: false, positionerRef: { current: null }, allowMouseUpTriggerRef: { current: false }, + backdropRendered: false, + setBackdropRendered: () => {}, }; describe('', () => { From adb94d6d8337af38a03325cc6e23c4ec02de87d3 Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 17:47:42 +1100 Subject: [PATCH 06/10] New outsidePressEvent --- packages/react/src/menu/root/useMenuRoot.ts | 2 +- packages/react/src/popover/root/usePopoverRoot.ts | 4 +++- packages/react/src/select/root/useSelectRoot.ts | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/react/src/menu/root/useMenuRoot.ts b/packages/react/src/menu/root/useMenuRoot.ts index 2c5f9d5637..9ff047e3c8 100644 --- a/packages/react/src/menu/root/useMenuRoot.ts +++ b/packages/react/src/menu/root/useMenuRoot.ts @@ -107,7 +107,7 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret const dismiss = useDismiss(floatingRootContext, { bubbles: closeParentOnEsc && nested, - outsidePressEvent: 'mousedown', + outsidePressEvent: backdropRendered ? 'mousedown' : undefined, }); const role = useRole(floatingRootContext, { diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index 12a24e43ca..48f2f6eeab 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -146,7 +146,9 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo stickIfOpen: false, }); - const dismiss = useDismiss(context); + const dismiss = useDismiss(context, { + outsidePressEvent: backdropRendered ? 'mousedown' : undefined, + }); const role = useRole(context); diff --git a/packages/react/src/select/root/useSelectRoot.ts b/packages/react/src/select/root/useSelectRoot.ts index 09245ad6d0..03e65dab7c 100644 --- a/packages/react/src/select/root/useSelectRoot.ts +++ b/packages/react/src/select/root/useSelectRoot.ts @@ -174,7 +174,7 @@ export function useSelectRoot(params: useSelectRoot.Parameters): useSelect const dismiss = useDismiss(floatingRootContext, { bubbles: false, - outsidePressEvent: 'mousedown', + outsidePressEvent: backdropRendered ? 'mousedown' : undefined, }); const role = useRole(floatingRootContext, { From f7d826d7a74269a96689ab777775f873fc55cc57 Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 17:48:30 +1100 Subject: [PATCH 07/10] Check for modal --- packages/react/src/menu/root/useMenuRoot.ts | 2 +- packages/react/src/popover/root/usePopoverRoot.ts | 2 +- packages/react/src/select/root/useSelectRoot.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/react/src/menu/root/useMenuRoot.ts b/packages/react/src/menu/root/useMenuRoot.ts index 9ff047e3c8..a8e9fb539f 100644 --- a/packages/react/src/menu/root/useMenuRoot.ts +++ b/packages/react/src/menu/root/useMenuRoot.ts @@ -107,7 +107,7 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret const dismiss = useDismiss(floatingRootContext, { bubbles: closeParentOnEsc && nested, - outsidePressEvent: backdropRendered ? 'mousedown' : undefined, + outsidePressEvent: modal || backdropRendered ? 'mousedown' : undefined, }); const role = useRole(floatingRootContext, { diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index 48f2f6eeab..1841b070e1 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -147,7 +147,7 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo }); const dismiss = useDismiss(context, { - outsidePressEvent: backdropRendered ? 'mousedown' : undefined, + outsidePressEvent: modal || backdropRendered ? 'mousedown' : undefined, }); const role = useRole(context); diff --git a/packages/react/src/select/root/useSelectRoot.ts b/packages/react/src/select/root/useSelectRoot.ts index 03e65dab7c..5b40f22983 100644 --- a/packages/react/src/select/root/useSelectRoot.ts +++ b/packages/react/src/select/root/useSelectRoot.ts @@ -174,7 +174,7 @@ export function useSelectRoot(params: useSelectRoot.Parameters): useSelect const dismiss = useDismiss(floatingRootContext, { bubbles: false, - outsidePressEvent: backdropRendered ? 'mousedown' : undefined, + outsidePressEvent: modal || backdropRendered ? 'mousedown' : undefined, }); const role = useRole(floatingRootContext, { From b7e27611529c3e1caf403983045a1a47c3f2d9ae Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 17:56:04 +1100 Subject: [PATCH 08/10] Fixes/lint --- docs/reference/generated/menu-root.json | 2 +- docs/reference/generated/popover-root.json | 2 +- docs/reference/generated/select-root.json | 2 +- packages/react/src/menu/root/MenuRoot.tsx | 4 ++-- packages/react/src/menu/root/useMenuRoot.ts | 4 +--- packages/react/src/popover/root/PopoverRoot.tsx | 4 ++-- packages/react/src/popover/root/usePopoverRoot.ts | 2 +- packages/react/src/select/backdrop/SelectBackdrop.tsx | 2 +- packages/react/src/select/positioner/useSelectPositioner.ts | 1 - packages/react/src/select/root/SelectRoot.tsx | 2 +- packages/react/src/select/root/useSelectRoot.ts | 2 +- 11 files changed, 12 insertions(+), 15 deletions(-) diff --git a/docs/reference/generated/menu-root.json b/docs/reference/generated/menu-root.json index bd7770c797..df50a3806f 100644 --- a/docs/reference/generated/menu-root.json +++ b/docs/reference/generated/menu-root.json @@ -23,7 +23,7 @@ "modal": { "type": "boolean", "default": "true", - "description": "Whether the menu should prevent interactivity of other elements\non the page when open and the anchor is visible." + "description": "Whether the menu should prevent interactivity of other elements\non the page when open and its positioning anchor is visible." }, "disabled": { "type": "boolean", diff --git a/docs/reference/generated/popover-root.json b/docs/reference/generated/popover-root.json index 37812728f0..30515a9d5e 100644 --- a/docs/reference/generated/popover-root.json +++ b/docs/reference/generated/popover-root.json @@ -18,7 +18,7 @@ "modal": { "type": "boolean", "default": "true", - "description": "Whether the popover should prevent interactivity of other elements\non the page when open and the anchor is visible." + "description": "Whether the popover should prevent interactivity of other elements\non the page when open and its positioning anchor is visible." }, "openOnHover": { "type": "boolean", diff --git a/docs/reference/generated/select-root.json b/docs/reference/generated/select-root.json index 6a55af37d0..68d109c879 100644 --- a/docs/reference/generated/select-root.json +++ b/docs/reference/generated/select-root.json @@ -40,7 +40,7 @@ "modal": { "type": "boolean", "default": "true", - "description": "Whether the select should prevent interactivity of other elements\non the page when open and the anchor is visible." + "description": "Whether the select should prevent interactivity of other elements\non the page when open and its positioning anchor is visible." }, "disabled": { "type": "boolean", diff --git a/packages/react/src/menu/root/MenuRoot.tsx b/packages/react/src/menu/root/MenuRoot.tsx index 4d35fcf245..2e6a5bf39b 100644 --- a/packages/react/src/menu/root/MenuRoot.tsx +++ b/packages/react/src/menu/root/MenuRoot.tsx @@ -106,7 +106,7 @@ namespace MenuRoot { loop?: boolean; /** * Whether the menu should prevent interactivity of other elements - * on the page when open and the anchor is visible. + * on the page when open and its positioning anchor is visible. * @default true */ modal?: boolean; @@ -193,7 +193,7 @@ MenuRoot.propTypes /* remove-proptypes */ = { loop: PropTypes.bool, /** * Whether the menu should prevent interactivity of other elements - * on the page when open and the anchor is visible. + * on the page when open and its positioning anchor is visible. * @default true */ modal: PropTypes.bool, diff --git a/packages/react/src/menu/root/useMenuRoot.ts b/packages/react/src/menu/root/useMenuRoot.ts index a8e9fb539f..77113ccf5d 100644 --- a/packages/react/src/menu/root/useMenuRoot.ts +++ b/packages/react/src/menu/root/useMenuRoot.ts @@ -201,12 +201,10 @@ export function useMenuRoot(parameters: useMenuRoot.Parameters): useMenuRoot.Ret getItemProps, getPopupProps, getTriggerProps, - itemDomElements, - itemLabels, mounted, open, - positionerRef, setOpen, + setPositionerElement, transitionStatus, backdropRendered, ], diff --git a/packages/react/src/popover/root/PopoverRoot.tsx b/packages/react/src/popover/root/PopoverRoot.tsx index 544c09c3f5..d59b22cc0a 100644 --- a/packages/react/src/popover/root/PopoverRoot.tsx +++ b/packages/react/src/popover/root/PopoverRoot.tsx @@ -35,7 +35,7 @@ const PopoverRoot: React.FC = function PopoverRoot(props) { closeDelay, modal, }), - [popoverRoot, openOnHover, delayWithDefault, closeDelay, open, modal], + [popoverRoot, openOnHover, delayWithDefault, closeDelay, modal], ); return ( @@ -86,7 +86,7 @@ PopoverRoot.propTypes /* remove-proptypes */ = { delay: PropTypes.number, /** * Whether the popover should prevent interactivity of other elements - * on the page when open and the anchor is visible. + * on the page when open and its positioning anchor is visible. * @default true */ modal: PropTypes.bool, diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index 1841b070e1..e42cafb2cb 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -241,7 +241,7 @@ export namespace usePopoverRoot { closeDelay?: number; /** * Whether the popover should prevent interactivity of other elements - * on the page when open and the anchor is visible. + * on the page when open and its positioning anchor is visible. * @default true */ modal?: boolean; diff --git a/packages/react/src/select/backdrop/SelectBackdrop.tsx b/packages/react/src/select/backdrop/SelectBackdrop.tsx index d85e4e982e..957feaaaa2 100644 --- a/packages/react/src/select/backdrop/SelectBackdrop.tsx +++ b/packages/react/src/select/backdrop/SelectBackdrop.tsx @@ -8,7 +8,7 @@ import { popupStateMapping } from '../../utils/popupStateMapping'; import type { CustomStyleHookMapping } from '../../utils/getStyleHookProps'; import type { TransitionStatus } from '../../utils/useTransitionStatus'; import { transitionStatusMapping } from '../../utils/styleHookMapping'; -import { useEnhancedEffect } from '@base-ui-components/react/utils'; +import { useEnhancedEffect } from '../../utils/useEnhancedEffect'; const customStyleHookMapping: CustomStyleHookMapping = { ...popupStateMapping, diff --git a/packages/react/src/select/positioner/useSelectPositioner.ts b/packages/react/src/select/positioner/useSelectPositioner.ts index f15e1c4628..fb29495ce1 100644 --- a/packages/react/src/select/positioner/useSelectPositioner.ts +++ b/packages/react/src/select/positioner/useSelectPositioner.ts @@ -10,7 +10,6 @@ import type { GenericHTMLProps } from '../../utils/types'; import { type Boundary, type Side, useAnchorPositioning } from '../../utils/useAnchorPositioning'; import { mergeReactProps } from '../../utils/mergeReactProps'; import { useSelectRootContext } from '../root/SelectRootContext'; -import { useScrollLock } from '../../utils/useScrollLock'; export function useSelectPositioner( params: useSelectPositioner.Parameters, diff --git a/packages/react/src/select/root/SelectRoot.tsx b/packages/react/src/select/root/SelectRoot.tsx index d516fc8c17..d1e5337bd2 100644 --- a/packages/react/src/select/root/SelectRoot.tsx +++ b/packages/react/src/select/root/SelectRoot.tsx @@ -146,7 +146,7 @@ SelectRoot.propTypes /* remove-proptypes */ = { disabled: PropTypes.bool, /** * Whether the select should prevent interactivity of other elements - * on the page when open and the anchor is visible. + * on the page when open and its positioning anchor is visible. * @default true */ modal: PropTypes.bool, diff --git a/packages/react/src/select/root/useSelectRoot.ts b/packages/react/src/select/root/useSelectRoot.ts index 5b40f22983..8d82b78689 100644 --- a/packages/react/src/select/root/useSelectRoot.ts +++ b/packages/react/src/select/root/useSelectRoot.ts @@ -384,7 +384,7 @@ export namespace useSelectRoot { transitionStatus?: TransitionStatus; /** * Whether the select should prevent interactivity of other elements - * on the page when open and the anchor is visible. + * on the page when open and its positioning anchor is visible. * @default true */ modal?: boolean; From 12399b1bea460deb339dcf4454f32e355dafb452 Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 18:14:53 +1100 Subject: [PATCH 09/10] Handle infotips --- packages/react/src/popover/root/usePopoverRoot.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index e42cafb2cb..5e67a20daf 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -147,7 +147,8 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo }); const dismiss = useDismiss(context, { - outsidePressEvent: modal || backdropRendered ? 'mousedown' : undefined, + // For infotips (`openOnHover`), ensure another infotip can immediately open on tap + outsidePressEvent: !openOnHover && (modal || backdropRendered) ? 'mousedown' : undefined, }); const role = useRole(context); From 91f4a637cd22f4cb1647dde64c1bfcc4b76557be Mon Sep 17 00:00:00 2001 From: atomiks Date: Thu, 26 Dec 2024 18:19:39 +1100 Subject: [PATCH 10/10] Improve outside press event check --- packages/react/src/popover/root/usePopoverRoot.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/packages/react/src/popover/root/usePopoverRoot.ts b/packages/react/src/popover/root/usePopoverRoot.ts index 5e67a20daf..f7cd2a1990 100644 --- a/packages/react/src/popover/root/usePopoverRoot.ts +++ b/packages/react/src/popover/root/usePopoverRoot.ts @@ -67,6 +67,8 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo const { mounted, setMounted, transitionStatus } = useTransitionStatus(open); + const { openMethod, triggerProps } = useOpenInteractionType(open); + useScrollLock(open && modal && backdropRendered, triggerElement); const setOpen = useEventCallback( @@ -146,17 +148,20 @@ export function usePopoverRoot(params: usePopoverRoot.Parameters): usePopoverRoo stickIfOpen: false, }); + let outsidePressEvent: 'mousedown' | undefined = + modal || backdropRendered ? 'mousedown' : undefined; + // For infotips (`openOnHover`), ensure another infotip can immediately open on tap + if (!backdropRendered && openOnHover && openMethod === 'touch') { + outsidePressEvent = undefined; + } const dismiss = useDismiss(context, { - // For infotips (`openOnHover`), ensure another infotip can immediately open on tap - outsidePressEvent: !openOnHover && (modal || backdropRendered) ? 'mousedown' : undefined, + outsidePressEvent, }); const role = useRole(context); const { getReferenceProps, getFloatingProps } = useInteractions([hover, click, dismiss, role]); - const { openMethod, triggerProps } = useOpenInteractionType(open); - return React.useMemo( () => ({ open,