@accelint/map-toolkit 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/catalog-info.yaml +5 -5
  3. package/dist/cursor-coordinates/index.d.ts +14 -3
  4. package/dist/cursor-coordinates/index.js +16 -3
  5. package/dist/cursor-coordinates/use-cursor-coordinates.d.ts +20 -6
  6. package/dist/cursor-coordinates/use-cursor-coordinates.js +247 -128
  7. package/dist/cursor-coordinates/use-cursor-coordinates.js.map +1 -1
  8. package/dist/deckgl/base-map/constants.d.ts +14 -12
  9. package/dist/deckgl/base-map/constants.js +26 -12
  10. package/dist/deckgl/base-map/constants.js.map +1 -1
  11. package/dist/deckgl/base-map/events.d.ts +6 -4
  12. package/dist/deckgl/base-map/events.js +18 -4
  13. package/dist/deckgl/base-map/events.js.map +1 -1
  14. package/dist/deckgl/base-map/index.d.ts +45 -18
  15. package/dist/deckgl/base-map/index.js +216 -148
  16. package/dist/deckgl/base-map/index.js.map +1 -1
  17. package/dist/deckgl/base-map/provider.d.ts +48 -32
  18. package/dist/deckgl/base-map/provider.js +122 -11
  19. package/dist/deckgl/base-map/provider.js.map +1 -1
  20. package/dist/deckgl/base-map/types.d.ts +49 -39
  21. package/dist/deckgl/base-map/types.js +11 -2
  22. package/dist/deckgl/index.d.ts +18 -13
  23. package/dist/deckgl/index.js +19 -6
  24. package/dist/deckgl/symbol-layer/fiber.d.ts +21 -10
  25. package/dist/deckgl/symbol-layer/fiber.js +18 -3
  26. package/dist/deckgl/symbol-layer/fiber.js.map +1 -1
  27. package/dist/deckgl/symbol-layer/index.d.ts +68 -54
  28. package/dist/deckgl/symbol-layer/index.js +105 -85
  29. package/dist/deckgl/symbol-layer/index.js.map +1 -1
  30. package/dist/deckgl/text-layer/character-sets.d.ts +19 -17
  31. package/dist/deckgl/text-layer/character-sets.js +40 -19
  32. package/dist/deckgl/text-layer/character-sets.js.map +1 -1
  33. package/dist/deckgl/text-layer/default-settings.d.ts +16 -2
  34. package/dist/deckgl/text-layer/default-settings.js +42 -18
  35. package/dist/deckgl/text-layer/default-settings.js.map +1 -1
  36. package/dist/deckgl/text-layer/fiber.d.ts +38 -27
  37. package/dist/deckgl/text-layer/fiber.js +18 -3
  38. package/dist/deckgl/text-layer/fiber.js.map +1 -1
  39. package/dist/deckgl/text-layer/index.d.ts +39 -25
  40. package/dist/deckgl/text-layer/index.js +47 -29
  41. package/dist/deckgl/text-layer/index.js.map +1 -1
  42. package/dist/decorators/deckgl.d.ts +16 -2
  43. package/dist/decorators/deckgl.js +25 -7
  44. package/dist/decorators/deckgl.js.map +1 -1
  45. package/dist/map-cursor/events.d.ts +16 -0
  46. package/dist/map-cursor/events.js +27 -0
  47. package/dist/map-cursor/events.js.map +1 -0
  48. package/dist/map-cursor/index.d.ts +17 -0
  49. package/dist/map-cursor/index.js +18 -0
  50. package/dist/map-cursor/store.d.ts +93 -0
  51. package/dist/map-cursor/store.js +351 -0
  52. package/dist/map-cursor/store.js.map +1 -0
  53. package/dist/map-cursor/types.d.ts +81 -0
  54. package/dist/map-cursor/types.js +12 -0
  55. package/dist/map-cursor/use-map-cursor.d.ts +99 -0
  56. package/dist/map-cursor/use-map-cursor.js +116 -0
  57. package/dist/map-cursor/use-map-cursor.js.map +1 -0
  58. package/dist/map-mode/events.d.ts +11 -9
  59. package/dist/map-mode/events.js +43 -9
  60. package/dist/map-mode/events.js.map +1 -1
  61. package/dist/map-mode/index.d.ts +17 -6
  62. package/dist/map-mode/index.js +18 -5
  63. package/dist/map-mode/store.d.ts +26 -3
  64. package/dist/map-mode/store.js +329 -265
  65. package/dist/map-mode/store.js.map +1 -1
  66. package/dist/map-mode/types.d.ts +49 -35
  67. package/dist/map-mode/types.js +11 -2
  68. package/dist/map-mode/use-map-mode.d.ts +21 -7
  69. package/dist/map-mode/use-map-mode.js +66 -23
  70. package/dist/map-mode/use-map-mode.js.map +1 -1
  71. package/dist/maplibre/constants.d.ts +10 -8
  72. package/dist/maplibre/constants.js +22 -8
  73. package/dist/maplibre/constants.js.map +1 -1
  74. package/dist/maplibre/hooks/use-maplibre.d.ts +17 -2
  75. package/dist/maplibre/hooks/use-maplibre.js +77 -31
  76. package/dist/maplibre/hooks/use-maplibre.js.map +1 -1
  77. package/dist/maplibre/index.d.ts +15 -3
  78. package/dist/maplibre/index.js +17 -4
  79. package/dist/viewport/constants.d.ts +8 -6
  80. package/dist/viewport/constants.js +20 -6
  81. package/dist/viewport/constants.js.map +1 -1
  82. package/dist/viewport/index.d.ts +18 -13
  83. package/dist/viewport/index.js +19 -6
  84. package/dist/viewport/types.d.ts +27 -17
  85. package/dist/viewport/types.js +11 -2
  86. package/dist/viewport/use-viewport-state.d.ts +29 -14
  87. package/dist/viewport/use-viewport-state.js +200 -87
  88. package/dist/viewport/use-viewport-state.js.map +1 -1
  89. package/dist/viewport/utils.d.ts +25 -10
  90. package/dist/viewport/utils.js +67 -37
  91. package/dist/viewport/utils.js.map +1 -1
  92. package/dist/viewport/viewport-size.d.ts +27 -15
  93. package/dist/viewport/viewport-size.js +54 -11
  94. package/dist/viewport/viewport-size.js.map +1 -1
  95. package/package.json +55 -28
  96. package/dist/cursor-coordinates/index.js.map +0 -1
  97. package/dist/deckgl/base-map/types.js.map +0 -1
  98. package/dist/deckgl/index.js.map +0 -1
  99. package/dist/map-mode/index.js.map +0 -1
  100. package/dist/map-mode/types.js.map +0 -1
  101. package/dist/maplibre/index.js.map +0 -1
  102. package/dist/metafile-esm.json +0 -1
  103. package/dist/viewport/index.js.map +0 -1
  104. package/dist/viewport/types.js.map +0 -1
