import type { GeoJsonBbox } from "@trackunit/geo-json-utils"; import type { MapFocus } from "./mapFocus"; type Position = readonly [number, number, ...Array]; export type UseLabelPlacementParams = Readonly<{ /** When false the hook returns a stable empty set and clears incumbency memory. */ enabled: boolean; /** Candidate markers; only those matching a `focus` tier are label-eligible. */ items: ReadonlyArray; /** Stable id accessor — pass a referentially stable function (module const or `useCallback`). */ getId: (item: TAsset) => string; /** Stable position accessor — pass a referentially stable function. */ getPosition: (item: TAsset) => Position; /** Priority tiers (label order); `focus.id` also keys the incumbency memory. */ focus: MapFocus; /** Current camera view box; candidates outside it are skipped. `null` disables clipping and converts the footprint at the equator. */ bounds: Readonly | null; /** Current camera zoom; drives the px→geo footprint scale. */ zoom: number; /** Spacing added around every label footprint — the density dial. */ paddingPx: number; /** Maximum number of labels to place (DOM-node ceiling). */ ceiling: number; }>; /** * Viewport-driven label placement with hysteresis: returns the ids of the markers that should * render a label such that no two labels overlap, in priority order, bounded by `ceiling`. * * Stateful wrapper around the pure {@link buildLabelPlacement} — feeds the previous result back * as `previousIds` so labels that were shown stay shown across pan/zoom refetches (incumbents * that leave the view box drop via candidate clipping). Memory resets when `focus.id` changes, * not on viewport change. Returns the previous `Set` reference when content is unchanged so * downstream `useMemo`/callbacks stay stable. Same render-phase-setState pattern as * `useExpandedIds`. */ export declare const useLabelPlacement: ({ enabled, items, getId, getPosition, focus, bounds, zoom, paddingPx, ceiling, }: UseLabelPlacementParams) => ReadonlySet; export {};