@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.
- package/README.md +296 -0
- package/index.cjs.js +9851 -0
- package/index.d.ts +1 -0
- package/index.esm.js +9752 -0
- package/package.json +34 -0
- package/src/annotations/getDescriptorContentKey.d.ts +14 -0
- package/src/annotations/mapAnnotations.d.ts +76 -0
- package/src/annotations/useMapAnnotation.d.ts +16 -0
- package/src/annotations/useMapAnnotations.d.ts +17 -0
- package/src/appearance/AppearancePreview.d.ts +27 -0
- package/src/appearance/AppearancePreviewGrid.d.ts +29 -0
- package/src/appearance/appearanceTypes.d.ts +84 -0
- package/src/appearance/useMapAppearanceControls.d.ts +29 -0
- package/src/clusters/ClusterMarker.d.ts +41 -0
- package/src/clusters/ClusterStick.d.ts +97 -0
- package/src/clusters/formatClusterCount.d.ts +11 -0
- package/src/clusters/stories/ClusterMarkerCompactFormatsDemo.d.ts +7 -0
- package/src/clusters/stories/ClusterMarkerCountOnlyDemo.d.ts +7 -0
- package/src/clusters/stories/ClusterMarkerDefaultDemo.d.ts +12 -0
- package/src/clusters/stories/ClusterMarkerPlaygroundDemo.d.ts +10 -0
- package/src/clusters/stories/ClusterMarkerStateDemo.d.ts +9 -0
- package/src/clusters/stories/ClusterMarkerWithSegmentsDemo.d.ts +7 -0
- package/src/clusters/stories/ClusterMarkerWithSticksDemo.d.ts +10 -0
- package/src/clusters/useClusterCountFormat.d.ts +19 -0
- package/src/controls/AnnotationRenderer.d.ts +17 -0
- package/src/controls/AnnotationStack.d.ts +21 -0
- package/src/controls/ControlRenderer.d.ts +20 -0
- package/src/controls/Controls.d.ts +15 -0
- package/src/controls/annotationButtonClasses.d.ts +13 -0
- package/src/controls/collapseControls.d.ts +37 -0
- package/src/controls/defineControlStack.d.ts +10 -0
- package/src/controls/deriveResponsiveMode.d.ts +19 -0
- package/src/controls/longitudeToGlobeIcon.d.ts +3 -0
- package/src/controls/renderers/boolean/BooleanButton.d.ts +16 -0
- package/src/controls/renderers/boolean/MenuBooleanItem.d.ts +20 -0
- package/src/controls/renderers/boolean/MenuCheckbox.d.ts +14 -0
- package/src/controls/renderers/boolean/MenuToggle.d.ts +14 -0
- package/src/controls/renderers/button/Button.d.ts +14 -0
- package/src/controls/renderers/button/MenuButton.d.ts +16 -0
- package/src/controls/renderers/custom/Custom.d.ts +22 -0
- package/src/controls/renderers/menu/Menu.d.ts +23 -0
- package/src/controls/renderers/menu/Modal.d.ts +21 -0
- package/src/controls/renderers/menu/SectionHeader.d.ts +14 -0
- package/src/controls/renderers/menu/Separator.d.ts +11 -0
- package/src/controls/renderers/radio-group/MenuRadioGroup.d.ts +15 -0
- package/src/controls/renderers/radio-group/RadioGroup.d.ts +19 -0
- package/src/controls/renderers/radio-group/RadioGroupField.d.ts +17 -0
- package/src/controls/renderers/search/MenuSearch.d.ts +15 -0
- package/src/controls/renderers/search/Search.d.ts +14 -0
- package/src/controls/renderers/select/MenuSelect.d.ts +15 -0
- package/src/controls/renderers/select/Select.d.ts +14 -0
- package/src/controls/renderers/stepper/MenuStepper.d.ts +17 -0
- package/src/controls/renderers/stepper/Stepper.d.ts +18 -0
- package/src/controls/renderers/toggle-group/MenuToggleGroup.d.ts +17 -0
- package/src/controls/renderers/toggle-group/ToggleGroup.d.ts +15 -0
- package/src/controls/renderers/toggle-group/ToggleGroupField.d.ts +19 -0
- package/src/controls/renderingRules.d.ts +26 -0
- package/src/controls/types.d.ts +395 -0
- package/src/controls/useAnimatedPresence.d.ts +15 -0
- package/src/controls/useAnnotationPresence.d.ts +16 -0
- package/src/controls/useControlStack.d.ts +21 -0
- package/src/controls/useControlsConfig.d.ts +27 -0
- package/src/controls/usePopoverPlacement.d.ts +33 -0
- package/src/core/LoadingIndicatorPill.d.ts +9 -0
- package/src/core/MapLoadingState.d.ts +17 -0
- package/src/core/SafeAreaLayoutContext.d.ts +5 -0
- package/src/core/__testHelpers.d.ts +23 -0
- package/src/core/createMapComponent.d.ts +32 -0
- package/src/core/loadingIndicator.d.ts +21 -0
- package/src/core/padWithInsets.d.ts +5 -0
- package/src/core/types.d.ts +208 -0
- package/src/core/useCameraIdle.d.ts +2 -0
- package/src/core/useCameraState.d.ts +3 -0
- package/src/core/useMap.d.ts +57 -0
- package/src/core/useMapAdapterState.d.ts +14 -0
- package/src/core/useMapKeyboardNavigation.d.ts +38 -0
- package/src/core/usePreviewMap.d.ts +43 -0
- package/src/index.d.ts +69 -0
- package/src/interactions/interactionReducer.d.ts +31 -0
- package/src/layers/Layers.d.ts +32 -0
- package/src/layers/__testHelpers.d.ts +24 -0
- package/src/layers/buildExpandedIds.d.ts +17 -0
- package/src/layers/image-overlay/useImageOverlay.d.ts +39 -0
- package/src/layers/internal/MapLayerContext.d.ts +24 -0
- package/src/layers/internal/adaptiveMarkerResolution.d.ts +33 -0
- package/src/layers/internal/computeBounds.d.ts +34 -0
- package/src/layers/internal/countFeaturesInViewport.d.ts +14 -0
- package/src/layers/internal/createLazyGetter.d.ts +16 -0
- package/src/layers/internal/layerHelpers.d.ts +18 -0
- package/src/layers/internal/markerPortalZIndex.d.ts +17 -0
- package/src/layers/internal/useDblClickFit.d.ts +13 -0
- package/src/layers/internal/useEntityInteraction.d.ts +21 -0
- package/src/layers/internal/useFitFeatureBounds.d.ts +19 -0
- package/src/layers/internal/useLayerHandleSync.d.ts +18 -0
- package/src/layers/internal/useLayerReady.d.ts +25 -0
- package/src/layers/internal/useMarkerMountBridge.d.ts +41 -0
- package/src/layers/internal/useViewportContext.d.ts +34 -0
- package/src/layers/mapFocus.d.ts +29 -0
- package/src/layers/routes/useRoute.d.ts +39 -0
- package/src/layers/shared/measureLabelWidth.d.ts +11 -0
- package/src/layers/types.d.ts +131 -0
- package/src/layers/useExpandedIds.d.ts +20 -0
- package/src/layers/useFitToContent.d.ts +57 -0
- package/src/layers/useLayers.d.ts +58 -0
- package/src/layers/useMarkers/adaptiveHelpers.d.ts +156 -0
- package/src/layers/useMarkers/resolveServerClusters.d.ts +26 -0
- package/src/layers/useMarkers/useAdaptiveMarkerHelpers.d.ts +38 -0
- package/src/layers/useMarkers/useMarkers.d.ts +127 -0
- package/src/layers/useShapes/InteractiveDecoration.d.ts +23 -0
- package/src/layers/useShapes/MultiGeometryPlusBadge.d.ts +17 -0
- package/src/layers/useShapes/MultiPartBadge.d.ts +11 -0
- package/src/layers/useShapes/ShapeAnnotationLabel.d.ts +30 -0
- package/src/layers/useShapes/ShapeIcon.d.ts +21 -0
- package/src/layers/useShapes/ShapeLabelPill.d.ts +25 -0
- package/src/layers/useShapes/buildShapeLabelResolutionContext.d.ts +23 -0
- package/src/layers/useShapes/decorationFactories.d.ts +47 -0
- package/src/layers/useShapes/edge/ShapeEdgeLabel.d.ts +13 -0
- package/src/layers/useShapes/edge/computeEdgeAutoPlacement.d.ts +69 -0
- package/src/layers/useShapes/edge/computeEdgeProperties.d.ts +21 -0
- package/src/layers/useShapes/edge/edgeInsetsForFeature.d.ts +27 -0
- package/src/layers/useShapes/edge/edgeReservations.d.ts +36 -0
- package/src/layers/useShapes/edge/findBestEdgePosition.d.ts +247 -0
- package/src/layers/useShapes/extractMultiParts.d.ts +25 -0
- package/src/layers/useShapes/findBestVisibleVertex.d.ts +18 -0
- package/src/layers/useShapes/multiPartDecorations.d.ts +19 -0
- package/src/layers/useShapes/shapeDecorations.d.ts +154 -0
- package/src/layers/useShapes/shapeFeatureBuilders.d.ts +25 -0
- package/src/layers/useShapes/shapeLabelPolicy.d.ts +42 -0
- package/src/layers/useShapes/shapeLabelResolution.d.ts +45 -0
- package/src/layers/useShapes/shapeSyntheticMarkerRender.d.ts +16 -0
- package/src/layers/useShapes/useShapeDecorations.d.ts +56 -0
- package/src/layers/useShapes/useShapeLabelHelpers.d.ts +29 -0
- package/src/layers/useShapes/useShapes.d.ts +50 -0
- package/src/markers/MapMarker.d.ts +115 -0
- package/src/markers/MapMarkerIcon.d.ts +21 -0
- package/src/markers/animation/applyStickFrame.d.ts +15 -0
- package/src/markers/animation/spring.d.ts +45 -0
- package/src/markers/animation/stickFrame.d.ts +82 -0
- package/src/markers/animation/usePillBackgroundPaint.d.ts +15 -0
- package/src/markers/animation/useStickAnimation.d.ts +21 -0
- package/src/markers/animation/useStickTween.d.ts +28 -0
- package/src/markers/geometry/stickPositioning.d.ts +69 -0
- package/src/markers/geometry/useDirectionIndicator.d.ts +8 -0
- package/src/markers/internal/MapMarkerStickSurface.d.ts +47 -0
- package/src/markers/model/mapMarkerDomPortalStacking.d.ts +22 -0
- package/src/markers/model/markerDomTypes.d.ts +68 -0
- package/src/markers/model/markerResolvers.d.ts +34 -0
- package/src/markers/model/markerSizeMap.d.ts +82 -0
- package/src/markers/model/markerTuningParams.d.ts +60 -0
- package/src/markers/model/useMarkerStateResolvers.d.ts +25 -0
- package/src/markers/shared/MarkerAnimatedSurface.d.ts +20 -0
- package/src/markers/shared/MarkerDiscContent.d.ts +11 -0
- package/src/markers/shared/mapMarkerVariants.d.ts +35 -0
- package/src/markers/shared/markerColors.d.ts +55 -0
- package/src/markers/shared/useMarkerColors.d.ts +23 -0
- package/src/markers/stories/demoes/AnimationCircleVsPillDemo.d.ts +7 -0
- package/src/markers/stories/demoes/CircleIconGuidanceDemo.d.ts +2 -0
- package/src/markers/stories/demoes/DefaultDemo.d.ts +14 -0
- package/src/markers/stories/demoes/DirectionBehaviorDemo.d.ts +2 -0
- package/src/markers/stories/demoes/PillLabelLengthsDemo.d.ts +2 -0
- package/src/markers/stories/demoes/StatesDemo.d.ts +7 -0
- package/src/markers/stories/demoes/StickModeDemo.d.ts +2 -0
- package/src/markers/stories/demoes/StickModePlaygroundDemo.d.ts +10 -0
- package/src/markers/stories/helpers/AbsoluteGridPicker.d.ts +17 -0
- package/src/markers/stories/helpers/InlineLabel.d.ts +4 -0
- package/src/markers/stories/helpers/InlineSlider.d.ts +11 -0
- package/src/markers/stories/helpers/LabeledMarker.d.ts +7 -0
- package/src/markers/stories/helpers/MarkerRow.d.ts +4 -0
- package/src/markers/stories/helpers/SectionHeader.d.ts +4 -0
- package/src/markers/stories/helpers/StatesMarkerCell.d.ts +15 -0
- package/src/markers/stories/helpers/ThemedPreview.d.ts +10 -0
- package/src/markers/stories/helpers/mapMarkerStoryConstants.d.ts +4 -0
- package/src/panel/Panel.d.ts +60 -0
- package/src/panel/PanelOrchestrator.d.ts +24 -0
- package/src/panel/preload/preloadInitiators.d.ts +44 -0
- package/src/panel/preload/useHoverPreloadInitiator.d.ts +8 -0
- package/src/panel/preload/usePanelPreload.d.ts +46 -0
- package/src/panel/preload/useProximityPreloadInitiator.d.ts +13 -0
- package/src/panel/store/panels.d.ts +76 -0
- package/src/panel/storyHelpers.d.ts +9 -0
- package/src/panel/usePanel.d.ts +81 -0
- package/src/panel/utils/autoPan.d.ts +78 -0
- package/src/panel/utils/panelShellConstants.d.ts +8 -0
- package/src/panel/utils/useAutoPanResolver.d.ts +23 -0
- package/src/panel/utils/useWheelForwarding.d.ts +18 -0
- package/src/stories/InteractionDisplay.d.ts +9 -0
- package/src/stories/PositionDisplay.d.ts +9 -0
- package/src/stories/_storyCoordUtils.d.ts +8 -0
- package/src/testing/mockMapApi.d.ts +29 -0
- package/src/translation.d.ts +30 -0
- package/translation.cjs.js +30 -0
- package/translation.cjs10.js +30 -0
- package/translation.cjs11.js +30 -0
- package/translation.cjs12.js +30 -0
- package/translation.cjs13.js +30 -0
- package/translation.cjs14.js +30 -0
- package/translation.cjs15.js +30 -0
- package/translation.cjs16.js +30 -0
- package/translation.cjs17.js +30 -0
- package/translation.cjs2.js +30 -0
- package/translation.cjs3.js +30 -0
- package/translation.cjs4.js +30 -0
- package/translation.cjs5.js +30 -0
- package/translation.cjs6.js +30 -0
- package/translation.cjs7.js +30 -0
- package/translation.cjs8.js +30 -0
- package/translation.cjs9.js +30 -0
- package/translation.esm.js +28 -0
- package/translation.esm10.js +28 -0
- package/translation.esm11.js +28 -0
- package/translation.esm12.js +28 -0
- package/translation.esm13.js +28 -0
- package/translation.esm14.js +28 -0
- package/translation.esm15.js +28 -0
- package/translation.esm16.js +28 -0
- package/translation.esm17.js +28 -0
- package/translation.esm2.js +28 -0
- package/translation.esm3.js +28 -0
- package/translation.esm4.js +28 -0
- package/translation.esm5.js +28 -0
- package/translation.esm6.js +28 -0
- package/translation.esm7.js +28 -0
- package/translation.esm8.js +28 -0
- 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,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 {};
|