import type { JSX } from "@solidjs/web"; import type { MutableRef } from "../types.js"; /** * Upward-flowing state written by a `FloatingFocusManager` that is mounted * as a descendant of the portal. The portal uses this to decide whether to * render tab-guard sentinels and where to bounce focus on guard activation. */ export interface FloatingFocusManagerState { modal: boolean; open: boolean; onOpenChange(open: boolean, details: { reason?: string | undefined; event?: Event | undefined; }): void; domReference: Element | null; closeOnFocusOut: boolean; } /** * Context value shared with descendants of ``. */ export interface FloatingPortalContextValue { /** * The resolved portal wrapper `
`. `null` until the portal mounts. */ portalNode: HTMLElement | null; /** * Setter for focus-manager state — called by the focus-trap descendant * to advertise its modal/open state up to the portal so guards can be * rendered appropriately. */ setFocusManagerState(state: FloatingFocusManagerState | null): void; /** * Ref to the outer-boundary `before` sentinel (the guard that sits * before the portal subtree in DOM order). */ beforeOutsideRef: MutableRef; /** * Ref to the outer-boundary `after` sentinel (the guard that sits * after the portal subtree in DOM order). */ afterOutsideRef: MutableRef; /** * Ref to the inner-boundary `before` sentinel — focus-trap wires the * first tabbable of the floating element after this. */ beforeInsideRef: MutableRef; /** * Ref to the inner-boundary `after` sentinel — focus-trap wires the * last tabbable of the floating element before this. */ afterInsideRef: MutableRef; /** * This portal's node in the logical portal ancestry chain (see * `isInsideNestedPortal`). Nested portals link to it as their parent. */ ancestryNode: PortalAncestryNode; } declare const FloatingPortalContext: import("solid-js").Context; /** * Read the nearest `FloatingPortalContext`. Returns `null` when used * outside a mounted ``. */ export declare function usePortalContext(): FloatingPortalContextValue | null; /** * Returns the resolved portal node (the wrapper `
`) of the nearest * ``. Returns `null` when used outside a mounted portal or * before the portal has committed. */ export declare function useFloatingPortalNode(): () => HTMLElement | null; /** * Logical portal ancestry — the Solid analogue of Base UI React's * `insideReactTree` latch. React marks presses via synthetic capture * handlers on the popup (`onClickCapture` etc. in `useDismiss`'s floating * bag), and those fire even for presses inside PORTALED descendants * because React portals propagate synthetic events through the component * tree. Solid events follow the DOM tree, so a press inside a nested * portaled popup (a Select popup inside a Dialog, say) never reaches the * dialog popup's handlers and would read as an outside press, dismissing * the ancestor overlay. * * Instead, every `` records its logical parent portal — * the nearest portal in the COMPONENT tree, which context preserves even * across DOM portals — and stamps its wrapper element with that chain. * Dismissal hooks then ask "is the press target inside a portal that is a * logical DESCENDANT of my own portal?" (`isInsideNestedPortal`), * recovering the logical-tree walk Base UI gets from React for free. */ export interface PortalAncestryNode { parent: PortalAncestryNode | null; } /** * Whether `target` sits inside a portal that is a logical (component-tree) * descendant of the portal hosting `ownElement`. Strict descendants only: * a press inside our own portal wrapper but not in a nested portal (e.g. * on the dialog's internal backdrop or viewport) is still an outside * press for the popup itself. */ export declare function isInsideNestedPortal(target: EventTarget | null, ownElement: Element | null): boolean; /** * Target the user can supply. Ports the React source's `container` shape * (element / ref / null / undefined) and adds: * * - a CSS selector string (resolved via `document.querySelector`); * - a zero-arg function returning any of the above. */ export type FloatingPortalTarget = HTMLElement | ShadowRoot | string | MutableRef | (() => HTMLElement | ShadowRoot | string | null | undefined) | null | undefined; export interface FloatingPortalProps { /** * Portal children. Mounted into the resolved target element (by default * `document.body`). */ children?: JSX.Element; /** * Parent element (or selector, ref, or thunk) to render the portal * wrapper into. Defaults to `document.body`. React's `container` name is * honored below as an alias. */ root?: FloatingPortalTarget; /** * Alias for `root`, matching the Base UI React source's prop name. * If both are supplied, `root` takes precedence. */ container?: FloatingPortalTarget; /** * Optional id. If supplied, the portal wrapper is attached inside an * element with this id under the resolved root. If no such element * exists, one is auto-created (and ref-counted across instances — the * last unmount removes the auto-created root). */ id?: string | undefined; /** * Override the automatic guard-rendering heuristic. When unset, guards * render whenever a non-modal focus-manager is mounted and open. */ renderGuards?: boolean | undefined; /** * Extra attributes / style forwarded onto the portal wrapper `
`. */ wrapperProps?: JSX.HTMLAttributes | undefined; } /** * Portals the floating element into the body (or a supplied target), * carrying CSP nonce and focus-guard plumbing for strict-CSP consumers and * `FloatingFocusManager` tab traversal. * * @see https://floating-ui.com/docs/FloatingPortal */ export declare function FloatingPortal(props: FloatingPortalProps): JSX.Element; export { FloatingPortalContext }; //# sourceMappingURL=floating-portal.d.ts.map