/** What `onFocusOutside` receives: `focusin` is not cancelable, so the handler gets a cancelable stand-in carrying the original as its `detail`. */ export type FocusOutsideEvent = CustomEvent; /** Either flavour of outside interaction, as `onInteractOutside` sees it. */ export type InteractOutsideEvent = PointerEvent | FocusOutsideEvent; /** One open dismissible layer, as the stack knows it: only what counts as inside it. */ export interface DismissLayer { /** The layer's own elements, read fresh each time since a panel mounts and unmounts under the same layer. */ insideElements: () => Array; } /** Registers an open layer and returns its teardown; layers close out of order (a parent unmount takes its children), so the teardown removes by identity, not by position. */ export declare function pushDismissLayer(layer: DismissLayer): () => void; /** * Whether `target` sits inside a layer that opened within `layer`: a portalled * listbox or popover whose trigger lives in this panel. `contains()` cannot see * it, so an outside-interaction check must ask the stack as well. Transitive, * so a Select inside a Popover inside a Dialog still counts for the Dialog. */ export declare function nestedLayerContains(layer: DismissLayer, target: Node): boolean; /** The layer nothing else is open inside: push order cannot rank nested layers, because a framework's effects run child-first. */ export declare function topDismissLayer(candidates?: readonly DismissLayer[]): DismissLayer | undefined; /** The one layer an Escape belongs to: sibling non-modal layers can be open at once, so the layer holding the key's target answers, and the top layer only when none does. */ export declare function escapeLayer(target: Node | null): DismissLayer | undefined; /** * Runs one layer's share of a document-level Escape keydown: at most one layer * handles a given Escape, and `preventDefault()` comes after the consumer's * handler — never before, so a veto is read from the same event — and only when * this layer was the one that handled it. Preventing matters because the close * watcher of an ancestor native `` skips a canceled Escape, which is * what stops one press from closing both the top layer and the Dialog around it. * * Listen on the document, not the panel: a layer must answer Escape while focus * sits outside it (virtual focus, a portalled submenu), which a panel-level * listener never sees. * * @param event the document keydown * @param layer the layer asking whether the key is its own * @param handler the consumer's Escape handler, or `undefined` for a layer that leaves Escape to the platform (a native ``) * @returns whether this layer handled the key */ export declare function handleEscapeKeyDown(event: KeyboardEvent, layer: DismissLayer, handler: ((event: KeyboardEvent) => void) | undefined): boolean; /** The cancelable stand-in an auto-focus handler receives; there is no native event for "about to move focus". */ export type AutoFocusEvent = CustomEvent; /** Announces an automatic focus move as a cancelable event and reports whether it may go ahead. */ export declare function autoFocusEvent(type: 'open-auto-focus' | 'close-auto-focus', handler?: (event: AutoFocusEvent) => void): boolean; /** The cancelable stand-in for a `focusin` that landed outside the layer. */ export declare function focusOutsideEvent(event: FocusEvent): FocusOutsideEvent; /** Marks an overlay's open-time focus move so other layers don't read it as outside interaction; released in a microtask because `focus()` dispatches `focusin` synchronously. */ export declare function focusOnOpen(move: () => void): void; /** The node a `focusin` moved focus to, or `null` when it is not a move this layer may be dismissed by: another layer opening, or focus clearing to ``. */ export declare function focusOutsideTarget(event: FocusEvent): Node | null; /** Whether an outside-interaction target is the overlay's own trigger, including through the trigger's shadow root. */ export declare function triggerContains(trigger: Element | null | undefined, target: Node | null): boolean; /** * The native `` backdrop, normalised onto the same `PointerEvent` channel as every other outside pointer-down, or `null` when the press landed inside the panel. The backdrop is not an element: a pointer on it targets the dialog itself, which `contains()` would misread as inside. */ export declare function backdropPointerDown(event: MouseEvent, dialog: Element | null | undefined): PointerEvent | null;