import type { Dialog } from "@base-ui/react/dialog"; /** * True while at least one modal dialog or popover is open. Read synchronously * by the keyboard shortcut registry to suppress lower-layer page shortcuts so * an open overlay does not hijack keystrokes (e.g. native Ctrl+F find). */ export declare function isOverlayScopeActive(): boolean; export interface OverlayScope { /** Call exactly once when the surface closes. */ release: () => void; /** Whether this surface is the overlay opened LAST, and so the one a * dismissal keystroke belongs to. */ isTopmost: () => boolean; } /** * Imperatively marks an overlay surface as open. Prefer the `useOverlayScope` * hook in React components — this is the testable core. */ export declare function pushOverlayScope(): OverlayScope; /** * Marks an overlay surface as open while `active` is true, and reports whether * it is the topmost one. Call this from overlay primitives (Dialog, Popover, * etc.), not from individual call sites. * * The returned reader is stable and answers `false` while the surface is * closed, so a dismissal handler can consult it unconditionally. */ export declare function useOverlayScope(active: boolean): { isTopmost: () => boolean; }; /** * THE `onOpenChange` EVERY KIT OVERLAY PASSES BASE UI — its dismissal defaults * in one place, and the surface registered as open for as long as it is. * * It refuses one thing: an Escape addressed to a surface ABOVE this one. Base * UI listens on the document per open dialog and scopes the key by React-tree * nesting, so a confirm mounted in its own root, or written as a sibling, * closes the record behind it as well. `isTopmost` is the only reading of * "which overlay is the keystroke for" that spans React roots. * * DECLINING THE KEY IS NOT KEEPING IT. Base UI stops an Escape's propagation * unless the refusal says otherwise, so a surface that only cancelled swallowed * the keystroke on its way to the layer it was FOR: a date picker opened inside * a dialog is a popover whose own listener sits on the document, the dialog's * handler ran first, cancelled, and stopped the key there — two presses, the * calendar still open over the commit, and the dialog still open behind it. * Allowing propagation is what makes "Escape closes the topmost layer" hold for * a layer whose listener is further out than the one that declined. * * Backdrop dismissal is refused at the Root instead (`disablePointerDismissal`), * because it is a fact about the whole surface rather than about one event. */ export declare function useOverlayOpenChange(open: boolean, onOpenChange: (open: boolean) => void): (next: boolean, details: Dialog.Root.ChangeEventDetails) => void;