'use client'; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); function _export(target, all) { for(var name in all)Object.defineProperty(target, name, { enumerable: true, get: all[name] }); } _export(exports, { usePopoverBase_unstable: function() { return usePopoverBase_unstable; }, usePopover_unstable: function() { return usePopover_unstable; } }); const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); const _reactutilities = require("@fluentui/react-utilities"); const _reactsharedcontexts = require("@fluentui/react-shared-contexts"); const _reactpositioning = require("@fluentui/react-positioning"); const _reacttabster = require("@fluentui/react-tabster"); const _index = require("../PopoverSurface/index"); const _constants = require("./constants"); const _reactmotion = require("@fluentui/react-motion"); const _PopoverSurfaceMotion = require("./PopoverSurfaceMotion"); const usePopover_unstable = (props)=>{ const { appearance, size = 'medium' } = props; const positioning = (0, _reactpositioning.resolvePositioningShorthand)(props.positioning); const withArrow = props.withArrow && !positioning.coverTarget; const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)(); const handlePositionEnd = (0, _reactpositioning.usePositioningSlideDirection)({ targetDocument, onPositioningEnd: positioning.onPositioningEnd }); const state = usePopoverBase_unstable({ ...props, positioning: { ...positioning, onPositioningEnd: handlePositionEnd, // Update the offset with the arrow size only when it's available ...withArrow ? { offset: (0, _reactpositioning.mergeArrowOffset)(positioning.offset, _index.arrowHeights[size]) } : {} } }); return { components: { surfaceMotion: _PopoverSurfaceMotion.PopoverSurfaceMotion }, appearance, size, ...state, surfaceMotion: (0, _reactmotion.presenceMotionSlot)(props.surfaceMotion, { elementType: _PopoverSurfaceMotion.PopoverSurfaceMotion, defaultProps: { visible: state.open, appear: true, unmountOnExit: true } }) }; }; const usePopoverBase_unstable = (props)=>{ const [contextTarget, setContextTarget] = (0, _reactpositioning.usePositioningMouseTarget)(); const initialState = { contextTarget, setContextTarget, ...props }; const children = _react.Children.toArray(props.children); if (process.env.NODE_ENV !== 'production') { if (children.length === 0) { // eslint-disable-next-line no-console console.warn('Popover must contain at least one child'); } if (children.length > 2) { // eslint-disable-next-line no-console console.warn('Popover must contain at most two children'); } } let popoverTrigger = undefined; let popoverSurface = undefined; if (children.length === 2) { popoverTrigger = children[0]; popoverSurface = children[1]; } else if (children.length === 1) { popoverSurface = children[0]; } const [open, setOpenState] = useOpenState(initialState); const [setOpenTimeout, clearOpenTimeout] = (0, _reactutilities.useTimeout)(); const setOpen = (0, _reactutilities.useEventCallback)((e, shouldOpen)=>{ clearOpenTimeout(); if (!(e instanceof Event) && e.persist) { // < React 17 still uses pooled synthetic events e.persist(); } if (e.type === 'mouseleave') { var _props_mouseLeaveDelay; // FIXME leaking Node timeout type // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore setOpenTimeout(()=>{ setOpenState(e, shouldOpen); }, (_props_mouseLeaveDelay = props.mouseLeaveDelay) !== null && _props_mouseLeaveDelay !== void 0 ? _props_mouseLeaveDelay : 500); } else { setOpenState(e, shouldOpen); } }); const toggleOpen = _react.useCallback((e)=>{ setOpen(e, !open); }, [ setOpen, open ]); const positioningRefs = usePopoverRefs(initialState); const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)(); var _props_closeOnIframeFocus; (0, _reactutilities.useOnClickOutside)({ contains: _reactutilities.elementContains, element: targetDocument, callback: (ev)=>setOpen(ev, false), refs: [ positioningRefs.triggerRef, positioningRefs.contentRef ], disabled: !open, disabledFocusOnIframe: !((_props_closeOnIframeFocus = props.closeOnIframeFocus) !== null && _props_closeOnIframeFocus !== void 0 ? _props_closeOnIframeFocus : true) }); // only close on scroll for context, or when closeOnScroll is specified const closeOnScroll = initialState.openOnContext || initialState.closeOnScroll; (0, _reactutilities.useOnScrollOutside)({ contains: _reactutilities.elementContains, element: targetDocument, callback: (ev)=>setOpen(ev, false), refs: [ positioningRefs.triggerRef, positioningRefs.contentRef ], disabled: !open || !closeOnScroll }); const { findFirstFocusable } = (0, _reacttabster.useFocusFinders)(); const activateModal = (0, _reacttabster.useActivateModal)(); _react.useEffect(()=>{ if (props.unstable_disableAutoFocus) { return; } const contentElement = positioningRefs.contentRef.current; if (open && contentElement) { var _contentElement_getAttribute; const shouldFocusContainer = !isNaN((_contentElement_getAttribute = contentElement.getAttribute('tabIndex')) !== null && _contentElement_getAttribute !== void 0 ? _contentElement_getAttribute : undefined); const firstFocusable = shouldFocusContainer ? contentElement : findFirstFocusable(contentElement); firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus(); if (shouldFocusContainer) { // Modal activation happens automatically when something inside the modal is focused programmatically. // When the container is focused, we need to activate the modal manually. activateModal(contentElement); } } }, [ findFirstFocusable, activateModal, open, positioningRefs.contentRef, props.unstable_disableAutoFocus ]); var _props_inertTrapFocus, _props_inline; return { ...initialState, ...positioningRefs, // eslint-disable-next-line @typescript-eslint/no-deprecated inertTrapFocus: (_props_inertTrapFocus = props.inertTrapFocus) !== null && _props_inertTrapFocus !== void 0 ? _props_inertTrapFocus : props.legacyTrapFocus === undefined ? false : !props.legacyTrapFocus, popoverTrigger, popoverSurface, open, setOpen, toggleOpen, setContextTarget, contextTarget, inline: (_props_inline = props.inline) !== null && _props_inline !== void 0 ? _props_inline : false }; }; /** * Creates and manages the Popover open state */ function useOpenState(state) { 'use no memo'; const onOpenChange = (0, _reactutilities.useEventCallback)((e, data)=>{ var _state_onOpenChange; return (_state_onOpenChange = state.onOpenChange) === null || _state_onOpenChange === void 0 ? void 0 : _state_onOpenChange.call(state, e, data); }); const [open, setOpenState] = (0, _reactutilities.useControllableState)({ state: state.open, defaultState: state.defaultOpen, initialState: false }); state.open = open !== undefined ? open : state.open; const setContextTarget = state.setContextTarget; const setOpen = _react.useCallback((e, shouldOpen)=>{ if (shouldOpen && e.type === 'contextmenu') { setContextTarget(e); } if (!shouldOpen) { setContextTarget(undefined); } setOpenState(shouldOpen); onOpenChange === null || onOpenChange === void 0 ? void 0 : onOpenChange(e, { open: shouldOpen }); }, [ setOpenState, onOpenChange, setContextTarget ]); return [ open, setOpen ]; } /** * Creates and sets the necessary trigger, target and content refs used by Popover */ function usePopoverRefs(state) { 'use no memo'; const positioningOptions = { position: 'above', align: 'center', arrowPadding: 2 * _constants.popoverSurfaceBorderRadius, target: state.openOnContext ? state.contextTarget : undefined, ...(0, _reactpositioning.resolvePositioningShorthand)(state.positioning) }; // no reason to render arrow when covering the target if (positioningOptions.coverTarget) { state.withArrow = false; } const { targetRef: triggerRef, containerRef: contentRef, arrowRef } = (0, _reactpositioning.usePositioning)(positioningOptions); return { triggerRef, contentRef, arrowRef }; }