import type { JSX } from "@solidjs/web";
/**
* `createMenu` — headless primitive for the Menu compound.
*
* Owns the logical state surface only:
* - `open` — consumer-owned signal, read through the option accessor.
* - `activeIndex` — keyboard-highlighted item index.
* - `payload` — active trigger payload (for handle-driven workflows).
* - `setOpen` — pure event-emitter via `runWithOwner(null, ...)`.
*
* All DOM concerns (FloatingTree, floating-ui interaction hooks, focus trap,
* portal, transition) stay in `
`.
*/
import { type Accessor } from "solid-js";
import { type MaybeAccessor } from "../internals/maybe-accessor.js";
import type { MenuRootChangeEventDetails, MenuRootChangeEventReason } from "./root/menu-root-context.js";
export type MenuChangeReason = MenuRootChangeEventReason;
export interface CreateMenuOptions<_Payload = unknown> {
/**
* Open state. Consumer-owned signal — the primitive reads through the
* accessor and does NOT keep an internal copy.
*/
open: MaybeAccessor;
/**
* Whether the menu is disabled.
* @default false
*/
disabled?: MaybeAccessor;
/**
* Whether the menu is modal (top-level only; ignored for submenus).
* @default true
*/
modal?: MaybeAccessor;
/**
* Called via `runWithOwner(null, ...)` so consumer signal writes don't
* trigger SIGNAL_WRITE_IN_OWNED_SCOPE.
*/
onOpenChange?: (open: boolean, details: MenuRootChangeEventDetails) => void;
}
export interface MenuApi {
/** Reactive accessor for the current open state. */
open: Accessor;
/** Whether the menu is disabled. */
disabled: Accessor;
/** Whether the menu is in modal mode. */
modal: Accessor;
/** Keyboard-highlighted item index (null = none). */
activeIndex: Accessor;
/** Current payload for handle-driven workflows. */
payload: Accessor;
/**
* Pure event-emitter — fires `onOpenChange` via `runWithOwner(null, ...)`.
* The consumer owns the signal write.
*/
setOpen: (next: boolean, details?: MenuRootChangeEventDetails) => void;
/** Update the highlighted item index. Internal coordination for nav hooks. */
setActiveIndex: (index: number | null) => void;
/** Update the active payload. Internal coordination for handle-driven flow. */
setPayload: (payload: Payload | undefined) => void;
/** Context provider — expose the api via `useMenu()`. */
Provider: (props: {
children: JSX.Element;
}) => JSX.Element;
}
/**
* Read the nearest {@link MenuApi}. Throws unless `optional` is true.
*/
export declare function useMenu(): MenuApi;
export declare function useMenu(optional: true): MenuApi | null;
/**
* Headless primitive for the Menu compound. Owns logical state — open,
* disabled, modal, active item index, and payload. DOM concerns (floating-ui,
* focus trap, portal, animation) live in ``.
*/
export declare function createMenu(options: CreateMenuOptions): MenuApi;
//# sourceMappingURL=create-menu.d.ts.map