@trackunit/react-map 0.0.4-alpha-9d327375fc1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/README.md +296 -0
  2. package/index.cjs.js +9851 -0
  3. package/index.d.ts +1 -0
  4. package/index.esm.js +9752 -0
  5. package/package.json +34 -0
  6. package/src/annotations/getDescriptorContentKey.d.ts +14 -0
  7. package/src/annotations/mapAnnotations.d.ts +76 -0
  8. package/src/annotations/useMapAnnotation.d.ts +16 -0
  9. package/src/annotations/useMapAnnotations.d.ts +17 -0
  10. package/src/appearance/AppearancePreview.d.ts +27 -0
  11. package/src/appearance/AppearancePreviewGrid.d.ts +29 -0
  12. package/src/appearance/appearanceTypes.d.ts +84 -0
  13. package/src/appearance/useMapAppearanceControls.d.ts +29 -0
  14. package/src/clusters/ClusterMarker.d.ts +41 -0
  15. package/src/clusters/ClusterStick.d.ts +97 -0
  16. package/src/clusters/formatClusterCount.d.ts +11 -0
  17. package/src/clusters/stories/ClusterMarkerCompactFormatsDemo.d.ts +7 -0
  18. package/src/clusters/stories/ClusterMarkerCountOnlyDemo.d.ts +7 -0
  19. package/src/clusters/stories/ClusterMarkerDefaultDemo.d.ts +12 -0
  20. package/src/clusters/stories/ClusterMarkerPlaygroundDemo.d.ts +10 -0
  21. package/src/clusters/stories/ClusterMarkerStateDemo.d.ts +9 -0
  22. package/src/clusters/stories/ClusterMarkerWithSegmentsDemo.d.ts +7 -0
  23. package/src/clusters/stories/ClusterMarkerWithSticksDemo.d.ts +10 -0
  24. package/src/clusters/useClusterCountFormat.d.ts +19 -0
  25. package/src/controls/AnnotationRenderer.d.ts +17 -0
  26. package/src/controls/AnnotationStack.d.ts +21 -0
  27. package/src/controls/ControlRenderer.d.ts +20 -0
  28. package/src/controls/Controls.d.ts +15 -0
  29. package/src/controls/annotationButtonClasses.d.ts +13 -0
  30. package/src/controls/collapseControls.d.ts +37 -0
  31. package/src/controls/defineControlStack.d.ts +10 -0
  32. package/src/controls/deriveResponsiveMode.d.ts +19 -0
  33. package/src/controls/longitudeToGlobeIcon.d.ts +3 -0
  34. package/src/controls/renderers/boolean/BooleanButton.d.ts +16 -0
  35. package/src/controls/renderers/boolean/MenuBooleanItem.d.ts +20 -0
  36. package/src/controls/renderers/boolean/MenuCheckbox.d.ts +14 -0
  37. package/src/controls/renderers/boolean/MenuToggle.d.ts +14 -0
  38. package/src/controls/renderers/button/Button.d.ts +14 -0
  39. package/src/controls/renderers/button/MenuButton.d.ts +16 -0
  40. package/src/controls/renderers/custom/Custom.d.ts +22 -0
  41. package/src/controls/renderers/menu/Menu.d.ts +23 -0
  42. package/src/controls/renderers/menu/Modal.d.ts +21 -0
  43. package/src/controls/renderers/menu/SectionHeader.d.ts +14 -0
  44. package/src/controls/renderers/menu/Separator.d.ts +11 -0
  45. package/src/controls/renderers/radio-group/MenuRadioGroup.d.ts +15 -0
  46. package/src/controls/renderers/radio-group/RadioGroup.d.ts +19 -0
  47. package/src/controls/renderers/radio-group/RadioGroupField.d.ts +17 -0
  48. package/src/controls/renderers/search/MenuSearch.d.ts +15 -0
  49. package/src/controls/renderers/search/Search.d.ts +14 -0
  50. package/src/controls/renderers/select/MenuSelect.d.ts +15 -0
  51. package/src/controls/renderers/select/Select.d.ts +14 -0
  52. package/src/controls/renderers/stepper/MenuStepper.d.ts +17 -0
  53. package/src/controls/renderers/stepper/Stepper.d.ts +18 -0
  54. package/src/controls/renderers/toggle-group/MenuToggleGroup.d.ts +17 -0
  55. package/src/controls/renderers/toggle-group/ToggleGroup.d.ts +15 -0
  56. package/src/controls/renderers/toggle-group/ToggleGroupField.d.ts +19 -0
  57. package/src/controls/renderingRules.d.ts +26 -0
  58. package/src/controls/types.d.ts +395 -0
  59. package/src/controls/useAnimatedPresence.d.ts +15 -0
  60. package/src/controls/useAnnotationPresence.d.ts +16 -0
  61. package/src/controls/useControlStack.d.ts +21 -0
  62. package/src/controls/useControlsConfig.d.ts +27 -0
  63. package/src/controls/usePopoverPlacement.d.ts +33 -0
  64. package/src/core/LoadingIndicatorPill.d.ts +9 -0
  65. package/src/core/MapLoadingState.d.ts +17 -0
  66. package/src/core/SafeAreaLayoutContext.d.ts +5 -0
  67. package/src/core/__testHelpers.d.ts +23 -0
  68. package/src/core/createMapComponent.d.ts +32 -0
  69. package/src/core/loadingIndicator.d.ts +21 -0
  70. package/src/core/padWithInsets.d.ts +5 -0
  71. package/src/core/types.d.ts +208 -0
  72. package/src/core/useCameraIdle.d.ts +2 -0
  73. package/src/core/useCameraState.d.ts +3 -0
  74. package/src/core/useMap.d.ts +57 -0
  75. package/src/core/useMapAdapterState.d.ts +14 -0
  76. package/src/core/useMapKeyboardNavigation.d.ts +38 -0
  77. package/src/core/usePreviewMap.d.ts +43 -0
  78. package/src/index.d.ts +69 -0
  79. package/src/interactions/interactionReducer.d.ts +31 -0
  80. package/src/layers/Layers.d.ts +32 -0
  81. package/src/layers/__testHelpers.d.ts +24 -0
  82. package/src/layers/buildExpandedIds.d.ts +17 -0
  83. package/src/layers/image-overlay/useImageOverlay.d.ts +39 -0
  84. package/src/layers/internal/MapLayerContext.d.ts +24 -0
  85. package/src/layers/internal/adaptiveMarkerResolution.d.ts +33 -0
  86. package/src/layers/internal/computeBounds.d.ts +34 -0
  87. package/src/layers/internal/countFeaturesInViewport.d.ts +14 -0
  88. package/src/layers/internal/createLazyGetter.d.ts +16 -0
  89. package/src/layers/internal/layerHelpers.d.ts +18 -0
  90. package/src/layers/internal/markerPortalZIndex.d.ts +17 -0
  91. package/src/layers/internal/useDblClickFit.d.ts +13 -0
  92. package/src/layers/internal/useEntityInteraction.d.ts +21 -0
  93. package/src/layers/internal/useFitFeatureBounds.d.ts +19 -0
  94. package/src/layers/internal/useLayerHandleSync.d.ts +18 -0
  95. package/src/layers/internal/useLayerReady.d.ts +25 -0
  96. package/src/layers/internal/useMarkerMountBridge.d.ts +41 -0
  97. package/src/layers/internal/useViewportContext.d.ts +34 -0
  98. package/src/layers/mapFocus.d.ts +29 -0
  99. package/src/layers/routes/useRoute.d.ts +39 -0
  100. package/src/layers/shared/measureLabelWidth.d.ts +11 -0
  101. package/src/layers/types.d.ts +131 -0
  102. package/src/layers/useExpandedIds.d.ts +20 -0
  103. package/src/layers/useFitToContent.d.ts +57 -0
  104. package/src/layers/useLayers.d.ts +58 -0
  105. package/src/layers/useMarkers/adaptiveHelpers.d.ts +156 -0
  106. package/src/layers/useMarkers/resolveServerClusters.d.ts +26 -0
  107. package/src/layers/useMarkers/useAdaptiveMarkerHelpers.d.ts +38 -0
  108. package/src/layers/useMarkers/useMarkers.d.ts +127 -0
  109. package/src/layers/useShapes/InteractiveDecoration.d.ts +23 -0
  110. package/src/layers/useShapes/MultiGeometryPlusBadge.d.ts +17 -0
  111. package/src/layers/useShapes/MultiPartBadge.d.ts +11 -0
  112. package/src/layers/useShapes/ShapeAnnotationLabel.d.ts +30 -0
  113. package/src/layers/useShapes/ShapeIcon.d.ts +21 -0
  114. package/src/layers/useShapes/ShapeLabelPill.d.ts +25 -0
  115. package/src/layers/useShapes/buildShapeLabelResolutionContext.d.ts +23 -0
  116. package/src/layers/useShapes/decorationFactories.d.ts +47 -0
  117. package/src/layers/useShapes/edge/ShapeEdgeLabel.d.ts +13 -0
  118. package/src/layers/useShapes/edge/computeEdgeAutoPlacement.d.ts +69 -0
  119. package/src/layers/useShapes/edge/computeEdgeProperties.d.ts +21 -0
  120. package/src/layers/useShapes/edge/edgeInsetsForFeature.d.ts +27 -0
  121. package/src/layers/useShapes/edge/edgeReservations.d.ts +36 -0
  122. package/src/layers/useShapes/edge/findBestEdgePosition.d.ts +247 -0
  123. package/src/layers/useShapes/extractMultiParts.d.ts +25 -0
  124. package/src/layers/useShapes/findBestVisibleVertex.d.ts +18 -0
  125. package/src/layers/useShapes/multiPartDecorations.d.ts +19 -0
  126. package/src/layers/useShapes/shapeDecorations.d.ts +154 -0
  127. package/src/layers/useShapes/shapeFeatureBuilders.d.ts +25 -0
  128. package/src/layers/useShapes/shapeLabelPolicy.d.ts +42 -0
  129. package/src/layers/useShapes/shapeLabelResolution.d.ts +45 -0
  130. package/src/layers/useShapes/shapeSyntheticMarkerRender.d.ts +16 -0
  131. package/src/layers/useShapes/useShapeDecorations.d.ts +56 -0
  132. package/src/layers/useShapes/useShapeLabelHelpers.d.ts +29 -0
  133. package/src/layers/useShapes/useShapes.d.ts +50 -0
  134. package/src/markers/MapMarker.d.ts +115 -0
  135. package/src/markers/MapMarkerIcon.d.ts +21 -0
  136. package/src/markers/animation/applyStickFrame.d.ts +15 -0
  137. package/src/markers/animation/spring.d.ts +45 -0
  138. package/src/markers/animation/stickFrame.d.ts +82 -0
  139. package/src/markers/animation/usePillBackgroundPaint.d.ts +15 -0
  140. package/src/markers/animation/useStickAnimation.d.ts +21 -0
  141. package/src/markers/animation/useStickTween.d.ts +28 -0
  142. package/src/markers/geometry/stickPositioning.d.ts +69 -0
  143. package/src/markers/geometry/useDirectionIndicator.d.ts +8 -0
  144. package/src/markers/internal/MapMarkerStickSurface.d.ts +47 -0
  145. package/src/markers/model/mapMarkerDomPortalStacking.d.ts +22 -0
  146. package/src/markers/model/markerDomTypes.d.ts +68 -0
  147. package/src/markers/model/markerResolvers.d.ts +34 -0
  148. package/src/markers/model/markerSizeMap.d.ts +82 -0
  149. package/src/markers/model/markerTuningParams.d.ts +60 -0
  150. package/src/markers/model/useMarkerStateResolvers.d.ts +25 -0
  151. package/src/markers/shared/MarkerAnimatedSurface.d.ts +20 -0
  152. package/src/markers/shared/MarkerDiscContent.d.ts +11 -0
  153. package/src/markers/shared/mapMarkerVariants.d.ts +35 -0
  154. package/src/markers/shared/markerColors.d.ts +55 -0
  155. package/src/markers/shared/useMarkerColors.d.ts +23 -0
  156. package/src/markers/stories/demoes/AnimationCircleVsPillDemo.d.ts +7 -0
  157. package/src/markers/stories/demoes/CircleIconGuidanceDemo.d.ts +2 -0
  158. package/src/markers/stories/demoes/DefaultDemo.d.ts +14 -0
  159. package/src/markers/stories/demoes/DirectionBehaviorDemo.d.ts +2 -0
  160. package/src/markers/stories/demoes/PillLabelLengthsDemo.d.ts +2 -0
  161. package/src/markers/stories/demoes/StatesDemo.d.ts +7 -0
  162. package/src/markers/stories/demoes/StickModeDemo.d.ts +2 -0
  163. package/src/markers/stories/demoes/StickModePlaygroundDemo.d.ts +10 -0
  164. package/src/markers/stories/helpers/AbsoluteGridPicker.d.ts +17 -0
  165. package/src/markers/stories/helpers/InlineLabel.d.ts +4 -0
  166. package/src/markers/stories/helpers/InlineSlider.d.ts +11 -0
  167. package/src/markers/stories/helpers/LabeledMarker.d.ts +7 -0
  168. package/src/markers/stories/helpers/MarkerRow.d.ts +4 -0
  169. package/src/markers/stories/helpers/SectionHeader.d.ts +4 -0
  170. package/src/markers/stories/helpers/StatesMarkerCell.d.ts +15 -0
  171. package/src/markers/stories/helpers/ThemedPreview.d.ts +10 -0
  172. package/src/markers/stories/helpers/mapMarkerStoryConstants.d.ts +4 -0
  173. package/src/panel/Panel.d.ts +60 -0
  174. package/src/panel/PanelOrchestrator.d.ts +24 -0
  175. package/src/panel/preload/preloadInitiators.d.ts +44 -0
  176. package/src/panel/preload/useHoverPreloadInitiator.d.ts +8 -0
  177. package/src/panel/preload/usePanelPreload.d.ts +46 -0
  178. package/src/panel/preload/useProximityPreloadInitiator.d.ts +13 -0
  179. package/src/panel/store/panels.d.ts +76 -0
  180. package/src/panel/storyHelpers.d.ts +9 -0
  181. package/src/panel/usePanel.d.ts +81 -0
  182. package/src/panel/utils/autoPan.d.ts +78 -0
  183. package/src/panel/utils/panelShellConstants.d.ts +8 -0
  184. package/src/panel/utils/useAutoPanResolver.d.ts +23 -0
  185. package/src/panel/utils/useWheelForwarding.d.ts +18 -0
  186. package/src/stories/InteractionDisplay.d.ts +9 -0
  187. package/src/stories/PositionDisplay.d.ts +9 -0
  188. package/src/stories/_storyCoordUtils.d.ts +8 -0
  189. package/src/testing/mockMapApi.d.ts +29 -0
  190. package/src/translation.d.ts +30 -0
  191. package/translation.cjs.js +30 -0
  192. package/translation.cjs10.js +30 -0
  193. package/translation.cjs11.js +30 -0
  194. package/translation.cjs12.js +30 -0
  195. package/translation.cjs13.js +30 -0
  196. package/translation.cjs14.js +30 -0
  197. package/translation.cjs15.js +30 -0
  198. package/translation.cjs16.js +30 -0
  199. package/translation.cjs17.js +30 -0
  200. package/translation.cjs2.js +30 -0
  201. package/translation.cjs3.js +30 -0
  202. package/translation.cjs4.js +30 -0
  203. package/translation.cjs5.js +30 -0
  204. package/translation.cjs6.js +30 -0
  205. package/translation.cjs7.js +30 -0
  206. package/translation.cjs8.js +30 -0
  207. package/translation.cjs9.js +30 -0
  208. package/translation.esm.js +28 -0
  209. package/translation.esm10.js +28 -0
  210. package/translation.esm11.js +28 -0
  211. package/translation.esm12.js +28 -0
  212. package/translation.esm13.js +28 -0
  213. package/translation.esm14.js +28 -0
  214. package/translation.esm15.js +28 -0
  215. package/translation.esm16.js +28 -0
  216. package/translation.esm17.js +28 -0
  217. package/translation.esm2.js +28 -0
  218. package/translation.esm3.js +28 -0
  219. package/translation.esm4.js +28 -0
  220. package/translation.esm5.js +28 -0
  221. package/translation.esm6.js +28 -0
  222. package/translation.esm7.js +28 -0
  223. package/translation.esm8.js +28 -0
  224. package/translation.esm9.js +28 -0
