import type { ComputedRef, Ref, ShallowRef } from 'vue'; import type { Direction } from '../../utilities/config-provider'; import type { Orientation } from '../../utilities/roving-focus'; import { useContextFactory } from '@robonen/vue'; /** * Context shared by `NavigationMenuRoot` and `NavigationMenuSub`. Children * (item / list / trigger / content / viewport / indicator) read from this * single context regardless of whether they are inside a root or a submenu. */ export interface NavigationMenuContext { isRootMenu: boolean; modelValue: Ref; previousValue: Ref; baseId: ComputedRef | Ref; dir: Ref; orientation: Orientation; disableClickTrigger: Ref; disableHoverTrigger: Ref; disablePointerLeaveClose: Ref; unmountOnHide: Ref; rootNavigationMenu: ShallowRef; activeTrigger: ShallowRef; onActiveTriggerChange: (el: HTMLElement | undefined) => void; indicatorTrack: ShallowRef; onIndicatorTrackChange: (el: HTMLElement | undefined) => void; viewport: ShallowRef; onViewportChange: (el: HTMLElement | undefined) => void; onTriggerEnter: (itemValue: string) => void; onTriggerLeave: () => void; onContentEnter: (itemValue: string) => void; onContentLeave: () => void; onItemSelect: (itemValue: string) => void; onItemDismiss: () => void; } export interface NavigationMenuItemContext { value: string; contentId: string; triggerId: string; triggerRef: ShallowRef; onTriggerChange: (el: HTMLElement | undefined) => void; focusProxyRef: ShallowRef; onFocusProxyChange: (el: HTMLElement | undefined) => void; wasEscapeCloseRef: Ref; onEntryKeyDown: () => void; onFocusProxyEnter: (side: 'start' | 'end') => void; onContentFocusOutside: () => void; onRootContentClose: () => void; } export const { inject: useNavigationMenuContext, provide: provideNavigationMenuContext, } = useContextFactory('NavigationMenu'); export const { inject: useNavigationMenuItemContext, provide: provideNavigationMenuItemContext, } = useContextFactory('NavigationMenuItem');