@trackunit/react-map 0.1.6 → 0.1.14

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/index.cjs.js CHANGED
@@ -672,6 +672,30 @@ const useLayerPort = () => {
672
672
  return react.useContext(MapLayerContext);
673
673
  };
674
674
 
675
+ /**
676
+ * Default visual styles for each shape type.
677
+ *
678
+ * These are a map consumer concern — injected into the adapter via
679
+ * `createMapComponent` so adapters remain style-agnostic.
680
+ */
681
+ const SHAPE_STYLE_DEFAULTS = {
682
+ polygon: {
683
+ fillOpacity: 0.05,
684
+ strokeWidth: 1,
685
+ strokeOpacity: 1,
686
+ },
687
+ line: {
688
+ strokeWidth: 1,
689
+ strokeOpacity: 1,
690
+ },
691
+ point: {
692
+ fillOpacity: 0.2,
693
+ strokeWidth: 1,
694
+ strokeOpacity: 1,
695
+ pointRadius: 5,
696
+ },
697
+ };
698
+
675
699
  /**
676
700
  * CSS `max-height` of the Panel shell — `min(320px, 40vh)`.
677
701
  *
@@ -964,8 +988,6 @@ const MapLoadingState = ({ isLoading, error = false, className, style }) => {
964
988
  }, children: [isLoading ? jsxRuntime.jsx(reactComponents.Spinner, { "aria-label": t("map.loading"), centering: "centered", size: "large" }) : null, error ? (jsxRuntime.jsx("span", { role: "alert", children: jsxRuntime.jsx(reactComponents.Text, { italicize: true, subtle: true, weight: "thick", children: t("map.loadingErrorMessage") }) })) : null] }));
965
989
  };
966
990
 
967
- const SafeAreaLayoutContext = react.createContext(null);
968
-
969
991
  /** Build padding style that combines spacing with safe area insets. */