@@ -0,0 +1,208 @@
1
+ export { DEFAULT_MAP_APPEARANCE, INITIAL_CAMERA_STATE, INITIAL_MAP_STATE, INITIAL_MAP_STATUS, mapAppearanceSchema, mapThemeSchema, mapTypeSchema, } from "@trackunit/react-map-adapter-shared";
2
+ export type { CameraState, ContainerRefHolder, FitBoundsOptions, GeoJsonBbox, GeoJsonPosition, InitialViewport, MapAppearance, MapComponentProps, MapEvent, MapEventHandler, MapEventOfType, MapState, MapStatus, MapTheme, MapType, StoredEventHandler, } from "@trackunit/react-map-adapter-shared";
3
+ import type { AdapterConfig, CameraState, ContainerRefHolder, FitBoundsOptions, GeoJsonBbox, GeoJsonPosition, MapComponentProps, MapEvent, MapEventHandler, MapStatus, MapTheme, MapType } from "@trackunit/react-map-adapter-shared";
4
+ import type { ComponentType } from "react";
5
+ import type { MapAnnotationStore } from "../annotations/mapAnnotations";
6
+ import type { ControlsConfig, UseMapOptions } from "../controls/types";
7
+ import type { PanelStore } from "../panel/store/panels";
8
+ import type { MapLoadingIndicatorStore } from "./loadingIndicator";
9
+ /**
10
+ * Map actions - methods to control the map
11
+ * All action references are stable across re-renders
12
+ */
13
+ export type MapActions = Readonly<{
14
+ /**
15
+ * Set the map center
16
+ *
17
+ * @param center - Position as [longitude, latitude]
18
+ * @returns Promise that resolves when the map finishes moving
19
+ */
20
+ setCenter: (center: GeoJsonPosition) => Promise<void>;
21
+ /**
22
+ * Set the zoom level (absolute)
23
+ *
24
+ * @param zoom - Zoom level (0-22)
25
+ * @returns Promise that resolves when the map finishes zooming
26
+ */
27
+ setZoom: (zoom: number) => Promise<void>;
28
+ /**
29
+ * Adjust zoom by delta (relative)
30
+ *
31
+ * @param delta - Amount to adjust zoom (positive = zoom in, negative = zoom out)
32
+ * @returns Promise that resolves when the map finishes zooming
33
+ */
34
+ zoomBy: (delta: number) => Promise<void>;
35
+ /**
36
+ * Fit the map to the given bounds
37
+ *
38
+ * @param bounds - Bounding box as [minLon, minLat, maxLon, maxLat]
39
+ * @param options - Optional configuration for the fit operation
40
+ * @param options.padding - Padding in pixels around the bounds. Defaults to 0 if omitted.
41
+ * @param options.maxZoom - Maximum zoom level after fitting
42
+ * @param options.animate - Whether to animate the transition
43
+ * @returns Promise that resolves when the map finishes fitting
44
+ */
45
+ fitBounds: (bounds: GeoJsonBbox, options?: FitBoundsOptions) => Promise<void>;
46
+ /**
47
+ * Pan the map to the given center with animation
48
+ *
49
+ * @param center - Position as [longitude, latitude]
50
+ * @returns Promise that resolves when the map finishes panning
51
+ */
52
+ panTo: (center: GeoJsonPosition) => Promise<void>;
53
+ /**
54
+ * Pan the map by pixel offsets (for keyboard navigation and UI-driven panning).
55
+ * Unlike geographic methods (setCenter, panTo), this operates in screen space.
56
+ *
57
+ * @param deltaX - Horizontal offset in pixels (positive = right)
58
+ * @param deltaY - Vertical offset in pixels (positive = down)
59
+ * @returns Promise that resolves when the map finishes panning
60
+ */
61
+ panBy: (deltaX: number, deltaY: number) => Promise<void>;
62
+ /**
63
+ * Set the map type (base layer)
64
+ *
65
+ * @param type - Map type ("roadmap", "satellite", or "hybrid")
66
+ * @returns Promise that resolves when the map type is set
67
+ */
68
+ setMapType: (type: MapType) => Promise<void>;
69
+ /**
70
+ * Set the map theme (visual appearance)
71
+ *
72
+ * @param theme - Map theme ("light" or "dark")
73
+ * @returns Promise that resolves when the theme is applied
74
+ */
75
+ setTheme: (theme: MapTheme) => Promise<void>;
76
+ /**
77
+ * Set whether road labels are shown over satellite/hybrid imagery
78
+ *
79
+ * @param showRoads - Whether to show road labels
80
+ * @returns Promise that resolves when the change is applied
81
+ */
82
+ setShowRoads: (showRoads: boolean) => Promise<void>;
83
+ }>;
84
+ /**
85
+ * The API object returned as the second element of the useMap tuple.
86
+ * Contains low-frequency map status, actions, event subscription, and controls
87
+ * configuration. All properties are readonly and action references are stable.
88
+ *
89
+ * `api.state` is the MapStatus channel. `api` identity is stable between camera
90
+ * events (pan/zoom), so components that only need status are not tied to viewport
91
+ * updates. To react to viewport changes, use `useCameraState(api)`.
92
+ */
93
+ export type MapApi = Readonly<{
94
+ /**
95
+ * MapStatus — lifecycle and appearance state.
96
+ * Changes on initialization, failure, theme/type changes, or tile-size updates.
97
+ * For viewport state (center, zoom, bounds, isIdle), use `useCameraState(api)`.
98
+ */
99
+ state: MapStatus;
100
+ /**
101
+ * Subscribe to camera state changes (center, zoom, bounds, isIdle).
102
+ * Stable reference across re-renders (only changes on adapter swap).
103
+ * Prefer `useCameraState(api)` from React components; this method is exposed
104
+ * for lower-level integration code.
105
+ */
106
+ subscribeCamera: (listener: () => void) => () => void;
107
+ /**
108
+ * Get the latest camera state snapshot.
109
+ * Stable reference across re-renders (only changes on adapter swap).
110
+ * Prefer `useCameraState(api)` when a React component should re-render on
111
+ * camera changes.
112
+ */
113
+ getCameraState: () => CameraState;
114
+ /**
115
+ * Map actions - stable references for controlling the map
116
+ */
117
+ actions: MapActions;
118
+ /**
119
+ * Subscribe to map events
120
+ *
121
+ * @param event - Event type to listen for
122
+ * @param handler - Handler function called when event occurs
123
+ * @returns Unsubscribe function
124
+ * @example
125
+ * ```tsx
126
+ * useEffect(() => {
127
+ * return api.on("click", (e) => {
128
+ * console.log("Clicked at:", e.position);
129
+ * });
130
+ * }, [api.on]);
131
+ * ```
132
+ */
133
+ on: <TEventType extends MapEvent["type"]>(event: TEventType, handler: MapEventHandler<TEventType>) => () => void;
134
+ /**
135
+ * Options passed to useMap for controls configuration.
136
+ * Used by the Controls component to build the controls config.
137
+ */
138
+ options?: UseMapOptions;
139
+ /**
140
+ * Stabilized adapter configuration used to create this map instance.
141
+ * Use `adapterConfig.derive(overrides)` to create variant configs
142
+ * for spawning sibling map instances (e.g., preview maps with different themes).
143
+ * Equivalent inline adapter factory calls do not replace this reference.
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * const darkPreview = api.adapterConfig.derive({ theme: "dark" });
148
+ * ```
149
+ */
150
+ adapterConfig: AdapterConfig;
151
+ /**
152
+ * Ref to the Map component's wrapper div.
153
+ * Can be used for fullscreen requests, portal targeting, or measuring the container.
154
+ * The ref is populated after the Map component mounts.
155
+ */
156
+ containerRef: ContainerRefHolder;
157
+ /**
158
+ * Annotation store for registering map-level labels and status content.
159
+ * Used by `useMapAnnotation` to register annotations and by `Controls`
160
+ * to subscribe and render them. Stable reference across re-renders.
161
+ */
162
+ annotations: MapAnnotationStore;
163
+ /**
164
+ * Loading indicator store. `useLayers` pushes its aggregated loading
165
+ * state here; the Map component subscribes and renders a spinner overlay.
166
+ * Stable reference across re-renders.
167
+ */
168
+ loadingIndicator: MapLoadingIndicatorStore;
169
+ /**
170
+ * Panel store for marker/layer info panels. Layers register panels via
171
+ * `usePanel`; the Map's internal `PanelOrchestrator` subscribes
172
+ * and renders them as a Sheet (narrow containers) or floating elements
173
+ * anchored to the marker (wide containers). Stable reference across
174
+ * re-renders.
175
+ */
176
+ panels: PanelStore;
177
+ /**
178
+ * Controls configuration - pure data describing what controls are enabled.
179
+ * Used by the Controls component to determine what to render.
180
+ *
181
+ * @deprecated Use `api.options` for `useMap` options, or pass `controlsConfig`
182
+ * directly to `<Controls />` for custom controls.
183
+ */
184
+ controlsConfig?: ControlsConfig;
185
+ }>;
186
+ /**
187
+ * Result returned by useMap hook as a tuple.
188
+ *
189
+ * First element is the Map component, second is the API object.
190
+ * This follows the idiomatic React pattern (like useState, useReducer).
191
+ *
192
+ * @example
193
+ * ```tsx
194
+ * const [Map, api] = useMap(googleMapsAdapter({ apiKey }));
195
+ *
196
+ * return (
197
+ * <Map>
198
+ * <Controls api={api} />
199
+ * </Map>
200
+ * );
201
+ * ```
202
+ */
203
+ export type UseMapReturn = readonly [
204
+ /** Map component to render - reference is stable across re-renders */
205
+ ComponentType<MapComponentProps>,
206
+ /** API object with status, actions, event subscriptions, and map stores */
207
+ MapApi
208
+ ];
@@ -0,0 +1,2 @@
1
+ import type { MapApi } from "./types";
2
+ export declare const useCameraIdle: (api: MapApi | undefined) => boolean;
@@ -0,0 +1,3 @@
1
+ import { type CameraState } from "@trackunit/react-map-adapter-shared";
2
+ import type { MapApi } from "./types";
3
+ export declare const useCameraState: (api: MapApi | undefined) => CameraState;
@@ -0,0 +1,57 @@
1
+ import { type AdapterConfig } from "@trackunit/react-map-adapter-shared";
2
+ import type { UseMapOptions } from "../controls/types";
3
+ import { type UseMapReturn } from "./types";
4
+ /**
5
+ * useMap hook - the main entry point for using the map
6
+ *
7
+ * Returns a tuple of [Map, api] where Map is the component to render
8
+ * and api contains map status, actions, event subscriptions, containerRef, and
9
+ * controls configuration. `api.state` is MapStatus only: use it for readiness,
10
+ * initialization failure, appearance, and tile size.
11
+ *
12
+ * Camera state (center, zoom, bounds, isIdle) is exposed through
13
+ * `useCameraState(api)` so components opt in to high-frequency viewport updates.
14
+ *
15
+ * All action functions and the Map component reference are stable across re-renders.
16
+ *
17
+ * @param adapterConfig - Adapter configuration from an adapter factory (e.g., googleMapsAdapter)
18
+ * @param options - Optional configuration for controls and other features
19
+ * @returns Tuple of [Map component, API object]
20
+ * @example Basic usage
21
+ * ```tsx
22
+ * import { useMap, Controls } from "@trackunit/react-map";
23
+ * import { googleMapsAdapter } from "@trackunit/react-map-adapter-google";
24
+ *
25
+ * const MyMap = () => {
26
+ * const [Map, api] = useMap(googleMapsAdapter({
27
+ * apiKey: "...",
28
+ * theme: "light",
29
+ * }));
30
+ *
31
+ * return (
32
+ * <Map>
33
+ * <Controls api={api} />
34
+ * </Map>
35
+ * );
36
+ * };
37
+ * ```
38
+ * @example Accessing camera state (center, zoom, bounds)
39
+ * Camera state (viewport) can update continuously during panning and zooming.
40
+ * Use `useCameraState` only from components that render or react to viewport changes:
41
+ * ```tsx
42
+ * import { useDebounce } from "@trackunit/react-components";
43
+ * import { useMap, useCameraState } from "@trackunit/react-map";
44
+ * import { googleMapsAdapter } from "@trackunit/react-map-adapter-google";
45
+ *
46
+ * const MyComponent = () => {
47
+ * const [Map, api] = useMap(googleMapsAdapter({ apiKey: "..." }));
48
+ * const { center, zoom, bounds } = useCameraState(api);
49
+ *
50
+ * // Debounce bounds for API calls (wait 200ms after map stops moving)
51
+ * const debouncedBounds = useDebounce(bounds, { delay: 200 });
52
+ *
53
+ * return <Map>...</Map>;
54
+ * };
55
+ * ```
56
+ */
57
+ export declare const useMap: <TConfig extends Record<string, unknown>>(adapterConfig: AdapterConfig<TConfig>, options?: UseMapOptions) => UseMapReturn;
@@ -0,0 +1,14 @@
1
+ import type { AdapterConfig, AdapterInstance } from "@trackunit/react-map-adapter-shared";
2
+ type MapAdapterState = Readonly<{
3
+ adapter: AdapterInstance;
4
+ renderConfig: AdapterConfig;
5
+ }>;
6
+ /**
7
+ * Manages adapter instance and render config as related state.
8
+ * Handles adapter switching when adapterConfig changes to a different provider,
9
+ * preserving viewport (center, zoom, bounds when available).
10
+ *
11
+ * @internal
12
+ */
13
+ export declare function useMapAdapterState(adapterConfig: AdapterConfig): MapAdapterState;
14
+ export {};
@@ -0,0 +1,38 @@
1
+ import type { RefObject } from "react";
2
+ import type { ContainerRefHolder } from "./types";
3
+ /**
4
+ * Narrow structural type for the keyboard navigation hook.
5
+ * Contains only the stable properties the hook actually reads:
6
+ * - `actions.panBy` and `actions.zoomBy` (stable — memoized on adapter)
7
+ * - `containerRef` (stable — created via useState)
8
+ *
9
+ * `MapApi` satisfies this type via structural subtyping, so consumers
10
+ * can pass `api` from `useMap()` directly without any assertion.
11
+ */
12
+ export type MapKeyboardNavigationApi = Readonly<{
13
+ actions: Readonly<{
14
+ panBy: (deltaX: number, deltaY: number) => Promise<void>;
15
+ zoomBy: (delta: number) => Promise<void>;
16
+ }>;
17
+ containerRef: ContainerRefHolder;
18
+ }>;
19
+ /**
20
+ * Opt-in keyboard navigation hook for map components.
21
+ * Provides consistent keyboard shortcuts:
22
+ * - Arrow keys: Pan the map in all directions
23
+ * - `=` key: Zoom in
24
+ * - `-` key: Zoom out
25
+ *
26
+ * **Usage:**
27
+ * ```tsx
28
+ * import { useMap, useMapKeyboardNavigation } from "@trackunit/react-map";
29
+ * import { googleMapsAdapter } from "@trackunit/react-map-adapter-google";
30
+ *
31
+ * const [Map, api] = useMap(googleMapsAdapter({ apiKey }));
32
+ * useMapKeyboardNavigation(api);
33
+ * ```
34
+ *
35
+ * @param api - The map API object (or any object matching `MapKeyboardNavigationApi`)
36
+ * @param containerRef - Optional override for the keyboard event target. Defaults to `api.containerRef`.
37
+ */
38
+ export declare const useMapKeyboardNavigation: (api: MapKeyboardNavigationApi, containerRef?: RefObject<HTMLElement | null>) => void;
@@ -0,0 +1,43 @@
1
+ import type { AdapterConfig } from "@trackunit/react-map-adapter-shared";
2
+ import { type ComponentType } from "react";
3
+ import type { MapComponentProps, MapType } from "./types";
4
+ /**
5
+ * Options for the preview map
6
+ */
7
+ type UsePreviewMapOptions = Readonly<{
8
+ /** Map type to set once the map is ready (e.g., "satellite" for satellite previews) */
9
+ mapType?: MapType;
10
+ }>;
11
+ /**
12
+ * Return value of the `usePreviewMap` hook.
13
+ *
14
+ * Provides `Map` (a stable, memoised component reference) and `ready`
15
+ * to indicate whether the adapter instance has finished initializing.
16
+ */
17
+ export type UsePreviewMapReturn = Readonly<{
18
+ /** Stable Map component reference — safe to render without triggering the static-components lint rule */
19
+ Map: ComponentType<MapComponentProps>;
20
+ /** Whether the preview adapter instance reports `isReady` */
21
+ ready: boolean;
22
+ }>;
23
+ /**
24
+ * Creates a lightweight, non-interactive sibling map from a derived AdapterConfig.
25
+ *
26
+ * Returns a stable `Map` component reference and a `ready` flag.
27
+ * Use this to spawn preview maps for map style settings.
28
+ *
29
+ * The preview map optionally sets a mapType after the adapter connects,
30
+ * which is needed for satellite/hybrid previews where the base layer
31
+ * differs from the default.
32
+ *
33
+ * @param adapterConfig - Adapter config (typically from `api.adapterConfig.derive(overrides)`)
34
+ * @param options - Optional settings like mapType
35
+ * @returns Object with a stable `Map` component and a `ready` boolean
36
+ * @example
37
+ * ```tsx
38
+ * const { Map: PreviewMap } = usePreviewMap(api.adapterConfig.derive({ theme: "dark" }));
39
+ * return <PreviewMap className="h-18 w-18" />;
40
+ * ```
41
+ */
42
+ export declare const usePreviewMap: (adapterConfig: AdapterConfig, options?: UsePreviewMapOptions) => UsePreviewMapReturn;
43
+ export {};
package/src/index.d.ts ADDED
@@ -0,0 +1,69 @@
1
+ export type { CameraState, ContainerRefHolder, FitBoundsOptions, GeoJsonBbox, GeoJsonPosition, InitialViewport, MapActions, MapApi, MapAppearance, MapComponentProps, MapEvent, MapEventHandler, MapEventOfType, MapState, MapStatus, MapTheme, MapType, UseMapReturn, } from "./core/types";
2
+ export { DEFAULT_MAP_APPEARANCE, INITIAL_CAMERA_STATE, INITIAL_MAP_STATE, INITIAL_MAP_STATUS, mapAppearanceSchema, mapThemeSchema, mapTypeSchema, } from "./core/types";
3
+ export type { AvailableSpace, BooleanControlConfig, BuiltInControlsConfig, BuiltInNavigationConfig, BuiltInSettingsConfig, ButtonControlConfig, CategoryKey, CheckboxControlConfig, Compactness, ControlConfig, ControlsConfig, ControlsOptions, CustomControlConfig, CustomControlRenderContext, IconName, MenuControlConfig, MenuItemConfig, NavigationConfig, OverflowBehavior, Placement, RadioGroupControlConfig, RenderContext, ResolvedControlProps, ResolvedControlPropsBase, ResponsiveMode, SearchControlConfig, SelectControlConfig, SeparatorItemConfig, SettingsConfig, StatisticsConfig, StepperControlConfig, ToggleControlConfig, ToggleGroupControlConfig, ToggleGroupOption, UseMapOptions, } from "./controls/types";
4
+ export { defineAdapter } from "@trackunit/react-map-adapter-shared";
5
+ export type { AdapterConfig, AdapterConfigBase, AdapterInstance, AdapterRendererProps, SafeAreaInsets, } from "@trackunit/react-map-adapter-shared";
6
+ export { useCameraIdle } from "./core/useCameraIdle";
7
+ export { useCameraState } from "./core/useCameraState";
8
+ export { useMap } from "./core/useMap";
9
+ export { useMapKeyboardNavigation, type MapKeyboardNavigationApi } from "./core/useMapKeyboardNavigation";
10
+ export { usePreviewMap, type UsePreviewMapReturn } from "./core/usePreviewMap";
11
+ export { MapLoadingState } from "./core/MapLoadingState";
12
+ export { Controls } from "./controls/Controls";
13
+ export type { ControlStackItem } from "./controls/defineControlStack";
14
+ export { useControlsConfig } from "./controls/useControlsConfig";
15
+ export type { AppearanceAction, AppearanceOption, AppearanceOptions, MapAppearanceApi, PersistedAppearance, UseMapAppearanceControlsParams, } from "./appearance/appearanceTypes";
16
+ export { useMapAppearanceControls } from "./appearance/useMapAppearanceControls";
17
+ export type { ControlMiddleware, MiddlewareContext } from "./controls/renderingRules";
18
+ export type { CategoryMetadata } from "./controls/collapseControls";
19
+ export type { ClusterEntity, Entity, MapInteractionState, MarkerEntity, RouteEntity, ShapeEntity, ShapeType, } from "@trackunit/react-map-adapter-shared";
20
+ export { geometryTypeToShapeType, INITIAL_INTERACTION_STATE } from "@trackunit/react-map-adapter-shared";
21
+ export type { AdaptiveMarkerResolution, AdaptiveRenderConfig, AdaptiveRenderState, AdaptiveResolutionContext, CircleSymbolDescriptor, ClientClusterConfig, ClusterConfig, ClusterInfo, ClusterRenderState, ClusterSymbolStyle, CommonRenderState, DomPortalStackingInput, DomPortalStackingResolver, DomPortalStackingResult, DomRenderConfig, DomRenderState, FitParticipation, GeoJsonFeature, GeoJsonFeatureCollection, GeoJsonGeometry, ImageOverlayHandle, LayerHandle, LayerMeta, MarkerAnchor, MarkerDomPortalStackGeometry, MarkerDomPortalStackPhase, MarkerLayerHandle, RenderConfig, RenderMedium, ResolutionContext, RouteLayerHandle, RouteStyle, ServerClusterConfig, ShapeInteractiveMode, ShapeLayerHandle, ShapeStyle, ShapeStyleOverrides, SymbolDescriptor, SymbolRenderConfig, SymbolRenderState, } from "./layers/types";
22
+ export { computeMarkerDomPortalZIndex } from "./layers/types";
23
+ export { ANCHOR_SELECTOR, HIT_SURFACE_SELECTOR } from "@trackunit/react-map-adapter-shared";
24
+ export { ClusterMarker, type ClusterMarkerProps, type ClusterMarkerStickInput, type ClusterSegment, } from "./clusters/ClusterMarker";
25
+ export { ClusterStick, type ClusterStickProps } from "./clusters/ClusterStick";
26
+ export { useDirectionIndicator, type DirectionIndicatorDisplay, } from "./markers/geometry/useDirectionIndicator";
27
+ export { MapMarker, type MapMarkerProps } from "./markers/MapMarker";
28
+ export { MapMarkerIcon } from "./markers/MapMarkerIcon";
29
+ export type { MapMarkerDomPortalStackingByMarkerState, MapMarkerDomPortalStackingByPromotion, MapMarkerDomPortalStackingParams, } from "./markers/model/mapMarkerDomPortalStacking";
30
+ export type { ClusterStickState, MarkerDomSize, MarkerForm, MarkerSizeDimensions, MarkerState, StickDistanceMode, StickPositioning, } from "./markers/model/markerDomTypes";
31
+ export type { MarkerRenderStateInput } from "./markers/model/markerResolvers";
32
+ export { MARKER_PILL_CONTENT_LAYOUT_SIZE, MARKER_SIZE_MAP, } from "./markers/model/markerSizeMap";
33
+ export { MARKER_TUNING } from "./markers/model/markerTuningParams";
34
+ export { cvaMapMarker, cvaMarkerIndicator } from "./markers/shared/mapMarkerVariants";
35
+ export { MARKER_DARK_PILL, MARKER_LIGHT_PILL, } from "./markers/shared/markerColors";
36
+ export type { MarkerColorConfig, MarkerColorCssVars, ResolvedMarkerColors } from "./markers/shared/markerColors";
37
+ export { type HoverPanelPreloadInitiator, type PanelPreloadInitiator, type PanelPreloadInitiatorType, type ProximityPanelPreloadInitiator, } from "./panel/preload/preloadInitiators";
38
+ export { usePanelPreload, type UsePanelPreloadOptions } from "./panel/preload/usePanelPreload";
39
+ export { type PanelStore } from "./panel/store/panels";
40
+ export { usePanel, type UsePanelOptions } from "./panel/usePanel";
41
+ export { type AutoPanContext, type AutoPanResult } from "./panel/utils/autoPan";
42
+ export type { DecorationAnchor, EdgeSide, ShapeDecoration } from "./layers/useShapes/shapeDecorations";
43
+ export { type AnnotationContext, type ShapeLabelPolicy, } from "./layers/useShapes/shapeLabelPolicy";
44
+ export type { ResolveShapeLabel, ShapeLabelResolution, ShapeLabelResolutionContext, } from "./layers/useShapes/shapeLabelResolution";
45
+ export { useImageOverlay, type UseImageOverlayOptions, type UseImageOverlayReturn, } from "./layers/image-overlay/useImageOverlay";
46
+ export { buildExpandedIds, useExpandedIds, type MapFocus, type MapFocusTier, type MapFocusTierDisplay, } from "./layers/mapFocus";
47
+ export { useRoute, type UseRouteOptions, type UseRouteReturn } from "./layers/routes/useRoute";
48
+ export { useFitToContent, type FitToContentOptions, type FitToContentResult } from "./layers/useFitToContent";
49
+ export { useLayers, type UseLayersReturn } from "./layers/useLayers";
50
+ export { DEFAULT_MARKER_SIZE_BREAKPOINTS, MARKER_DISC_BORDER_WIDTH_PX, type MarkerSizeBreakpoint, type PickMarkerSizeOptions, type PickRenderMediumOptions, type PickSymbolDiameterOptions, } from "./layers/useMarkers/adaptiveHelpers";
51
+ export { useMarkers, type UseMarkersOptions, type UseMarkersReturn } from "./layers/useMarkers/useMarkers";
52
+ export { useShapes, type UseShapesOptions, type UseShapesReturn } from "./layers/useShapes/useShapes";
53
+ export { Layers } from "./layers/Layers";
54
+ export { type MapLoadingIndicatorStore } from "./core/loadingIndicator";
55
+ export { type MapAnnotationDescriptor, type MapAnnotationStore, } from "./annotations/mapAnnotations";
56
+ export { useMapAnnotation } from "./annotations/useMapAnnotation";
57
+ export { useMapAnnotations } from "./annotations/useMapAnnotations";
58
+ export { ShapeAnnotationLabel } from "./layers/useShapes/ShapeAnnotationLabel";
59
+ export { useViewportContext, type ViewportContext } from "./layers/internal/useViewportContext";
60
+ export type { AnchoredContentConfig, EntityInteractionEvent, EntityInteractionHandler, ImageOverlayConfig as ImageOverlaySourceConfig, InteractiveMarkerConfig, LayerPort, LayerSnapshot, MapLayer, MarkerSourceConfig, RouteSourceConfig, ShapeInteractionState, ShapeSourceConfig, } from "@trackunit/react-map-adapter-shared";
61
+ export { useAdaptiveMarkerHelpers, type AdaptiveMarkerHelpers } from "./layers/useMarkers/useAdaptiveMarkerHelpers";
62
+ export { useFitFeatureBounds, type FitFeatureBoundsHelpers } from "./layers/internal/useFitFeatureBounds";
63
+ export { useAutoPanResolver, type AutoPanResolverHelpers } from "./panel/utils/useAutoPanResolver";
64
+ export { useClusterCountFormat, type ClusterCountFormatHelpers } from "./clusters/useClusterCountFormat";
65
+ export { useControlStack, type ControlStackHelpers } from "./controls/useControlStack";
66
+ export { useMarkerColors, type MarkerColorHelpers } from "./markers/shared/useMarkerColors";
67
+ export { useMarkerStateResolvers, type MarkerStateResolvers } from "./markers/model/useMarkerStateResolvers";
68
+ export { useShapeLabelHelpers, type ShapeLabelHelpers } from "./layers/useShapes/useShapeLabelHelpers";
69
+ export { mockMapApi } from "./testing/mockMapApi";
@@ -0,0 +1,31 @@
1
+ import { type Entity, type MapInteractionState } from "@trackunit/react-map-adapter-shared";
2
+ type SelectAction = Readonly<{
3
+ type: "SELECT";
4
+ entity: Entity | null;
5
+ }>;
6
+ type HoverAction = Readonly<{
7
+ type: "HOVER";
8
+ entity: Entity | null;
9
+ }>;
10
+ type ClearSelectionAction = Readonly<{
11
+ type: "CLEAR_SELECTION";
12
+ }>;
13
+ type ClearHoverAction = Readonly<{
14
+ type: "CLEAR_HOVER";
15
+ }>;
16
+ type ClearAllAction = Readonly<{
17
+ type: "CLEAR_ALL";
18
+ }>;
19
+ /**
20
+ * Discriminated union of all interaction actions.
21
+ */
22
+ export type InteractionAction = Readonly<SelectAction | HoverAction | ClearSelectionAction | ClearHoverAction | ClearAllAction>;
23
+ /**
24
+ * Pure reducer for map entity interaction state.
25
+ *
26
+ * - SELECT / HOVER replace the current selected/hovered entity (cross-layer).
27
+ * - CLEAR_SELECTION / CLEAR_HOVER reset that specific field.
28
+ * - CLEAR_ALL resets both to null.
29
+ */
30
+ export declare const interactionReducer: (state: MapInteractionState, action: InteractionAction) => MapInteractionState;
31
+ export {};
@@ -0,0 +1,32 @@
1
+ import type { MapApi } from "../core/types";
2
+ import type { UseLayersReturn } from "./useLayers";
3
+ type LayersProps = Readonly<{
4
+ /** The result from `useLayers()` */
5
+ layers: UseLayersReturn;
6
+ /** Map API for viewport-aware features (e.g. edge labels). Optional for backward compat. */
7
+ api?: MapApi;
8
+ }>;
9
+ /**
10
+ * `<Layers>` -- rendering bridge between layer handles and the map adapter.
11
+ *
12
+ * Rendered as a child of `<Map>`. Reads the `LayerPort` from context
13
+ * (provided by `createMapComponent`) and pushes a full `LayerSnapshot` to
14
+ * the adapter on every change. The adapter owns the diff.
15
+ *
16
+ * This component is renderless -- it produces no DOM output. It exists
17
+ * solely to manage the lifecycle of layer sources on the adapter.
18
+ *
19
+ * @example
20
+ * ```tsx
21
+ * const layers = useLayers(api, [markers, zones]);
22
+ *
23
+ * return (
24
+ * <Map>
25
+ * <Controls api={api} />
26
+ * <Layers api={api} layers={layers} />
27
+ * </Map>
28
+ * );
29
+ * ```
30
+ */
31
+ export declare const Layers: ({ layers, api }: LayersProps) => import("react/jsx-runtime").JSX.Element | null;
32
+ export {};
@@ -0,0 +1,24 @@
1
+ import type { GeoJsonBbox, GeoJsonFeature, GeoJsonFeatureCollection } from "@trackunit/geo-json-utils";
2
+ import type { LayerPort } from "@trackunit/react-map-adapter-shared";
3
+ import { type Mock } from "vitest";
4
+ import type { MapApi, MapState } from "../core/types";
5
+ import type { LayerHandle, ShapeLayerHandle } from "./types";
6
+ import type { UseLayersReturn } from "./useLayers";
7
+ export declare const POLYGON_FEATURES: GeoJsonFeatureCollection;
8
+ export declare const VIEWPORT_BOUNDS: GeoJsonBbox;
9
+ /** Viewport entirely inside the polygon (edges at 0/10) so no edge is visible */
10
+ export declare const INTERIOR_ONLY_BOUNDS: GeoJsonBbox;
11
+ export type MockLayerPort = LayerPort & {
12
+ setSnapshot: Mock;
13
+ onEntityInteraction: Mock;
14
+ onBackgroundClick: Mock;
15
+ onSourceReady: Mock;
16
+ };
17
+ export type MockLayerPortWithReadiness = {
18
+ port: MockLayerPort;
19
+ fireSourceReady: (configId: string) => void;
20
+ };
21
+ export declare const createMockLayerPort: () => MockLayerPortWithReadiness;
22
+ export declare const createMockMapApi: (bounds?: GeoJsonBbox | null, stateOverrides?: Partial<MapState>) => MapApi;
23
+ export declare const createShapeHandle: (id: string, labelFn?: (feature: GeoJsonFeature) => string | undefined, features?: GeoJsonFeatureCollection) => ShapeLayerHandle;
24
+ export declare const createMockLayersReturn: (handles: ReadonlyArray<LayerHandle>) => UseLayersReturn;
@@ -0,0 +1,17 @@
1
+ import type { MapFocus } from "./mapFocus";
2
+ /**
3
+ * Builds the set of item ids that should render as expanded by walking tiers
4
+ * in order and filling up to `limit`.
5
+ *
6
+ * When `getPosition` is provided and a tier would overflow the remaining
7
+ * budget, farthest-point spread sampling is applied so the chosen markers
8
+ * are distributed across the viewport rather than biased toward whatever
9
+ * order the server happened to return.
10
+ *
11
+ * When `previousIds` is provided, candidates that appear in it are
12
+ * pre-selected within each tier before the spread runs on the remaining
13
+ * candidates. This produces hysteresis: markers that were already expanded
14
+ * stay expanded across incremental data updates. Tier order is always
15
+ * respected — a lower-tier incumbent never displaces a higher-tier newcomer.
16
+ */
17
+ export declare const buildExpandedIds: <TAsset>(items: ReadonlyArray<TAsset>, getId: (item: TAsset) => string, focus: MapFocus<TAsset>, limit: number, getPosition?: (item: TAsset) => readonly [number, number, ...Array<number>], previousIds?: ReadonlySet<string>) => ReadonlySet<string>;
@@ -0,0 +1,39 @@
1
+ import { type GeoJsonBbox } from "@trackunit/geo-json-utils";
2
+ import type { ControlConfig } from "../../controls/types";
3
+ import type { FitParticipation, ImageOverlayHandle } from "../types";
4
+ export type UseImageOverlayOptions = Readonly<{
5
+ /** Unique ID for this layer */
6
+ id: string;
7
+ /** Human-readable name */
8
+ name: string;
9
+ /** URL of the image to display on the map */
10
+ url: string;
11
+ /** Geographic bounds the image covers as [minLon, minLat, maxLon, maxLat] */
12
+ imageBounds: GeoJsonBbox;
13
+ /** Opacity from 0 to 1. Default: 1 */
14
+ opacity?: number;
15
+ /** Optional controls to contribute to the map UI */
16
+ controls?: ReadonlyArray<ControlConfig>;
17
+ /** Whether the layer is currently loading its initial data. Omit for static (non-loading) layers. */
18
+ loading?: boolean;
19
+ /** Controls whether this layer's bounds are included in fit-to-content operations. Default: `"all"` */
20
+ fitParticipation?: FitParticipation;
21
+ }>;
22
+ export type UseImageOverlayReturn = ImageOverlayHandle;
23
+ /**
24
+ * `useImageOverlay` -- creates an image overlay layer handle.
25
+ *
26
+ * Renders a georeferenced image on the map within the given bounds.
27
+ *
28
+ * @example
29
+ * ```tsx
30
+ * const overlay = useImageOverlay({
31
+ * id: "site-plan",
32
+ * name: "Site Plan",
33
+ * url: "https://example.com/site-plan.png",
34
+ * imageBounds: [-73.99, 40.74, -73.97, 40.76],
35
+ * opacity: 0.7,
36
+ * });
37
+ * ```
38
+ */
39
+ export declare const useImageOverlay: (options: UseImageOverlayOptions) => UseImageOverlayReturn;
@@ -0,0 +1,24 @@
1
+ import type { LayerPort } from "@trackunit/react-map-adapter-shared";
2
+ /**
3
+ * Internal context that provides the adapter's LayerPort to layer rendering components.
4
+ *
5
+ * Provided by `createMapComponent` when the adapter has layer capabilities.
6
+ * Consumed by the `<Layers>` component to communicate layer data to the adapter.
7
+ *
8
+ * @internal
9
+ */
10
+ export declare const MapLayerContext: import("react").Context<Readonly<{
11
+ setSnapshot: (snapshot: import("@trackunit/react-map-adapter-shared").LayerSnapshot) => void;
12
+ onEntityInteraction: (handler: import("@trackunit/react-map-adapter-shared").EntityInteractionHandler) => () => void;
13
+ onBackgroundClick: (handler: () => void) => () => void;
14
+ onSourceReady: (configId: string, callback: () => void) => () => void;
15
+ markerPortals?: import("@trackunit/react-map-adapter-shared").DomPortalStore | null;
16
+ clusterPortals?: import("@trackunit/react-map-adapter-shared").DomPortalStore | null;
17
+ }> | null>;
18
+ /**
19
+ * Hook to access the LayerPort from the nearest MapLayerContext.
20
+ * Returns null if the adapter doesn't support layers.
21
+ *
22
+ * @internal
23
+ */
24
+ export declare const useLayerPort: () => LayerPort | null;
@@ -0,0 +1,33 @@
1
+ import type { GeoJsonFeatureCollection } from "@trackunit/geo-json-utils";
2
+ import { type AdaptiveMarkerResolution, type AdaptiveRenderConfig, type MapInteractionState, type RenderMedium } from "@trackunit/react-map-adapter-shared";
3
+ import type { MapApi } from "../../core/types";
4
+ import type { LayerHandle } from "../types";
5
+ type AdaptiveResolutionInputs = Readonly<{
6
+ zoom: number;
7
+ markersInViewport: number;
8
+ selectedMarkerId: string | null;
9
+ hoveredMarkerId: string | null;
10
+ debouncedHoveredMarkerId: string | null;
11
+ }>;
12
+ /**
13
+ * Pure resolution for one adaptive marker layer (used by the hook and tests).
14
+ */
15
+ export declare const computeAdaptiveMarkerResolutionForLayer: (collection: GeoJsonFeatureCollection, markerRender: AdaptiveRenderConfig<unknown>, inputs: AdaptiveResolutionInputs, previousModes: ReadonlyMap<string, RenderMedium> | undefined) => AdaptiveMarkerResolution;
16
+ /**
17
+ * Computes per-feature adaptive modes for all `mode: "adaptive"` marker layers.
18
+ * Intended for use inside `<Layers>` only.
19
+ *
20
+ * Resolution is computed **during render** (via `useMemo`) so it stays aligned with
21
+ * `interaction` in the same commit — avoids one frame of stale `adaptiveResolution`
22
+ * on hover/select before effects ran (which caused visible DOM/symbol flicker).
23
+ *
24
+ * Viewport state (`zoom`, `bounds`) is read from the camera store with
25
+ * `useSyncExternalStore`, keeping idle/moving transitions aligned with the same
26
+ * snapshot that drives viewport consumers.
27
+ *
28
+ * Previous-frame mode tracking (for animation continuity) is intentionally left to
29
+ * each adapter — they own the mutable DOM marker state and can diff their own
30
+ * previous modes on each `setSnapshot` call without coupling to React render cycles.
31
+ */
32
+ export declare const useAdaptiveMarkerResolution: (handles: ReadonlyArray<LayerHandle>, interaction: MapInteractionState, api: MapApi | undefined) => ReadonlyMap<string, AdaptiveMarkerResolution>;
33
+ export {};