import { CSSProperties } from 'react'; /** * Promote a Floating UI element into the browser **top layer** so it paints above a native modal * `` — but **only when the floating node is NOT already portalled into that dialog**. * * `StyledDialog` opens via `.showModal()`, which puts the dialog in the top layer. The top * layer sits above the entire normal stacking context, so a popover/menu/listbox portalled to * `document.body` is occluded by the dialog **no matter how high its `z-index`** (and is `inert` * while the modal is open). * * Two complementary fixes: * 1. **Portal into the open modal ``** (see {@link getOpenModalDialogAncestor}) — escapes * `inert` and paints inside the dialog's own top-layer entry via normal z-index. * 2. **Popover API** (`popover="manual"` + `showPopover()`) — only when portalling to `document.body` * (e.g. nested under another top-layer `StyledPopover`). Nested `showPopover()` *inside* a modal * dialog is unreliable on mobile Safari: it either no-ops (UA keeps * `[popover]:not(:popover-open){display:none!important}` → looks like it never opened) or stacks * the popover *under* the dialog. Use {@link shouldUsePopoverTopLayer} to gate (1) vs (2). * * Usage when body-portalled: spread {@link TOP_LAYER_PROPS}, put {@link TOP_LAYER_RESET_STYLE} before * `...floatingStyles`, `strategy: 'fixed'`, and pass `refs.setFloating` to {@link useTopLayerRef}. * Promoting on the ref callback (not a `useEffect`) runs the instant the node is connected. */ export declare const TOP_LAYER_PROPS: { readonly popover: "manual"; }; /** * Neutralises the UA popover box styles (`[popover]{ inset: 0; margin: auto }`) that would * otherwise fight Floating UI's `top`/`left`. Spread this BEFORE `...floatingStyles`. */ export declare const TOP_LAYER_RESET_STYLE: CSSProperties; /** * Find the nearest **open modal** `` ancestor of a reference node, or `undefined`. * * A native modal `` (`showModal()`) marks every node **outside its own subtree** as `inert` * — including a popover we promote into the top layer. An inert popover still *paints* (so it looks * fine, even on top), but it is skipped by hit-testing: pointer clicks fall through to the dialog * behind it and options can't be selected. Promoting to the top layer only fixes painting/z-order, * NOT inertness. The one place a popover is both unclipped *and* interactive is **inside the modal * dialog's own subtree** (descendant of the dialog → not inert; dialog is already fullscreen * `inset-0`, so in-dialog `position:fixed` + z-index clears the paper without a nested Popover API * entry). Returns `undefined` for the non-dialog case (and for non-modal containers like * `MinimizableDialog`, which are plain z-indexed `
`s), so the caller falls back to the default * body portal. */ export declare function getOpenModalDialogAncestor(node: unknown): HTMLElement | undefined; declare global { interface Window { rawWindow?: Window; __asmaOpenModalDialogRegistry__?: OpenModalDialogRegistry; } } interface OpenModalDialogRegistry { dialogs: HTMLDialogElement[]; listeners: Set<() => void>; } /** * Publish an open modal `` as the current top-layer occupant. Call right after * `showModal()`; the returned unregister must run before/as the dialog closes. `StyledDialog` wires * this from the same layout effect that opens the dialog. */ export declare function registerOpenModalDialog(dialog: HTMLDialogElement): () => void; /** * The modal `` currently at the top of the browser top layer, or `undefined` when no ui-core * modal is open. Stale entries (a dialog torn down without its cleanup running) are skipped rather * than trusted, so a missed unregister can never strand an overlay in a detached subtree. */ export declare function getTopmostOpenModalDialog(): HTMLDialogElement | undefined; /** * Reactive {@link getTopmostOpenModalDialog} — re-renders the caller when a modal `` opens or * closes. Use as the portal root for an **anchorless** overlay that must clear an open modal * (`SnackbarProvider`, `StyledSnackbar`); anchored overlays use {@link getOpenModalDialogAncestor}. */ export declare function useTopmostOpenModalDialog(): HTMLDialogElement | undefined; /** * `true` when the floating node should join the top layer via the Popover API. * `false` when it is (or will be) portalled into an open modal `` — see hook docs. */ export declare function shouldUsePopoverTopLayer(portalRoot: HTMLElement | undefined | null): boolean; type RefSetter = (node: HTMLElement | null) => void; /** * Returns a ref callback that wires the node into Floating UI (`setFloating`) and, when `enabled`, * promotes it to the top layer via the Popover API. Pass `enabled: false` inside a modal dialog * (see {@link shouldUsePopoverTopLayer}). Degrades to plain z-index if unsupported. */ export declare function useTopLayerRef(setFloating: RefSetter, enabled?: boolean): RefSetter; export {};