970
992
  const padWithInsets = (availableSpace, insets) => {
971
993
  const base = availableSpace === "constrained" ? "var(--spacing-2)" : "var(--spacing-4)";
@@ -975,6 +997,8 @@ const padWithInsets = (availableSpace, insets) => {
975
997
  : { padding: base };
976
998
  };
977
999
 
1000
+ const SafeAreaLayoutContext = react.createContext(null);
1001
+
978
1002
  /**
979
1003
  * Renders the AnnotationStack when no external renderer (Controls) has
980
1004
  * claimed annotation rendering. Subscribes to the store's renderer-claim
@@ -1081,7 +1105,10 @@ const SafeAreaOverlay = ({ safeAreaInsets, safeAreaContentRef, children }) => {
1081
1105
  *
1082
1106
  * @internal
1083
1107
  */
1084
- const createMapComponent = ({ adapter, Renderer, adapterName, containerRefHolder, containerId, annotationStore, loadingIndicatorStore, panelStore, safeAreaInsets, }) => {
1108
+ const createMapComponent = ({ adapter, Renderer, adapterName, containerRefHolder, containerId, annotationStore, loadingIndicatorStore, panelStore, safeAreaInsets, shapeStyleDefaults = SHAPE_STYLE_DEFAULTS, }) => {
1109
+ // Inject consumer-owned shape style defaults into the adapter's layer port so
1110
+ // adapters don't need to hard-code visual defaults themselves.
1111
+ adapter.layers?.setShapeStyleDefaults(shapeStyleDefaults);
1085
1112
  // Preview maps (no containerRefHolder) — Renderer fills a relative wrapper; readiness overlay lives here (SAGA-374).
1086
1113
  // No `min-h-[200px]` on this shell: thumbnails (e.g. AppearancePreview 72×96) must respect consumer `style` /
1087
1114
  // `className`. The full-map branch keeps the floor on the inner map cell / Mapbox container.
@@ -6470,8 +6497,8 @@ const useShapes = (options) => {
6470
6497
  const mapEntry = featureKey !== undefined ? featureStyles.get(featureKey) : undefined;
6471
6498
  const resolvedStyle = mapEntry ?? resolveStyleRef.current(feature);
6472
6499
  const strokeColor = resolvedStyle.stroke ?? "#000";
6473
- const pointRadius = mapEntry?.pointRadius ?? resolvedStyle.pointRadius ?? reactMapAdapterShared.SHAPE_STYLE_DEFAULTS.point.pointRadius;
6474
- const strokeWidth = mapEntry?.strokeWidth ?? resolvedStyle.strokeWidth ?? reactMapAdapterShared.SHAPE_STYLE_DEFAULTS.point.strokeWidth;
6500
+ const pointRadius = mapEntry?.pointRadius ?? resolvedStyle.pointRadius ?? SHAPE_STYLE_DEFAULTS.point.pointRadius;
6501
+ const strokeWidth = mapEntry?.strokeWidth ?? resolvedStyle.strokeWidth ?? SHAPE_STYLE_DEFAULTS.point.strokeWidth;
6475
6502
  const auto = buildMultiPartDecorations(feature, strokeColor, pointRadius, strokeWidth);
6476
6503
  return auto.length > 0 ? [...custom, ...auto] : custom;
6477
6504
  }, [skipAutoDecorations, featureStyles]);
package/index.esm.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
2
2
  import { useNamespaceTranslation, registerTranslations } from '@trackunit/i18n-library-translation';
3
- import { INITIAL_CAMERA_STATE, INITIAL_MAP_STATUS, KEYBOARD_PAN_AMOUNT, KEYBOARD_ZOOM_AMOUNT, mapAppearanceSchema, DEFAULT_MAP_APPEARANCE, WORLD_BBOX, INITIAL_INTERACTION_STATE, darkenColor, lightenColor, mapThemeSchema, SHAPE_STYLE_DEFAULTS, extractSourceData, computeMarkerDomPortalZIndex, densifyGeodesicFeatures, angularDistance, intermediatePoint, GEODESIC_MAX_SEGMENT_KM, geometryTypeToShapeType, resolveStrokeColors } from '@trackunit/react-map-adapter-shared';
3
+ import { INITIAL_CAMERA_STATE, INITIAL_MAP_STATUS, KEYBOARD_PAN_AMOUNT, KEYBOARD_ZOOM_AMOUNT, mapAppearanceSchema, DEFAULT_MAP_APPEARANCE, WORLD_BBOX, INITIAL_INTERACTION_STATE, darkenColor, lightenColor, mapThemeSchema, extractSourceData, computeMarkerDomPortalZIndex, densifyGeodesicFeatures, angularDistance, intermediatePoint, GEODESIC_MAX_SEGMENT_KM, geometryTypeToShapeType, resolveStrokeColors } from '@trackunit/react-map-adapter-shared';
4
4
  export { ANCHOR_SELECTOR, DEFAULT_MAP_APPEARANCE, HIT_SURFACE_SELECTOR, INITIAL_CAMERA_STATE, INITIAL_INTERACTION_STATE, INITIAL_MAP_STATE, INITIAL_MAP_STATUS, computeMarkerDomPortalZIndex, defineAdapter, geometryTypeToShapeType, mapAppearanceSchema, mapThemeSchema, mapTypeSchema } from '@trackunit/react-map-adapter-shared';
5
5
  import { useSyncExternalStore, useMemo, useState, useRef, useCallback, useLayoutEffect, useEffect, useReducer, createContext, useContext, memo, Suspense, useId, Fragment as Fragment$1, forwardRef } from 'react';
6
6
  import { cvaMerge } from '@trackunit/css-class-variance-utilities';
@@ -671,6 +671,30 @@ const useLayerPort = () => {
671
671
  return useContext(MapLayerContext);
672
672
  };
673
673
 
674
+ /**
675
+ * Default visual styles for each shape type.
676
+ *
677
+ * These are a map consumer concern — injected into the adapter via
678
+ * `createMapComponent` so adapters remain style-agnostic.
679
+ */
680
+ const SHAPE_STYLE_DEFAULTS = {
681
+ polygon: {
682
+ fillOpacity: 0.05,
683
+ strokeWidth: 1,
684
+ strokeOpacity: 1,
685
+ },
686
+ line: {
687
+ strokeWidth: 1,
688
+ strokeOpacity: 1,
689
+ },
690
+ point: {
691
+ fillOpacity: 0.2,
692
+ strokeWidth: 1,
693
+ strokeOpacity: 1,
694
+ pointRadius: 5,
695
+ },
696
+ };
697
+
674
698
  /**
675
699
  * CSS `max-height` of the Panel shell — `min(320px, 40vh)`.
676
700
  *
@@ -963,8 +987,6 @@ const MapLoadingState = ({ isLoading, error = false, className, style }) => {
963
987
  }, children: [isLoading ? jsx(Spinner, { "aria-label": t("map.loading"), centering: "centered", size: "large" }) : null, error ? (jsx("span", { role: "alert", children: jsx(Text, { italicize: true, subtle: true, weight: "thick", children: t("map.loadingErrorMessage") }) })) : null] }));
964
988
  };
965
989
 
966
- const SafeAreaLayoutContext = createContext(null);
967
-
968
990
  /** Build padding style that combines spacing with safe area insets. */
969
991
  const padWithInsets = (availableSpace, insets) => {
970
992
  const base = availableSpace === "constrained" ? "var(--spacing-2)" : "var(--spacing-4)";
@@ -974,6 +996,8 @@ const padWithInsets = (availableSpace, insets) => {
974
996
  : { padding: base };
975
997
  };
976
998
 
999
+ const SafeAreaLayoutContext = createContext(null);
1000
+
977
1001
  /**
978
1002
  * Renders the AnnotationStack when no external renderer (Controls) has
979
1003
  * claimed annotation rendering. Subscribes to the store's renderer-claim
@@ -1080,7 +1104,10 @@ const SafeAreaOverlay = ({ safeAreaInsets, safeAreaContentRef, children }) => {
1080
1104
  *
1081
1105
  * @internal
1082
1106
  */
1083
- const createMapComponent = ({ adapter, Renderer, adapterName, containerRefHolder, containerId, annotationStore, loadingIndicatorStore, panelStore, safeAreaInsets, }) => {
1107
+ const createMapComponent = ({ adapter, Renderer, adapterName, containerRefHolder, containerId, annotationStore, loadingIndicatorStore, panelStore, safeAreaInsets, shapeStyleDefaults = SHAPE_STYLE_DEFAULTS, }) => {
1108
+ // Inject consumer-owned shape style defaults into the adapter's layer port so
1109
+ // adapters don't need to hard-code visual defaults themselves.
1110
+ adapter.layers?.setShapeStyleDefaults(shapeStyleDefaults);
1084
1111
  // Preview maps (no containerRefHolder) — Renderer fills a relative wrapper; readiness overlay lives here (SAGA-374).
1085
1112
  // No `min-h-[200px]` on this shell: thumbnails (e.g. AppearancePreview 72×96) must respect consumer `style` /
1086
1113
  // `className`. The full-map branch keeps the floor on the inner map cell / Mapbox container.
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@trackunit/react-map",
3
- "version": "0.1.6",
3
+ "version": "0.1.14",
4
4
  "repository": "https://github.com/Trackunit/manager",
5
5
  "license": "SEE LICENSE IN LICENSE.txt",
6
6
  "engines": {
7
7
  "node": ">=24.x"
8
8
  },
9
9
  "dependencies": {
10
- "@trackunit/react-components": "2.1.24",
11
- "@trackunit/css-class-variance-utilities": "1.13.30",
12
- "@trackunit/react-form-components": "2.1.25",
13
- "@trackunit/react-core-hooks": "1.17.38",
14
- "@trackunit/geo-json-utils": "1.14.32",
15
- "@trackunit/i18n-library-translation": "2.0.26",
16
- "@trackunit/react-modal": "2.1.26",
10
+ "@trackunit/react-components": "2.1.28",
11
+ "@trackunit/css-class-variance-utilities": "1.13.32",
12
+ "@trackunit/react-form-components": "2.1.29",
13
+ "@trackunit/react-core-hooks": "1.17.41",
14
+ "@trackunit/geo-json-utils": "1.14.35",
15
+ "@trackunit/i18n-library-translation": "2.0.29",
16
+ "@trackunit/react-modal": "2.1.30",
17
17
  "react-minimal-pie-chart": "^8.4.0",
18
- "@trackunit/react-map-adapter-shared": "0.0.12",
19
- "@trackunit/ui-design-tokens": "1.13.30",
18
+ "@trackunit/react-map-adapter-shared": "0.0.16",
19
+ "@trackunit/ui-design-tokens": "1.13.32",
20
20
  "@floating-ui/react": "^0.26.25",
21
21
  "es-toolkit": "^1.39.10",
22
22
  "tailwind-merge": "^2.0.0",
@@ -1,4 +1,4 @@
1
- import type { AdapterInstance, AdapterRendererProps, SafeAreaInsets } from "@trackunit/react-map-adapter-shared";
1
+ import type { AdapterInstance, AdapterRendererProps, SafeAreaInsets, ShapeStyleDefaults } from "@trackunit/react-map-adapter-shared";
2
2
  import { type ComponentType } from "react";
3
3
  import type { MapAnnotationStore } from "../annotations/mapAnnotations";
4
4
  import type { PanelStore } from "../panel/store/panels";
@@ -14,6 +14,16 @@ type CreateMapComponentConfig = Readonly<{
14
14
  loadingIndicatorStore?: MapLoadingIndicatorStore;
15
15
  panelStore?: PanelStore;
16
16
  safeAreaInsets?: SafeAreaInsets | null;
17
+ /**
18
+ * Per-shape-type visual defaults injected into the adapter's layer port.
19
+ * Defaults to `SHAPE_STYLE_DEFAULTS` from react-map. Override to customise
20
+ * adapter stroke/fill fallbacks across all adapters.
21
+ *
22
+ * Note: only affects adapter-level rendering fallbacks. React-side decoration
23
+ * geometry (e.g. multi-part "+" badge sizing in `useShapes`) continues to use
24
+ * the built-in `SHAPE_STYLE_DEFAULTS`.
25
+ */
26
+ shapeStyleDefaults?: ShapeStyleDefaults;
17
27
  }>;
18
28
  /**
19
29
  * Creates a named Map component for the given adapter.
@@ -28,5 +38,5 @@ type CreateMapComponentConfig = Readonly<{
28
38
  *
29
39
  * @internal
30
40
  */
31
- export declare const createMapComponent: ({ adapter, Renderer, adapterName, containerRefHolder, containerId, annotationStore, loadingIndicatorStore, panelStore, safeAreaInsets, }: CreateMapComponentConfig) => ComponentType<MapComponentProps>;
41
+ export declare const createMapComponent: ({ adapter, Renderer, adapterName, containerRefHolder, containerId, annotationStore, loadingIndicatorStore, panelStore, safeAreaInsets, shapeStyleDefaults, }: CreateMapComponentConfig) => ComponentType<MapComponentProps>;
32
42
  export {};
@@ -10,6 +10,7 @@ export declare const VIEWPORT_BOUNDS: GeoJsonBbox;
10
10
  export declare const INTERIOR_ONLY_BOUNDS: GeoJsonBbox;
11
11
  export type MockLayerPort = LayerPort & {
12
12
  setSnapshot: Mock;
13
+ setShapeStyleDefaults: Mock;
13
14
  onEntityInteraction: Mock;
14
15
  onBackgroundClick: Mock;
15
16
  onSourceReady: Mock;
@@ -12,6 +12,7 @@ export declare const MapLayerContext: import("react").Context<Readonly<{
12
12
  onEntityInteraction: (handler: import("@trackunit/react-map-adapter-shared").EntityInteractionHandler) => () => void;
13
13
  onBackgroundClick: (handler: () => void) => () => void;
14
14
  onSourceReady: (configId: string, callback: () => void) => () => void;
15
+ setShapeStyleDefaults: (defaults: import("@trackunit/react-map-adapter-shared").ShapeStyleDefaults) => void;
15
16
  markerPortals?: import("@trackunit/react-map-adapter-shared").DomPortalStore | null;
16
17
  clusterPortals?: import("@trackunit/react-map-adapter-shared").DomPortalStore | null;
17
18
  }> | null>;
@@ -0,0 +1,8 @@
1
+ import type { ShapeStyleDefaults } from "@trackunit/react-map-adapter-shared";
2
+ /**
3
+ * Default visual styles for each shape type.
4
+ *
5
+ * These are a map consumer concern — injected into the adapter via
6
+ * `createMapComponent` so adapters remain style-agnostic.
7
+ */
8
+ export declare const SHAPE_STYLE_DEFAULTS: ShapeStyleDefaults;