@@ -1,18 +1,32 @@
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+
14
+ //#region src/deckgl/base-map/constants.ts
1
15
  const BASE_MAP_STYLE = "https://tiles.basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json";
2
16
  const PARAMETERS = {
3
- depthWriteEnabled: true,
4
- depthCompare: "always",
5
- depthBias: 0,
6
- blend: true,
7
- depthTest: false,
8
- blendColorSrcFactor: "src-alpha",
9
- blendColorDstFactor: "one-minus-src-alpha",
10
- blendAlphaSrcFactor: "one",
11
- blendAlphaDstFactor: "one-minus-src-alpha",
12
- blendColorOperation: "add",
13
- blendAlphaOperation: "add"
17
+ depthWriteEnabled: true,
18
+ depthCompare: "always",
19
+ depthBias: 0,
20
+ blend: true,
21
+ depthTest: false,
22
+ blendColorSrcFactor: "src-alpha",
23
+ blendColorDstFactor: "one-minus-src-alpha",
24
+ blendAlphaSrcFactor: "one",
25
+ blendAlphaDstFactor: "one-minus-src-alpha",
26
+ blendColorOperation: "add",
27
+ blendAlphaOperation: "add"
14
28
  };
15
29
 
30
+ //#endregion
16
31
  export { BASE_MAP_STYLE, PARAMETERS };
17
- //# sourceMappingURL=constants.js.map
18
32
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/deckgl/base-map/constants.ts"],"names":[],"mappings":"AAaO,MAAM,cAAA,GACX;AAEK,MAAM,UAAA,GAAa;AAAA,EACxB,iBAAA,EAAmB,IAAA;AAAA,EACnB,YAAA,EAAc,QAAA;AAAA,EACd,SAAA,EAAW,CAAA;AAAA,EACX,KAAA,EAAO,IAAA;AAAA,EACP,SAAA,EAAW,KAAA;AAAA,EACX,mBAAA,EAAqB,WAAA;AAAA,EACrB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,mBAAA,EAAqB,KAAA;AAAA,EACrB,mBAAA,EAAqB,qBAAA;AAAA,EACrB,mBAAA,EAAqB,KAAA;AAAA,EACrB,mBAAA,EAAqB;AACvB","file":"constants.js","sourcesContent":["// __private-exports\n/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport const BASE_MAP_STYLE =\n 'https://tiles.basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json';\n\nexport const PARAMETERS = {\n depthWriteEnabled: true,\n depthCompare: 'always',\n depthBias: 0,\n blend: true,\n depthTest: false,\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n blendColorOperation: 'add',\n blendAlphaOperation: 'add',\n};\n"]}
1
+ {"version":3,"file":"constants.js","names":[],"sources":["../../../src/deckgl/base-map/constants.ts"],"sourcesContent":["// __private-exports\n/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport const BASE_MAP_STYLE =\n 'https://tiles.basemaps.cartocdn.com/gl/dark-matter-gl-style/style.json';\n\nexport const PARAMETERS = {\n depthWriteEnabled: true,\n depthCompare: 'always',\n depthBias: 0,\n blend: true,\n depthTest: false,\n blendColorSrcFactor: 'src-alpha',\n blendColorDstFactor: 'one-minus-src-alpha',\n blendAlphaSrcFactor: 'one',\n blendAlphaDstFactor: 'one-minus-src-alpha',\n blendColorOperation: 'add',\n blendAlphaOperation: 'add',\n};\n"],"mappings":";;;;;;;;;;;;;;AAaA,MAAa,iBACX;AAEF,MAAa,aAAa;CACxB,mBAAmB;CACnB,cAAc;CACd,WAAW;CACX,OAAO;CACP,WAAW;CACX,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACrB,qBAAqB;CACtB"}
@@ -1,8 +1,10 @@
1
+ //#region src/deckgl/base-map/events.d.ts
1
2
  declare const MapEventsNamespace = "map";
2
3
  declare const MapEvents: {
3
- readonly click: "map:click";
4
- readonly hover: "map:hover";
5
- readonly viewport: "map:viewport";
4
+ readonly click: "map:click";
5
+ readonly hover: "map:hover";
6
+ readonly viewport: "map:viewport";
6
7
  };
7
-
8
+ //#endregion
8
9
  export { MapEvents, MapEventsNamespace };
10
+ //# sourceMappingURL=events.d.ts.map
@@ -1,10 +1,24 @@
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
12
+
13
+
14
+ //#region src/deckgl/base-map/events.ts
1
15
  const MapEventsNamespace = "map";
2
16
  const MapEvents = {
3
- click: `${MapEventsNamespace}:click`,
4
- hover: `${MapEventsNamespace}:hover`,
5
- viewport: `${MapEventsNamespace}:viewport`
17
+ click: `${MapEventsNamespace}:click`,
18
+ hover: `${MapEventsNamespace}:hover`,
19
+ viewport: `${MapEventsNamespace}:viewport`
6
20
  };
7
21
 
22
+ //#endregion
8
23
  export { MapEvents, MapEventsNamespace };
9
- //# sourceMappingURL=events.js.map
10
24
  //# sourceMappingURL=events.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/deckgl/base-map/events.ts"],"names":[],"mappings":"AAYO,MAAM,kBAAA,GAAqB;AAE3B,MAAM,SAAA,GAAY;AAAA,EACvB,KAAA,EAAO,GAAG,kBAAkB,CAAA,MAAA,CAAA;AAAA,EAC5B,KAAA,EAAO,GAAG,kBAAkB,CAAA,MAAA,CAAA;AAAA,EAC5B,QAAA,EAAU,GAAG,kBAAkB,CAAA,SAAA;AACjC","file":"events.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport const MapEventsNamespace = 'map';\n\nexport const MapEvents = {\n click: `${MapEventsNamespace}:click`,\n hover: `${MapEventsNamespace}:hover`,\n viewport: `${MapEventsNamespace}:viewport`,\n} as const;\n"]}
1
+ {"version":3,"file":"events.js","names":[],"sources":["../../../src/deckgl/base-map/events.ts"],"sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport const MapEventsNamespace = 'map';\n\nexport const MapEvents = {\n click: `${MapEventsNamespace}:click`,\n hover: `${MapEventsNamespace}:hover`,\n viewport: `${MapEventsNamespace}:viewport`,\n} as const;\n"],"mappings":";;;;;;;;;;;;;;AAYA,MAAa,qBAAqB;AAElC,MAAa,YAAY;CACvB,OAAO,GAAG,mBAAmB;CAC7B,OAAO,GAAG,mBAAmB;CAC7B,UAAU,GAAG,mBAAmB;CACjC"}
@@ -1,24 +1,37 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { UniqueId } from '@accelint/core';
3
- import { DeckglProps } from '@deckgl-fiber-renderer/types';
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
4
12
 
