import type { JSX } from "@solidjs/web";
/**
* `createContextMenu` — headless primitive for the ContextMenu compound.
*
* ContextMenu is a thin façade over `
` that:
* - Owns an `anchor` signal (virtual element at the right-click point).
* - Owns the open state per Base UI's controlled/uncontrolled contract:
* the gesture (right-click / long-press) writes the internal signal,
* seeded once from `defaultOpen`; a defined `open` option wins.
* - Exposes `setAnchor` + `setOpen` so `` can update
* both atomically on contextmenu / pointerdown events.
*
* Gesture capture (contextmenu event, long-press timer, move threshold)
* and DOM concerns stay in `` / ``.
*
* Why a separate primitive instead of reusing `createMenu` directly?
* ContextMenu needs the `anchor` state and the gesture-driven internal open
* signal. `createMenu` owns `open` as a pure pass-through, but ContextMenu
* must manage its own open signal that the trigger writes imperatively —
* that asymmetry warrants a dedicated primitive rather than composing
* createMenu with extra options.
*/
import { type Accessor } from "solid-js";
import { type MaybeAccessor } from "../internals/maybe-accessor.js";
import type { MenuRootChangeEventDetails, MenuRootChangeEventReason } from "../menu/root/menu-root-context.js";
import type { ContextMenuAnchor } from "./root/context-menu-root-context.js";
export type ContextMenuChangeReason = MenuRootChangeEventReason;
export interface CreateContextMenuOptions {
/**
* Controlled open state. While its resolved value is not `undefined`
* the consumer owns the state — pair with `onOpenChange`. When
* omitted, the gesture-driven internal signal (seeded from
* {@link defaultOpen}) backs the state.
*/
open?: MaybeAccessor;
/**
* Initial open state when uncontrolled. Read once at creation.
* @default false
*/
defaultOpen?: MaybeAccessor;
/**
* Whether the menu is disabled.
* @default false
*/
disabled?: 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 ContextMenuApi {
/** Reactive accessor for the effective open state. */
open: Accessor;
/** Whether the menu is disabled. */
disabled: Accessor;
/** Virtual anchor element — updated by the trigger on each gesture. */
anchor: Accessor;
/**
* Update the anchor position. Called by `` when the
* contextmenu / long-press gesture fires.
*/
setAnchor: (anchor: ContextMenuAnchor) => void;
/**
* Fires `onOpenChange` via `runWithOwner(null, ...)`, honors
* `details.cancel()`, then writes the internal gesture-driven open
* signal so uncontrolled consumers see the change (the write is inert
* while a controlled `open` option is provided).
*/
setOpen: (next: boolean, details?: MenuRootChangeEventDetails) => void;
/** Context provider — expose the api via `useContextMenu()`. */
Provider: (props: {
children: JSX.Element;
}) => JSX.Element;
}
/**
* Read the nearest {@link ContextMenuApi}. Throws unless `optional` is true.
*/
export declare function useContextMenu(): ContextMenuApi;
export declare function useContextMenu(optional: true): ContextMenuApi | null;
/**
* Headless primitive for the ContextMenu compound. Owns logical state — open,
* disabled, anchor. Gesture capture and DOM concerns live in
* `` and ``.
*/
export declare function createContextMenu(options?: CreateContextMenuOptions): ContextMenuApi;
//# sourceMappingURL=create-context-menu.d.ts.map