/** * A surface-scoped count of overlays (⋯ menus, popovers) currently open INSIDE * that surface, so the surface can suspend behaviour that would move the ground * under them. * * ## Why * * An open menu stays anchored to its trigger. In a chat thread the ground moves * on its own: a streaming reply grows the transcript and the auto-scroll follows * the bottom, carrying the trigger — and its menu — upward until the menu is * pinned to an off-screen anchor at the panel edge, visually detached from the * card it belongs to. * * The honest fix is not to dismiss the menu on every scroll event (that breaks * touch, where momentum scrolling fires constantly) but to stop pulling the * ground: while an overlay is open the thread stops chasing the bottom, exactly * how ChatGPT/Claude stop chasing once you interact with the transcript. When * the overlay closes, the thread catches up if it was at the bottom before. * * ## Wiring * * Surface: wrap the region in ``. * Overlay: call `useReportOverlayOpen(open)`. No provider → the hook is inert, * so overlays outside such a surface behave exactly as before. */ import * as React from 'react'; export interface OverlayOpenRegistry { /** Register one open overlay; call the returned fn to release it. */ acquire: () => () => void; } export declare const OverlayOpenRegistryContext: React.Context; /** Read the surrounding registry (or `null` when there is no provider). */ export declare function useOverlayOpenRegistry(): OverlayOpenRegistry | null; /** * Report this overlay's open state to the surrounding surface. Safe to call * unconditionally — with no provider it does nothing. */ export declare function useReportOverlayOpen(open: boolean): void; export interface OverlayOpenRegistryProviderProps { /** Fires on 0 → 1 and 1 → 0 transitions only, not on every acquire. */ onOpenChange?: (hasOpenOverlay: boolean) => void; children: React.ReactNode; } /** * Owns the count for one surface. The context value is referentially stable, so * mounting this provider does not re-render overlays when the count changes — * only the surface's own `onOpenChange` callback fires. */ export declare function OverlayOpenRegistryProvider({ onOpenChange, children, }: OverlayOpenRegistryProviderProps): React.JSX.Element; //# sourceMappingURL=overlay-open-registry.d.ts.map