13
+ import { UniqueId } from "@accelint/core";
14
+ import * as react_jsx_runtime0 from "react/jsx-runtime";
15
+ import { DeckglProps } from "@deckgl-fiber-renderer/types";
16
+
17
+ //#region src/deckgl/base-map/index.d.ts
5
18
  /**
6
19
  * Props for the BaseMap component.
7
20
  * Extends all Deck.gl props and adds additional map-specific properties.
8
21
  */
9
22
  type BaseMapProps = DeckglProps & {
10
- /** Optional CSS class name to apply to the map container element */
11
- className?: string;
12
- /**
13
- * Unique identifier for this map instance (required).
14
- *
15
- * Used to isolate map mode state between multiple map instances (e.g., main map vs minimap).
16
- * This should be a UUID generated using `uuid()` from `@accelint/core`.
17
- *
18
- * The same id should be passed to `useMapMode()` when accessing map mode state
19
- * from components rendered outside of the BaseMap's children (i.e., as siblings).
20
- */
21
- id: UniqueId;
23
+ /** Optional CSS class name to apply to the map container element */
24
+ className?: string;
25
+ /**
26
+ * Unique identifier for this map instance (required).
27
+ *
28
+ * Used to isolate map mode state between multiple map instances (e.g., main map vs minimap).
29
+ * This should be a UUID generated using `uuid()` from `@accelint/core`.
30
+ *
31
+ * The same id should be passed to `useMapMode()` when accessing map mode state
32
+ * from components rendered outside of the BaseMap's children (i.e., as siblings).
33
+ */
34
+ id: UniqueId;
22
35
  };
23
36
  /**
24
37
  * A React component that provides a Deck.gl-powered base map with MapLibre GL integration.
@@ -93,6 +106,20 @@ type BaseMapProps = DeckglProps & {
93
106
  * }
94
107
  * ```
95
108
  */
96
- declare function BaseMap({ id, className, children, controller, interleaved, parameters, useDevicePixels, widgets: widgetsProp, onClick, onHover, onViewStateChange, ...rest }: BaseMapProps): react_jsx_runtime.JSX.Element;
97
-
98
- export { BaseMap, type BaseMapProps };
109
+ declare function BaseMap({
110
+ id,
111
+ className,
112
+ children,
113
+ controller,
114
+ interleaved,
115
+ parameters,
116
+ useDevicePixels,
117
+ widgets: widgetsProp,
118
+ onClick,
119
+ onHover,
120
+ onViewStateChange,
121
+ ...rest
122
+ }: BaseMapProps): react_jsx_runtime0.JSX.Element;
123
+ //#endregion
124
+ export { BaseMap, BaseMapProps };
125
+ //# sourceMappingURL=index.d.ts.map
@@ -1,153 +1,221 @@
1
- import { jsx } from 'react/jsx-runtime';
2
- import 'client-only';
3
- import { useEmit, useEffectEvent } from '@accelint/bus/react';
4
- import { useDeckgl, Deckgl } from '@deckgl-fiber-renderer/dom';
5
- import { useId, useMemo, useCallback } from 'react';
6
- import { INITIAL_VIEW_STATE } from '../../maplibre/constants.js';
7
- import { useMapLibre } from '../../maplibre/hooks/use-maplibre.js';
8
- import { BASE_MAP_STYLE, PARAMETERS } from './constants.js';
9
- import { MapEvents } from './events.js';
10
- import { MapProvider } from './provider.js';
1
+ /*
2
+ * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.
3
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
4
+ * you may not use this file except in compliance with the License. You may obtain a copy
5
+ * of the License at https://www.apache.org/licenses/LICENSE-2.0
6
+ *
7
+ * Unless required by applicable law or agreed to in writing, software distributed under
8
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
9
+ * OF ANY KIND, either express or implied. See the License for the specific language
10
+ * governing permissions and limitations under the License.
11
+ */
11
12
 
