@trackunit/react-map 0.2.30-alpha-0322e181a48.0 → 0.2.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/index.cjs.js +34 -23
  2. package/index.esm.js +35 -24
  3. package/package.json +10 -10
  4. package/src/layers/useShapes/multiPartDecorations.d.ts +9 -5
  5. /package/{translation10.cjs.js → translation.cjs10.js} +0 -0
  6. /package/{translation11.cjs.js → translation.cjs11.js} +0 -0
  7. /package/{translation12.cjs.js → translation.cjs12.js} +0 -0
  8. /package/{translation13.cjs.js → translation.cjs13.js} +0 -0
  9. /package/{translation14.cjs.js → translation.cjs14.js} +0 -0
  10. /package/{translation15.cjs.js → translation.cjs15.js} +0 -0
  11. /package/{translation16.cjs.js → translation.cjs16.js} +0 -0
  12. /package/{translation17.cjs.js → translation.cjs17.js} +0 -0
  13. /package/{translation2.cjs.js → translation.cjs2.js} +0 -0
  14. /package/{translation3.cjs.js → translation.cjs3.js} +0 -0
  15. /package/{translation4.cjs.js → translation.cjs4.js} +0 -0
  16. /package/{translation5.cjs.js → translation.cjs5.js} +0 -0
  17. /package/{translation6.cjs.js → translation.cjs6.js} +0 -0
  18. /package/{translation7.cjs.js → translation.cjs7.js} +0 -0
  19. /package/{translation8.cjs.js → translation.cjs8.js} +0 -0
  20. /package/{translation9.cjs.js → translation.cjs9.js} +0 -0
  21. /package/{translation10.esm.js → translation.esm10.js} +0 -0
  22. /package/{translation11.esm.js → translation.esm11.js} +0 -0
  23. /package/{translation12.esm.js → translation.esm12.js} +0 -0
  24. /package/{translation13.esm.js → translation.esm13.js} +0 -0
  25. /package/{translation14.esm.js → translation.esm14.js} +0 -0
  26. /package/{translation15.esm.js → translation.esm15.js} +0 -0
  27. /package/{translation16.esm.js → translation.esm16.js} +0 -0
  28. /package/{translation17.esm.js → translation.esm17.js} +0 -0
  29. /package/{translation2.esm.js → translation.esm2.js} +0 -0
  30. /package/{translation3.esm.js → translation.esm3.js} +0 -0
  31. /package/{translation4.esm.js → translation.esm4.js} +0 -0
  32. /package/{translation5.esm.js → translation.esm5.js} +0 -0
  33. /package/{translation6.esm.js → translation.esm6.js} +0 -0
  34. /package/{translation7.esm.js → translation.esm7.js} +0 -0
  35. /package/{translation8.esm.js → translation.esm8.js} +0 -0
  36. /package/{translation9.esm.js → translation.esm9.js} +0 -0
