@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
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@trackunit/react-map",
|
|
3
|
+
"version": "0.0.4-alpha-9d327375fc1.0",
|
|
4
|
+
"repository": "https://github.com/Trackunit/manager",
|
|
5
|
+
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=24.x"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {
|
|
10
|
+
"@trackunit/react-components": "2.1.15-alpha-9d327375fc1.0",
|
|
11
|
+
"@trackunit/css-class-variance-utilities": "1.13.24-alpha-9d327375fc1.0",
|
|
12
|
+
"@trackunit/react-form-components": "2.1.16-alpha-9d327375fc1.0",
|
|
13
|
+
"@trackunit/react-core-hooks": "1.17.29-alpha-9d327375fc1.0",
|
|
14
|
+
"@trackunit/geo-json-utils": "1.14.25-alpha-9d327375fc1.0",
|
|
15
|
+
"@trackunit/i18n-library-translation": "2.0.17-alpha-9d327375fc1.0",
|
|
16
|
+
"@trackunit/react-modal": "2.1.17-alpha-9d327375fc1.0",
|
|
17
|
+
"react-minimal-pie-chart": "^8.4.0",
|
|
18
|
+
"@trackunit/react-map-adapter-shared": "0.0.4-alpha-9d327375fc1.0",
|
|
19
|
+
"@trackunit/ui-design-tokens": "1.13.24-alpha-9d327375fc1.0",
|
|
20
|
+
"@floating-ui/react": "^0.26.25",
|
|
21
|
+
"es-toolkit": "^1.39.10",
|
|
22
|
+
"tailwind-merge": "^2.0.0",
|
|
23
|
+
"zod": "^3.25.76"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": "^19.0.0",
|
|
27
|
+
"react-dom": "^19.0.0",
|
|
28
|
+
"@tanstack/react-router": "1.114.29",
|
|
29
|
+
"react-hook-form": "7.62.0"
|
|
30
|
+
},
|
|
31
|
+
"module": "./index.esm.js",
|
|
32
|
+
"main": "./index.cjs.js",
|
|
33
|
+
"types": "./index.d.ts"
|
|
34
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MapAnnotationDescriptor } from "./mapAnnotations";
|
|
2
|
+
/**
|
|
3
|
+
* Returns a stable content key for the descriptor so that inline objects with
|
|
4
|
+
* the same logical content do not trigger effect re-runs.
|
|
5
|
+
*
|
|
6
|
+
* For simple descriptors, `onClick` and `icon` are tracked by reference
|
|
7
|
+
* identity so a new click handler or a new icon element causes re-registration,
|
|
8
|
+
* preventing stale-closure bugs.
|
|
9
|
+
*
|
|
10
|
+
* For custom descriptors, the descriptor's own object identity is used so the
|
|
11
|
+
* key changes whenever the render function reference changes (e.g. when
|
|
12
|
+
* isHovered / isSelected state changes).
|
|
13
|
+
*/
|
|
14
|
+
export declare const getDescriptorContentKey: (descriptor: MapAnnotationDescriptor | null) => string;
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* Describes an annotation to be rendered in the map's Controls overlay.
|
|
4
|
+
*
|
|
5
|
+
* Discriminated union on `type`:
|
|
6
|
+
* - `"simple"`: icon + label + optional color -- rendered as a compact pill/badge
|
|
7
|
+
* - `"custom"`: arbitrary ReactNode via render function -- full control
|
|
8
|
+
*/
|
|
9
|
+
export type MapAnnotationDescriptor = Readonly<{
|
|
10
|
+
type: "simple";
|
|
11
|
+
id: string;
|
|
12
|
+
/** Lower number = higher priority in layout order */
|
|
13
|
+
priority?: number;
|
|
14
|
+
icon?: ReactNode;
|
|
15
|
+
label: string;
|
|
16
|
+
color?: string;
|
|
17
|
+
/**
|
|
18
|
+
* When set, the pill is rendered as a button and the handler runs on click.
|
|
19
|
+
* Implementations should call `stopPropagation` so multi-annotation stack
|
|
20
|
+
* expand/pin toggles on the outer container are not triggered accidentally.
|
|
21
|
+
*/
|
|
22
|
+
onClick?: () => void;
|
|
23
|
+
}> | Readonly<{
|
|
24
|
+
type: "custom";
|
|
25
|
+
id: string;
|
|
26
|
+
/** Lower number = higher priority in layout order */
|
|
27
|
+
priority?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Render function that returns the annotation's content.
|
|
30
|
+
*
|
|
31
|
+
* **Peek-card convention (`data-peek-root`):**
|
|
32
|
+
* When multiple annotations are stacked, only the top card is fully
|
|
33
|
+
* visible. Older annotations appear as narrow peek strips behind it.
|
|
34
|
+
* To make peek strips show the correct background color, border-radius,
|
|
35
|
+
* and shadow, place a `data-peek-root` attribute on the outermost
|
|
36
|
+
* visual container element (the element that carries the background
|
|
37
|
+
* and shape styles). Its direct children will be automatically hidden
|
|
38
|
+
* via `visibility: hidden` when the annotation is rendered as a peek
|
|
39
|
+
* strip, while the container's own appearance is preserved.
|
|
40
|
+
*
|
|
41
|
+
* If `data-peek-root` is omitted the peek strip still renders but
|
|
42
|
+
* will show raw, unstyled content at 3 px height.
|
|
43
|
+
*/
|
|
44
|
+
render: () => ReactNode;
|
|
45
|
+
}>;
|
|
46
|
+
/**
|
|
47
|
+
* Subscription-based store for map annotations.
|
|
48
|
+
* Compatible with `useSyncExternalStore(subscribe, getSnapshot)`.
|
|
49
|
+
*
|
|
50
|
+
* Exposed on `MapApi.annotations` so consumers and Controls can
|
|
51
|
+
* interact with annotations without React context indirection.
|
|
52
|
+
*
|
|
53
|
+
* The `claimRenderer` / `subscribeHasRenderer` / `getHasRendererSnapshot`
|
|
54
|
+
* trio lets the Map component detect whether an external renderer (Controls)
|
|
55
|
+
* has claimed annotation rendering. When unclaimed, the Map renders a
|
|
56
|
+
* built-in fallback AnnotationStack.
|
|
57
|
+
*/
|
|
58
|
+
export type MapAnnotationStore = Readonly<{
|
|
59
|
+
register: (descriptor: MapAnnotationDescriptor) => void;
|
|
60
|
+
unregister: (id: string) => void;
|
|
61
|
+
subscribe: (callback: () => void) => () => void;
|
|
62
|
+
getSnapshot: () => ReadonlyArray<MapAnnotationDescriptor>;
|
|
63
|
+
claimRenderer: () => () => void;
|
|
64
|
+
subscribeHasRenderer: (callback: () => void) => () => void;
|
|
65
|
+
getHasRendererSnapshot: () => boolean;
|
|
66
|
+
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Creates a `MapAnnotationStore` instance.
|
|
69
|
+
*
|
|
70
|
+
* Uses a `Set<() => void>` for subscribers and a `Map<string, MapAnnotationDescriptor>`
|
|
71
|
+
* for registered annotations. `getSnapshot` returns a stable `ReadonlyArray` reference
|
|
72
|
+
* that only changes when annotations are mutated.
|
|
73
|
+
*
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
export declare const createMapAnnotationStore: () => MapAnnotationStore;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { MapApi } from "../core/types";
|
|
2
|
+
import type { MapAnnotationDescriptor } from "./mapAnnotations";
|
|
3
|
+
/**
|
|
4
|
+
* Registers a map annotation to be rendered in the Controls overlay.
|
|
5
|
+
*
|
|
6
|
+
* Pass a descriptor to register, or `null` to unregister.
|
|
7
|
+
* Automatically cleans up on unmount.
|
|
8
|
+
*
|
|
9
|
+
* Same-id rerenders are stable: passing an inline descriptor with identical
|
|
10
|
+
* content (id, label, priority, etc.) will not cause unregister/register churn,
|
|
11
|
+
* avoiding reordering and enter/exit animation retriggers.
|
|
12
|
+
*
|
|
13
|
+
* @param api - The map API object from `useMap`
|
|
14
|
+
* @param descriptor - Annotation descriptor to register, or `null` to unregister
|
|
15
|
+
*/
|
|
16
|
+
export declare const useMapAnnotation: (api: MapApi, descriptor: MapAnnotationDescriptor | null) => void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MapApi } from "../core/types";
|
|
2
|
+
import type { MapAnnotationDescriptor } from "./mapAnnotations";
|
|
3
|
+
/**
|
|
4
|
+
* Registers a list of map annotations to be rendered in the Controls overlay.
|
|
5
|
+
*
|
|
6
|
+
* Syncs the reactive `descriptors` list to the annotation store: newly added
|
|
7
|
+
* descriptors are registered, removed ones are unregistered on each render.
|
|
8
|
+
* Automatically cleans up all registrations on unmount.
|
|
9
|
+
*
|
|
10
|
+
* Stable on re-render with identical content: passing a new array reference
|
|
11
|
+
* with descriptors whose id/label/priority/color fields are unchanged does not
|
|
12
|
+
* cause unregister/register churn.
|
|
13
|
+
*
|
|
14
|
+
* @param api - The map API object from `useMap`
|
|
15
|
+
* @param descriptors - Array of annotation descriptors to sync
|
|
16
|
+
*/
|
|
17
|
+
export declare const useMapAnnotations: (api: MapApi, descriptors: ReadonlyArray<MapAnnotationDescriptor>) => void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AdapterConfig } from "@trackunit/react-map-adapter-shared";
|
|
2
|
+
import type { MapType } from "../core/types";
|
|
3
|
+
type AppearancePreviewProps = Readonly<{
|
|
4
|
+
/** Derived adapter config for this preview (with the correct theme baked in) */
|
|
5
|
+
adapterConfig: AdapterConfig;
|
|
6
|
+
/** Map type to display in this preview */
|
|
7
|
+
mapType: MapType;
|
|
8
|
+
/** Display label shown under the preview */
|
|
9
|
+
label: string;
|
|
10
|
+
/** Whether this preview is the currently selected appearance */
|
|
11
|
+
selected: boolean;
|
|
12
|
+
/** Called when this preview is clicked */
|
|
13
|
+
onSelect: () => void;
|
|
14
|
+
/** Test ID */
|
|
15
|
+
"data-testid"?: string;
|
|
16
|
+
}>;
|
|
17
|
+
/**
|
|
18
|
+
* A single map appearance preview cell.
|
|
19
|
+
*
|
|
20
|
+
* Renders a tiny non-interactive map using `usePreviewMap` with a derived adapter config.
|
|
21
|
+
* The map renders taller than the visible area to crop out the Google attribution at the bottom.
|
|
22
|
+
* Uses `cvaInteractableItem` with a hidden radio input for selection styling.
|
|
23
|
+
*
|
|
24
|
+
* @internal
|
|
25
|
+
*/
|
|
26
|
+
export declare const AppearancePreview: ({ adapterConfig, mapType, label, selected, onSelect, "data-testid": dataTestId, }: AppearancePreviewProps) => import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { AdapterConfig } from "@trackunit/react-map-adapter-shared";
|
|
2
|
+
import type { MapTheme, MapType } from "../core/types";
|
|
3
|
+
import type { AppearanceOption } from "./appearanceTypes";
|
|
4
|
+
type AppearancePreviewGridProps = Readonly<{
|
|
5
|
+
/** The adapter config from the main map (used to derive preview configs) */
|
|
6
|
+
adapterConfig: AdapterConfig;
|
|
7
|
+
/** Appearance options to display */
|
|
8
|
+
options: ReadonlyArray<AppearanceOption>;
|
|
9
|
+
/** Currently active theme */
|
|
10
|
+
currentTheme: MapTheme;
|
|
11
|
+
/** Currently active map type */
|
|
12
|
+
currentMapType: MapType;
|
|
13
|
+
/** Called when user selects an appearance option */
|
|
14
|
+
onChange: (theme: MapTheme, mapType: MapType) => void;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Grid of tiny live map previews for selecting map appearance.
|
|
18
|
+
*
|
|
19
|
+
* Each preview renders a real map instance using `usePreviewMap` with
|
|
20
|
+
* a derived adapter config. The grid is rendered as a `radiogroup`
|
|
21
|
+
* for accessibility.
|
|
22
|
+
*
|
|
23
|
+
* This component is always rendered inside a menu (as a custom menu item),
|
|
24
|
+
* so it uses menu-appropriate spacing (`px-3 py-2`).
|
|
25
|
+
*
|
|
26
|
+
* @internal
|
|
27
|
+
*/
|
|
28
|
+
export declare const AppearancePreviewGrid: ({ adapterConfig, options, currentTheme, currentMapType, onChange, }: AppearancePreviewGridProps) => import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import type { AdapterConfig } from "@trackunit/react-map-adapter-shared";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { type MapActions, type MapStatus, type MapTheme, type MapType } from "../core/types";
|
|
4
|
+
/**
|
|
5
|
+
* Increment this number to invalidate stored appearance settings in localStorage
|
|
6
|
+
* and reset all users to defaults.
|
|
7
|
+
*/
|
|
8
|
+
export declare const APPEARANCE_SETTINGS_VERSION = 1;
|
|
9
|
+
export declare const persistedAppearanceSchema: z.ZodObject<{
|
|
10
|
+
theme: z.ZodEnum<["light", "dark"]>;
|
|
11
|
+
mapType: z.ZodEnum<["roadmap", "satellite", "hybrid"]>;
|
|
12
|
+
showRoads: z.ZodBoolean;
|
|
13
|
+
} & {
|
|
14
|
+
version: z.ZodLiteral<1>;
|
|
15
|
+
}, "strip", z.ZodTypeAny, {
|
|
16
|
+
mapType: "roadmap" | "satellite" | "hybrid";
|
|
17
|
+
theme: "light" | "dark";
|
|
18
|
+
version: 1;
|
|
19
|
+
showRoads: boolean;
|
|
20
|
+
}, {
|
|
21
|
+
mapType: "roadmap" | "satellite" | "hybrid";
|
|
22
|
+
theme: "light" | "dark";
|
|
23
|
+
version: 1;
|
|
24
|
+
showRoads: boolean;
|
|
25
|
+
}>;
|
|
26
|
+
/** Appearance state persisted to localStorage (MapAppearance + migration version) */
|
|
27
|
+
export type PersistedAppearance = Readonly<z.infer<typeof persistedAppearanceSchema>>;
|
|
28
|
+
/** Default persisted appearance when nothing is stored */
|
|
29
|
+
export declare const DEFAULT_PERSISTED_APPEARANCE: PersistedAppearance;
|
|
30
|
+
type SetThemeAction = Readonly<{
|
|
31
|
+
type: "setTheme";
|
|
32
|
+
payload: MapTheme;
|
|
33
|
+
}>;
|
|
34
|
+
type SetMapTypeAction = Readonly<{
|
|
35
|
+
type: "setMapType";
|
|
36
|
+
payload: MapType;
|
|
37
|
+
}>;
|
|
38
|
+
type SetShowRoadsAction = Readonly<{
|
|
39
|
+
type: "setShowRoads";
|
|
40
|
+
payload: boolean;
|
|
41
|
+
}>;
|
|
42
|
+
export type AppearanceAction = Readonly<SetThemeAction | SetMapTypeAction | SetShowRoadsAction>;
|
|
43
|
+
/** Reducer for persisted appearance state */
|
|
44
|
+
export declare const appearanceReducer: (state: PersistedAppearance, action: AppearanceAction) => PersistedAppearance;
|
|
45
|
+
/** Configuration for which appearance options to show in the settings panel */
|
|
46
|
+
export type AppearanceOptions = Readonly<{
|
|
47
|
+
/** Which themes to offer. Default: ["light", "dark"] */
|
|
48
|
+
themes?: ReadonlyArray<MapTheme>;
|
|
49
|
+
/** Which map types to offer. Default: ["roadmap", "satellite"] */
|
|
50
|
+
mapTypes?: ReadonlyArray<MapType>;
|
|
51
|
+
/** Whether to show the roads toggle when satellite/hybrid is selected. Default: true */
|
|
52
|
+
roads?: boolean;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Narrowed API surface that useMapAppearanceControls actually needs.
|
|
56
|
+
* Accepts the full MapApi (structural subtyping) but avoids
|
|
57
|
+
* coupling the hook to fields it never touches.
|
|
58
|
+
*/
|
|
59
|
+
export type MapAppearanceApi = Readonly<{
|
|
60
|
+
state: MapStatus;
|
|
61
|
+
actions: MapActions;
|
|
62
|
+
adapterConfig: AdapterConfig;
|
|
63
|
+
}>;
|
|
64
|
+
/** Parameters for the useMapAppearanceControls hook */
|
|
65
|
+
export type UseMapAppearanceControlsParams = Readonly<{
|
|
66
|
+
/** The map API object from useMap (only state, actions, and adapterConfig are used) */
|
|
67
|
+
api: MapAppearanceApi;
|
|
68
|
+
/** Optional: configure which appearance options to show */
|
|
69
|
+
options?: AppearanceOptions;
|
|
70
|
+
/** Optional: localStorage persistence key. Default: "map-appearance-settings" */
|
|
71
|
+
persistenceKey?: string;
|
|
72
|
+
}>;
|
|
73
|
+
/** A single appearance option shown in the preview grid */
|
|
74
|
+
export type AppearanceOption = Readonly<{
|
|
75
|
+
/** Unique key for this option */
|
|
76
|
+
key: string;
|
|
77
|
+
/** Display label (translated) */
|
|
78
|
+
label: string;
|
|
79
|
+
/** Theme for this option */
|
|
80
|
+
theme: MapTheme;
|
|
81
|
+
/** Map type for this option */
|
|
82
|
+
mapType: MapType;
|
|
83
|
+
}>;
|
|
84
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { MenuControlConfig } from "../controls/types";
|
|
2
|
+
import { type UseMapAppearanceControlsParams } from "./appearanceTypes";
|
|
3
|
+
/**
|
|
4
|
+
* Hook that returns `ControlConfig[]` for the map appearance settings area.
|
|
5
|
+
*
|
|
6
|
+
* Manages appearance state (theme, map type, roads toggle) using `useLocalStorageReducer`
|
|
7
|
+
* with Zod schema validation. Bidirectionally syncs with the adapter's
|
|
8
|
+
* `api.state.appearance` so external changes (e.g. from Storybook controls)
|
|
9
|
+
* are reflected in the UI and localStorage.
|
|
10
|
+
*
|
|
11
|
+
* Returns an array with a single `MenuControlConfig` that contains:
|
|
12
|
+
* - A custom item with a grid of live tiny map previews
|
|
13
|
+
* - A toggle item for roads overlay (when satellite/hybrid is selected)
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```tsx
|
|
17
|
+
* const appearanceControls = useMapAppearanceControls({ api });
|
|
18
|
+
*
|
|
19
|
+
* const controlsConfig: ControlsConfig = {
|
|
20
|
+
* navigation: { controls: navigationControls },
|
|
21
|
+
* settings: { controls: appearanceControls },
|
|
22
|
+
* tools: null,
|
|
23
|
+
* statistics: { controls: [] },
|
|
24
|
+
* };
|
|
25
|
+
*
|
|
26
|
+
* <Controls api={api} controlsConfig={controlsConfig} />
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export declare const useMapAppearanceControls: ({ api, options: appearanceOptions, persistenceKey, }: UseMapAppearanceControlsParams) => ReadonlyArray<MenuControlConfig>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { type CommonProps, type Refable, type Styleable } from "@trackunit/react-components";
|
|
2
|
+
import { type HTMLAttributes } from "react";
|
|
3
|
+
import type { MapTheme } from "../core/types";
|
|
4
|
+
import type { MarkerState } from "../markers/model/markerDomTypes";
|
|
5
|
+
import { type MarkerColorConfig } from "../markers/shared/markerColors";
|
|
6
|
+
import { type ClusterStickProps } from "./ClusterStick";
|
|
7
|
+
/** Pre-computed doughnut segment input. `weight` maps directly to `value` in `BaseDataEntry`. */
|
|
8
|
+
export type ClusterSegment = {
|
|
9
|
+
readonly color: string;
|
|
10
|
+
readonly weight: number;
|
|
11
|
+
};
|
|
12
|
+
/** Distributive `Omit` so the `label`/`aria-label` discriminated union of `ClusterStickProps` is preserved. */
|
|
13
|
+
type DistributiveOmit<TUnion, TKey extends string> = TUnion extends unknown ? Omit<TUnion, TKey> : never;
|
|
14
|
+
/**
|
|
15
|
+
* Per-member stick input. `onStickClick` is owned by `ClusterMarker` and forwarded with the stick's `id`.
|
|
16
|
+
* `positioning` is computed by `ClusterMarker` from the fan angle — callers do not provide it.
|
|
17
|
+
* `open` is managed internally — callers do not provide it.
|
|
18
|
+
*/
|
|
19
|
+
export type ClusterMarkerStickInput = DistributiveOmit<ClusterStickProps, "onStickClick" | "positioning" | "open">;
|
|
20
|
+
type ClusterMarkerDivHandlers = Pick<HTMLAttributes<HTMLDivElement>, "onClick" | "onKeyDown" | "onMouseEnter" | "onMouseLeave" | "onFocus" | "onBlur">;
|
|
21
|
+
type ClusterMarkerBaseProps = CommonProps & Styleable & Refable<HTMLDivElement> & ClusterMarkerDivHandlers & {
|
|
22
|
+
/** Total member count. Rendered via {@link formatClusterCount}. */
|
|
23
|
+
count: number;
|
|
24
|
+
/** Doughnut ring segments. Empty array suppresses the ring. */
|
|
25
|
+
segments: ReadonlyArray<ClusterSegment>;
|
|
26
|
+
/**
|
|
27
|
+
* Optional cluster member sticks fanned out around the bubble at evenly spread angles.
|
|
28
|
+
* Intended for clusters with 6 or fewer members; above that, stick labels become crowded.
|
|
29
|
+
*/
|
|
30
|
+
sticks?: ReadonlyArray<ClusterMarkerStickInput>;
|
|
31
|
+
/** Fired by each fanned-out stick with its `id`. */
|
|
32
|
+
onStickClick?: (id: string) => void;
|
|
33
|
+
state?: MarkerState;
|
|
34
|
+
theme: MapTheme;
|
|
35
|
+
colorConfig?: MarkerColorConfig;
|
|
36
|
+
};
|
|
37
|
+
export type ClusterMarkerProps = ClusterMarkerBaseProps & {
|
|
38
|
+
"aria-label"?: string;
|
|
39
|
+
};
|
|
40
|
+
export declare const ClusterMarker: import("react").ForwardRefExoticComponent<Omit<ClusterMarkerProps, "ref"> & import("react").RefAttributes<HTMLDivElement>>;
|
|
41
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { type CommonProps, type Refable, type Styleable } from "@trackunit/react-components";
|
|
2
|
+
import { type HTMLAttributes, type ReactElement } from "react";
|
|
3
|
+
import type { MapTheme } from "../core/types";
|
|
4
|
+
import type { ClusterStickState, MarkerDomSize, StickPositioning } from "../markers/model/markerDomTypes";
|
|
5
|
+
import { type MarkerColorConfig } from "../markers/shared/markerColors";
|
|
6
|
+
type ClusterStickDivHandlers = Pick<HTMLAttributes<HTMLDivElement>, "onKeyDown" | "onMouseEnter" | "onMouseLeave" | "onFocus" | "onBlur">;
|
|
7
|
+
type ClusterStickBaseProps = CommonProps & Styleable & Refable<HTMLDivElement> & ClusterStickDivHandlers & {
|
|
8
|
+
/** Stable identifier for the stick; forwarded to `onStickClick`. */
|
|
9
|
+
id: string;
|
|
10
|
+
/** Indicator fill (CSS color). Shares the disc/pill color system with `MapMarker`. */
|
|
11
|
+
color: string;
|
|
12
|
+
state?: ClusterStickState;
|
|
13
|
+
size: MarkerDomSize;
|
|
14
|
+
theme: MapTheme;
|
|
15
|
+
colorConfig?: MarkerColorConfig;
|
|
16
|
+
icon?: ReactElement | null;
|
|
17
|
+
/**
|
|
18
|
+
* How the pill is positioned relative to the cluster anchor.
|
|
19
|
+
* Defaults to `MARKER_TUNING.stick.defaultPositioning` (straight up, 40 px).
|
|
20
|
+
* In practice `ClusterMarker` always computes a polar fan angle and passes it here.
|
|
21
|
+
*/
|
|
22
|
+
positioning?: StickPositioning;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the stick is fanned out (`true`, default) or animating back to the
|
|
25
|
+
* cluster center (`false`). `ClusterMarker` sets this to `false` for sticks
|
|
26
|
+
* that have left the `sticks` array so they can animate in before unmounting.
|
|
27
|
+
* Callers rendering `ClusterStick` standalone should leave this at the default.
|
|
28
|
+
*/
|
|
29
|
+
open?: boolean;
|
|
30
|
+
/** Fires with the `id` prop on click or keyboard activation. */
|
|
31
|
+
onStickClick?: (id: string) => void;
|
|
32
|
+
};
|
|
33
|
+
export type ClusterStickProps = (ClusterStickBaseProps & {
|
|
34
|
+
label: string;
|
|
35
|
+
"aria-label"?: string;
|
|
36
|
+
}) | (ClusterStickBaseProps & {
|
|
37
|
+
label?: never;
|
|
38
|
+
"aria-label": string;
|
|
39
|
+
});
|
|
40
|
+
export declare const ClusterStick: import("react").ForwardRefExoticComponent<(Omit<CommonProps & Styleable & Refable<HTMLDivElement> & ClusterStickDivHandlers & {
|
|
41
|
+
/** Stable identifier for the stick; forwarded to `onStickClick`. */
|
|
42
|
+
id: string;
|
|
43
|
+
/** Indicator fill (CSS color). Shares the disc/pill color system with `MapMarker`. */
|
|
44
|
+
color: string;
|
|
45
|
+
state?: ClusterStickState;
|
|
46
|
+
size: MarkerDomSize;
|
|
47
|
+
theme: MapTheme;
|
|
48
|
+
colorConfig?: MarkerColorConfig;
|
|
49
|
+
icon?: ReactElement | null;
|
|
50
|
+
/**
|
|
51
|
+
* How the pill is positioned relative to the cluster anchor.
|
|
52
|
+
* Defaults to `MARKER_TUNING.stick.defaultPositioning` (straight up, 40 px).
|
|
53
|
+
* In practice `ClusterMarker` always computes a polar fan angle and passes it here.
|
|
54
|
+
*/
|
|
55
|
+
positioning?: StickPositioning;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the stick is fanned out (`true`, default) or animating back to the
|
|
58
|
+
* cluster center (`false`). `ClusterMarker` sets this to `false` for sticks
|
|
59
|
+
* that have left the `sticks` array so they can animate in before unmounting.
|
|
60
|
+
* Callers rendering `ClusterStick` standalone should leave this at the default.
|
|
61
|
+
*/
|
|
62
|
+
open?: boolean;
|
|
63
|
+
/** Fires with the `id` prop on click or keyboard activation. */
|
|
64
|
+
onStickClick?: (id: string) => void;
|
|
65
|
+
} & {
|
|
66
|
+
label: string;
|
|
67
|
+
"aria-label"?: string;
|
|
68
|
+
}, "ref"> | Omit<CommonProps & Styleable & Refable<HTMLDivElement> & ClusterStickDivHandlers & {
|
|
69
|
+
/** Stable identifier for the stick; forwarded to `onStickClick`. */
|
|
70
|
+
id: string;
|
|
71
|
+
/** Indicator fill (CSS color). Shares the disc/pill color system with `MapMarker`. */
|
|
72
|
+
color: string;
|
|
73
|
+
state?: ClusterStickState;
|
|
74
|
+
size: MarkerDomSize;
|
|
75
|
+
theme: MapTheme;
|
|
76
|
+
colorConfig?: MarkerColorConfig;
|
|
77
|
+
icon?: ReactElement | null;
|
|
78
|
+
/**
|
|
79
|
+
* How the pill is positioned relative to the cluster anchor.
|
|
80
|
+
* Defaults to `MARKER_TUNING.stick.defaultPositioning` (straight up, 40 px).
|
|
81
|
+
* In practice `ClusterMarker` always computes a polar fan angle and passes it here.
|
|
82
|
+
*/
|
|
83
|
+
positioning?: StickPositioning;
|
|
84
|
+
/**
|
|
85
|
+
* Whether the stick is fanned out (`true`, default) or animating back to the
|
|
86
|
+
* cluster center (`false`). `ClusterMarker` sets this to `false` for sticks
|
|
87
|
+
* that have left the `sticks` array so they can animate in before unmounting.
|
|
88
|
+
* Callers rendering `ClusterStick` standalone should leave this at the default.
|
|
89
|
+
*/
|
|
90
|
+
open?: boolean;
|
|
91
|
+
/** Fires with the `id` prop on click or keyboard activation. */
|
|
92
|
+
onStickClick?: (id: string) => void;
|
|
93
|
+
} & {
|
|
94
|
+
label?: never;
|
|
95
|
+
"aria-label": string;
|
|
96
|
+
}, "ref">) & import("react").RefAttributes<HTMLDivElement>>;
|
|
97
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formats a cluster member count for display inside `MapCluster`.
|
|
3
|
+
*
|
|
4
|
+
* Rules:
|
|
5
|
+
* - `n < 1 000` → raw integer string
|
|
6
|
+
* - `1 000 ≤ n < 1 000 000` → `Xk` (truncated to whole thousands)
|
|
7
|
+
* - `n ≥ 1 000 000` → `X.Xm` (truncated to one decimal of millions)
|
|
8
|
+
*
|
|
9
|
+
* Truncation (not rounding) is used so the displayed value never overstates the count.
|
|
10
|
+
*/
|
|
11
|
+
export declare const formatClusterCount: (n: number) => string;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { MapTheme } from "../../core/types";
|
|
3
|
+
type ClusterMarkerCompactFormatsDemoProps = {
|
|
4
|
+
readonly theme: MapTheme;
|
|
5
|
+
};
|
|
6
|
+
export declare const ClusterMarkerCompactFormatsDemo: ({ theme }: ClusterMarkerCompactFormatsDemoProps) => ReactElement;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { MapTheme } from "../../core/types";
|
|
3
|
+
type ClusterMarkerCountOnlyDemoProps = {
|
|
4
|
+
readonly theme: MapTheme;
|
|
5
|
+
};
|
|
6
|
+
export declare const ClusterMarkerCountOnlyDemo: ({ theme }: ClusterMarkerCountOnlyDemoProps) => ReactElement;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { MapTheme } from "../../core/types";
|
|
3
|
+
import type { MarkerState } from "../../markers/model/markerDomTypes";
|
|
4
|
+
type ClusterMarkerDefaultDemoProps = {
|
|
5
|
+
readonly count: number;
|
|
6
|
+
readonly state: MarkerState;
|
|
7
|
+
readonly theme: MapTheme;
|
|
8
|
+
readonly showSegments: boolean;
|
|
9
|
+
readonly showSticks: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare const ClusterMarkerDefaultDemo: ({ count, state, theme, showSegments, showSticks, }: ClusterMarkerDefaultDemoProps) => ReactElement;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type ReactElement } from "react";
|
|
2
|
+
import type { MapTheme } from "../../core/types";
|
|
3
|
+
type ClusterMarkerPlaygroundDemoProps = {
|
|
4
|
+
readonly theme: MapTheme;
|
|
5
|
+
readonly stickCount: number;
|
|
6
|
+
readonly showSegments: boolean;
|
|
7
|
+
readonly showIndicators: boolean;
|
|
8
|
+
};
|
|
9
|
+
export declare const ClusterMarkerPlaygroundDemo: ({ theme, stickCount, showSegments, showIndicators, }: ClusterMarkerPlaygroundDemoProps) => ReactElement;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { MapTheme } from "../../core/types";
|
|
3
|
+
import type { MarkerState } from "../../markers/model/markerDomTypes";
|
|
4
|
+
type ClusterMarkerStateDemoProps = {
|
|
5
|
+
readonly theme: MapTheme;
|
|
6
|
+
readonly state: MarkerState;
|
|
7
|
+
};
|
|
8
|
+
export declare const ClusterMarkerStateDemo: ({ theme, state }: ClusterMarkerStateDemoProps) => ReactElement;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { MapTheme } from "../../core/types";
|
|
3
|
+
type ClusterMarkerWithSegmentsDemoProps = {
|
|
4
|
+
readonly theme: MapTheme;
|
|
5
|
+
};
|
|
6
|
+
export declare const ClusterMarkerWithSegmentsDemo: ({ theme }: ClusterMarkerWithSegmentsDemoProps) => ReactElement;
|
|
7
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactElement } from "react";
|
|
2
|
+
import type { MapTheme } from "../../core/types";
|
|
3
|
+
type ClusterMarkerWithSticksDemoProps = {
|
|
4
|
+
readonly theme: MapTheme;
|
|
5
|
+
readonly showSegments: boolean;
|
|
6
|
+
readonly showIndicators: boolean;
|
|
7
|
+
readonly stickCount: number;
|
|
8
|
+
};
|
|
9
|
+
export declare const ClusterMarkerWithSticksDemo: ({ theme, showSegments, showIndicators, stickCount, }: ClusterMarkerWithSticksDemoProps) => ReactElement;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { formatClusterCount } from "./formatClusterCount";
|
|
2
|
+
export type ClusterCountFormatHelpers = Readonly<{
|
|
3
|
+
formatClusterCount: typeof formatClusterCount;
|
|
4
|
+
}>;
|
|
5
|
+
/**
|
|
6
|
+
* Build-your-own hook: stable reference to the cluster count formatter.
|
|
7
|
+
*
|
|
8
|
+
* Returns `formatClusterCount` for consumers building custom cluster markers
|
|
9
|
+
* that need consistent `"1.2k / 3.4m"` formatting without reimplementing
|
|
10
|
+
* the truncation rules.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const { formatClusterCount } = useClusterCountFormat();
|
|
15
|
+
* // Inside your cluster render:
|
|
16
|
+
* return <div>{formatClusterCount(clusterCount)}</div>;
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
19
|
+
export declare const useClusterCountFormat: () => ClusterCountFormatHelpers;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { MapAnnotationDescriptor } from "../annotations/mapAnnotations";
|
|
2
|
+
type AnnotationRendererProps = Readonly<{
|
|
3
|
+
annotation: MapAnnotationDescriptor;
|
|
4
|
+
}>;
|
|
5
|
+
/**
|
|
6
|
+
* Renders a single map annotation based on its content type.
|
|
7
|
+
*
|
|
8
|
+
* - `"simple"`: compact pill with optional icon, label, and color; optional `onClick`
|
|
9
|
+
* renders as a `<button type="button">` instead of a non-interactive div
|
|
10
|
+
* - `"custom"`: delegates entirely to the descriptor's render function.
|
|
11
|
+
* The render function's root element is rendered directly (no wrapper),
|
|
12
|
+
* so it should handle its own overflow (e.g. truncation).
|
|
13
|
+
*
|
|
14
|
+
* @internal
|
|
15
|
+
*/
|
|
16
|
+
export declare const AnnotationRenderer: ({ annotation }: AnnotationRendererProps) => import("react/jsx-runtime").JSX.Element;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { MapAnnotationDescriptor } from "../annotations/mapAnnotations";
|
|
2
|
+
import "./AnnotationStack.css";
|
|
3
|
+
type AnnotationStackProps = Readonly<{
|
|
4
|
+
annotations: ReadonlyArray<MapAnnotationDescriptor>;
|
|
5
|
+
isExiting: boolean;
|
|
6
|
+
}>;
|
|
7
|
+
/**
|
|
8
|
+
* Renders annotations as a collapsible card-deck stack.
|
|
9
|
+
*
|
|
10
|
+
* Only the newest (last) annotation is fully visible. Older annotations
|
|
11
|
+
* peek behind it as offset strips. The stack expands on hover (temporary)
|
|
12
|
+
* or click (pinned).
|
|
13
|
+
*
|
|
14
|
+
* The expanded panel uses Floating UI with safePolygon so it doesn't
|
|
15
|
+
* close when moving the pointer between the reference and floating
|
|
16
|
+
* elements, and doesn't affect the surrounding Controls grid layout.
|
|
17
|
+
*
|
|
18
|
+
* @internal
|
|
19
|
+
*/
|
|
20
|
+
export declare const AnnotationStack: ({ annotations, isExiting }: AnnotationStackProps) => import("react/jsx-runtime").JSX.Element | null;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ComponentRef, RefObject } from "react";
|
|
2
|
+
import { type AvailableSpace } from "./renderingRules";
|
|
3
|
+
import type { ControlConfig, MenuPresentation } from "./types";
|
|
4
|
+
type ControlRendererProps = Readonly<{
|
|
5
|
+
availableSpace: AvailableSpace;
|
|
6
|
+
/** Ref to the controls overlay container, used to compute popover placement */
|
|
7
|
+
containerRef: RefObject<ComponentRef<"div"> | null>;
|
|
8
|
+
control: ControlConfig;
|
|
9
|
+
customPortalId?: string;
|
|
10
|
+
menuPresentation: MenuPresentation;
|
|
11
|
+
}>;
|
|
12
|
+
/**
|
|
13
|
+
* Renders a control based on its type using exhaustive switch.
|
|
14
|
+
* Calls resolveControl to compute rendering decisions, then passes
|
|
15
|
+
* both the config and resolved props to the presentational renderer.
|
|
16
|
+
*
|
|
17
|
+
* @internal
|
|
18
|
+
*/
|
|
19
|
+
export declare const ControlRenderer: ({ availableSpace, containerRef, control, customPortalId, menuPresentation, }: ControlRendererProps) => import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
export {};
|