12
- function BaseMap({
13
- id,
14
- className,
15
- children,
16
- controller = true,
17
- interleaved = true,
18
- parameters = {},
19
- useDevicePixels = false,
20
- widgets: widgetsProp = [],
21
- onClick,
22
- onHover,
23
- onViewStateChange,
24
- ...rest
25
- }) {
26
- const deckglInstance = useDeckgl();
27
- const container = useId();
28
- const mapOptions = useMemo(
29
- () => ({
30
- container,
31
- center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude],
32
- zoom: INITIAL_VIEW_STATE.zoom,
33
- doubleClickZoom: false,
34
- dragRotate: false,
35
- pitchWithRotate: false,
36
- rollEnabled: false,
37
- attributionControl: { compact: true }
38
- }),
39
- [container]
40
- );
41
- useMapLibre(deckglInstance, BASE_MAP_STYLE, mapOptions);
42
- const emitClick = useEmit(MapEvents.click);
43
- const emitHover = useEmit(MapEvents.hover);
44
- const emitViewport = useEmit(MapEvents.viewport);
45
- const handleClick = useCallback(
46
- (info, event) => {
47
- onClick?.(info, event);
48
- const { viewport, layer, sourceLayer, ...infoRest } = info;
49
- const infoObject = {
50
- layerId: layer?.id,
51
- sourceLayerId: sourceLayer?.id,
52
- ...infoRest
53
- };
54
- const {
55
- stopImmediatePropagation,
56
- stopPropagation,
57
- preventDefault,
58
- srcEvent,
59
- rootElement,
60
- target,
61
- changedPointers,
62
- pointers,
63
- ...eventRest
64
- } = event;
65
- emitClick({
66
- info: infoObject,
67
- event: eventRest,
68
- id
69
- });
70
- },
71
- [emitClick, id, onClick]
72
- );
73
- const handleHover = useCallback(
74
- (info, event) => {
75
- onHover?.(info, event);
76
- const { viewport, layer, sourceLayer, ...infoRest } = info;
77
- const infoObject = {
78
- layerId: layer?.id,
79
- sourceLayerId: sourceLayer?.id,
80
- ...infoRest
81
- };
82
- const {
83
- stopImmediatePropagation,
84
- stopPropagation,
85
- preventDefault,
86
- srcEvent,
87
- rootElement,
88
- target,
89
- ...eventRest
90
- } = event;
91
- emitHover({
92
- info: infoObject,
93
- event: eventRest,
94
- id
95
- });
96
- },
97
- [emitHover, id, onHover]
98
- );
99
- const handleViewStateChange = useEffectEvent(
100
- (params) => {
101
- onViewStateChange?.(params);
102
- const {
103
- viewId,
104
- viewState: { latitude, longitude, zoom }
105
- } = params;
106
- const viewport = deckglInstance._deck.getViewports()?.find((vp) => vp.id === viewId);
107
- emitViewport({
108
- id,
109
- bounds: viewport?.getBounds(),
110
- latitude,
111
- longitude,
112
- zoom,
113
- width: viewport?.width ?? 0,
114
- height: viewport?.height ?? 0
115
- });
116
- }
117
- );
118
- const handleLoad = useEffectEvent(() => {
119
- deckglInstance._deck.getViewports().forEach((vp) => {
120
- handleViewStateChange({
121
- viewId: vp.id,
122
- viewState: {
123
- latitude: vp.latitude,
124
- longitude: vp.longitude,
125
- zoom: vp.zoom,
126
- id: vp.id,
127
- bounds: vp.getBounds(),
128
- width: vp.width,
129
- height: vp.height
130
- }
131
- });
132
- });
133
- });
134
- return /* @__PURE__ */ jsx("div", { id: container, className, children: /* @__PURE__ */ jsx(MapProvider, { id, children: /* @__PURE__ */ jsx(
135
- Deckgl,
136
- {
137
- ...rest,
138
- controller,
139
- interleaved,
140
- useDevicePixels,
141
- onClick: handleClick,
142
- onHover: handleHover,
143
- onLoad: handleLoad,
144
- onViewStateChange: handleViewStateChange,
145
- parameters: { ...PARAMETERS, ...parameters },
146
- children
147
- }
148
- ) }) });
13
+
14
+ 'use client';
15
+
16
+ import { MapEvents } from "./events.js";
17
+ import { getCursor } from "../../map-cursor/store.js";
18
+ import { MapProvider } from "./provider.js";
19
+ import { INITIAL_VIEW_STATE } from "../../maplibre/constants.js";
20
+ import { useMapLibre } from "../../maplibre/hooks/use-maplibre.js";
21
+ import { BASE_MAP_STYLE, PARAMETERS } from "./constants.js";
22
+ import { useCallback, useId, useMemo } from "react";
23
+ import { jsx } from "react/jsx-runtime";
24
+ import { useEffectEvent, useEmit } from "@accelint/bus/react";
25
+ import { Deckgl, useDeckgl } from "@deckgl-fiber-renderer/dom";
26
+
27
+ //#region src/deckgl/base-map/index.tsx
28
+ /**
29
+ * Serializes PickingInfo for event bus transmission.
30
+ * Omits viewport, layer, and sourceLayer (contain functions) but preserves layer IDs.
31
+ */
32
+ function serializePickingInfo(info) {
33
+ const { viewport, layer, sourceLayer, ...infoRest } = info;
34
+ return {
35
+ layerId: layer?.id,
36
+ sourceLayerId: sourceLayer?.id,
37
+ ...infoRest
38
+ };
39
+ }
40
+ function serializeMjolnirEvent(event) {
41
+ const { stopImmediatePropagation, stopPropagation, preventDefault, srcEvent, rootElement, target, ...rest } = event;
42
+ if ("changedPointers" in rest) {
43
+ const { changedPointers, pointers, ...gestureRest } = rest;
44
+ return gestureRest;
45
+ }
46
+ return rest;
47
+ }
48
+ /**
49
+ * A React component that provides a Deck.gl-powered base map with MapLibre GL integration.
50
+ *
51
+ * This component serves as the foundation for building interactive map applications with
52
+ * support for click and hover events through a centralized event bus. It integrates
53
+ * Deck.gl for 3D visualizations with MapLibre GL for the base map tiles.
54
+ *
55
+ * **Map Mode Integration**: BaseMap automatically creates a `MapProvider` internally,
56
+ * which sets up the map mode state management for this instance.
57
+ * - **Children**: Only Deck.gl layer components can be rendered as children. Custom Deck.gl
58
+ * layers can use `useMapMode()` without parameters to access context.
59
+ * - **Siblings**: UI components (buttons, toolbars, etc.) must be rendered as siblings
60
+ * and pass `id` to `useMapMode(id)`.
61
+ *
62
+ * **Event Bus**: Click and hover events are emitted through the event bus with the `id`
63
+ * included in the payload, allowing multiple map instances to coexist without interference.
64
+ *
65
+ * @param props - Component props including id (required), className, onClick, onHover, and all Deck.gl props
66
+ * @returns A map component with Deck.gl and MapLibre GL integration
67
+ *
68
+ * @example
69
+ * Basic usage with id (recommended: module-level constant):
70
+ * ```tsx
71
+ * import { BaseMap } from '@accelint/map-toolkit/deckgl';
72
+ * import { View } from '@deckgl-fiber-renderer/dom';
73
+ * import { uuid } from '@accelint/core';
74
+ *
75
+ * // Create id at module level for stability and easy sharing
76
+ * const MAIN_MAP_ID = uuid();
77
+ *
78
+ * export function MapView() {
79
+ * return (
80
+ * <BaseMap className="w-full h-full" id={MAIN_MAP_ID}>
81
+ * <View id="main" controller />
82
+ * </BaseMap>
83
+ * );
84
+ * }
85
+ * ```
86
+ *
87
+ * @example
88
+ * With map mode and event handlers (module-level constant for sharing):
89
+ * ```tsx
90
+ * import { BaseMap } from '@accelint/map-toolkit/deckgl';
91
+ * import { useMapMode } from '@accelint/map-toolkit/map-mode';
92
+ * import { uuid } from '@accelint/core';
93
+ * import type { PickingInfo } from '@deck.gl/core';
94
+ * import type { MjolnirGestureEvent } from 'mjolnir.js';
95
+ *
96
+ * // Module-level constant - stable and shareable across all components
97
+ * const MAIN_MAP_ID = uuid();
98
+ *
99
+ * function Toolbar() {
100
+ * // Access map mode using the shared id
101
+ * const { mode, requestModeChange } = useMapMode(MAIN_MAP_ID);
102
+ * return <div>Current mode: {mode}</div>;
103
+ * }
104
+ *
105
+ * export function InteractiveMap() {
106
+ * const handleClick = (info: PickingInfo, event: MjolnirGestureEvent) => {
107
+ * console.log('Clicked:', info.object);
108
+ * };
109
+ *
110
+ * return (
111
+ * <div className="relative w-full h-full">
112
+ * <BaseMap className="absolute inset-0" id={MAIN_MAP_ID} onClick={handleClick}>
113
+ * <View id="main" controller />
114
+ * </BaseMap>
115
+ * <Toolbar />
116
+ * </div>
117
+ * );
118
+ * }
119
+ * ```
120
+ */
121
+ function BaseMap({ id, className, children, controller = true, interleaved = true, parameters = {}, useDevicePixels = false, widgets: widgetsProp = [], onClick, onHover, onViewStateChange, ...rest }) {
122
+ const deckglInstance = useDeckgl();
123
+ const container = useId();
124
+ useMapLibre(deckglInstance, BASE_MAP_STYLE, useMemo(() => ({
125
+ container,
126
+ center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude],
127
+ zoom: INITIAL_VIEW_STATE.zoom,
128
+ doubleClickZoom: false,
129
+ dragRotate: false,
130
+ pitchWithRotate: false,
131
+ rollEnabled: false,
132
+ attributionControl: { compact: true }
133
+ }), [container]));
134
+ const emitClick = useEmit(MapEvents.click);
135
+ const emitHover = useEmit(MapEvents.hover);
136
+ const emitViewport = useEmit(MapEvents.viewport);
137
+ const handleClick = useCallback((info, event) => {
138
+ onClick?.(info, event);
139
+ emitClick({
140
+ info: serializePickingInfo(info),
141
+ event: serializeMjolnirEvent(event),
142
+ id
143
+ });
144
+ }, [
145
+ emitClick,
146
+ id,
147
+ onClick
148
+ ]);
149
+ const handleHover = useCallback((info, event) => {
150
+ onHover?.(info, event);
151
+ emitHover({
152
+ info: serializePickingInfo(info),
153
+ event: serializeMjolnirEvent(event),
154
+ id
155
+ });
156
+ }, [
157
+ emitHover,
158
+ id,
159
+ onHover
160
+ ]);
161
+ const handleGetCursor = useCallback(() => {
162
+ return getCursor(id);
163
+ }, [id]);
164
+ const handleViewStateChange = useEffectEvent((params) => {
165
+ onViewStateChange?.(params);
166
+ const { viewId, viewState: { latitude, longitude, zoom } } = params;
167
+ const viewport = deckglInstance._deck.getViewports()?.find((vp) => vp.id === viewId);
168
+ emitViewport({
169
+ id,
170
+ bounds: viewport?.getBounds(),
171
+ latitude,
172
+ longitude,
173
+ zoom,
174
+ width: viewport?.width ?? 0,
175
+ height: viewport?.height ?? 0
176
+ });
177
+ });
178
+ const handleLoad = useEffectEvent(() => {
179
+ deckglInstance._deck.getViewports().forEach((vp) => {
180
+ handleViewStateChange({
181
+ viewId: vp.id,
182
+ viewState: {
183
+ latitude: vp.latitude,
184
+ longitude: vp.longitude,
185
+ zoom: vp.zoom,
186
+ id: vp.id,
187
+ bounds: vp.getBounds(),
188
+ width: vp.width,
189
+ height: vp.height
190
+ }
191
+ });
192
+ });
193
+ });
194
+ return /* @__PURE__ */ jsx("div", {
195
+ id: container,
196
+ className,
197
+ children: /* @__PURE__ */ jsx(MapProvider, {
198
+ id,
199
+ children: /* @__PURE__ */ jsx(Deckgl, {
200
+ ...rest,
201
+ controller,
202
+ interleaved,
203
+ useDevicePixels,
204
+ onClick: handleClick,
205
+ onHover: handleHover,
206
+ onLoad: handleLoad,
207
+ onViewStateChange: handleViewStateChange,
208
+ getCursor: handleGetCursor,
209
+ parameters: {
210
+ ...PARAMETERS,
211
+ ...parameters
212
+ },
213
+ children
214
+ })
215
+ })
216
+ });
149
217
  }
