@gooddata/sdk-ui-geo 11.6.0-alpha.5 → 11.6.0-alpha.7

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 (231) hide show
  1. package/esm/next/GeoPushpinChartNext.d.ts +12 -0
  2. package/esm/next/GeoPushpinChartNext.d.ts.map +1 -0
  3. package/esm/next/GeoPushpinChartNext.js +42 -0
  4. package/esm/next/GeoPushpinChartNext.js.map +1 -0
  5. package/esm/next/RenderGeoPushpinChart.d.ts +15 -0
  6. package/esm/next/RenderGeoPushpinChart.d.ts.map +1 -0
  7. package/esm/next/RenderGeoPushpinChart.js +97 -0
  8. package/esm/next/RenderGeoPushpinChart.js.map +1 -0
  9. package/esm/next/components/ErrorComponent.d.ts +13 -0
  10. package/esm/next/components/ErrorComponent.d.ts.map +1 -0
  11. package/esm/next/components/ErrorComponent.js +19 -0
  12. package/esm/next/components/ErrorComponent.js.map +1 -0
  13. package/esm/next/components/LoadingComponent.d.ts +5 -0
  14. package/esm/next/components/LoadingComponent.d.ts.map +1 -0
  15. package/esm/next/components/LoadingComponent.js +13 -0
  16. package/esm/next/components/LoadingComponent.js.map +1 -0
  17. package/esm/next/components/legends/Legend.d.ts +28 -0
  18. package/esm/next/components/legends/Legend.d.ts.map +1 -0
  19. package/esm/next/components/legends/Legend.js +54 -0
  20. package/esm/next/components/legends/Legend.js.map +1 -0
  21. package/esm/next/components/legends/LegendBody.d.ts +12 -0
  22. package/esm/next/components/legends/LegendBody.d.ts.map +1 -0
  23. package/esm/next/components/legends/LegendBody.js +30 -0
  24. package/esm/next/components/legends/LegendBody.js.map +1 -0
  25. package/esm/next/components/legends/legendPropsAdapter.d.ts +14 -0
  26. package/esm/next/components/legends/legendPropsAdapter.d.ts.map +1 -0
  27. package/esm/next/components/legends/legendPropsAdapter.js +34 -0
  28. package/esm/next/components/legends/legendPropsAdapter.js.map +1 -0
  29. package/esm/next/components/legends/types.d.ts +16 -0
  30. package/esm/next/components/legends/types.d.ts.map +1 -0
  31. package/esm/next/components/legends/types.js +3 -0
  32. package/esm/next/components/legends/types.js.map +1 -0
  33. package/esm/next/constants/geoChart.d.ts +108 -0
  34. package/esm/next/constants/geoChart.d.ts.map +1 -0
  35. package/esm/next/constants/geoChart.js +130 -0
  36. package/esm/next/constants/geoChart.js.map +1 -0
  37. package/esm/next/constants/internal.d.ts +19 -0
  38. package/esm/next/constants/internal.d.ts.map +1 -0
  39. package/esm/next/constants/internal.js +20 -0
  40. package/esm/next/constants/internal.js.map +1 -0
  41. package/esm/next/context/GeoDataContext.d.ts +69 -0
  42. package/esm/next/context/GeoDataContext.d.ts.map +1 -0
  43. package/esm/next/context/GeoDataContext.js +80 -0
  44. package/esm/next/context/GeoDataContext.js.map +1 -0
  45. package/esm/next/context/GeoLegendContext.d.ts +78 -0
  46. package/esm/next/context/GeoLegendContext.d.ts.map +1 -0
  47. package/esm/next/context/GeoLegendContext.js +74 -0
  48. package/esm/next/context/GeoLegendContext.js.map +1 -0
  49. package/esm/next/context/GeoPushpinPropsContext.d.ts +47 -0
  50. package/esm/next/context/GeoPushpinPropsContext.d.ts.map +1 -0
  51. package/esm/next/context/GeoPushpinPropsContext.js +81 -0
  52. package/esm/next/context/GeoPushpinPropsContext.js.map +1 -0
  53. package/esm/next/context/InitialExecutionContext.d.ts +43 -0
  54. package/esm/next/context/InitialExecutionContext.d.ts.map +1 -0
  55. package/esm/next/context/InitialExecutionContext.js +45 -0
  56. package/esm/next/context/InitialExecutionContext.js.map +1 -0
  57. package/esm/next/context/MapInstanceContext.d.ts +42 -0
  58. package/esm/next/context/MapInstanceContext.d.ts.map +1 -0
  59. package/esm/next/context/MapInstanceContext.js +62 -0
  60. package/esm/next/context/MapInstanceContext.js.map +1 -0
  61. package/esm/next/features/clustering/clustering.d.ts +23 -0
  62. package/esm/next/features/clustering/clustering.d.ts.map +1 -0
  63. package/esm/next/features/clustering/clustering.js +26 -0
  64. package/esm/next/features/clustering/clustering.js.map +1 -0
  65. package/esm/next/features/coloring/colorStrategy.d.ts +22 -0
  66. package/esm/next/features/coloring/colorStrategy.d.ts.map +1 -0
  67. package/esm/next/features/coloring/colorStrategy.js +83 -0
  68. package/esm/next/features/coloring/colorStrategy.js.map +1 -0
  69. package/esm/next/features/coloring/palette.d.ts +81 -0
  70. package/esm/next/features/coloring/palette.d.ts.map +1 -0
  71. package/esm/next/features/coloring/palette.js +233 -0
  72. package/esm/next/features/coloring/palette.js.map +1 -0
  73. package/esm/next/features/data/dataSourceManagement.d.ts +20 -0
  74. package/esm/next/features/data/dataSourceManagement.d.ts.map +1 -0
  75. package/esm/next/features/data/dataSourceManagement.js +30 -0
  76. package/esm/next/features/data/dataSourceManagement.js.map +1 -0
  77. package/esm/next/features/data/transformation.d.ts +99 -0
  78. package/esm/next/features/data/transformation.d.ts.map +1 -0
  79. package/esm/next/features/data/transformation.js +369 -0
  80. package/esm/next/features/data/transformation.js.map +1 -0
  81. package/esm/next/features/map/initializeMap.d.ts +30 -0
  82. package/esm/next/features/map/initializeMap.d.ts.map +1 -0
  83. package/esm/next/features/map/initializeMap.js +58 -0
  84. package/esm/next/features/map/initializeMap.js.map +1 -0
  85. package/esm/next/features/map/layerManagement.d.ts +51 -0
  86. package/esm/next/features/map/layerManagement.d.ts.map +1 -0
  87. package/esm/next/features/map/layerManagement.js +95 -0
  88. package/esm/next/features/map/layerManagement.js.map +1 -0
  89. package/esm/next/features/map/viewportManagement.d.ts +76 -0
  90. package/esm/next/features/map/viewportManagement.d.ts.map +1 -0
  91. package/esm/next/features/map/viewportManagement.js +193 -0
  92. package/esm/next/features/map/viewportManagement.js.map +1 -0
  93. package/esm/next/features/size/calculations.d.ts +32 -0
  94. package/esm/next/features/size/calculations.d.ts.map +1 -0
  95. package/esm/next/features/size/calculations.js +37 -0
  96. package/esm/next/features/size/calculations.js.map +1 -0
  97. package/esm/next/features/tooltip/formatting.d.ts +28 -0
  98. package/esm/next/features/tooltip/formatting.d.ts.map +1 -0
  99. package/esm/next/features/tooltip/formatting.js +51 -0
  100. package/esm/next/features/tooltip/formatting.js.map +1 -0
  101. package/esm/next/features/tooltip/tooltipManagement.d.ts +47 -0
  102. package/esm/next/features/tooltip/tooltipManagement.d.ts.map +1 -0
  103. package/esm/next/features/tooltip/tooltipManagement.js +73 -0
  104. package/esm/next/features/tooltip/tooltipManagement.js.map +1 -0
  105. package/esm/next/hooks/init/useInitExecution.d.ts +29 -0
  106. package/esm/next/hooks/init/useInitExecution.d.ts.map +1 -0
  107. package/esm/next/hooks/init/useInitExecution.js +91 -0
  108. package/esm/next/hooks/init/useInitExecution.js.map +1 -0
  109. package/esm/next/hooks/init/useInitExecutionResult.d.ts +17 -0
  110. package/esm/next/hooks/init/useInitExecutionResult.d.ts.map +1 -0
  111. package/esm/next/hooks/init/useInitExecutionResult.js +44 -0
  112. package/esm/next/hooks/init/useInitExecutionResult.js.map +1 -0
  113. package/esm/next/hooks/legend/useLegendConfig.d.ts +35 -0
  114. package/esm/next/hooks/legend/useLegendConfig.d.ts.map +1 -0
  115. package/esm/next/hooks/legend/useLegendConfig.js +25 -0
  116. package/esm/next/hooks/legend/useLegendConfig.js.map +1 -0
  117. package/esm/next/hooks/legend/useLegendDetails.d.ts +27 -0
  118. package/esm/next/hooks/legend/useLegendDetails.d.ts.map +1 -0
  119. package/esm/next/hooks/legend/useLegendDetails.js +39 -0
  120. package/esm/next/hooks/legend/useLegendDetails.js.map +1 -0
  121. package/esm/next/hooks/legend/useLegendItemClick.d.ts +16 -0
  122. package/esm/next/hooks/legend/useLegendItemClick.d.ts.map +1 -0
  123. package/esm/next/hooks/legend/useLegendItemClick.js +23 -0
  124. package/esm/next/hooks/legend/useLegendItemClick.js.map +1 -0
  125. package/esm/next/hooks/legend/useLegendItems.d.ts +27 -0
  126. package/esm/next/hooks/legend/useLegendItems.d.ts.map +1 -0
  127. package/esm/next/hooks/legend/useLegendItems.js +54 -0
  128. package/esm/next/hooks/legend/useLegendItems.js.map +1 -0
  129. package/esm/next/hooks/legend/useLegendItemsWithState.d.ts +21 -0
  130. package/esm/next/hooks/legend/useLegendItemsWithState.d.ts.map +1 -0
  131. package/esm/next/hooks/legend/useLegendItemsWithState.js +42 -0
  132. package/esm/next/hooks/legend/useLegendItemsWithState.js.map +1 -0
  133. package/esm/next/hooks/legend/useLegendProps.d.ts +53 -0
  134. package/esm/next/hooks/legend/useLegendProps.d.ts.map +1 -0
  135. package/esm/next/hooks/legend/useLegendProps.js +38 -0
  136. package/esm/next/hooks/legend/useLegendProps.js.map +1 -0
  137. package/esm/next/hooks/legend/useSelectedSegments.d.ts +17 -0
  138. package/esm/next/hooks/legend/useSelectedSegments.d.ts.map +1 -0
  139. package/esm/next/hooks/legend/useSelectedSegments.js +32 -0
  140. package/esm/next/hooks/legend/useSelectedSegments.js.map +1 -0
  141. package/esm/next/hooks/map/useAfterRender.d.ts +19 -0
  142. package/esm/next/hooks/map/useAfterRender.d.ts.map +1 -0
  143. package/esm/next/hooks/map/useAfterRender.js +99 -0
  144. package/esm/next/hooks/map/useAfterRender.js.map +1 -0
  145. package/esm/next/hooks/map/useMapCallbacks.d.ts +20 -0
  146. package/esm/next/hooks/map/useMapCallbacks.d.ts.map +1 -0
  147. package/esm/next/hooks/map/useMapCallbacks.js +44 -0
  148. package/esm/next/hooks/map/useMapCallbacks.js.map +1 -0
  149. package/esm/next/hooks/map/useMapDataSync.d.ts +44 -0
  150. package/esm/next/hooks/map/useMapDataSync.d.ts.map +1 -0
  151. package/esm/next/hooks/map/useMapDataSync.js +87 -0
  152. package/esm/next/hooks/map/useMapDataSync.js.map +1 -0
  153. package/esm/next/hooks/map/useMapInitialization.d.ts +56 -0
  154. package/esm/next/hooks/map/useMapInitialization.d.ts.map +1 -0
  155. package/esm/next/hooks/map/useMapInitialization.js +121 -0
  156. package/esm/next/hooks/map/useMapInitialization.js.map +1 -0
  157. package/esm/next/hooks/map/useTooltipHandlers.d.ts +22 -0
  158. package/esm/next/hooks/map/useTooltipHandlers.d.ts.map +1 -0
  159. package/esm/next/hooks/map/useTooltipHandlers.js +28 -0
  160. package/esm/next/hooks/map/useTooltipHandlers.js.map +1 -0
  161. package/esm/next/hooks/shared/useGeoDataTransformation.d.ts +23 -0
  162. package/esm/next/hooks/shared/useGeoDataTransformation.d.ts.map +1 -0
  163. package/esm/next/hooks/shared/useGeoDataTransformation.js +37 -0
  164. package/esm/next/hooks/shared/useGeoDataTransformation.js.map +1 -0
  165. package/esm/next/hooks/shared/usePushData.d.ts +8 -0
  166. package/esm/next/hooks/shared/usePushData.d.ts.map +1 -0
  167. package/esm/next/hooks/shared/usePushData.js +36 -0
  168. package/esm/next/hooks/shared/usePushData.js.map +1 -0
  169. package/esm/next/hooks/shared/useResolvedProps.d.ts +16 -0
  170. package/esm/next/hooks/shared/useResolvedProps.d.ts.map +1 -0
  171. package/esm/next/hooks/shared/useResolvedProps.js +40 -0
  172. package/esm/next/hooks/shared/useResolvedProps.js.map +1 -0
  173. package/esm/next/index.d.ts +5 -0
  174. package/esm/next/index.d.ts.map +1 -0
  175. package/esm/next/index.js +3 -0
  176. package/esm/next/index.js.map +1 -0
  177. package/esm/next/providers/maplibre/maplibreConfig.d.ts +68 -0
  178. package/esm/next/providers/maplibre/maplibreConfig.d.ts.map +1 -0
  179. package/esm/next/providers/maplibre/maplibreConfig.js +104 -0
  180. package/esm/next/providers/maplibre/maplibreConfig.js.map +1 -0
  181. package/esm/next/providers/maplibre/maplibreDataLayers.d.ts +51 -0
  182. package/esm/next/providers/maplibre/maplibreDataLayers.d.ts.map +1 -0
  183. package/esm/next/providers/maplibre/maplibreDataLayers.js +195 -0
  184. package/esm/next/providers/maplibre/maplibreDataLayers.js.map +1 -0
  185. package/esm/next/providers/maplibre/maplibreDataSource.d.ts +28 -0
  186. package/esm/next/providers/maplibre/maplibreDataSource.d.ts.map +1 -0
  187. package/esm/next/providers/maplibre/maplibreDataSource.js +117 -0
  188. package/esm/next/providers/maplibre/maplibreDataSource.js.map +1 -0
  189. package/esm/next/providers/maplibre/maplibreTooltip.d.ts +54 -0
  190. package/esm/next/providers/maplibre/maplibreTooltip.d.ts.map +1 -0
  191. package/esm/next/providers/maplibre/maplibreTooltip.js +158 -0
  192. package/esm/next/providers/maplibre/maplibreTooltip.js.map +1 -0
  193. package/esm/next/providers/maplibre/maplibreViewport.d.ts +45 -0
  194. package/esm/next/providers/maplibre/maplibreViewport.d.ts.map +1 -0
  195. package/esm/next/providers/maplibre/maplibreViewport.js +92 -0
  196. package/esm/next/providers/maplibre/maplibreViewport.js.map +1 -0
  197. package/esm/next/providers/maplibre/style.d.ts +3 -0
  198. package/esm/next/providers/maplibre/style.d.ts.map +1 -0
  199. package/esm/next/providers/maplibre/style.js +8361 -0
  200. package/esm/next/providers/maplibre/style.js.map +1 -0
  201. package/esm/next/types/config.d.ts +89 -0
  202. package/esm/next/types/config.d.ts.map +1 -0
  203. package/esm/next/types/config.js +3 -0
  204. package/esm/next/types/config.js.map +1 -0
  205. package/esm/next/types/internal.d.ts +17 -0
  206. package/esm/next/types/internal.d.ts.map +1 -0
  207. package/esm/next/types/internal.js +3 -0
  208. package/esm/next/types/internal.js.map +1 -0
  209. package/esm/next/types/mapProvider.d.ts +122 -0
  210. package/esm/next/types/mapProvider.d.ts.map +1 -0
  211. package/esm/next/types/mapProvider.js +3 -0
  212. package/esm/next/types/mapProvider.js.map +1 -0
  213. package/esm/next/types/public.d.ts +84 -0
  214. package/esm/next/types/public.d.ts.map +1 -0
  215. package/esm/next/types/public.js +15 -0
  216. package/esm/next/types/public.js.map +1 -0
  217. package/esm/next/types/shared.d.ts +209 -0
  218. package/esm/next/types/shared.d.ts.map +1 -0
  219. package/esm/next/types/shared.js +3 -0
  220. package/esm/next/types/shared.js.map +1 -0
  221. package/esm/next/utils/mapLocale.d.ts +26 -0
  222. package/esm/next/utils/mapLocale.d.ts.map +1 -0
  223. package/esm/next/utils/mapLocale.js +22 -0
  224. package/esm/next/utils/mapLocale.js.map +1 -0
  225. package/package.json +13 -10
  226. package/styles/css/main.css +925 -0
  227. package/styles/css/main.css.map +1 -1
  228. package/styles/scss/_geo-pushpin-next-legend.scss +166 -0
  229. package/styles/scss/_maplibre-overrides.scss +64 -0
  230. package/styles/scss/geo-pushpin-next.scss +58 -0
  231. package/styles/scss/main.scss +1 -0
