import { type Accessor, createContext, useContext } from "solid-js"; import type { ListState } from "../list"; import type { Placement } from "../popper/utils"; import type { CollectionItemWithRef } from "../primitives"; import type { FocusStrategy } from "../selection"; import type { GraceIntent, Side } from "./utils"; export interface MenuDataSet { "data-expanded": string | undefined; "data-closed": string | undefined; } export interface MenuContextValue { dataset: Accessor; isOpen: Accessor; contentPresent: Accessor; currentPlacement: Accessor; pointerGraceTimeoutId: Accessor; autoFocus: Accessor; listState: Accessor; parentMenuContext: Accessor; triggerRef: Accessor; contentRef: Accessor; triggerId: Accessor; contentId: Accessor; setTriggerRef: (el: HTMLElement) => void; setContentRef: (el: HTMLElement | undefined) => void; open: (focusStrategy: FocusStrategy | boolean) => void; close: (recursively?: boolean) => void; toggle: (focusStrategy: FocusStrategy | boolean) => void; focusContent: () => void; onItemEnter: (e: PointerEvent) => void; onItemLeave: (e: PointerEvent) => void; onTriggerLeave: (e: PointerEvent) => void; setPointerDir: (dir: Side) => void; setPointerGraceTimeoutId: (id: number) => void; setPointerGraceIntent: (intent: GraceIntent | null) => void; registerNestedMenu: (element: HTMLElement) => () => void; registerItemToParentDomCollection: | ((item: CollectionItemWithRef) => () => void) | undefined; registerTriggerId: (id: string) => () => void; registerContentId: (id: string) => () => void; nestedMenus: Accessor; } export const MenuContext = createContext(); export function useOptionalMenuContext() { return useContext(MenuContext); } export function useMenuContext() { const context = useOptionalMenuContext(); if (context === undefined) { throw new Error( "[kobalte]: `useMenuContext` must be used within a `Menu` component", ); } return context; }