'use client'; "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "useMenuTrigger_unstable", { enumerable: true, get: function() { return useMenuTrigger_unstable; } }); const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); const _reactaria = require("@fluentui/react-aria"); const _keyboardkeys = require("@fluentui/keyboard-keys"); const _reactsharedcontexts = require("@fluentui/react-shared-contexts"); const _reacttabster = require("@fluentui/react-tabster"); const _reactutilities = require("@fluentui/react-utilities"); const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); const _menuContext = require("../../contexts/menuContext"); const _menuListContext = require("../../contexts/menuListContext"); const _utils = require("../../utils"); function noop() { // does nothing } const useMenuTrigger_unstable = (props)=>{ const { children, disableButtonEnhancement = false } = props; const triggerRef = (0, _menuContext.useMenuContext_unstable)((context)=>context.triggerRef); const menuPopoverRef = (0, _menuContext.useMenuContext_unstable)((context)=>context.menuPopoverRef); const setOpen = (0, _menuContext.useMenuContext_unstable)((context)=>context.setOpen); const open = (0, _menuContext.useMenuContext_unstable)((context)=>context.open); const triggerId = (0, _menuContext.useMenuContext_unstable)((context)=>context.triggerId); const openOnHover = (0, _menuContext.useMenuContext_unstable)((context)=>context.openOnHover); const openOnContext = (0, _menuContext.useMenuContext_unstable)((context)=>context.openOnContext); const isSubmenu = (0, _utils.useIsSubmenu)(); const shouldOpenOnArrowRight = (0, _menuListContext.useMenuListContext_unstable)((ctx)=>{ var _ctx_shouldOpenOnArrowRight; return (_ctx_shouldOpenOnArrowRight = ctx.shouldOpenOnArrowRight) !== null && _ctx_shouldOpenOnArrowRight !== void 0 ? _ctx_shouldOpenOnArrowRight : true; }); const { findFirstFocusable } = (0, _reacttabster.useFocusFinders)(); const focusFirst = _react.useCallback(()=>{ const firstFocusable = findFirstFocusable(menuPopoverRef.current); firstFocusable === null || firstFocusable === void 0 ? void 0 : firstFocusable.focus(); }, [ findFirstFocusable, menuPopoverRef ]); const openedWithKeyboardRef = _react.useRef(false); const openedViaSafeZoneRef = _react.useRef(false); const hasMouseMovedRef = _react.useRef(false); const { dir } = (0, _reactsharedcontexts.useFluent_unstable)(); const OpenArrowKey = dir === 'ltr' ? _keyboardkeys.ArrowRight : _keyboardkeys.ArrowLeft; const child = (0, _reactutilities.getTriggerChild)(children); // Heads up! // // Handles an edge case where mouse movement over the menu trigger didn't happen as safe zone blocked pointer events, // but the cursor is already over the menu trigger. const safeZoneHandlerRef = (0, _utils.useOnMenuSafeZoneTimeout)((0, _reactutilities.useEventCallback)(()=>{ if (isSubmenu) { openedViaSafeZoneRef.current = true; } })); const onContextMenu = (event)=>{ if (isTargetDisabled(event) || event.isDefaultPrevented()) { return; } if (openOnContext) { event.preventDefault(); setOpen(event, { open: true, keyboard: false, type: 'menuTriggerContextMenu', event }); } }; const onClick = (event)=>{ if (isTargetDisabled(event)) { return; } if (!openOnContext) { setOpen(event, { open: !open, keyboard: openedWithKeyboardRef.current, type: 'menuTriggerClick', event }); openedWithKeyboardRef.current = false; } }; const onKeyDown = (event)=>{ if (isTargetDisabled(event) || event.isDefaultPrevented()) { return; } const key = event.key; if (!openOnContext && (isSubmenu && shouldOpenOnArrowRight && key === OpenArrowKey || !isSubmenu && key === _keyboardkeys.ArrowDown)) { setOpen(event, { open: true, keyboard: true, type: 'menuTriggerKeyDown', event }); } if (key === _keyboardkeys.Escape && !isSubmenu) { setOpen(event, { open: false, keyboard: true, type: 'menuTriggerKeyDown', event }); } // if menu is already open, can't rely on effects to focus if (open && key === OpenArrowKey && isSubmenu && shouldOpenOnArrowRight) { focusFirst(); } }; const onMouseOver = (event)=>{ if (isTargetDisabled(event)) { return; } if (openOnHover) { if (hasMouseMovedRef.current) { setOpen(event, { open: true, keyboard: false, type: 'menuTriggerMouseEnter', event }); } else if (openedViaSafeZoneRef.current) { setOpen(event, { open: true, keyboard: false, ignoreHoverDelay: true, type: 'menuTriggerMouseEnter', event }); openedViaSafeZoneRef.current = false; } } }; // Opening a menu when a mouse hasn't moved and just entering the trigger is a bad a11y experience // First time open the mouse using mousemove and then continue with mouseenter // Only use once to determine that the user is using the mouse since it is an expensive event to handle const onMouseMove = (event)=>{ if (isTargetDisabled(event)) { return; } if (openOnHover && !hasMouseMovedRef.current) { setOpen(event, { open: true, keyboard: false, type: 'menuTriggerMouseMove', event }); hasMouseMovedRef.current = true; } }; const onMouseLeave = (event)=>{ if (isTargetDisabled(event)) { return; } if (openOnHover) { setOpen(event, { open: false, keyboard: false, type: 'menuTriggerMouseLeave', event }); } }; var _child_props_onMouseEnter; const contextMenuProps = { id: triggerId, ...child === null || child === void 0 ? void 0 : child.props, ref: (0, _reactutilities.useMergedRefs)(triggerRef, (0, _reactutilities.getReactElementRef)(child), safeZoneHandlerRef), onMouseEnter: (0, _reactutilities.useEventCallback)((_child_props_onMouseEnter = child === null || child === void 0 ? void 0 : child.props.onMouseEnter) !== null && _child_props_onMouseEnter !== void 0 ? _child_props_onMouseEnter : noop), onMouseLeave: (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(child === null || child === void 0 ? void 0 : child.props.onMouseLeave, onMouseLeave)), onContextMenu: (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(child === null || child === void 0 ? void 0 : child.props.onContextMenu, onContextMenu)), onMouseMove: (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(child === null || child === void 0 ? void 0 : child.props.onMouseMove, onMouseMove)), onMouseOver: (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(child === null || child === void 0 ? void 0 : child.props.onMouseOver, onMouseOver)) }; const triggerChildProps = { 'aria-haspopup': 'menu', 'aria-expanded': !open && !isSubmenu ? undefined : open, ...contextMenuProps, onClick: (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(child === null || child === void 0 ? void 0 : child.props.onClick, onClick)), onKeyDown: (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(child === null || child === void 0 ? void 0 : child.props.onKeyDown, onKeyDown)) }; const ariaButtonTriggerChildProps = (0, _reactaria.useARIAButtonProps)((child === null || child === void 0 ? void 0 : child.type) === 'button' || (child === null || child === void 0 ? void 0 : child.type) === 'a' ? child.type : 'div', triggerChildProps); return { isSubmenu, children: (0, _reactutilities.applyTriggerPropsToChildren)(children, openOnContext ? contextMenuProps : disableButtonEnhancement ? triggerChildProps : ariaButtonTriggerChildProps) }; }; const isTargetDisabled = (event)=>{ const isDisabled = (el)=>el.hasAttribute('disabled') || el.hasAttribute('aria-disabled') && el.getAttribute('aria-disabled') === 'true'; if ((0, _reactutilities.isHTMLElement)(event.target) && isDisabled(event.target)) { return true; } return (0, _reactutilities.isHTMLElement)(event.currentTarget) && isDisabled(event.currentTarget); };