Files
2025-03-07 19:22:02 +01:00

169 lines
7.5 KiB
JavaScript

"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 _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
const _menuContext = require("../../contexts/menuContext");
const _useIsSubmenu = require("../../utils/useIsSubmenu");
const _reacttabster = require("@fluentui/react-tabster");
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
const _keyboardkeys = require("@fluentui/keyboard-keys");
const _reactutilities = require("@fluentui/react-utilities");
const _reactaria = require("@fluentui/react-aria");
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, _useIsSubmenu.useIsSubmenu)();
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 hasMouseMoved = _react.useRef(false);
const { dir } = (0, _reactsharedcontexts.useFluent_unstable)();
const OpenArrowKey = dir === 'ltr' ? _keyboardkeys.ArrowRight : _keyboardkeys.ArrowLeft;
const child = (0, _reactutilities.getTriggerChild)(children);
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)) {
return;
}
const key = event.key;
if (!openOnContext && (isSubmenu && 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) {
focusFirst();
}
};
const onMouseEnter = (event)=>{
if (isTargetDisabled(event)) {
return;
}
if (openOnHover && hasMouseMoved.current) {
setOpen(event, {
open: true,
keyboard: false,
type: 'menuTriggerMouseEnter',
event
});
}
};
// 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 && !hasMouseMoved.current) {
setOpen(event, {
open: true,
keyboard: false,
type: 'menuTriggerMouseMove',
event
});
hasMouseMoved.current = true;
}
};
const onMouseLeave = (event)=>{
if (isTargetDisabled(event)) {
return;
}
if (openOnHover) {
setOpen(event, {
open: false,
keyboard: false,
type: 'menuTriggerMouseLeave',
event
});
}
};
const contextMenuProps = {
id: triggerId,
...child === null || child === void 0 ? void 0 : child.props,
ref: (0, _reactutilities.useMergedRefs)(triggerRef, child === null || child === void 0 ? void 0 : child.ref),
onMouseEnter: (0, _reactutilities.useEventCallback)((0, _reactutilities.mergeCallbacks)(child === null || child === void 0 ? void 0 : child.props.onMouseEnter, onMouseEnter)),
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))
};
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);
};