import type { Placement } from "@floating-ui/react"; import { type ReactNode, type RefCallback } from "react"; import type { MapApi } from "../core/types"; import type { AutoPanContext, AutoPanResult } from "./utils/autoPan"; export type UsePanelOptions = Readonly<{ /** Stable id used as the descriptor key in the panel store. */ id: string; /** * When true, the panel is registered (or upserted) on every render. * When false (or after unmount), the panel is removed from the store. * Toggle this instead of conditionally calling the hook. */ open: boolean; /** Lower number = higher priority. Default active in the Sheet carousel. */ priority?: number; /** Floating-mode placement preference. Default: "bottom". */ placement?: Placement; /** * Called on Sheet gesture/ESC dismiss (when this descriptor is the active * one in the carousel) or on floating-mode outside-press. The hook captures * the latest closure on every render, so consumers do not need to memoize. */ onDismiss?: () => void; /** * Accessible label for the close button rendered by the panel shell. * Pass `t("panel.close")` from the consuming library to keep it translated. * Defaults to `"Close"` when omitted. */ closeLabel?: string; /** * Accessible label for the panel dialog, announced by screen readers on open. * Pass `t("panel.label")` from the consuming library to keep it translated. */ "aria-label"?: string; /** * Where vertical overflow scrolls. Default `shell` keeps the Panel scroll slot * as `overflow-auto`; use `internal` when panel content owns its own scroll region. */ contentScroll?: "shell" | "internal"; /** * Optional resolver for auto-panning the map when the panel first commits * in anchored mode. Called once per open-cycle with an {@link AutoPanContext} * describing the panel's position relative to the map container. Return an * `{ x, y }` pixel offset to pan by, or `null` to skip panning. * * Use {@link defaultAutoPanResolver} for the standard behavior (pan minimum * to clear clipping with 12 px padding): * * ```tsx * import { defaultAutoPanResolver } from "@trackunit/react-map"; * * usePanel(api, { * id: "my-panel", * open: isOpen, * resolveAutoPan: defaultAutoPanResolver, * children: , * }); * ``` * * Omit to opt out of auto-panning entirely. */ resolveAutoPan?: (ctx: AutoPanContext) => AutoPanResult; /** * Panel content. Identity may change every render; the hook upserts the * descriptor in place so the orchestrator simply re-renders the existing * slot for this id without remounting Floating UI or the Sheet. */ children: ReactNode; }>; /** * Registers a panel for the given map and returns a callback ref that the * consumer must spread on the anchor element (typically ``). * * The orchestrator owned by `createMapComponent` decides whether to render * the panel as a Sheet (narrow containers) or a floating element anchored * to the marker (wide containers). * * The returned ref callback identity is stable across re-renders; consumers * can pass it to multiple refs via `useMergeRefs` if needed. */ export declare const usePanel: (api: MapApi, options: UsePanelOptions) => RefCallback;