import { type Placement } from "@floating-ui/react"; import { ReactNode } from "react"; import type { MapApi } from "../core/types"; import "./Panel.css"; export type PanelContentScroll = "shell" | "internal"; export type PanelProps = Readonly<{ /** Anchor element. The panel positions itself next to this element. */ anchor: HTMLElement | null; /** Placement preference. Default: "bottom". */ placement?: Placement; /** Called when the panel is dismissed (Escape key or pointer-down outside). */ onDismiss?: () => void; /** * Accessible label for the close button. Consumers should pass a translated * string (e.g. `t("panel.close")`). Defaults to `"Close"`. */ closeLabel?: string; /** * Called exactly once when the panel first becomes visible (isCommitted * transitions from false to true). Does not re-fire on subsequent Floating * UI recomputes. Fires again on the next open-cycle (anchor null → non-null). * * @param panelRect Bounding rect of the floating panel element. * @param anchorRect Bounding rect of the anchor element. * @param placement Resolved Floating UI placement (after flip). * @param panelScrollHeight Natural content height of the inner scroll div — * greater than `panelRect.height` when content is scroll-constrained. */ onCommit?: (panelRect: DOMRect, anchorRect: DOMRect, placement: Placement, panelScrollHeight: number) => void; /** * Map container element. Used as the shift boundary so panels cannot bleed * outside the map viewport. Falls back to clipping ancestors when null. */ containerEl?: HTMLElement | null; /** * Map event source for repositioning during pan/zoom. When provided, the panel * updates on `moveend` and runs a lightweight rAF loop only while the map is * moving — avoiding perpetual `autoUpdate({ animationFrame: true })`. */ mapMoveSource?: Pick; /** Accessible label for the panel dialog, announced by screen readers on open. */ "aria-label"?: string; /** * Where vertical overflow scrolls. Default `shell` keeps `overflow-auto` on the * scroll slot; `internal` uses `overflow-hidden` so panel content owns scroll. */ contentScroll?: PanelContentScroll; children: ReactNode; }>; /** * Renders a marker info panel positioned next to its anchor with Floating UI. * * Middleware chain: `offset(8) → flip() → shift(8) → hide` * * Animation state is driven by the `data-panel` attribute: * "" — element is in DOM (for Floating UI to measure) but hidden via * CSS `visibility: hidden` so the pre-commit translate(0,0) * position is never visible. * "open" — appears instantly once placement is committed (no enter * animation — see docs/adr/0027-instant-panel-first-paint.md). * "closing" — fades out during the EXIT_DURATION_MS window before unmount. * * @internal */ export declare const Panel: { ({ anchor, placement, onDismiss, closeLabel, onCommit, containerEl, mapMoveSource, "aria-label": ariaLabel, contentScroll, children, }: PanelProps): import("react/jsx-runtime").JSX.Element | null; displayName: string; };