@@ -0,0 +1,17 @@
1
+ import { IPushpinCategoryLegendItem } from "@gooddata/sdk-ui-vis-commons";
2
+ /**
3
+ * Hook to compute selected segment URIs from enabled legend items.
4
+ *
5
+ * @remarks
6
+ * This hook filters category legend items to only include visible ones,
7
+ * and returns their URIs for use in map filtering. If no legend items are
8
+ * provided or the enabled list is empty (meaning all are enabled), returns
9
+ * an empty array which signals "show all".
10
+ *
11
+ * @param categoryItems - All category legend items
12
+ * @returns Array of URIs for enabled segments (empty array means "show all")
13
+ *
14
+ * @alpha
15
+ */
16
+ export declare function useSelectedSegments(categoryItems: IPushpinCategoryLegendItem[]): string[];
17
+ //# sourceMappingURL=useSelectedSegments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSelectedSegments.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/legend/useSelectedSegments.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAI1E;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,0BAA0B,EAAE,GAAG,MAAM,EAAE,CAgBzF"}
@@ -0,0 +1,32 @@
1
+ // (C) 2025 GoodData Corporation
2
+ import { useMemo } from "react";
3
+ import { useGeoLegend } from "../../context/GeoLegendContext.js";
4
+ /**
5
+ * Hook to compute selected segment URIs from enabled legend items.
6
+ *
7
+ * @remarks
8
+ * This hook filters category legend items to only include visible ones,
9
+ * and returns their URIs for use in map filtering. If no legend items are
10
+ * provided or the enabled list is empty (meaning all are enabled), returns
11
+ * an empty array which signals "show all".
12
+ *
13
+ * @param categoryItems - All category legend items
14
+ * @returns Array of URIs for enabled segments (empty array means "show all")
15
+ *
16
+ * @alpha
17
+ */
18
+ export function useSelectedSegments(categoryItems) {
19
+ const { enabledLegendItems } = useGeoLegend();
20
+ return useMemo(() => {
21
+ if (!categoryItems.length) {
22
+ return [];
23
+ }
24
+ // If no items are explicitly enabled, show all
25
+ if (enabledLegendItems.length === 0) {
26
+ return [];
27
+ }
28
+ // Filter to only enabled items
29
+ return categoryItems.filter((item) => enabledLegendItems.includes(item.uri)).map((item) => item.uri);
30
+ }, [categoryItems, enabledLegendItems]);
31
+ }
32
+ //# sourceMappingURL=useSelectedSegments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSelectedSegments.js","sourceRoot":"","sources":["../../../../src/next/hooks/legend/useSelectedSegments.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAIhC,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAC;AAEjE;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,aAA2C;IAC3E,MAAM,EAAE,kBAAkB,EAAE,GAAG,YAAY,EAAE,CAAC;IAE9C,OAAO,OAAO,CAAC,GAAG,EAAE;QAChB,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC;YACxB,OAAO,EAAE,CAAC;QACd,CAAC;QAED,+CAA+C;QAC/C,IAAI,kBAAkB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,CAAC;QACd,CAAC;QAED,+BAA+B;QAC/B,OAAO,aAAa,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACzG,CAAC,EAAE,CAAC,aAAa,EAAE,kBAAkB,CAAC,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { Map as MapLibreMap } from "maplibre-gl";
2
+ /**
3
+ * Calls afterRender callback when map finishes rendering
4
+ *
5
+ * @remarks
6
+ * This hook listens to the map's "idle" event and calls the afterRender
7
+ * callback once. This is used by the Analytical Designer to know when
8
+ * the chart has finished rendering and can remove the loading spinner.
9
+ *
10
+ * The callback is only called once per resetSignal change to avoid repeated calls.
11
+ *
12
+ * @param map - MapLibre map instance
13
+ * @param afterRender - Callback to call when rendering is complete
14
+ * @param resetSignal - Value that indicates the map should re-signal completion (e.g., execution object)
15
+ *
16
+ * @internal
17
+ */
18
+ export declare function useAfterRender(map: MapLibreMap | null, afterRender?: () => void, resetSignal?: unknown): void;
19
+ //# sourceMappingURL=useAfterRender.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAfterRender.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/map/useAfterRender.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AA2CtD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAC1B,GAAG,EAAE,WAAW,GAAG,IAAI,EACvB,WAAW,CAAC,EAAE,MAAM,IAAI,EACxB,WAAW,CAAC,EAAE,OAAO,GACtB,IAAI,CAkDN"}
@@ -0,0 +1,99 @@
1
+ // (C) 2025 GoodData Corporation
2
+ import { useEffect, useRef } from "react";
3
+ /**
4
+ * Check if map is fully idle (loaded and tiles ready)
5
+ *
6
+ * @remarks
7
+ * Pure function that checks if the map is in an idle state, meaning both
8
+ * the style and tiles are loaded and ready for rendering.
9
+ *
10
+ * @param map - MapLibre map instance
11
+ * @returns true if map is idle, false otherwise
12
+ *
13
+ * @internal
14
+ */
15
+ function isMapFullyIdle(map) {
16
+ // Check if tiles are loaded (if method exists)
17
+ const tilesLoaded = typeof map.areTilesLoaded === "function"
18
+ ? map.areTilesLoaded()
19
+ : true;
20
+ return map.loaded() && tilesLoaded;
21
+ }
22
+ /**
23
+ * Schedule callback to run asynchronously
24
+ *
25
+ * @remarks
26
+ * Pure function that schedules a callback to run on the next frame or tick.
27
+ * Prefers requestAnimationFrame for smoother rendering, falls back to setTimeout.
28
+ *
29
+ * @param callback - Function to schedule
30
+ *
31
+ * @internal
32
+ */
33
+ function scheduleAsync(callback) {
34
+ if (typeof requestAnimationFrame === "function") {
35
+ requestAnimationFrame(callback);
36
+ }
37
+ else {
38
+ setTimeout(callback, 0);
39
+ }
40
+ }
41
+ /**
42
+ * Calls afterRender callback when map finishes rendering
43
+ *
44
+ * @remarks
45
+ * This hook listens to the map's "idle" event and calls the afterRender
46
+ * callback once. This is used by the Analytical Designer to know when
47
+ * the chart has finished rendering and can remove the loading spinner.
48
+ *
49
+ * The callback is only called once per resetSignal change to avoid repeated calls.
50
+ *
51
+ * @param map - MapLibre map instance
52
+ * @param afterRender - Callback to call when rendering is complete
53
+ * @param resetSignal - Value that indicates the map should re-signal completion (e.g., execution object)
54
+ *
55
+ * @internal
56
+ */
57
+ export function useAfterRender(map, afterRender, resetSignal) {
58
+ const hasCalledRef = useRef(false);
59
+ const lastResetSignalRef = useRef(resetSignal);
60
+ // Reset the "called" flag when resetSignal changes
61
+ useEffect(() => {
62
+ if (resetSignal !== lastResetSignalRef.current) {
63
+ hasCalledRef.current = false;
64
+ lastResetSignalRef.current = resetSignal;
65
+ }
66
+ }, [resetSignal]);
67
+ // Set up idle listener and invoke callbacks
68
+ useEffect(() => {
69
+ // Guard: skip if no map, already called, or no callbacks
70
+ if (!map || hasCalledRef.current || !afterRender) {
71
+ return;
72
+ }
73
+ const invokeCallbacks = () => {
74
+ // Double-check we haven't called yet (race condition guard)
75
+ if (hasCalledRef.current) {
76
+ return;
77
+ }
78
+ hasCalledRef.current = true;
79
+ // Invoke callbacks
80
+ if (afterRender) {
81
+ afterRender();
82
+ }
83
+ };
84
+ const handleIdle = () => {
85
+ map.off("idle", handleIdle);
86
+ invokeCallbacks();
87
+ };
88
+ // Register idle listener
89
+ map.on("idle", handleIdle);
90
+ // If already idle, trigger immediately (async to avoid sync effects)
91
+ if (isMapFullyIdle(map)) {
92
+ scheduleAsync(handleIdle);
93
+ }
94
+ return () => {
95
+ map.off("idle", handleIdle);
96
+ };
97
+ }, [map, afterRender, resetSignal]);
98
+ }
99
+ //# sourceMappingURL=useAfterRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAfterRender.js","sourceRoot":"","sources":["../../../../src/next/hooks/map/useAfterRender.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAI1C;;;;;;;;;;;GAWG;AACH,SAAS,cAAc,CAAC,GAAgB;IACpC,+CAA+C;IAC/C,MAAM,WAAW,GACb,OAAQ,GAAqD,CAAC,cAAc,KAAK,UAAU;QACvF,CAAC,CAAE,GAAoD,CAAC,cAAc,EAAE;QACxE,CAAC,CAAC,IAAI,CAAC;IAEf,OAAO,GAAG,CAAC,MAAM,EAAE,IAAI,WAAW,CAAC;AACvC,CAAC;AAED;;;;;;;;;;GAUG;AACH,SAAS,aAAa,CAAC,QAAoB;IACvC,IAAI,OAAO,qBAAqB,KAAK,UAAU,EAAE,CAAC;QAC9C,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACpC,CAAC;SAAM,CAAC;QACJ,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAC5B,CAAC;AACL,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,cAAc,CAC1B,GAAuB,EACvB,WAAwB,EACxB,WAAqB;IAErB,MAAM,YAAY,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACnC,MAAM,kBAAkB,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IAE/C,mDAAmD;IACnD,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,WAAW,KAAK,kBAAkB,CAAC,OAAO,EAAE,CAAC;YAC7C,YAAY,CAAC,OAAO,GAAG,KAAK,CAAC;YAC7B,kBAAkB,CAAC,OAAO,GAAG,WAAW,CAAC;QAC7C,CAAC;IACL,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;IAElB,4CAA4C;IAC5C,SAAS,CAAC,GAAG,EAAE;QACX,yDAAyD;QACzD,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC;YAC/C,OAAO;QACX,CAAC;QAED,MAAM,eAAe,GAAG,GAAG,EAAE;YACzB,4DAA4D;YAC5D,IAAI,YAAY,CAAC,OAAO,EAAE,CAAC;gBACvB,OAAO;YACX,CAAC;YAED,YAAY,CAAC,OAAO,GAAG,IAAI,CAAC;YAE5B,mBAAmB;YACnB,IAAI,WAAW,EAAE,CAAC;gBACd,WAAW,EAAE,CAAC;YAClB,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,UAAU,GAAG,GAAG,EAAE;YACpB,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;YAC5B,eAAe,EAAE,CAAC;QACtB,CAAC,CAAC;QAEF,yBAAyB;QACzB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAE3B,qEAAqE;QACrE,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACtB,aAAa,CAAC,UAAU,CAAC,CAAC;QAC9B,CAAC;QAED,OAAO,GAAG,EAAE;YACR,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAChC,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,EAAE,WAAW,CAAC,CAAC,CAAC;AACxC,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { Map as MapLibreMap } from "maplibre-gl";
2
+ import { CenterPositionChangedCallback, ZoomChangedCallback } from "../../types/shared.js";
3
+ /**
4
+ * Set up map interaction callbacks
5
+ *
6
+ * @remarks
7
+ * This hook sets up event listeners for map interactions like pan and zoom,
8
+ * and calls the provided callbacks when these events occur. It properly
9
+ * cleans up listeners on unmount or when dependencies change.
10
+ *
11
+ * @param map - MapLibre map instance
12
+ * @param callbacks - Callback functions for map events
13
+ *
14
+ * @internal
15
+ */
16
+ export declare function useMapCallbacks(map: MapLibreMap | null, callbacks: {
17
+ onCenterPositionChanged?: CenterPositionChangedCallback;
18
+ onZoomChanged?: ZoomChangedCallback;
19
+ }): void;
20
+ //# sourceMappingURL=useMapCallbacks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapCallbacks.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/map/useMapCallbacks.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,6BAA6B,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE3F;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC3B,GAAG,EAAE,WAAW,GAAG,IAAI,EACvB,SAAS,EAAE;IACP,uBAAuB,CAAC,EAAE,6BAA6B,CAAC;IACxD,aAAa,CAAC,EAAE,mBAAmB,CAAC;CACvC,GACF,IAAI,CAgCN"}
@@ -0,0 +1,44 @@
1
+ // (C) 2025 GoodData Corporation
2
+ import { useEffect } from "react";
3
+ /**
4
+ * Set up map interaction callbacks
5
+ *
6
+ * @remarks
7
+ * This hook sets up event listeners for map interactions like pan and zoom,
8
+ * and calls the provided callbacks when these events occur. It properly
9
+ * cleans up listeners on unmount or when dependencies change.
10
+ *
11
+ * @param map - MapLibre map instance
12
+ * @param callbacks - Callback functions for map events
13
+ *
14
+ * @internal
15
+ */
16
+ export function useMapCallbacks(map, callbacks) {
17
+ const { onCenterPositionChanged, onZoomChanged } = callbacks;
18
+ useEffect(() => {
19
+ if (!map) {
20
+ return;
21
+ }
22
+ const handleMoveEnd = () => {
23
+ if (onCenterPositionChanged) {
24
+ const center = map.getCenter();
25
+ onCenterPositionChanged({
26
+ lat: center.lat,
27
+ lng: center.lng,
28
+ });
29
+ }
30
+ };
31
+ const handleZoomEnd = () => {
32
+ if (onZoomChanged) {
33
+ onZoomChanged(map.getZoom());
34
+ }
35
+ };
36
+ map.on("moveend", handleMoveEnd);
37
+ map.on("zoomend", handleZoomEnd);
38
+ return () => {
39
+ map.off("moveend", handleMoveEnd);
40
+ map.off("zoomend", handleZoomEnd);
41
+ };
42
+ }, [map, onCenterPositionChanged, onZoomChanged]);
43
+ }
44
+ //# sourceMappingURL=useMapCallbacks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapCallbacks.js","sourceRoot":"","sources":["../../../../src/next/hooks/map/useMapCallbacks.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAMlC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,eAAe,CAC3B,GAAuB,EACvB,SAGC;IAED,MAAM,EAAE,uBAAuB,EAAE,aAAa,EAAE,GAAG,SAAS,CAAC;IAE7D,SAAS,CAAC,GAAG,EAAE;QACX,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,OAAO;QACX,CAAC;QAED,MAAM,aAAa,GAAG,GAAG,EAAE;YACvB,IAAI,uBAAuB,EAAE,CAAC;gBAC1B,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;gBAC/B,uBAAuB,CAAC;oBACpB,GAAG,EAAE,MAAM,CAAC,GAAG;oBACf,GAAG,EAAE,MAAM,CAAC,GAAG;iBAClB,CAAC,CAAC;YACP,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,aAAa,GAAG,GAAG,EAAE;YACvB,IAAI,aAAa,EAAE,CAAC;gBAChB,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YACjC,CAAC;QACL,CAAC,CAAC;QAEF,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACjC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QAEjC,OAAO,GAAG,EAAE;YACR,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YAClC,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACtC,CAAC,CAAC;IACN,CAAC,EAAE,CAAC,GAAG,EAAE,uBAAuB,EAAE,aAAa,CAAC,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,44 @@
1
+ import type { Map as MapLibreMap } from "maplibre-gl";
2
+ import { DataViewFacade } from "@gooddata/sdk-ui";
3
+ import { IColorStrategy } from "@gooddata/sdk-ui-vis-commons";
4
+ import { IMapConfig } from "../../types/mapProvider.js";
5
+ import { IGeoData, IGeoLngLat } from "../../types/shared.js";
6
+ /**
7
+ * Filter out invalid coordinates
8
+ *
9
+ * @remarks
10
+ * Pure function that filters location data to only include valid coordinates.
11
+ * Valid coordinates must be present and have finite lat/lng values.
12
+ *
13
+ * @param locations - Array of location coordinates (may include nulls/undefined)
14
+ * @returns Filtered array of valid coordinates
15
+ *
16
+ * @internal
17
+ */
18
+ export declare function getValidLocations(locations: Array<IGeoLngLat | null | undefined>): IGeoLngLat[];
19
+ /**
20
+ * Synchronize geo data with map layers
21
+ *
22
+ * @remarks
23
+ * This hook updates map layers when data, config, or color strategy changes.
24
+ * It handles:
25
+ * - Removing old layers
26
+ * - Creating new data source
27
+ * - Adding appropriate layers (clustered or unclustered)
28
+ * - Setting viewport based on data (unless frozen or on first render)
29
+ *
30
+ * The hook waits for the map to be ready before attempting any updates.
31
+ * On first render, viewport setting is skipped because it was already set
32
+ * during map initialization.
33
+ *
34
+ * @param map - MapLibre map instance (null if not initialized)
35
+ * @param geoData - Geographic data to display (null if not loaded)
36
+ * @param config - Map configuration (null if not ready)
37
+ * @param colorStrategy - Color strategy for styling (null if not ready)
38
+ * @param isMapReady - Whether map is ready for updates
39
+ * @param result - Execution result for data access
40
+ *
41
+ * @internal
42
+ */
43
+ export declare function useMapDataSync(map: MapLibreMap | null, geoData: IGeoData | null, config: IMapConfig | null, colorStrategy: IColorStrategy | null, isMapReady: boolean, result: DataViewFacade | null): void;
44
+ //# sourceMappingURL=useMapDataSync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapDataSync.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/map/useMapDataSync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,IAAI,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAI9D,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAE7D;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,KAAK,CAAC,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC,GAAG,UAAU,EAAE,CAQ/F;AAkBD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,cAAc,CAC1B,GAAG,EAAE,WAAW,GAAG,IAAI,EACvB,OAAO,EAAE,QAAQ,GAAG,IAAI,EACxB,MAAM,EAAE,UAAU,GAAG,IAAI,EACzB,aAAa,EAAE,cAAc,GAAG,IAAI,EACpC,UAAU,EAAE,OAAO,EACnB,MAAM,EAAE,cAAc,GAAG,IAAI,GAC9B,IAAI,CAqCN"}
@@ -0,0 +1,87 @@
1
+ // (C) 2025 GoodData Corporation
2
+ import { useEffect, useMemo, useRef } from "react";
3
+ import { updateMapLayers } from "../../features/map/layerManagement.js";
4
+ import { applyViewportSafely, calculateViewport } from "../../features/map/viewportManagement.js";
5
+ /**
6
+ * Filter out invalid coordinates
7
+ *
8
+ * @remarks
9
+ * Pure function that filters location data to only include valid coordinates.
10
+ * Valid coordinates must be present and have finite lat/lng values.
11
+ *
12
+ * @param locations - Array of location coordinates (may include nulls/undefined)
13
+ * @returns Filtered array of valid coordinates
14
+ *
15
+ * @internal
16
+ */
17
+ export function getValidLocations(locations) {
18
+ return locations.filter((coords) => coords !== null &&
19
+ coords !== undefined &&
20
+ Number.isFinite(coords.lat) &&
21
+ Number.isFinite(coords.lng));
22
+ }
23
+ /**
24
+ * Check if viewport should be updated
25
+ *
26
+ * @remarks
27
+ * Pure function that determines whether the viewport should be updated
28
+ * based on configuration. The viewport is frozen when explicitly configured.
29
+ *
30
+ * @param config - Map configuration
31
+ * @returns true if viewport should remain frozen, false if it should update
32
+ *
33
+ * @internal
34
+ */
35
+ function isViewportFrozen(config) {
36
+ return Boolean(config.viewport?.frozen);
37
+ }
38
+ /**
39
+ * Synchronize geo data with map layers
40
+ *
41
+ * @remarks
42
+ * This hook updates map layers when data, config, or color strategy changes.
43
+ * It handles:
44
+ * - Removing old layers
45
+ * - Creating new data source
46
+ * - Adding appropriate layers (clustered or unclustered)
47
+ * - Setting viewport based on data (unless frozen or on first render)
48
+ *
49
+ * The hook waits for the map to be ready before attempting any updates.
50
+ * On first render, viewport setting is skipped because it was already set
51
+ * during map initialization.
52
+ *
53
+ * @param map - MapLibre map instance (null if not initialized)
54
+ * @param geoData - Geographic data to display (null if not loaded)
55
+ * @param config - Map configuration (null if not ready)
56
+ * @param colorStrategy - Color strategy for styling (null if not ready)
57
+ * @param isMapReady - Whether map is ready for updates
58
+ * @param result - Execution result for data access
59
+ *
60
+ * @internal
61
+ */
62
+ export function useMapDataSync(map, geoData, config, colorStrategy, isMapReady, result) {
63
+ // Track first render to avoid re-applying viewport that was set during initialization
64
+ const isFirstRenderRef = useRef(true);
65
+ // Compute valid locations (pure function, memoized)
66
+ const validLocations = useMemo(() => (geoData?.location?.data ? getValidLocations(geoData.location.data) : []), [geoData?.location?.data]);
67
+ // Compute viewport (pure function, memoized)
68
+ const viewport = useMemo(() => (config ? calculateViewport(validLocations, config) : null), [validLocations, config]);
69
+ useEffect(() => {
70
+ // Guard: ensure all dependencies are ready
71
+ if (!map || !isMapReady || !geoData || !config || !colorStrategy || !result || !viewport) {
72
+ return undefined;
73
+ }
74
+ // Update layers with new data
75
+ updateMapLayers(map, geoData, config, colorStrategy);
76
+ // Skip viewport update on first render (already set during initialization)
77
+ // Update viewport on subsequent renders if not frozen
78
+ if (!isFirstRenderRef.current && !isViewportFrozen(config)) {
79
+ map.resize();
80
+ return applyViewportSafely(map, viewport);
81
+ }
82
+ // Mark that first render has completed
83
+ isFirstRenderRef.current = false;
84
+ return undefined;
85
+ }, [map, geoData, config, colorStrategy, result, isMapReady, viewport]);
86
+ }
87
+ //# sourceMappingURL=useMapDataSync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapDataSync.js","sourceRoot":"","sources":["../../../../src/next/hooks/map/useMapDataSync.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAOnD,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,0CAA0C,CAAC;AAIlG;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAAC,SAA+C;IAC7E,OAAO,SAAS,CAAC,MAAM,CACnB,CAAC,MAAM,EAAwB,EAAE,CAC7B,MAAM,KAAK,IAAI;QACf,MAAM,KAAK,SAAS;QACpB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC;QAC3B,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAClC,CAAC;AACN,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,gBAAgB,CAAC,MAAkB;IACxC,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,cAAc,CAC1B,GAAuB,EACvB,OAAwB,EACxB,MAAyB,EACzB,aAAoC,EACpC,UAAmB,EACnB,MAA6B;IAE7B,sFAAsF;IACtF,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAEtC,oDAAoD;IACpD,MAAM,cAAc,GAAG,OAAO,CAC1B,GAAG,EAAE,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAC/E,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAC5B,CAAC;IAEF,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,OAAO,CACpB,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EACjE,CAAC,cAAc,EAAE,MAAM,CAAC,CAC3B,CAAC;IAEF,SAAS,CAAC,GAAG,EAAE;QACX,2CAA2C;QAC3C,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,IAAI,CAAC,MAAM,IAAI,CAAC,aAAa,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvF,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,8BAA8B;QAC9B,eAAe,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC;QAErD,2EAA2E;QAC3E,sDAAsD;QACtD,IAAI,CAAC,gBAAgB,CAAC,OAAO,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,CAAC;YACzD,GAAG,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,mBAAmB,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC9C,CAAC;QAED,uCAAuC;QACvC,gBAAgB,CAAC,OAAO,GAAG,KAAK,CAAC;QAEjC,OAAO,SAAS,CAAC;IACrB,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC5E,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { RefObject } from "react";
2
+ import type { Map as MapLibreMap, Popup } from "maplibre-gl";
3
+ import { IntlShape } from "react-intl";
4
+ import { IGeoPushpinChartNextConfig } from "../../types/config.js";
5
+ import { IMapViewport } from "../../types/mapProvider.js";
6
+ /**
7
+ * Hook return value
8
+ *
9
+ * @internal
10
+ */
11
+ export interface IUseMapInitializationResult {
12
+ /**
13
+ * MapLibre map instance (null until initialized)
14
+ */
15
+ map: MapLibreMap | null;
16
+ /**
17
+ * Tooltip popup instance (null until initialized)
18
+ */
19
+ tooltip: Popup | null;
20
+ /**
21
+ * Whether map is ready for use
22
+ */
23
+ isMapReady: boolean;
24
+ /**
25
+ * Error that occurred during initialization
26
+ */
27
+ error: Error | null;
28
+ }
29
+ /**
30
+ * Initialize map instance
31
+ *
32
+ * @remarks
33
+ * This hook handles map creation, loading state, and cleanup.
34
+ * It creates the MapLibre map instance when the container is ready
35
+ * and cleans it up on unmount.
36
+ *
37
+ * The map instance is returned along with loading/error states.
38
+ *
39
+ * Key behaviors:
40
+ * - Accepts pre-calculated viewport to prevent initial world view
41
+ * - Captures initial center/zoom on first render (prevents re-centering on config changes)
42
+ * - Creates map instance asynchronously
43
+ * - Handles race conditions with isMounted flag
44
+ * - Cleans up resources on unmount or style change
45
+ * - Supports cooperative gestures with localized messages
46
+ *
47
+ * @param containerRef - Ref to the map container element
48
+ * @param intl - react-intl instance for translations
49
+ * @param config - Geo configuration (optional)
50
+ * @param initialViewport - Pre-calculated viewport from data (optional)
51
+ * @returns Map instance, tooltip, ready state, and error
52
+ *
53
+ * @internal
54
+ */
55
+ export declare function useMapInitialization(containerRef: RefObject<HTMLDivElement | null>, intl: IntlShape, config?: IGeoPushpinChartNextConfig, initialViewport?: Partial<IMapViewport> | null): IUseMapInitializationResult;
56
+ //# sourceMappingURL=useMapInitialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapInitialization.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/map/useMapInitialization.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAwC,MAAM,OAAO,CAAC;AAExE,OAAO,KAAK,EAAE,GAAG,IAAI,WAAW,EAAE,KAAK,EAAsB,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAGvC,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG1D;;;;GAIG;AACH,MAAM,WAAW,2BAA2B;IACxC;;OAEG;IACH,GAAG,EAAE,WAAW,GAAG,IAAI,CAAC;IAExB;;OAEG;IACH,OAAO,EAAE,KAAK,GAAG,IAAI,CAAC;IAEtB;;OAEG;IACH,UAAU,EAAE,OAAO,CAAC;IAEpB;;OAEG;IACH,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACvB;AAmBD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,oBAAoB,CAChC,YAAY,EAAE,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAC9C,IAAI,EAAE,SAAS,EACf,MAAM,CAAC,EAAE,0BAA0B,EACnC,eAAe,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI,GAC/C,2BAA2B,CAqF7B"}
@@ -0,0 +1,121 @@
1
+ // (C) 2025 GoodData Corporation
2
+ import { useEffect, useMemo, useRef, useState } from "react";
3
+ import { initializeMapLibreMap } from "../../features/map/initializeMap.js";
4
+ import { generateMapLibreLocale } from "../../utils/mapLocale.js";
5
+ /**
6
+ * Cleanup map resources
7
+ *
8
+ * @remarks
9
+ * Pure function that safely removes map and tooltip instances.
10
+ * Handles null checks internally for clean code.
11
+ *
12
+ * @param map - MapLibre map instance to remove (or null)
13
+ * @param tooltip - Tooltip popup instance to remove (or null)
14
+ *
15
+ * @internal
16
+ */
17
+ function cleanupMapResources(map, tooltip) {
18
+ tooltip?.remove();
19
+ map?.remove();
20
+ }
21
+ /**
22
+ * Initialize map instance
23
+ *
24
+ * @remarks
25
+ * This hook handles map creation, loading state, and cleanup.
26
+ * It creates the MapLibre map instance when the container is ready
27
+ * and cleans it up on unmount.
28
+ *
29
+ * The map instance is returned along with loading/error states.
30
+ *
31
+ * Key behaviors:
32
+ * - Accepts pre-calculated viewport to prevent initial world view
33
+ * - Captures initial center/zoom on first render (prevents re-centering on config changes)
34
+ * - Creates map instance asynchronously
35
+ * - Handles race conditions with isMounted flag
36
+ * - Cleans up resources on unmount or style change
37
+ * - Supports cooperative gestures with localized messages
38
+ *
39
+ * @param containerRef - Ref to the map container element
40
+ * @param intl - react-intl instance for translations
41
+ * @param config - Geo configuration (optional)
42
+ * @param initialViewport - Pre-calculated viewport from data (optional)
43
+ * @returns Map instance, tooltip, ready state, and error
44
+ *
45
+ * @internal
46
+ */
47
+ export function useMapInitialization(containerRef, intl, config, initialViewport) {
48
+ const [map, setMap] = useState(null);
49
+ const [tooltip, setTooltip] = useState(null);
50
+ const [isMapReady, setIsMapReady] = useState(false);
51
+ const [error, setError] = useState(null);
52
+ // Refs for instance tracking and cleanup
53
+ const mapInstanceRef = useRef(null);
54
+ const tooltipInstanceRef = useRef(null);
55
+ // Capture initial viewport config (prevents re-centering when config changes)
56
+ // Prioritize initialViewport from data, then fall back to config
57
+ const initialCenterRef = useRef(initialViewport?.center ?? config?.center);
58
+ const initialZoomRef = useRef(initialViewport?.zoom ?? config?.zoom);
59
+ const initialBoundsRef = useRef(initialViewport?.bounds);
60
+ // Update initial refs if map hasn't been created yet
61
+ useEffect(() => {
62
+ if (!mapInstanceRef.current) {
63
+ initialCenterRef.current = initialViewport?.center ?? config?.center;
64
+ initialZoomRef.current = initialViewport?.zoom ?? config?.zoom;
65
+ initialBoundsRef.current = initialViewport?.bounds;
66
+ }
67
+ }, [config?.center, config?.zoom, initialViewport]);
68
+ // Generate locale for cooperative gestures
69
+ const cooperativeGestures = config?.cooperativeGestures ?? true;
70
+ const locale = useMemo(() => {
71
+ return cooperativeGestures ? generateMapLibreLocale(intl) : undefined;
72
+ }, [cooperativeGestures, intl]);
73
+ // Create and manage map instance
74
+ useEffect(() => {
75
+ const container = containerRef.current;
76
+ if (!container) {
77
+ return;
78
+ }
79
+ let isMounted = true;
80
+ // Initialize map with captured initial viewport
81
+ // Use bounds if available (calculated from data), otherwise use center/zoom
82
+ initializeMapLibreMap({
83
+ container,
84
+ bounds: initialBoundsRef.current,
85
+ center: initialCenterRef.current,
86
+ zoom: initialZoomRef.current,
87
+ cooperativeGestures,
88
+ style: config?.mapStyle,
89
+ }, locale)
90
+ .then((result) => {
91
+ if (isMounted) {
92
+ // Store in refs and state
93
+ mapInstanceRef.current = result.map;
94
+ tooltipInstanceRef.current = result.tooltip;
95
+ setMap(result.map);
96
+ setTooltip(result.tooltip);
97
+ setIsMapReady(true);
98
+ }
99
+ else {
100
+ // Component unmounted during initialization - clean up
101
+ cleanupMapResources(result.map, result.tooltip);
102
+ }
103
+ })
104
+ .catch((err) => {
105
+ if (isMounted) {
106
+ console.error("[useMapInitialization] Failed to initialize map:", err);
107
+ setError(err);
108
+ }
109
+ });
110
+ return () => {
111
+ isMounted = false;
112
+ setIsMapReady(false);
113
+ // Clean up resources
114
+ cleanupMapResources(mapInstanceRef.current, tooltipInstanceRef.current);
115
+ mapInstanceRef.current = null;
116
+ tooltipInstanceRef.current = null;
117
+ };
118
+ }, [containerRef, config?.mapStyle, cooperativeGestures, locale]);
119
+ return { map, tooltip, isMapReady, error };
120
+ }
121
+ //# sourceMappingURL=useMapInitialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMapInitialization.js","sourceRoot":"","sources":["../../../../src/next/hooks/map/useMapInitialization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import type { Map as MapLibreMap, Popup } from "maplibre-gl";
2
+ import { IntlShape } from "react-intl";
3
+ import { IHeaderPredicate } from "@gooddata/sdk-ui";
4
+ import { IMapConfig } from "../../types/mapProvider.js";
5
+ /**
6
+ * Set up tooltip handlers for map interactions
7
+ *
8
+ * @remarks
9
+ * This hook manages tooltip event listeners for the map. It sets up
10
+ * mousemove handlers to show/hide tooltips when hovering over pushpins,
11
+ * and properly cleans them up when dependencies change or on unmount.
12
+ *
13
+ * @param map - MapLibre map instance (null if not initialized)
14
+ * @param tooltip - Popup instance for displaying tooltips (null if not initialized)
15
+ * @param config - Map configuration
16
+ * @param drillablePredicates - Array of drillable item predicates
17
+ * @param intl - Internationalization configuration
18
+ *
19
+ * @internal
20
+ */
21
+ export declare function useTooltipHandlers(map: MapLibreMap | null, tooltip: Popup | null, config: IMapConfig | undefined, drillablePredicates: IHeaderPredicate[], intl: IntlShape): void;
22
+ //# sourceMappingURL=useTooltipHandlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTooltipHandlers.d.ts","sourceRoot":"","sources":["../../../../src/next/hooks/map/useTooltipHandlers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,GAAG,IAAI,WAAW,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAGpD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAExD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAC9B,GAAG,EAAE,WAAW,GAAG,IAAI,EACvB,OAAO,EAAE,KAAK,GAAG,IAAI,EACrB,MAAM,EAAE,UAAU,GAAG,SAAS,EAC9B,mBAAmB,EAAE,gBAAgB,EAAE,EACvC,IAAI,EAAE,SAAS,GAChB,IAAI,CAQN"}
@@ -0,0 +1,28 @@
1
+ // (C) 2025 GoodData Corporation
2
+ import { useEffect } from "react";
3
+ import { setupTooltipHandlers } from "../../features/tooltip/tooltipManagement.js";
4
+ /**
5
+ * Set up tooltip handlers for map interactions
6
+ *
7
+ * @remarks
8
+ * This hook manages tooltip event listeners for the map. It sets up
9
+ * mousemove handlers to show/hide tooltips when hovering over pushpins,
10
+ * and properly cleans them up when dependencies change or on unmount.
11
+ *
12
+ * @param map - MapLibre map instance (null if not initialized)
13
+ * @param tooltip - Popup instance for displaying tooltips (null if not initialized)
14
+ * @param config - Map configuration
15
+ * @param drillablePredicates - Array of drillable item predicates
16
+ * @param intl - Internationalization configuration
17
+ *
18
+ * @internal
19
+ */
20
+ export function useTooltipHandlers(map, tooltip, config, drillablePredicates, intl) {
21
+ useEffect(() => {
22
+ if (!map || !tooltip || !config) {
23
+ return undefined;
24
+ }
25
+ return setupTooltipHandlers(map, tooltip, config, drillablePredicates, intl);
26
+ }, [map, tooltip, config, drillablePredicates, intl]);
27
+ }
28
+ //# sourceMappingURL=useTooltipHandlers.js.map