{"mappings":";;;;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;;;AAiEM,SAAS,0CAAqB,KAA8B,EAAE,KAA0B,EAAE,GAAuC;IACtI,IAAI,iBAAC,aAAa,cAAE,UAAU,QAAE,OAAO,oBAAQ,UAAU,SAAE,QAAQ,4BAAK,qBAAqB,EAAC,GAAG;IACjG,IAAI,mBAAmB,CAAA,GAAA,+BAAI;IAC3B,IAAI,YAAY,CAAA,GAAA,+BAAI;IACpB,IAAI,aAAC,SAAS,EAAC,GAAG,CAAA,GAAA,mCAAQ;IAC1B,IAAI,cAAc,CAAA,GAAA,mBAAK,EAA6C;IACpE,IAAI,oBAAoB,CAAA,GAAA,wBAAU,EAAE;QAClC,IAAI,YAAY,OAAO,EAAE;YACvB,aAAa,YAAY,OAAO;YAChC,YAAY,OAAO,GAAG;QACxB;IACF,GAAG;QAAC;KAAY;IAEhB,IAAI,gBAAgB,CAAA,GAAA,wBAAU,EAAE,CAAC;QAC/B;QACA,MAAM,IAAI,CAAC;IACb,GAAG;QAAC;QAAO;KAAkB;IAE7B,IAAI,iBAAiB,CAAA,GAAA,wBAAU,EAAE;QAC/B;QACA,MAAM,KAAK;IACb,GAAG;QAAC;QAAO;KAAkB;IAE7B,CAAA,GAAA,yCAAc,EAAE;QACd,OAAO;YACL;QACF;IACF,GAAG;QAAC;KAAkB;IAEtB,IAAI,iBAAiB,CAAC;QACpB,uEAAuE;QACvE,kGAAkG;QAClG,IAAI,CAAC,CAAA,GAAA,uCAAY,EAAE,EAAE,aAAa,GAChC;QAGF,OAAQ,EAAE,GAAG;YACX,KAAK;gBACH,IAAI,cAAc,SAAS,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAE,CAAA,GAAA,wCAAa,EAAE,KAAgB;oBACtF,EAAE,cAAc;oBAChB,EAAE,eAAe;oBACjB;oBACA,IAAI,CAAC,yBAAyB,IAAI,OAAO,EACvC,CAAA,GAAA,+CAAoB,EAAE,IAAI,OAAO;gBAErC;gBACA;YACF,KAAK;gBACH,IAAI,cAAc,SAAS,CAAA,GAAA,sCAAW,EAAE,EAAE,aAAa,EAAE,CAAA,GAAA,wCAAa,EAAE,KAAgB;oBACtF,EAAE,cAAc;oBAChB,EAAE,eAAe;oBACjB;oBACA,IAAI,CAAC,yBAAyB,IAAI,OAAO,EACvC,CAAA,GAAA,+CAAoB,EAAE,IAAI,OAAO;gBAErC;gBACA;YACF,KAAK;gBACH,2DAA2D;gBAC3D,IAAI,CAAA,GAAA,sCAAW,EAAE,WAAW,OAAO,EAAE,CAAA,GAAA,wCAAa,EAAE,KAAgB;oBAClE,EAAE,eAAe;oBACjB;oBACA,IAAI,CAAC,yBAAyB,IAAI,OAAO,EACvC,CAAA,GAAA,+CAAoB,EAAE,IAAI,OAAO;gBAErC;gBACA;QACJ;IACF;IAEA,IAAI,eAAe;QACjB,IAAI;QACJ,mBAAmB;QACnB,cAAc,MAAM,YAAY;QAChC,GAAI,SAAS,UAAU;YACrB,SAAS,MAAM,QAAQ;YACvB,WAAW,MAAM,aAAa,IAAI;YAClC,WAAW;QACb,CAAC;IACH;IAEA,IAAI,wBAAwB,CAAC;QAC3B,OAAQ,EAAE,GAAG;YACX,KAAK;gBACH,IAAI,CAAC,YAAY;oBACf,IAAI,cAAc,OAAO;wBACvB,EAAE,cAAc;wBAChB,IAAI,CAAC,MAAM,MAAM,EACf,cAAc;wBAGhB,IAAI,SAAS,UAAU,CAAC,CAAC,YAAY,WAAW,CAAA,GAAA,0CAAe,QAAQ,KAAK,SAC1E,CAAA,GAAA,+CAAoB,EAAE,WAAW,OAAO;oBAE5C,OAAO,IAAI,MAAM,MAAM,EACrB;yBAEA,EAAE,mBAAmB;gBAEzB;gBAEA;YACF,KAAK;gBACH,IAAI,CAAC,YAAY;oBACf,IAAI,cAAc,OAAO;wBACvB,EAAE,cAAc;wBAChB,IAAI,CAAC,MAAM,MAAM,EACf,cAAc;wBAGhB,IAAI,SAAS,UAAU,CAAC,CAAC,YAAY,WAAW,CAAA,GAAA,0CAAe,QAAQ,KAAK,SAC1E,CAAA,GAAA,+CAAoB,EAAE,WAAW,OAAO;oBAE5C,OAAO,IAAI,MAAM,MAAM,EACrB;yBAEA,EAAE,mBAAmB;gBAEzB;gBACA;YACF;gBACE,EAAE,mBAAmB;gBACrB;QACJ;IACF;IAEA,IAAI,eAAe,CAAC;QAClB,IAAI,CAAC,cAAe,CAAA,EAAE,WAAW,KAAK,aAAa,EAAE,WAAW,KAAK,UAAS,GAC5E,iFAAiF;QACjF,cAAc;IAElB;IAEA,IAAI,UAAU,CAAC;QACb,IAAI,CAAC,cAAe,CAAA,EAAE,WAAW,KAAK,WAAW,EAAE,WAAW,KAAK,OAAM,GACvE,kGAAkG;QAClG,oDAAoD;QACpD;IAEJ;IAEA,IAAI,gBAAgB,CAAC;QACnB,IAAI,CAAC,YAAY;YACf,IAAI,aAAa,CAAC,MAAM,MAAM,EAC5B;gBAAA,IAAI,CAAC,YAAY,OAAO,EACtB,YAAY,OAAO,GAAG,WAAW;oBAC/B;gBACF,GAAG;YACL,OACK,IAAI,CAAC,WACV;QAEJ;IACF;IAEA,CAAA,GAAA,kCAAO,EAAE,eAAe,WAAW,CAAC;QAClC,8GAA8G;QAC9G,oHAAoH;QACpH,IAAI,MAAM,MAAM,IAAK,CAAA,GAAA,sCAAW,EAAE,cAAc,OAAO,EAAE,CAAA,GAAA,wCAAa,EAAE,OAAsB,CAAA,GAAA,wCAAa,EAAE,OAAO,IAAI,OAAO,EAC7H;IAEJ;IAEA,IAAI,+BAA+B,CAAC;QAClC,IAAI,WAAW,IAAI,OAAO,EACxB,OAAO;QAGT,OAAO;IACT;IAEA,CAAA,GAAA,iDAAsB,EAAE;QAAC,SAAS;oBAAe;QAAY,QAAQ,MAAM,MAAM;QAAE,YAAY;IAAU;IAEzG,OAAO;QACL,qBAAqB;YACnB,IAAI;YACJ,iBAAiB,MAAM,MAAM,GAAG,YAAY;YAC5C,iBAAiB,CAAC,aAAa,OAAO;YACtC,iBAAiB,MAAM,MAAM,GAAG,SAAS;0BACzC;qBACA;2BACA;YACA,WAAW;YACX,QAAQ,MAAM,MAAM;QACtB;sBACA;QACA,cAAc;YACZ,YAAY;0CACZ;QACF;IACF;AACF","sources":["packages/react-aria/src/menu/useSubmenuTrigger.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {AriaMenuItemProps} from './useMenuItem';\nimport {AriaMenuOptions} from './useMenu';\nimport type {AriaPopoverProps} from '../overlays/usePopover';\nimport {FocusableElement, FocusStrategy, KeyboardEvent, Node, PressEvent, RefObject} from '@react-types/shared';\nimport {focusWithoutScrolling} from '../utils/focusWithoutScrolling';\nimport {getActiveElement, getEventTarget, isFocusWithin, nodeContains} from '../utils/shadowdom/DOMFunctions';\nimport type {OverlayProps} from '../overlays/Overlay';\nimport type {SubmenuTriggerState} from 'react-stately/useMenuTriggerState';\nimport {useCallback, useRef} from 'react';\nimport {useEvent} from '../utils/useEvent';\nimport {useId} from '../utils/useId';\nimport {useLayoutEffect} from '../utils/useLayoutEffect';\nimport {useLocale} from '../i18n/I18nProvider';\nimport {useSafelyMouseToSubmenu} from './useSafelyMouseToSubmenu';\n\nexport interface AriaSubmenuTriggerProps {\n  /**\n   * An object representing the submenu trigger menu item. Contains all the relevant information that makes up the menu item.\n   * @deprecated\n   */\n  node?: Node<unknown>,\n  /** Whether the submenu trigger is disabled. */\n  isDisabled?: boolean,\n  /** The type of the contents that the submenu trigger opens. */\n  type?: 'dialog' | 'menu',\n  /** Ref of the menu that contains the submenu trigger. */\n  parentMenuRef: RefObject<HTMLElement | null>,\n  /** Ref of the submenu opened by the submenu trigger. */\n  submenuRef: RefObject<HTMLElement | null>,\n  /**\n   * The delay time in milliseconds for the submenu to appear after hovering over the trigger.\n   * @default 200\n   */\n  delay?: number,\n  /** Whether the submenu trigger uses virtual focus. */\n  shouldUseVirtualFocus?: boolean\n}\n\ninterface SubmenuTriggerProps extends Omit<AriaMenuItemProps, 'key' | 'onAction'> {\n  /** Whether the submenu trigger is in an expanded state. */\n  isOpen: boolean\n}\n\ninterface SubmenuProps<T> extends AriaMenuOptions<T> {\n  /** The level of the submenu. */\n  submenuLevel: number\n}\n\nexport interface SubmenuTriggerAria<T> {\n  /** Props for the submenu trigger menu item. */\n  submenuTriggerProps: SubmenuTriggerProps,\n  /** Props for the submenu controlled by the submenu trigger menu item. */\n  submenuProps: SubmenuProps<T>,\n  /** Props for the submenu's popover container. */\n  popoverProps: Pick<AriaPopoverProps, 'isNonModal' | 'shouldCloseOnInteractOutside'> & Pick<OverlayProps, 'disableFocusManagement'>\n}\n\n/**\n * Provides the behavior and accessibility implementation for a submenu trigger and its associated submenu.\n * @param props - Props for the submenu trigger and refs attach to its submenu and parent menu.\n * @param state - State for the submenu trigger.\n * @param ref - Ref to the submenu trigger element.\n */\nexport function useSubmenuTrigger<T>(props: AriaSubmenuTriggerProps, state: SubmenuTriggerState, ref: RefObject<FocusableElement | null>): SubmenuTriggerAria<T> {\n  let {parentMenuRef, submenuRef, type = 'menu', isDisabled, delay = 200, shouldUseVirtualFocus} = props;\n  let submenuTriggerId = useId();\n  let overlayId = useId();\n  let {direction} = useLocale();\n  let openTimeout = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n  let cancelOpenTimeout = useCallback(() => {\n    if (openTimeout.current) {\n      clearTimeout(openTimeout.current);\n      openTimeout.current = undefined;\n    }\n  }, [openTimeout]);\n\n  let onSubmenuOpen = useCallback((focusStrategy?: FocusStrategy) => {\n    cancelOpenTimeout();\n    state.open(focusStrategy);\n  }, [state, cancelOpenTimeout]);\n\n  let onSubmenuClose = useCallback(() => {\n    cancelOpenTimeout();\n    state.close();\n  }, [state, cancelOpenTimeout]);\n\n  useLayoutEffect(() => {\n    return () => {\n      cancelOpenTimeout();\n    };\n  }, [cancelOpenTimeout]);\n\n  let submenuKeyDown = (e: KeyboardEvent) => {\n    // If focus is not within the menu, assume virtual focus is being used.\n    // This means some other input element is also within the popover, so we shouldn't close the menu.\n    if (!isFocusWithin(e.currentTarget)) {\n      return;\n    }\n\n    switch (e.key) {\n      case 'ArrowLeft':\n        if (direction === 'ltr' && nodeContains(e.currentTarget, getEventTarget(e) as Element)) {\n          e.preventDefault();\n          e.stopPropagation();\n          onSubmenuClose();\n          if (!shouldUseVirtualFocus && ref.current) {\n            focusWithoutScrolling(ref.current);\n          }\n        }\n        break;\n      case 'ArrowRight':\n        if (direction === 'rtl' && nodeContains(e.currentTarget, getEventTarget(e) as Element)) {\n          e.preventDefault();\n          e.stopPropagation();\n          onSubmenuClose();\n          if (!shouldUseVirtualFocus && ref.current) {\n            focusWithoutScrolling(ref.current);\n          }\n        }\n        break;\n      case 'Escape':\n        // TODO: can remove this when we fix collection event leaks\n        if (nodeContains(submenuRef.current, getEventTarget(e) as Element)) {\n          e.stopPropagation();\n          onSubmenuClose();\n          if (!shouldUseVirtualFocus && ref.current) {\n            focusWithoutScrolling(ref.current);\n          }\n        }\n        break;\n    }\n  };\n\n  let submenuProps = {\n    id: overlayId,\n    'aria-labelledby': submenuTriggerId,\n    submenuLevel: state.submenuLevel,\n    ...(type === 'menu' && {\n      onClose: state.closeAll,\n      autoFocus: state.focusStrategy ?? undefined,\n      onKeyDown: submenuKeyDown\n    })\n  };\n\n  let submenuTriggerKeyDown = (e: KeyboardEvent) => {\n    switch (e.key) {\n      case 'ArrowRight':\n        if (!isDisabled) {\n          if (direction === 'ltr') {\n            e.preventDefault();\n            if (!state.isOpen) {\n              onSubmenuOpen('first');\n            }\n\n            if (type === 'menu' && !!submenuRef?.current && getActiveElement() === ref?.current) {\n              focusWithoutScrolling(submenuRef.current);\n            }\n          } else if (state.isOpen) {\n            onSubmenuClose();\n          } else {\n            e.continuePropagation();\n          }\n        }\n\n        break;\n      case 'ArrowLeft':\n        if (!isDisabled) {\n          if (direction === 'rtl') {\n            e.preventDefault();\n            if (!state.isOpen) {\n              onSubmenuOpen('first');\n            }\n\n            if (type === 'menu' && !!submenuRef?.current && getActiveElement() === ref?.current) {\n              focusWithoutScrolling(submenuRef.current);\n            }\n          } else if (state.isOpen) {\n            onSubmenuClose();\n          } else {\n            e.continuePropagation();\n          }\n        }\n        break;\n      default:\n        e.continuePropagation();\n        break;\n    }\n  };\n\n  let onPressStart = (e: PressEvent) => {\n    if (!isDisabled && (e.pointerType === 'virtual' || e.pointerType === 'keyboard')) {\n      // If opened with a screen reader or keyboard, auto focus the first submenu item.\n      onSubmenuOpen('first');\n    }\n  };\n\n  let onPress = (e: PressEvent) => {\n    if (!isDisabled && (e.pointerType === 'touch' || e.pointerType === 'mouse')) {\n      // For touch or on a desktop device with a small screen open on press up to possible problems with\n      // press up happening on the newly opened tray items\n      onSubmenuOpen();\n    }\n  };\n\n  let onHoverChange = (isHovered) => {\n    if (!isDisabled) {\n      if (isHovered && !state.isOpen) {\n        if (!openTimeout.current) {\n          openTimeout.current = setTimeout(() => {\n            onSubmenuOpen();\n          }, delay);\n        }\n      } else if (!isHovered) {\n        cancelOpenTimeout();\n      }\n    }\n  };\n\n  useEvent(parentMenuRef, 'focusin', (e) => {\n    // If we detect focus moved to a different item in the same menu that the currently open submenu trigger is in\n    // then close the submenu. This is for a case where the user hovers a root menu item when multiple submenus are open\n    if (state.isOpen && (nodeContains(parentMenuRef.current, getEventTarget(e) as HTMLElement) && getEventTarget(e) !== ref.current)) {\n      onSubmenuClose();\n    }\n  });\n\n  let shouldCloseOnInteractOutside = (target) => {\n    if (target !== ref.current) {\n      return true;\n    }\n\n    return false;\n  };\n\n  useSafelyMouseToSubmenu({menuRef: parentMenuRef, submenuRef, isOpen: state.isOpen, isDisabled: isDisabled});\n\n  return {\n    submenuTriggerProps: {\n      id: submenuTriggerId,\n      'aria-controls': state.isOpen ? overlayId : undefined,\n      'aria-haspopup': !isDisabled ? type : undefined,\n      'aria-expanded': state.isOpen ? 'true' : 'false',\n      onPressStart,\n      onPress,\n      onHoverChange,\n      onKeyDown: submenuTriggerKeyDown,\n      isOpen: state.isOpen\n    },\n    submenuProps,\n    popoverProps: {\n      isNonModal: true,\n      shouldCloseOnInteractOutside\n    }\n  };\n}\n"],"names":[],"version":3,"file":"useSubmenuTrigger.cjs.map"}