package/index.cjs.js CHANGED
@@ -59,22 +59,22 @@ const translations = {
59
59
  default: defaultTranslations,
60
60
  languages: {
61
61
  de: () => Promise.resolve().then(function () { return require('./translation.cjs.js'); }),
62
- da: () => Promise.resolve().then(function () { return require('./translation2.cjs.js'); }),
63
- cs: () => Promise.resolve().then(function () { return require('./translation3.cjs.js'); }),
64
- nl: () => Promise.resolve().then(function () { return require('./translation4.cjs.js'); }),
65
- fr: () => Promise.resolve().then(function () { return require('./translation5.cjs.js'); }),
66
- fi: () => Promise.resolve().then(function () { return require('./translation6.cjs.js'); }),
67
- hu: () => Promise.resolve().then(function () { return require('./translation7.cjs.js'); }),
68
- it: () => Promise.resolve().then(function () { return require('./translation8.cjs.js'); }),
69
- nb: () => Promise.resolve().then(function () { return require('./translation9.cjs.js'); }),
70
- pl: () => Promise.resolve().then(function () { return require('./translation10.cjs.js'); }),
71
- pt: () => Promise.resolve().then(function () { return require('./translation11.cjs.js'); }),
72
- ru: () => Promise.resolve().then(function () { return require('./translation12.cjs.js'); }),
73
- ro: () => Promise.resolve().then(function () { return require('./translation13.cjs.js'); }),
74
- es: () => Promise.resolve().then(function () { return require('./translation14.cjs.js'); }),
75
- sv: () => Promise.resolve().then(function () { return require('./translation15.cjs.js'); }),
76
- ja: () => Promise.resolve().then(function () { return require('./translation16.cjs.js'); }),
77
- th: () => Promise.resolve().then(function () { return require('./translation17.cjs.js'); }),
62
+ da: () => Promise.resolve().then(function () { return require('./translation.cjs2.js'); }),
63
+ cs: () => Promise.resolve().then(function () { return require('./translation.cjs3.js'); }),
64
+ nl: () => Promise.resolve().then(function () { return require('./translation.cjs4.js'); }),
65
+ fr: () => Promise.resolve().then(function () { return require('./translation.cjs5.js'); }),
66
+ fi: () => Promise.resolve().then(function () { return require('./translation.cjs6.js'); }),
67
+ hu: () => Promise.resolve().then(function () { return require('./translation.cjs7.js'); }),
68
+ it: () => Promise.resolve().then(function () { return require('./translation.cjs8.js'); }),
69
+ nb: () => Promise.resolve().then(function () { return require('./translation.cjs9.js'); }),
70
+ pl: () => Promise.resolve().then(function () { return require('./translation.cjs10.js'); }),
71
+ pt: () => Promise.resolve().then(function () { return require('./translation.cjs11.js'); }),
72
+ ru: () => Promise.resolve().then(function () { return require('./translation.cjs12.js'); }),
73
+ ro: () => Promise.resolve().then(function () { return require('./translation.cjs13.js'); }),
74
+ es: () => Promise.resolve().then(function () { return require('./translation.cjs14.js'); }),
75
+ sv: () => Promise.resolve().then(function () { return require('./translation.cjs15.js'); }),
76
+ ja: () => Promise.resolve().then(function () { return require('./translation.cjs16.js'); }),
77
+ th: () => Promise.resolve().then(function () { return require('./translation.cjs17.js'); }),
78
78
  },
79
79
  };
80
80
  /**
@@ -6522,22 +6522,33 @@ const CORNER_OFFSET_FACTOR = 0.707;
6522
6522
  /**
6523
6523
  * Generate multi-geometry "+" badge decorations for a feature.
6524
6524
  *
6525
- * Returns one decoration per part of a multi-geometry (MultiPolygon,
6526
- * MultiLineString, MultiPoint). Each badge is placed at the part's
6527
- * representative position (from `extractMultiParts`) using a `"position"`
6528
- * anchor with the pre-resolved coordinate.
6525
+ * Returns one decoration per **logical** part of a multi-geometry (MultiPolygon,
6526
+ * MultiLineString, MultiPoint). Parts are counted after running the feature
6527
+ * through the same antimeridian seam-merge the render adapters apply
6528
+ * (`mergeAntimeridianFeatures`), so a shape split at ±180° per RFC 7946 §3.1.9
6529
+ * counts as one part and gets no badge — the badge count always matches what
6530
+ * the user visually perceives as separate shapes (SAGA-648). Each badge is
6531
+ * placed at the part's representative position (from `extractMultiParts`)
6532
+ * using a `"position"` anchor with the pre-resolved coordinate.
6529
6533
  *
6530
6534
  * For MultiPoint features a `pixelOffset` displaces the badge to the
6531
6535
  * top-right edge of the point circle so it does not obscure the fill area.
6532
6536
  *
6533
6537
  * Returns an empty array for single-geometry features or multi-geometries
6534
- * with only one part.
6538
+ * with only one logical part.
6535
6539
  *
6536
6540
  * @internal
6537
6541
  */