150
218
 
219
+ //#endregion
151
220
  export { BaseMap };
152
- //# sourceMappingURL=index.js.map
153
221
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/deckgl/base-map/index.tsx"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport 'client-only';\nimport { useEffectEvent, useEmit } from '@accelint/bus/react';\nimport { Deckgl, useDeckgl } from '@deckgl-fiber-renderer/dom';\nimport { useCallback, useId, useMemo } from 'react';\nimport { INITIAL_VIEW_STATE } from '../../maplibre/constants';\nimport { useMapLibre } from '../../maplibre/hooks/use-maplibre';\nimport { BASE_MAP_STYLE, PARAMETERS } from './constants';\nimport { MapEvents } from './events';\nimport { MapProvider } from './provider';\nimport type { UniqueId } from '@accelint/core';\nimport type { PickingInfo, ViewStateChangeParameters } from '@deck.gl/core';\nimport type { DeckglProps } from '@deckgl-fiber-renderer/types';\nimport type { IControl } from 'maplibre-gl';\nimport type { MjolnirGestureEvent, MjolnirPointerEvent } from 'mjolnir.js';\nimport type { MapClickEvent, MapHoverEvent, MapViewportEvent } from './types';\n\n/**\n * Props for the BaseMap component.\n * Extends all Deck.gl props and adds additional map-specific properties.\n */\nexport type BaseMapProps = DeckglProps & {\n /** Optional CSS class name to apply to the map container element */\n className?: string;\n /**\n * Unique identifier for this map instance (required).\n *\n * Used to isolate map mode state between multiple map instances (e.g., main map vs minimap).\n * This should be a UUID generated using `uuid()` from `@accelint/core`.\n *\n * The same id should be passed to `useMapMode()` when accessing map mode state\n * from components rendered outside of the BaseMap's children (i.e., as siblings).\n */\n id: UniqueId;\n};\n\n/**\n * A React component that provides a Deck.gl-powered base map with MapLibre GL integration.\n *\n * This component serves as the foundation for building interactive map applications with\n * support for click and hover events through a centralized event bus. It integrates\n * Deck.gl for 3D visualizations with MapLibre GL for the base map tiles.\n *\n * **Map Mode Integration**: BaseMap automatically creates a `MapProvider` internally,\n * which sets up the map mode state management for this instance.\n * - **Children**: Only Deck.gl layer components can be rendered as children. Custom Deck.gl\n * layers can use `useMapMode()` without parameters to access context.\n * - **Siblings**: UI components (buttons, toolbars, etc.) must be rendered as siblings\n * and pass `id` to `useMapMode(id)`.\n *\n * **Event Bus**: Click and hover events are emitted through the event bus with the `id`\n * included in the payload, allowing multiple map instances to coexist without interference.\n *\n * @param props - Component props including id (required), className, onClick, onHover, and all Deck.gl props\n * @returns A map component with Deck.gl and MapLibre GL integration\n *\n * @example\n * Basic usage with id (recommended: module-level constant):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { View } from '@deckgl-fiber-renderer/dom';\n * import { uuid } from '@accelint/core';\n *\n * // Create id at module level for stability and easy sharing\n * const MAIN_MAP_ID = uuid();\n *\n * export function MapView() {\n * return (\n * <BaseMap className=\"w-full h-full\" id={MAIN_MAP_ID}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * );\n * }\n * ```\n *\n * @example\n * With map mode and event handlers (module-level constant for sharing):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { useMapMode } from '@accelint/map-toolkit/map-mode';\n * import { uuid } from '@accelint/core';\n * import type { PickingInfo } from '@deck.gl/core';\n * import type { MjolnirGestureEvent } from 'mjolnir.js';\n *\n * // Module-level constant - stable and shareable across all components\n * const MAIN_MAP_ID = uuid();\n *\n * function Toolbar() {\n * // Access map mode using the shared id\n * const { mode, requestModeChange } = useMapMode(MAIN_MAP_ID);\n * return <div>Current mode: {mode}</div>;\n * }\n *\n * export function InteractiveMap() {\n * const handleClick = (info: PickingInfo, event: MjolnirGestureEvent) => {\n * console.log('Clicked:', info.object);\n * };\n *\n * return (\n * <div className=\"relative w-full h-full\">\n * <BaseMap className=\"absolute inset-0\" id={MAIN_MAP_ID} onClick={handleClick}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * <Toolbar />\n * </div>\n * );\n * }\n * ```\n */\nexport function BaseMap({\n id,\n className,\n children,\n controller = true,\n interleaved = true,\n parameters = {},\n useDevicePixels = false,\n widgets: widgetsProp = [],\n onClick,\n onHover,\n onViewStateChange,\n ...rest\n}: BaseMapProps) {\n const deckglInstance = useDeckgl();\n const container = useId();\n\n // Memoize MapLibre options to avoid creating new object on every render\n const mapOptions = useMemo(\n () => ({\n container,\n center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude] as [\n number,\n number,\n ],\n zoom: INITIAL_VIEW_STATE.zoom,\n doubleClickZoom: false,\n dragRotate: false,\n pitchWithRotate: false,\n rollEnabled: false,\n attributionControl: { compact: true },\n }),\n [container],\n );\n\n // Use the custom hook to handle MapLibre\n useMapLibre(deckglInstance as IControl, BASE_MAP_STYLE, mapOptions);\n\n const emitClick = useEmit<MapClickEvent>(MapEvents.click);\n const emitHover = useEmit<MapHoverEvent>(MapEvents.hover);\n const emitViewport = useEmit<MapViewportEvent>(MapEvents.viewport);\n\n const handleClick = useCallback(\n (info: PickingInfo, event: MjolnirGestureEvent) => {\n // send full pickingInfo and event to user-defined onClick\n onClick?.(info, event);\n\n // omit viewport, layer, and sourceLayer (contain functions) for event bus serialization\n // extract layerId and sourceLayerId before omission to preserve layer identification\n const { viewport, layer, sourceLayer, ...infoRest } = info;\n const infoObject = {\n layerId: layer?.id,\n sourceLayerId: sourceLayer?.id,\n ...infoRest,\n };\n\n const {\n stopImmediatePropagation,\n stopPropagation,\n preventDefault,\n srcEvent,\n rootElement,\n target,\n changedPointers,\n pointers,\n ...eventRest\n } = event;\n\n emitClick({\n info: infoObject,\n event: eventRest,\n id,\n });\n },\n [emitClick, id, onClick],\n );\n\n const handleHover = useCallback(\n (info: PickingInfo, event: MjolnirPointerEvent) => {\n // send full pickingInfo and event to user-defined onHover\n onHover?.(info, event);\n\n // omit viewport, layer, and sourceLayer (contain functions) for event bus serialization\n // extract layerId and sourceLayerId before omission to preserve layer identification\n const { viewport, layer, sourceLayer, ...infoRest } = info;\n const infoObject = {\n layerId: layer?.id,\n sourceLayerId: sourceLayer?.id,\n ...infoRest,\n };\n\n const {\n stopImmediatePropagation,\n stopPropagation,\n preventDefault,\n srcEvent,\n rootElement,\n target,\n ...eventRest\n } = event;\n\n emitHover({\n info: infoObject,\n event: eventRest,\n id,\n });\n },\n [emitHover, id, onHover],\n );\n\n const handleViewStateChange = useEffectEvent(\n (params: ViewStateChangeParameters) => {\n onViewStateChange?.(params);\n\n const {\n viewId,\n viewState: { latitude, longitude, zoom },\n } = params;\n\n // @ts-expect-error squirrelly deckglInstance typing\n const viewport = deckglInstance._deck\n .getViewports()\n // @ts-expect-error squirrelly deckglInstance typing\n ?.find((vp) => vp.id === viewId);\n\n emitViewport({\n id,\n bounds: viewport?.getBounds(),\n latitude,\n longitude,\n zoom,\n width: viewport?.width ?? 0,\n height: viewport?.height ?? 0,\n });\n },\n );\n\n const handleLoad = useEffectEvent(() => {\n //--- force update viewport state once all viewports initialized ---\n // @ts-expect-error squirrelly deckglInstance typing\n deckglInstance._deck.getViewports().forEach((vp) => {\n handleViewStateChange({\n viewId: vp.id,\n viewState: {\n latitude: vp.latitude,\n longitude: vp.longitude,\n zoom: vp.zoom,\n id: vp.id,\n bounds: vp.getBounds(),\n width: vp.width,\n height: vp.height,\n },\n } as ViewStateChangeParameters);\n });\n });\n\n return (\n <div id={container} className={className}>\n <MapProvider id={id}>\n <Deckgl\n {...rest}\n controller={controller}\n interleaved={interleaved}\n useDevicePixels={useDevicePixels}\n onClick={handleClick}\n onHover={handleHover}\n onLoad={handleLoad}\n onViewStateChange={handleViewStateChange}\n // @ts-expect-error - DeckglProps parameters type is overly strict for WebGL parameter spreading.\n // The merged object is valid at runtime but TypeScript cannot verify all possible parameter combinations.\n parameters={{ ...PARAMETERS, ...parameters }}\n >\n {children}\n </Deckgl>\n </MapProvider>\n </div>\n );\n}\n"]}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/deckgl/base-map/index.tsx"],"sourcesContent":["/*\n * Copyright 2025 Hypergiant Galactic Systems Inc. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\n'use client';\n\nimport 'client-only';\nimport { useEffectEvent, useEmit } from '@accelint/bus/react';\nimport { Deckgl, useDeckgl } from '@deckgl-fiber-renderer/dom';\nimport { useCallback, useId, useMemo } from 'react';\nimport { getCursor } from '../../map-cursor/store';\nimport { INITIAL_VIEW_STATE } from '../../maplibre/constants';\nimport { useMapLibre } from '../../maplibre/hooks/use-maplibre';\nimport { BASE_MAP_STYLE, PARAMETERS } from './constants';\nimport { MapEvents } from './events';\nimport { MapProvider } from './provider';\nimport type { UniqueId } from '@accelint/core';\nimport type { PickingInfo, ViewStateChangeParameters } from '@deck.gl/core';\nimport type { DeckglProps } from '@deckgl-fiber-renderer/types';\nimport type { IControl } from 'maplibre-gl';\nimport type { MjolnirGestureEvent, MjolnirPointerEvent } from 'mjolnir.js';\nimport type {\n MapClickEvent,\n MapHoverEvent,\n MapViewportEvent,\n SerializablePickingInfo,\n} from './types';\n\n/**\n * Serializes PickingInfo for event bus transmission.\n * Omits viewport, layer, and sourceLayer (contain functions) but preserves layer IDs.\n */\nfunction serializePickingInfo(info: PickingInfo): SerializablePickingInfo {\n const { viewport, layer, sourceLayer, ...infoRest } = info;\n return {\n layerId: layer?.id,\n sourceLayerId: sourceLayer?.id,\n ...infoRest,\n };\n}\n\n/**\n * Strips non-serializable properties from MjolnirGestureEvent for event bus transmission.\n * Removes functions, DOM elements, and PointerEvent objects that cannot be cloned.\n */\nfunction serializeMjolnirEvent(\n event: MjolnirGestureEvent,\n): Omit<\n MjolnirGestureEvent,\n | 'stopPropagation'\n | 'preventDefault'\n | 'stopImmediatePropagation'\n | 'srcEvent'\n | 'rootElement'\n | 'target'\n | 'changedPointers'\n | 'pointers'\n>;\n/**\n * Strips non-serializable properties from MjolnirPointerEvent for event bus transmission.\n * Removes functions and DOM elements that cannot be cloned.\n */\nfunction serializeMjolnirEvent(\n event: MjolnirPointerEvent,\n): Omit<\n MjolnirPointerEvent,\n | 'stopPropagation'\n | 'preventDefault'\n | 'stopImmediatePropagation'\n | 'srcEvent'\n | 'rootElement'\n | 'target'\n>;\nfunction serializeMjolnirEvent(\n event: MjolnirGestureEvent | MjolnirPointerEvent,\n) {\n const {\n stopImmediatePropagation,\n stopPropagation,\n preventDefault,\n srcEvent,\n rootElement,\n target,\n ...rest\n } = event;\n\n // Remove pointer arrays if present (only on MjolnirGestureEvent)\n if ('changedPointers' in rest) {\n const { changedPointers, pointers, ...gestureRest } = rest;\n return gestureRest;\n }\n\n return rest;\n}\n\n/**\n * Props for the BaseMap component.\n * Extends all Deck.gl props and adds additional map-specific properties.\n */\nexport type BaseMapProps = DeckglProps & {\n /** Optional CSS class name to apply to the map container element */\n className?: string;\n /**\n * Unique identifier for this map instance (required).\n *\n * Used to isolate map mode state between multiple map instances (e.g., main map vs minimap).\n * This should be a UUID generated using `uuid()` from `@accelint/core`.\n *\n * The same id should be passed to `useMapMode()` when accessing map mode state\n * from components rendered outside of the BaseMap's children (i.e., as siblings).\n */\n id: UniqueId;\n};\n\n/**\n * A React component that provides a Deck.gl-powered base map with MapLibre GL integration.\n *\n * This component serves as the foundation for building interactive map applications with\n * support for click and hover events through a centralized event bus. It integrates\n * Deck.gl for 3D visualizations with MapLibre GL for the base map tiles.\n *\n * **Map Mode Integration**: BaseMap automatically creates a `MapProvider` internally,\n * which sets up the map mode state management for this instance.\n * - **Children**: Only Deck.gl layer components can be rendered as children. Custom Deck.gl\n * layers can use `useMapMode()` without parameters to access context.\n * - **Siblings**: UI components (buttons, toolbars, etc.) must be rendered as siblings\n * and pass `id` to `useMapMode(id)`.\n *\n * **Event Bus**: Click and hover events are emitted through the event bus with the `id`\n * included in the payload, allowing multiple map instances to coexist without interference.\n *\n * @param props - Component props including id (required), className, onClick, onHover, and all Deck.gl props\n * @returns A map component with Deck.gl and MapLibre GL integration\n *\n * @example\n * Basic usage with id (recommended: module-level constant):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { View } from '@deckgl-fiber-renderer/dom';\n * import { uuid } from '@accelint/core';\n *\n * // Create id at module level for stability and easy sharing\n * const MAIN_MAP_ID = uuid();\n *\n * export function MapView() {\n * return (\n * <BaseMap className=\"w-full h-full\" id={MAIN_MAP_ID}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * );\n * }\n * ```\n *\n * @example\n * With map mode and event handlers (module-level constant for sharing):\n * ```tsx\n * import { BaseMap } from '@accelint/map-toolkit/deckgl';\n * import { useMapMode } from '@accelint/map-toolkit/map-mode';\n * import { uuid } from '@accelint/core';\n * import type { PickingInfo } from '@deck.gl/core';\n * import type { MjolnirGestureEvent } from 'mjolnir.js';\n *\n * // Module-level constant - stable and shareable across all components\n * const MAIN_MAP_ID = uuid();\n *\n * function Toolbar() {\n * // Access map mode using the shared id\n * const { mode, requestModeChange } = useMapMode(MAIN_MAP_ID);\n * return <div>Current mode: {mode}</div>;\n * }\n *\n * export function InteractiveMap() {\n * const handleClick = (info: PickingInfo, event: MjolnirGestureEvent) => {\n * console.log('Clicked:', info.object);\n * };\n *\n * return (\n * <div className=\"relative w-full h-full\">\n * <BaseMap className=\"absolute inset-0\" id={MAIN_MAP_ID} onClick={handleClick}>\n * <View id=\"main\" controller />\n * </BaseMap>\n * <Toolbar />\n * </div>\n * );\n * }\n * ```\n */\nexport function BaseMap({\n id,\n className,\n children,\n controller = true,\n interleaved = true,\n parameters = {},\n useDevicePixels = false,\n widgets: widgetsProp = [],\n onClick,\n onHover,\n onViewStateChange,\n ...rest\n}: BaseMapProps) {\n const deckglInstance = useDeckgl();\n const container = useId();\n\n // Memoize MapLibre options to avoid creating new object on every render\n const mapOptions = useMemo(\n () => ({\n container,\n center: [INITIAL_VIEW_STATE.longitude, INITIAL_VIEW_STATE.latitude] as [\n number,\n number,\n ],\n zoom: INITIAL_VIEW_STATE.zoom,\n doubleClickZoom: false,\n dragRotate: false,\n pitchWithRotate: false,\n rollEnabled: false,\n attributionControl: { compact: true },\n }),\n [container],\n );\n\n // Use the custom hook to handle MapLibre\n useMapLibre(deckglInstance as IControl, BASE_MAP_STYLE, mapOptions);\n\n const emitClick = useEmit<MapClickEvent>(MapEvents.click);\n const emitHover = useEmit<MapHoverEvent>(MapEvents.hover);\n const emitViewport = useEmit<MapViewportEvent>(MapEvents.viewport);\n\n const handleClick = useCallback(\n (info: PickingInfo, event: MjolnirGestureEvent) => {\n // send full pickingInfo and event to user-defined onClick\n onClick?.(info, event);\n\n emitClick({\n info: serializePickingInfo(info),\n event: serializeMjolnirEvent(event),\n id,\n });\n },\n [emitClick, id, onClick],\n );\n\n const handleHover = useCallback(\n (info: PickingInfo, event: MjolnirPointerEvent) => {\n // send full pickingInfo and event to user-defined onHover\n onHover?.(info, event);\n\n emitHover({\n info: serializePickingInfo(info),\n event: serializeMjolnirEvent(event),\n id,\n });\n },\n [emitHover, id, onHover],\n );\n\n const handleGetCursor = useCallback(() => {\n return getCursor(id);\n }, [id]);\n\n const handleViewStateChange = useEffectEvent(\n (params: ViewStateChangeParameters) => {\n onViewStateChange?.(params);\n\n const {\n viewId,\n viewState: { latitude, longitude, zoom },\n } = params;\n\n // @ts-expect-error squirrelly deckglInstance typing\n const viewport = deckglInstance._deck\n .getViewports()\n // @ts-expect-error squirrelly deckglInstance typing\n ?.find((vp) => vp.id === viewId);\n\n emitViewport({\n id,\n bounds: viewport?.getBounds(),\n latitude,\n longitude,\n zoom,\n width: viewport?.width ?? 0,\n height: viewport?.height ?? 0,\n });\n },\n );\n\n const handleLoad = useEffectEvent(() => {\n //--- force update viewport state once all viewports initialized ---\n // @ts-expect-error squirrelly deckglInstance typing\n deckglInstance._deck.getViewports().forEach((vp) => {\n handleViewStateChange({\n viewId: vp.id,\n viewState: {\n latitude: vp.latitude,\n longitude: vp.longitude,\n zoom: vp.zoom,\n id: vp.id,\n bounds: vp.getBounds(),\n width: vp.width,\n height: vp.height,\n },\n } as ViewStateChangeParameters);\n });\n });\n\n return (\n <div id={container} className={className}>\n <MapProvider id={id}>\n <Deckgl\n {...rest}\n controller={controller}\n interleaved={interleaved}\n useDevicePixels={useDevicePixels}\n onClick={handleClick}\n onHover={handleHover}\n onLoad={handleLoad}\n onViewStateChange={handleViewStateChange}\n getCursor={handleGetCursor}\n // @ts-expect-error - DeckglProps parameters type is overly strict for WebGL parameter spreading.\n // The merged object is valid at runtime but TypeScript cannot verify all possible parameter combinations.\n parameters={{ ...PARAMETERS, ...parameters }}\n >\n {children}\n </Deckgl>\n </MapProvider>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAS,qBAAqB,MAA4C;CACxE,MAAM,EAAE,UAAU,OAAO,aAAa,GAAG,aAAa;AACtD,QAAO;EACL,SAAS,OAAO;EAChB,eAAe,aAAa;EAC5B,GAAG;EACJ;;AAmCH,SAAS,sBACP,OACA;CACA,MAAM,EACJ,0BACA,iBACA,gBACA,UACA,aACA,QACA,GAAG,SACD;AAGJ,KAAI,qBAAqB,MAAM;EAC7B,MAAM,EAAE,iBAAiB,UAAU,GAAG,gBAAgB;AACtD,SAAO;;AAGT,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+FT,SAAgB,QAAQ,EACtB,IACA,WACA,UACA,aAAa,MACb,cAAc,MACd,aAAa,EAAE,EACf,kBAAkB,OAClB,SAAS,cAAc,EAAE,EACzB,SACA,SACA,mBACA,GAAG,QACY;CACf,MAAM,iBAAiB,WAAW;CAClC,MAAM,YAAY,OAAO;AAqBzB,aAAY,gBAA4B,gBAlBrB,eACV;EACL;EACA,QAAQ,CAAC,mBAAmB,WAAW,mBAAmB,SAAS;EAInE,MAAM,mBAAmB;EACzB,iBAAiB;EACjB,YAAY;EACZ,iBAAiB;EACjB,aAAa;EACb,oBAAoB,EAAE,SAAS,MAAM;EACtC,GACD,CAAC,UAAU,CACZ,CAGkE;CAEnE,MAAM,YAAY,QAAuB,UAAU,MAAM;CACzD,MAAM,YAAY,QAAuB,UAAU,MAAM;CACzD,MAAM,eAAe,QAA0B,UAAU,SAAS;CAElE,MAAM,cAAc,aACjB,MAAmB,UAA+B;AAEjD,YAAU,MAAM,MAAM;AAEtB,YAAU;GACR,MAAM,qBAAqB,KAAK;GAChC,OAAO,sBAAsB,MAAM;GACnC;GACD,CAAC;IAEJ;EAAC;EAAW;EAAI;EAAQ,CACzB;CAED,MAAM,cAAc,aACjB,MAAmB,UAA+B;AAEjD,YAAU,MAAM,MAAM;AAEtB,YAAU;GACR,MAAM,qBAAqB,KAAK;GAChC,OAAO,sBAAsB,MAAM;GACnC;GACD,CAAC;IAEJ;EAAC;EAAW;EAAI;EAAQ,CACzB;CAED,MAAM,kBAAkB,kBAAkB;AACxC,SAAO,UAAU,GAAG;IACnB,CAAC,GAAG,CAAC;CAER,MAAM,wBAAwB,gBAC3B,WAAsC;AACrC,sBAAoB,OAAO;EAE3B,MAAM,EACJ,QACA,WAAW,EAAE,UAAU,WAAW,WAChC;EAGJ,MAAM,WAAW,eAAe,MAC7B,cAAc,EAEb,MAAM,OAAO,GAAG,OAAO,OAAO;AAElC,eAAa;GACX;GACA,QAAQ,UAAU,WAAW;GAC7B;GACA;GACA;GACA,OAAO,UAAU,SAAS;GAC1B,QAAQ,UAAU,UAAU;GAC7B,CAAC;GAEL;CAED,MAAM,aAAa,qBAAqB;AAGtC,iBAAe,MAAM,cAAc,CAAC,SAAS,OAAO;AAClD,yBAAsB;IACpB,QAAQ,GAAG;IACX,WAAW;KACT,UAAU,GAAG;KACb,WAAW,GAAG;KACd,MAAM,GAAG;KACT,IAAI,GAAG;KACP,QAAQ,GAAG,WAAW;KACtB,OAAO,GAAG;KACV,QAAQ,GAAG;KACZ;IACF,CAA8B;IAC/B;GACF;AAEF,QACE,oBAAC;EAAI,IAAI;EAAsB;YAC7B,oBAAC;GAAgB;aACf,oBAAC;IACC,GAAI;IACQ;IACC;IACI;IACjB,SAAS;IACT,SAAS;IACT,QAAQ;IACR,mBAAmB;IACnB,WAAW;IAGX,YAAY;KAAE,GAAG;KAAY,GAAG;KAAY;IAE3C;KACM;IACG;GACV"}