import { defineComponent, ref, computed, watchEffect, createBlock, openBlock, unref, mergeProps, withCtx, renderSlot } from 'vue'; import { _ as _sfc_main$1 } from '../DismissableLayer/DismissableLayer.js'; import { m as makeTriggerId, a as makeContentId, E as EVENT_ROOT_CONTENT_DISMISS, g as getOpenState, b as getTabbableCandidates, f as focusFirst } from './utils.js'; import { u as useCollection } from '../Collection/Collection.js'; import { u as useForwardExpose } from '../shared/useForwardExpose.js'; import { i as injectNavigationMenuItemContext } from './NavigationMenuItem.js'; import { g as getActiveElement } from '../shared/getActiveElement.js'; import { u as useArrowNavigation } from '../shared/useArrowNavigation.js'; import { i as injectNavigationMenuContext } from './NavigationMenuRoot.js'; const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "NavigationMenuContentImpl", props: { disableOutsidePointerEvents: { type: Boolean }, asChild: { type: Boolean }, as: {} }, emits: ["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside"], setup(__props, { emit: __emit }) { const props = __props; const emits = __emit; const { getItems } = useCollection({ key: "NavigationMenu" }); const { forwardRef, currentElement } = useForwardExpose(); const menuContext = injectNavigationMenuContext(); const itemContext = injectNavigationMenuItemContext(); const triggerId = makeTriggerId(menuContext.baseId, itemContext.value); const contentId = makeContentId(menuContext.baseId, itemContext.value); const prevMotionAttributeRef = ref(null); const motionAttribute = computed(() => { const values = getItems().map((i) => i.ref.id.split("trigger-")[1]); if (menuContext.dir.value === "rtl") values.reverse(); const index = values.indexOf(menuContext.modelValue.value); const prevIndex = values.indexOf(menuContext.previousValue.value); const isSelected = itemContext.value === menuContext.modelValue.value; const wasSelected = prevIndex === values.indexOf(itemContext.value); if (!isSelected && !wasSelected) return prevMotionAttributeRef.value; const attribute = (() => { if (index !== prevIndex) { if (isSelected && prevIndex !== -1) return index > prevIndex ? "from-end" : "from-start"; if (wasSelected && index !== -1) return index > prevIndex ? "to-start" : "to-end"; } return null; })(); prevMotionAttributeRef.value = attribute; return attribute; }); function handleFocusOutside(ev) { emits("focusOutside", ev); emits("interactOutside", ev); const target = ev.detail.originalEvent.target; if (target.hasAttribute("data-navigation-menu-trigger")) ev.preventDefault(); if (!ev.defaultPrevented) { itemContext.onContentFocusOutside(); const target2 = ev.target; if (menuContext.rootNavigationMenu?.value?.contains(target2)) ev.preventDefault(); } } function handlePointerDownOutside(ev) { emits("pointerDownOutside", ev); if (!ev.defaultPrevented) { const target = ev.target; const isTrigger = getItems().some( (i) => i.ref.contains(target) ); const isRootViewport = menuContext.isRootMenu && menuContext.viewport.value?.contains(target); if (isTrigger || isRootViewport || !menuContext.isRootMenu) ev.preventDefault(); } } watchEffect((cleanupFn) => { const content = currentElement.value; if (menuContext.isRootMenu && content) { const handleClose = () => { menuContext.onItemDismiss(); itemContext.onRootContentClose(); if (content.contains(getActiveElement())) itemContext.triggerRef.value?.focus(); }; content.addEventListener(EVENT_ROOT_CONTENT_DISMISS, handleClose); cleanupFn( () => content.removeEventListener(EVENT_ROOT_CONTENT_DISMISS, handleClose) ); } }); function handleEscapeKeyDown(ev) { emits("escapeKeyDown", ev); if (!ev.defaultPrevented) { menuContext.onItemDismiss(); itemContext.triggerRef?.value?.focus(); itemContext.wasEscapeCloseRef.value = true; } } function handleKeydown(ev) { if (ev.target.closest("[data-reka-navigation-menu]") !== menuContext.rootNavigationMenu.value) return; const isMetaKey = ev.altKey || ev.ctrlKey || ev.metaKey; const isTabKey = ev.key === "Tab" && !isMetaKey; const candidates = getTabbableCandidates(ev.currentTarget); if (isTabKey) { const focusedElement = getActiveElement(); const index = candidates.findIndex( (candidate) => candidate === focusedElement ); const isMovingBackwards = ev.shiftKey; const nextCandidates = isMovingBackwards ? candidates.slice(0, index).reverse() : candidates.slice(index + 1, candidates.length); if (focusFirst(nextCandidates)) { ev.preventDefault(); } else { itemContext.focusProxyRef.value?.focus(); return; } } const newSelectedElement = useArrowNavigation( ev, getActiveElement(), void 0, { itemsArray: candidates, loop: false, enableIgnoredElement: true } ); newSelectedElement?.focus(); } function handleDismiss() { const rootContentDismissEvent = new Event(EVENT_ROOT_CONTENT_DISMISS, { bubbles: true, cancelable: true }); currentElement.value?.dispatchEvent(rootContentDismissEvent); } return (_ctx, _cache) => { return openBlock(), createBlock(unref(_sfc_main$1), mergeProps({ id: unref(contentId), ref: unref(forwardRef), "aria-labelledby": unref(triggerId), "data-motion": motionAttribute.value, "data-state": unref(getOpenState)(unref(menuContext).modelValue.value === unref(itemContext).value), "data-orientation": unref(menuContext).orientation }, props, { onKeydown: handleKeydown, onEscapeKeyDown: handleEscapeKeyDown, onPointerDownOutside: handlePointerDownOutside, onFocusOutside: handleFocusOutside, onDismiss: handleDismiss }), { default: withCtx(() => [ renderSlot(_ctx.$slots, "default") ]), _: 3 }, 16, ["id", "aria-labelledby", "data-motion", "data-state", "data-orientation"]); }; } }); export { _sfc_main as _ }; //# sourceMappingURL=NavigationMenuContentImpl.js.map