6538
6542
  const buildMultiPartDecorations = (feature, strokeColor, pointRadius, strokeWidth) => {
6539
- const geometry = feature.geometry;
6540
- if (geometry === null)
6543
+ if (feature.geometry === null)
6544
+ return [];
6545
+ // Count logical parts on the seam-merged geometry so an antimeridian-split
6546
+ // pair yields no badge. Merged coordinates may be unwrapped (lng > 180) in
6547
+ // the mixed genuine-multi-part case; the adapters render those world-wrapped
6548
+ // longitudes natively, so badge anchors stay on the drawn stroke.
6549
+ const mergedFeature = reactMapAdapterShared.mergeAntimeridianFeatures({ type: "FeatureCollection", features: [feature] }).features[0];
6550
+ const geometry = mergedFeature?.geometry;
6551
+ if (geometry === undefined || geometry === null)
6541
6552
  return [];
6542
6553
  const parts = extractMultiParts(geometry);
6543
6554
  if (parts === null)
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, mapThemeSchema, 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, mapThemeSchema, mergeAntimeridianFeatures, 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';
@@ -58,22 +58,22 @@ const translations = {
58
58
  default: defaultTranslations,
59
59
  languages: {
60
60
  de: () => import('./translation.esm.js'),
61
- da: () => import('./translation2.esm.js'),
62
- cs: () => import('./translation3.esm.js'),
63
- nl: () => import('./translation4.esm.js'),
64
- fr: () => import('./translation5.esm.js'),
65
- fi: () => import('./translation6.esm.js'),
66
- hu: () => import('./translation7.esm.js'),
67
- it: () => import('./translation8.esm.js'),
68
- nb: () => import('./translation9.esm.js'),
69
- pl: () => import('./translation10.esm.js'),
70
- pt: () => import('./translation11.esm.js'),
71
- ru: () => import('./translation12.esm.js'),
72
- ro: () => import('./translation13.esm.js'),
73
- es: () => import('./translation14.esm.js'),
74
- sv: () => import('./translation15.esm.js'),
75
- ja: () => import('./translation16.esm.js'),
76
- th: () => import('./translation17.esm.js'),
61
+ da: () => import('./translation.esm2.js'),
62
+ cs: () => import('./translation.esm3.js'),
63
+ nl: () => import('./translation.esm4.js'),
64
+ fr: () => import('./translation.esm5.js'),
65
+ fi: () => import('./translation.esm6.js'),
66
+ hu: () => import('./translation.esm7.js'),
67
+ it: () => import('./translation.esm8.js'),
68
+ nb: () => import('./translation.esm9.js'),
69
+ pl: () => import('./translation.esm10.js'),
70
+ pt: () => import('./translation.esm11.js'),
71
+ ru: () => import('./translation.esm12.js'),
72
+ ro: () => import('./translation.esm13.js'),
73
+ es: () => import('./translation.esm14.js'),
74
+ sv: () => import('./translation.esm15.js'),
75
+ ja: () => import('./translation.esm16.js'),
76
+ th: () => import('./translation.esm17.js'),
77
77
  },
78
78
  };
79
79
  /**
@@ -6521,22 +6521,33 @@ const CORNER_OFFSET_FACTOR = 0.707;
6521
6521
  /**
6522
6522
  * Generate multi-geometry "+" badge decorations for a feature.
6523
6523
  *
6524
- * Returns one decoration per part of a multi-geometry (MultiPolygon,
6525
- * MultiLineString, MultiPoint). Each badge is placed at the part's
6526
- * representative position (from `extractMultiParts`) using a `"position"`
6527
- * anchor with the pre-resolved coordinate.
6524
+ * Returns one decoration per **logical** part of a multi-geometry (MultiPolygon,
6525
+ * MultiLineString, MultiPoint). Parts are counted after running the feature
6526
+ * through the same antimeridian seam-merge the render adapters apply
6527
+ * (`mergeAntimeridianFeatures`), so a shape split at ±180° per RFC 7946 §3.1.9
6528
+ * counts as one part and gets no badge — the badge count always matches what
6529
+ * the user visually perceives as separate shapes (SAGA-648). Each badge is
6530
+ * placed at the part's representative position (from `extractMultiParts`)
6531
+ * using a `"position"` anchor with the pre-resolved coordinate.
6528
6532
  *
6529
6533
  * For MultiPoint features a `pixelOffset` displaces the badge to the
6530
6534
  * top-right edge of the point circle so it does not obscure the fill area.
6531
6535
  *
6532
6536
  * Returns an empty array for single-geometry features or multi-geometries
6533
- * with only one part.
6537
+ * with only one logical part.
6534
6538
  *
6535
6539
  * @internal
6536
6540
  */
6537
6541
  const buildMultiPartDecorations = (feature, strokeColor, pointRadius, strokeWidth) => {
6538
- const geometry = feature.geometry;
6539
- if (geometry === null)
6542
+ if (feature.geometry === null)
6543
+ return [];
6544
+ // Count logical parts on the seam-merged geometry so an antimeridian-split
6545
+ // pair yields no badge. Merged coordinates may be unwrapped (lng > 180) in
6546
+ // the mixed genuine-multi-part case; the adapters render those world-wrapped
6547
+ // longitudes natively, so badge anchors stay on the drawn stroke.
6548
+ const mergedFeature = mergeAntimeridianFeatures({ type: "FeatureCollection", features: [feature] }).features[0];
6549
+ const geometry = mergedFeature?.geometry;
6550
+ if (geometry === undefined || geometry === null)
6540
6551
  return [];
6541
6552
  const parts = extractMultiParts(geometry);
6542
6553
  if (parts === null)
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@trackunit/react-map",
3
- "version": "0.2.30-alpha-0322e181a48.0",
3
+ "version": "0.2.31",
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.2.25-alpha-0322e181a48.0",
11
- "@trackunit/css-class-variance-utilities": "1.13.82-alpha-0322e181a48.0",
12
- "@trackunit/react-form-components": "2.2.26-alpha-0322e181a48.0",
13
- "@trackunit/react-core-hooks": "1.18.23-alpha-0322e181a48.0",
14
- "@trackunit/geo-json-utils": "1.14.85-alpha-0322e181a48.0",
15
- "@trackunit/i18n-library-translation": "2.1.23-alpha-0322e181a48.0",
10
+ "@trackunit/react-components": "2.2.25",
11
+ "@trackunit/css-class-variance-utilities": "1.13.82",
12
+ "@trackunit/react-form-components": "2.2.26",
13
+ "@trackunit/react-core-hooks": "1.18.23",
14
+ "@trackunit/geo-json-utils": "1.14.85",
15
+ "@trackunit/i18n-library-translation": "2.1.23",
16
16
  "react-minimal-pie-chart": "^8.4.0",
17
- "@trackunit/react-map-adapter-shared": "0.0.66-alpha-0322e181a48.0",
18
- "@trackunit/react-map-color-utils": "0.0.51-alpha-0322e181a48.0",
19
- "@trackunit/ui-design-tokens": "1.13.81-alpha-0322e181a48.0",
17
+ "@trackunit/react-map-adapter-shared": "0.0.66",
18
+ "@trackunit/react-map-color-utils": "0.0.51",
19
+ "@trackunit/ui-design-tokens": "1.13.81",
20
20
  "@floating-ui/react": "^0.26.25",
21
21
  "es-toolkit": "^1.39.10",
22
22
  "tailwind-merge": "^2.0.0",
@@ -3,16 +3,20 @@ import type { ShapeDecoration } from "./shapeDecorations";
3
3
  /**
4
4
  * Generate multi-geometry "+" badge decorations for a feature.
5
5
  *
6
- * Returns one decoration per part of a multi-geometry (MultiPolygon,
7
- * MultiLineString, MultiPoint). Each badge is placed at the part's
8
- * representative position (from `extractMultiParts`) using a `"position"`
9
- * anchor with the pre-resolved coordinate.
6
+ * Returns one decoration per **logical** part of a multi-geometry (MultiPolygon,
7
+ * MultiLineString, MultiPoint). Parts are counted after running the feature
8
+ * through the same antimeridian seam-merge the render adapters apply
9
+ * (`mergeAntimeridianFeatures`), so a shape split at ±180° per RFC 7946 §3.1.9
10
+ * counts as one part and gets no badge — the badge count always matches what
11
+ * the user visually perceives as separate shapes (SAGA-648). Each badge is
12
+ * placed at the part's representative position (from `extractMultiParts`)
13
+ * using a `"position"` anchor with the pre-resolved coordinate.
10
14
  *
11
15
  * For MultiPoint features a `pixelOffset` displaces the badge to the
12
16
  * top-right edge of the point circle so it does not obscure the fill area.
13
17
  *
14
18
  * Returns an empty array for single-geometry features or multi-geometries
15
- * with only one part.
19
+ * with only one logical part.
16
20
  *
17
21
  * @internal
18
22
  */
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes