@dynatrace/strato-geo 2.12.2 → 2.14.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/map/components/MapContent.js +23 -6
- package/esm/map/components/MapContent.js.map +2 -2
- package/esm/map/hooks/use-webgl-context-error.js +22 -0
- package/esm/map/hooks/use-webgl-context-error.js.map +7 -0
- package/esm/map/slots/Toolbar.js +7 -1
- package/esm/map/slots/Toolbar.js.map +2 -2
- package/esm/map/utils/iterate-config-slots.js +5 -2
- package/esm/map/utils/iterate-config-slots.js.map +2 -2
- package/map/components/MapContent.js +23 -6
- package/map/hooks/use-webgl-context-error.d.ts +5 -0
- package/map/hooks/use-webgl-context-error.js +41 -0
- package/map/slots/Toolbar.d.ts +1 -0
- package/map/slots/Toolbar.js +7 -1
- package/map/types/map-view.d.ts +7 -0
- package/map/utils/iterate-config-slots.js +4 -1
- package/package.json +5 -5
|
@@ -37,6 +37,7 @@ import { useMapLoading } from "../hooks/use-map-loading.js";
|
|
|
37
37
|
import { useMapPerformance } from "../hooks/use-map-performance.js";
|
|
38
38
|
import { useOverlayEvents } from "../hooks/use-overlay-events.js";
|
|
39
39
|
import { useTooltipEventListeners } from "../hooks/use-tooltip-event-listeners.js";
|
|
40
|
+
import { useWebGLContextError } from "../hooks/use-webgl-context-error.js";
|
|
40
41
|
import { defaultStyle } from "../map-styles/default-style.js";
|
|
41
42
|
import { MapViewImperativeHandler } from "../providers/imperative-handler.provider.js";
|
|
42
43
|
import { getColorFromToken } from "../utils/get-color-from-token.js";
|
|
@@ -87,9 +88,24 @@ const MapSource = () => {
|
|
|
87
88
|
)
|
|
88
89
|
] });
|
|
89
90
|
};
|
|
90
|
-
const MapInteractions = ({
|
|
91
|
+
const MapInteractions = ({
|
|
92
|
+
children,
|
|
93
|
+
onContextLostError
|
|
94
|
+
}) => {
|
|
95
|
+
const [contextLostError, setContextLostError] = useState(null);
|
|
91
96
|
useHoverInteraction();
|
|
92
97
|
useActiveInteraction();
|
|
98
|
+
useWebGLContextError(() => {
|
|
99
|
+
onContextLostError?.();
|
|
100
|
+
setContextLostError(
|
|
101
|
+
new Error(
|
|
102
|
+
"Too many active maps. This is a browser limitation. Try reducing the number of map instances."
|
|
103
|
+
)
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
if (contextLostError) {
|
|
107
|
+
throw contextLostError;
|
|
108
|
+
}
|
|
93
109
|
return children;
|
|
94
110
|
};
|
|
95
111
|
const MapContent = forwardRef((props, forwardedRef) => {
|
|
@@ -100,6 +116,7 @@ const MapContent = forwardRef((props, forwardedRef) => {
|
|
|
100
116
|
mapStyle = defaultStyle,
|
|
101
117
|
onViewStateChange,
|
|
102
118
|
onMapLoad,
|
|
119
|
+
onContextLostError,
|
|
103
120
|
...remaining
|
|
104
121
|
} = props;
|
|
105
122
|
const loading = useMapLoading();
|
|
@@ -162,15 +179,15 @@ const MapContent = forwardRef((props, forwardedRef) => {
|
|
|
162
179
|
children: /* @__PURE__ */ jsx(
|
|
163
180
|
Map,
|
|
164
181
|
{
|
|
165
|
-
onMove: (evt) => {
|
|
166
|
-
onViewStateChange?.(evt.viewState);
|
|
167
|
-
},
|
|
168
|
-
initialViewState: calculatedInitialViewState,
|
|
169
182
|
style: {
|
|
170
183
|
width: graphWidth,
|
|
171
184
|
height: `${graphHeight}px`,
|
|
172
185
|
...style
|
|
173
186
|
},
|
|
187
|
+
onMove: (evt) => {
|
|
188
|
+
onViewStateChange?.(evt.viewState);
|
|
189
|
+
},
|
|
190
|
+
initialViewState: calculatedInitialViewState,
|
|
174
191
|
mapStyle,
|
|
175
192
|
dragRotate: false,
|
|
176
193
|
fadeDuration: 0,
|
|
@@ -209,7 +226,7 @@ const MapContent = forwardRef((props, forwardedRef) => {
|
|
|
209
226
|
children: [
|
|
210
227
|
/* @__PURE__ */ jsx(MapSource, {}),
|
|
211
228
|
loading ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
212
|
-
/* @__PURE__ */ jsx(MapInteractions, { children }),
|
|
229
|
+
/* @__PURE__ */ jsx(MapInteractions, { onContextLostError, children }),
|
|
213
230
|
shouldRenderToolbar ? /* @__PURE__ */ jsx(MapToolbar, {}) : null
|
|
214
231
|
] })
|
|
215
232
|
]
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/map/components/MapContent.tsx"],
|
|
4
|
-
"sourcesContent": ["import {\n Layer,\n type LayerProps,\n Map,\n Source,\n type ViewStateChangeEvent,\n} from '@vis.gl/react-maplibre';\nimport { isUndefined } from 'lodash-es';\nimport type { MapLayerMouseEvent } from 'maplibre-gl';\nimport {\n forwardRef,\n type PropsWithChildren,\n useContext,\n useRef,\n useState,\n} from 'react';\n\nimport { _useGraphSize as useGraphSize } from '@dynatrace/strato-components-preview/charts';\nimport { useMergeRefs } from '@dynatrace/strato-components-preview/core';\n\nimport {\n BASE_LAYER_FILL_ID,\n BASE_LAYER_LINE_ID,\n COUNTRY_BORDER_WIDTH,\n DEFAULT_BOUNDARIES_BORDER_COLOR,\n DEFAULT_COUNTRIES_FILL_COLOR,\n MAX_LATITUDE,\n MAX_LONGITUDE,\n MIN_LATITUDE,\n MIN_LONGITUDE,\n REGION_BORDER_WIDTH,\n} from '../constants.js';\nimport { useMapZoomState, useSetStateZoom } from '../store/store.js';\nimport { MapToolbar } from './toolbar/MapToolbar.js';\nimport { LayerIdsContext } from '../contexts/layer-ids.context.js';\nimport { MapDataBoundingBoxContext } from '../contexts/map-data-bounding-box.context.js';\nimport { useActiveInteraction } from '../hooks/use-active-interaction.js';\nimport { useHoverInteraction } from '../hooks/use-hover-interaction.js';\nimport { useMapBaseLayerFeatures } from '../hooks/use-map-base-layer-features.js';\nimport { useMapConfig } from '../hooks/use-map-config.js';\nimport { useMapLoading } from '../hooks/use-map-loading.js';\nimport { useMapPerformance } from '../hooks/use-map-performance.js';\nimport { useOverlayEvents } from '../hooks/use-overlay-events.js';\nimport { useTooltipEventListeners } from '../hooks/use-tooltip-event-listeners.js';\nimport { defaultStyle } from '../map-styles/default-style.js';\nimport { MapViewImperativeHandler } from '../providers/imperative-handler.provider.js';\nimport type {\n MapViewProps,\n MapViewRef,\n ViewStateRequired,\n} from '../types/map-view.js';\nimport { getColorFromToken } from '../utils/get-color-from-token.js';\nimport { getDataLayersBoundingBox } from '../utils/get-data-layers-bounding-box.js';\nimport { toMapBoxInitialViewState } from '../utils/to-mapbox-initial-view-state.js';\nimport { useSetMapInitialConfiguration } from '../utils/use-set-map-initial-configuration.js';\nimport { generateNewZoomState } from './toolbar/utils/zoom-state-utils.js';\n\nconst lineLayer: LayerProps = {\n id: BASE_LAYER_LINE_ID,\n type: 'line',\n};\n\nconst fillLayer: LayerProps = {\n id: BASE_LAYER_FILL_ID,\n type: 'fill',\n};\n\nconst MapSource = () => {\n const baseLayerFeatures = useMapBaseLayerFeatures();\n return (\n baseLayerFeatures && (\n <Source id=\"data\" type=\"geojson\" data={baseLayerFeatures}>\n <Layer\n {...fillLayer}\n paint={{\n 'fill-color': getColorFromToken(DEFAULT_COUNTRIES_FILL_COLOR),\n }}\n />\n <Layer\n {...lineLayer}\n type=\"line\"\n filter={[\n 'any',\n ['==', 'region_type', 'COUNTRY'],\n ['==', 'region_type', 'REGION'],\n ]}\n paint={{\n 'line-color': getColorFromToken(DEFAULT_BOUNDARIES_BORDER_COLOR),\n 'line-width': [\n 'case',\n ['==', ['get', 'region_type'], 'REGION'],\n REGION_BORDER_WIDTH,\n COUNTRY_BORDER_WIDTH,\n ],\n }}\n />\n </Source>\n )\n );\n};\n\nconst MapInteractions = ({
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import {\n Layer,\n type LayerProps,\n Map,\n Source,\n type ViewStateChangeEvent,\n} from '@vis.gl/react-maplibre';\nimport { isUndefined } from 'lodash-es';\nimport type { MapLayerMouseEvent } from 'maplibre-gl';\nimport {\n forwardRef,\n type PropsWithChildren,\n useContext,\n useRef,\n useState,\n} from 'react';\n\nimport { _useGraphSize as useGraphSize } from '@dynatrace/strato-components-preview/charts';\nimport { useMergeRefs } from '@dynatrace/strato-components-preview/core';\n\nimport {\n BASE_LAYER_FILL_ID,\n BASE_LAYER_LINE_ID,\n COUNTRY_BORDER_WIDTH,\n DEFAULT_BOUNDARIES_BORDER_COLOR,\n DEFAULT_COUNTRIES_FILL_COLOR,\n MAX_LATITUDE,\n MAX_LONGITUDE,\n MIN_LATITUDE,\n MIN_LONGITUDE,\n REGION_BORDER_WIDTH,\n} from '../constants.js';\nimport { useMapZoomState, useSetStateZoom } from '../store/store.js';\nimport { MapToolbar } from './toolbar/MapToolbar.js';\nimport { LayerIdsContext } from '../contexts/layer-ids.context.js';\nimport { MapDataBoundingBoxContext } from '../contexts/map-data-bounding-box.context.js';\nimport { useActiveInteraction } from '../hooks/use-active-interaction.js';\nimport { useHoverInteraction } from '../hooks/use-hover-interaction.js';\nimport { useMapBaseLayerFeatures } from '../hooks/use-map-base-layer-features.js';\nimport { useMapConfig } from '../hooks/use-map-config.js';\nimport { useMapLoading } from '../hooks/use-map-loading.js';\nimport { useMapPerformance } from '../hooks/use-map-performance.js';\nimport { useOverlayEvents } from '../hooks/use-overlay-events.js';\nimport { useTooltipEventListeners } from '../hooks/use-tooltip-event-listeners.js';\nimport { useWebGLContextError } from '../hooks/use-webgl-context-error.js';\nimport { defaultStyle } from '../map-styles/default-style.js';\nimport { MapViewImperativeHandler } from '../providers/imperative-handler.provider.js';\nimport type {\n MapViewProps,\n MapViewRef,\n ViewStateRequired,\n} from '../types/map-view.js';\nimport { getColorFromToken } from '../utils/get-color-from-token.js';\nimport { getDataLayersBoundingBox } from '../utils/get-data-layers-bounding-box.js';\nimport { toMapBoxInitialViewState } from '../utils/to-mapbox-initial-view-state.js';\nimport { useSetMapInitialConfiguration } from '../utils/use-set-map-initial-configuration.js';\nimport { generateNewZoomState } from './toolbar/utils/zoom-state-utils.js';\n\nconst lineLayer: LayerProps = {\n id: BASE_LAYER_LINE_ID,\n type: 'line',\n};\n\nconst fillLayer: LayerProps = {\n id: BASE_LAYER_FILL_ID,\n type: 'fill',\n};\n\nconst MapSource = () => {\n const baseLayerFeatures = useMapBaseLayerFeatures();\n return (\n baseLayerFeatures && (\n <Source id=\"data\" type=\"geojson\" data={baseLayerFeatures}>\n <Layer\n {...fillLayer}\n paint={{\n 'fill-color': getColorFromToken(DEFAULT_COUNTRIES_FILL_COLOR),\n }}\n />\n <Layer\n {...lineLayer}\n type=\"line\"\n filter={[\n 'any',\n ['==', 'region_type', 'COUNTRY'],\n ['==', 'region_type', 'REGION'],\n ]}\n paint={{\n 'line-color': getColorFromToken(DEFAULT_BOUNDARIES_BORDER_COLOR),\n 'line-width': [\n 'case',\n ['==', ['get', 'region_type'], 'REGION'],\n REGION_BORDER_WIDTH,\n COUNTRY_BORDER_WIDTH,\n ],\n }}\n />\n </Source>\n )\n );\n};\n\nconst MapInteractions = ({\n children,\n onContextLostError,\n}: PropsWithChildren<{\n onContextLostError?: () => void;\n}>) => {\n const [contextLostError, setContextLostError] = useState<Error | null>(null);\n\n useHoverInteraction();\n useActiveInteraction();\n useWebGLContextError(() => {\n onContextLostError?.();\n setContextLostError(\n new Error(\n 'Too many active maps. This is a browser limitation. Try reducing the number of map instances.',\n ),\n );\n });\n\n if (contextLostError) {\n throw contextLostError;\n }\n\n return children;\n};\ntype MapContentProps = MapViewProps & {\n onMapLoad: () => void;\n};\n\nexport const MapContent = forwardRef<\n MapViewRef,\n PropsWithChildren<MapContentProps>\n>((props, forwardedRef) => {\n const {\n initialViewState: initialViewStateProp,\n children,\n style,\n mapStyle = defaultStyle,\n onViewStateChange,\n onMapLoad,\n onContextLostError,\n ...remaining\n } = props;\n\n const loading = useMapLoading();\n const setZoomState = useSetStateZoom();\n const [savedInitialViewState, setSavedInitialViewState] = useState<\n ViewStateRequired | undefined\n >();\n\n const mapContainerRef = useRef<HTMLDivElement>(null);\n\n const mergedRefs = useMergeRefs<MapViewRef | HTMLDivElement>([\n mapContainerRef,\n forwardedRef,\n ]);\n\n const baseFeatureCollection = useMapBaseLayerFeatures();\n\n const dataLayersBBox = getDataLayersBoundingBox(\n children,\n baseFeatureCollection?.features,\n );\n\n useTooltipEventListeners();\n\n const { toolbar: toolbarConfig, interactions: interactionsConfig } =\n useMapConfig();\n const layerIds = useContext(LayerIdsContext);\n\n const shouldRenderToolbar =\n (!isUndefined(toolbarConfig) && !toolbarConfig.hidden) ||\n !isUndefined(interactionsConfig);\n\n const { height: graphHeight, width: graphWidth } = useGraphSize();\n\n const {\n handleMouseEnter,\n handleMouseMove,\n handleMouseLeave,\n handleMouseClick,\n handleZoom,\n handleDrag,\n } = useOverlayEvents();\n\n const initialViewState = initialViewStateProp ?? dataLayersBBox;\n\n const { onLoadHandler, onRenderHandler } = useMapPerformance(mapContainerRef);\n const calculatedInitialViewState = toMapBoxInitialViewState(initialViewState);\n\n const { zoomToFitInProgress } = useMapZoomState();\n\n const handleZoomEnd = (event: ViewStateChangeEvent) => {\n if (savedInitialViewState) {\n const zoomState = generateNewZoomState(\n event,\n savedInitialViewState,\n zoomToFitInProgress,\n );\n\n setZoomState(zoomState);\n }\n };\n\n const handleDragEnd = (event: ViewStateChangeEvent) => {\n if (savedInitialViewState) {\n const zoomState = generateNewZoomState(\n event,\n savedInitialViewState,\n zoomToFitInProgress,\n );\n\n setZoomState(zoomState);\n }\n };\n\n return (\n <div\n data-testid=\"map-container\"\n ref={mergedRefs}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n >\n <Map\n style={{\n width: graphWidth,\n height: `${graphHeight}px`,\n ...style,\n }}\n onMove={(evt) => {\n onViewStateChange?.(evt.viewState);\n }}\n initialViewState={calculatedInitialViewState}\n mapStyle={mapStyle}\n dragRotate={false}\n fadeDuration={0}\n renderWorldCopies={false}\n interactiveLayerIds={layerIds}\n maxBounds={[\n [MIN_LONGITUDE, MIN_LATITUDE],\n [MAX_LONGITUDE, MAX_LATITUDE],\n ]}\n onMouseMove={(e) => handleMouseMove(e as MapLayerMouseEvent)}\n onClick={(e) => handleMouseClick(e as MapLayerMouseEvent)}\n onZoom={handleZoom}\n onZoomEnd={handleZoomEnd}\n onDrag={handleDrag}\n onDragEnd={handleDragEnd}\n attributionControl={false}\n onRender={() => onRenderHandler && onRenderHandler()}\n onLoad={(e) => {\n onMapLoad();\n onLoadHandler && onLoadHandler();\n\n const initialCenter = e.target.getCenter();\n\n setSavedInitialViewState({\n latitude: initialCenter.lat,\n longitude: initialCenter.lng,\n zoom: e.target.getZoom(),\n });\n }}\n ref={useSetMapInitialConfiguration()}\n interactive\n {...remaining}\n >\n <MapDataBoundingBoxContext.Provider value={dataLayersBBox}>\n <MapViewImperativeHandler\n forwardedRef={forwardedRef}\n containerRef={mapContainerRef}\n >\n <MapSource />\n {loading ? null : (\n <>\n <MapInteractions onContextLostError={onContextLostError}>\n {children}\n </MapInteractions>\n {shouldRenderToolbar ? <MapToolbar /> : null}\n </>\n )}\n </MapViewImperativeHandler>\n </MapDataBoundingBoxContext.Provider>\n </Map>\n </div>\n );\n});\n\n(MapContent as typeof MapContent & { displayName: string }).displayName =\n 'MapContent';\n"],
|
|
5
|
+
"mappings": "AAwEM,SA2MQ,UA1MN,KADF;AAxEN;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,OAEK;AACP,SAAS,mBAAmB;AAE5B;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,iBAAiB,oBAAoB;AAC9C,SAAS,oBAAoB;AAE7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,iBAAiB,uBAAuB;AACjD,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAChC,SAAS,iCAAiC;AAC1C,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AACpC,SAAS,+BAA+B;AACxC,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,gCAAgC;AACzC,SAAS,4BAA4B;AACrC,SAAS,oBAAoB;AAC7B,SAAS,gCAAgC;AAMzC,SAAS,yBAAyB;AAClC,SAAS,gCAAgC;AACzC,SAAS,gCAAgC;AACzC,SAAS,qCAAqC;AAC9C,SAAS,4BAA4B;AAErC,MAAM,YAAwB;AAAA,EAC5B,IAAI;AAAA,EACJ,MAAM;AACR;AAEA,MAAM,YAAwB;AAAA,EAC5B,IAAI;AAAA,EACJ,MAAM;AACR;AAEA,MAAM,YAAY,MAAM;AACtB,QAAM,oBAAoB,wBAAwB;AAClD,SACE,qBACE,qBAAC,UAAO,IAAG,QAAO,MAAK,WAAU,MAAM,mBACrC;AAAA;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,OAAO;AAAA,UACL,cAAc,kBAAkB,4BAA4B;AAAA,QAC9D;AAAA;AAAA,IACF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,MAAK;AAAA,QACL,QAAQ;AAAA,UACN;AAAA,UACA,CAAC,MAAM,eAAe,SAAS;AAAA,UAC/B,CAAC,MAAM,eAAe,QAAQ;AAAA,QAChC;AAAA,QACA,OAAO;AAAA,UACL,cAAc,kBAAkB,+BAA+B;AAAA,UAC/D,cAAc;AAAA,YACZ;AAAA,YACA,CAAC,MAAM,CAAC,OAAO,aAAa,GAAG,QAAQ;AAAA,YACvC;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA;AAAA,IACF;AAAA,KACF;AAGN;AAEA,MAAM,kBAAkB,CAAC;AAAA,EACvB;AAAA,EACA;AACF,MAEO;AACL,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAuB,IAAI;AAE3E,sBAAoB;AACpB,uBAAqB;AACrB,uBAAqB,MAAM;AACzB,yBAAqB;AACrB;AAAA,MACE,IAAI;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AAED,MAAI,kBAAkB;AACpB,UAAM;AAAA,EACR;AAEA,SAAO;AACT;AAKO,MAAM,aAAa,WAGxB,CAAC,OAAO,iBAAiB;AACzB,QAAM;AAAA,IACJ,kBAAkB;AAAA,IAClB;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,UAAU,cAAc;AAC9B,QAAM,eAAe,gBAAgB;AACrC,QAAM,CAAC,uBAAuB,wBAAwB,IAAI,SAExD;AAEF,QAAM,kBAAkB,OAAuB,IAAI;AAEnD,QAAM,aAAa,aAA0C;AAAA,IAC3D;AAAA,IACA;AAAA,EACF,CAAC;AAED,QAAM,wBAAwB,wBAAwB;AAEtD,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA,uBAAuB;AAAA,EACzB;AAEA,2BAAyB;AAEzB,QAAM,EAAE,SAAS,eAAe,cAAc,mBAAmB,IAC/D,aAAa;AACf,QAAM,WAAW,WAAW,eAAe;AAE3C,QAAM,sBACH,CAAC,YAAY,aAAa,KAAK,CAAC,cAAc,UAC/C,CAAC,YAAY,kBAAkB;AAEjC,QAAM,EAAE,QAAQ,aAAa,OAAO,WAAW,IAAI,aAAa;AAEhE,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,iBAAiB;AAErB,QAAM,mBAAmB,wBAAwB;AAEjD,QAAM,EAAE,eAAe,gBAAgB,IAAI,kBAAkB,eAAe;AAC5E,QAAM,6BAA6B,yBAAyB,gBAAgB;AAE5E,QAAM,EAAE,oBAAoB,IAAI,gBAAgB;AAEhD,QAAM,gBAAgB,CAAC,UAAgC;AACrD,QAAI,uBAAuB;AACzB,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,mBAAa,SAAS;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,gBAAgB,CAAC,UAAgC;AACrD,QAAI,uBAAuB;AACzB,YAAM,YAAY;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,mBAAa,SAAS;AAAA,IACxB;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAY;AAAA,MACZ,KAAK;AAAA,MACL,cAAc;AAAA,MACd,cAAc;AAAA,MAEd;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ,GAAG,WAAW;AAAA,YACtB,GAAG;AAAA,UACL;AAAA,UACA,QAAQ,CAAC,QAAQ;AACf,gCAAoB,IAAI,SAAS;AAAA,UACnC;AAAA,UACA,kBAAkB;AAAA,UAClB;AAAA,UACA,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,mBAAmB;AAAA,UACnB,qBAAqB;AAAA,UACrB,WAAW;AAAA,YACT,CAAC,eAAe,YAAY;AAAA,YAC5B,CAAC,eAAe,YAAY;AAAA,UAC9B;AAAA,UACA,aAAa,CAAC,MAAM,gBAAgB,CAAuB;AAAA,UAC3D,SAAS,CAAC,MAAM,iBAAiB,CAAuB;AAAA,UACxD,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,WAAW;AAAA,UACX,oBAAoB;AAAA,UACpB,UAAU,MAAM,mBAAmB,gBAAgB;AAAA,UACnD,QAAQ,CAAC,MAAM;AACb,sBAAU;AACV,6BAAiB,cAAc;AAE/B,kBAAM,gBAAgB,EAAE,OAAO,UAAU;AAEzC,qCAAyB;AAAA,cACvB,UAAU,cAAc;AAAA,cACxB,WAAW,cAAc;AAAA,cACzB,MAAM,EAAE,OAAO,QAAQ;AAAA,YACzB,CAAC;AAAA,UACH;AAAA,UACA,KAAK,8BAA8B;AAAA,UACnC,aAAW;AAAA,UACV,GAAG;AAAA,UAEJ,8BAAC,0BAA0B,UAA1B,EAAmC,OAAO,gBACzC;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,cAAc;AAAA,cAEd;AAAA,oCAAC,aAAU;AAAA,gBACV,UAAU,OACT,iCACE;AAAA,sCAAC,mBAAgB,oBACd,UACH;AAAA,kBACC,sBAAsB,oBAAC,cAAW,IAAK;AAAA,mBAC1C;AAAA;AAAA;AAAA,UAEJ,GACF;AAAA;AAAA,MACF;AAAA;AAAA,EACF;AAEJ,CAAC;AAEA,WAA2D,cAC1D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useMap } from "@vis.gl/react-maplibre";
|
|
2
|
+
import { useEffect } from "react";
|
|
3
|
+
const useWebGLContextError = (onContextLost) => {
|
|
4
|
+
const { current: mapRef } = useMap();
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const canvas = mapRef?.getMap()?.getCanvas();
|
|
7
|
+
if (!canvas) {
|
|
8
|
+
return;
|
|
9
|
+
}
|
|
10
|
+
const handleContextLost = () => {
|
|
11
|
+
onContextLost?.();
|
|
12
|
+
};
|
|
13
|
+
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
14
|
+
return () => {
|
|
15
|
+
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
16
|
+
};
|
|
17
|
+
}, [mapRef, onContextLost]);
|
|
18
|
+
};
|
|
19
|
+
export {
|
|
20
|
+
useWebGLContextError
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=use-webgl-context-error.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/map/hooks/use-webgl-context-error.ts"],
|
|
4
|
+
"sourcesContent": ["import { useMap } from '@vis.gl/react-maplibre';\nimport { useEffect } from 'react';\n\n/**\n * Hook to detect WebGL context loss events.\n * Browsers have a limit of active WebGL canvas contexts.\n */\nexport const useWebGLContextError = (onContextLost?: () => void) => {\n const { current: mapRef } = useMap();\n\n useEffect(() => {\n const canvas = mapRef?.getMap()?.getCanvas();\n if (!canvas) {\n return;\n }\n\n const handleContextLost = () => {\n onContextLost?.();\n };\n\n canvas.addEventListener('webglcontextlost', handleContextLost);\n\n return () => {\n canvas.removeEventListener('webglcontextlost', handleContextLost);\n };\n }, [mapRef, onContextLost]);\n};\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAMnB,MAAM,uBAAuB,CAAC,kBAA+B;AAClE,QAAM,EAAE,SAAS,OAAO,IAAI,OAAO;AAEnC,YAAU,MAAM;AACd,UAAM,SAAS,QAAQ,OAAO,GAAG,UAAU;AAC3C,QAAI,CAAC,QAAQ;AACX;AAAA,IACF;AAEA,UAAM,oBAAoB,MAAM;AAC9B,sBAAgB;AAAA,IAClB;AAEA,WAAO,iBAAiB,oBAAoB,iBAAiB;AAE7D,WAAO,MAAM;AACX,aAAO,oBAAoB,oBAAoB,iBAAiB;AAAA,IAClE;AAAA,EACF,GAAG,CAAC,QAAQ,aAAa,CAAC;AAC5B;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/esm/map/slots/Toolbar.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { pick } from "lodash-es";
|
|
2
|
+
const allowedProps = ["placement", "hidden", "draggable"];
|
|
3
|
+
const sanitizeProps = (externalProps) => {
|
|
4
|
+
return pick(externalProps, allowedProps);
|
|
5
|
+
};
|
|
1
6
|
const Toolbar = (props) => null;
|
|
2
7
|
Toolbar.displayName = "MapToolbar";
|
|
3
8
|
export {
|
|
4
|
-
Toolbar
|
|
9
|
+
Toolbar,
|
|
10
|
+
sanitizeProps
|
|
5
11
|
};
|
|
6
12
|
//# sourceMappingURL=Toolbar.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/map/slots/Toolbar.tsx"],
|
|
4
|
-
"sourcesContent": ["import { MapToolbarSlotProps } from '../types/toolbar.js';\n\n/**\n * Slot for configuring the toolbar within a MapView.\n * @public\n */\nexport const Toolbar = (props: MapToolbarSlotProps) => null;\n\nToolbar.displayName = 'MapToolbar';\n"],
|
|
5
|
-
"mappings": "AAMO,MAAM,UAAU,CAAC,UAA+B;AAEvD,QAAQ,cAAc;",
|
|
4
|
+
"sourcesContent": ["import { pick } from 'lodash-es';\n\nimport { MapToolbarSlotProps } from '../types/toolbar.js';\n\ntype PropKey = keyof MapToolbarSlotProps;\nconst allowedProps: PropKey[] = ['placement', 'hidden', 'draggable'];\n\nexport const sanitizeProps = <P extends MapToolbarSlotProps>(\n externalProps: P,\n): MapToolbarSlotProps => {\n return pick(externalProps, allowedProps);\n};\n\n/**\n * Slot for configuring the toolbar within a MapView.\n * @public\n */\nexport const Toolbar = (props: MapToolbarSlotProps) => null;\n\nToolbar.displayName = 'MapToolbar';\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,YAAY;AAKrB,MAAM,eAA0B,CAAC,aAAa,UAAU,WAAW;AAE5D,MAAM,gBAAgB,CAC3B,kBACwB;AACxB,SAAO,KAAK,eAAe,YAAY;AACzC;AAMO,MAAM,UAAU,CAAC,UAA+B;AAEvD,QAAQ,cAAc;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -15,7 +15,7 @@ import { ChartInteractions } from "../slots/ChartInteractions.js";
|
|
|
15
15
|
import { DownloadCSV } from "../slots/DownloadCSV.js";
|
|
16
16
|
import { SequentialLegend } from "../slots/SequentialLegend.js";
|
|
17
17
|
import { ThresholdLegend } from "../slots/ThresholdLegend.js";
|
|
18
|
-
import { Toolbar } from "../slots/Toolbar.js";
|
|
18
|
+
import { sanitizeProps, Toolbar } from "../slots/Toolbar.js";
|
|
19
19
|
import { Zoom } from "../slots/Zoom.js";
|
|
20
20
|
const iterateConfigSlots = (children, legendDomain) => {
|
|
21
21
|
let slots = {
|
|
@@ -85,7 +85,10 @@ const iterateConfigSlots = (children, legendDomain) => {
|
|
|
85
85
|
}
|
|
86
86
|
};
|
|
87
87
|
} else if (isSlot(child, Toolbar)) {
|
|
88
|
-
slotMapToolbarConfig = {
|
|
88
|
+
slotMapToolbarConfig = {
|
|
89
|
+
...slotMapToolbarConfig,
|
|
90
|
+
...sanitizeProps(child.props)
|
|
91
|
+
};
|
|
89
92
|
} else if (isSlot(child, DownloadCSV)) {
|
|
90
93
|
slotMapToolbarConfig = {
|
|
91
94
|
...slotMapToolbarConfig,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/map/utils/iterate-config-slots.ts"],
|
|
4
|
-
"sourcesContent": ["import { isEmpty } from 'lodash-es';\nimport { Children, type ReactNode } from 'react';\n\nimport { ChartToolbar } from '@dynatrace/strato-components-preview/charts';\n\nimport {\n DEFAULT_BASE_LAYER_RULES,\n DEFAULT_MAP_LEGEND_RATIO,\n DEFAULT_MAP_POSITION,\n DEFAULT_SEQUENTIAL_LEGEND_COLOR_PALETTE,\n} from '../constants.js';\nimport { isSlot } from './is-slot.js';\nimport { replaceInfiniteValuesInRanges } from './replace-infinite-values-in-ranges.js';\nimport { BaseLayer } from '../slots/BaseLayer.js';\nimport { CategoricalLegend } from '../slots/CategoricalLegend.js';\nimport { ChartInteractions } from '../slots/ChartInteractions.js';\nimport { DownloadCSV } from '../slots/DownloadCSV.js';\nimport { SequentialLegend } from '../slots/SequentialLegend.js';\nimport { ThresholdLegend } from '../slots/ThresholdLegend.js';\nimport { Toolbar } from '../slots/Toolbar.js';\nimport { Zoom } from '../slots/Zoom.js';\nimport type { MapConfig } from '../types/configuration.js';\nimport type {\n ChartInteractionsConfig,\n MapToolbarConfig,\n} from '../types/toolbar.js';\n\n/**\n * Generate map config based on slots\n * @param children - Map children\n * @param legendDomain - Domain containing min and max value relevant for legend\n * @returns Map slot config\n */\nexport const iterateConfigSlots = (\n children: ReactNode,\n legendDomain: [number, number],\n) => {\n let slots: MapConfig = {\n toolbar: undefined,\n interactions: undefined,\n legend: undefined,\n baseLayer: DEFAULT_BASE_LAYER_RULES,\n };\n\n let slotMapToolbarConfig: MapToolbarConfig = {};\n\n Children.forEach(children, (child) => {\n if (isSlot(child, ChartInteractions)) {\n const { children, ...previousInteractions } = child.props;\n\n const interactions = iterateChartInteractionsSlots(children);\n\n slots = {\n ...slots,\n interactions: {\n ...previousInteractions,\n ...interactions,\n },\n };\n } else if (isSlot(child, ChartToolbar)) {\n const { children, ...toolbar } = child.props;\n const childrenToolbar = iterateChartToolbarSlots(children);\n\n slots = {\n ...slots,\n toolbar: {\n ...toolbar,\n ...childrenToolbar,\n },\n };\n } else if (isSlot(child, SequentialLegend)) {\n slots = {\n ...slots,\n legend: {\n type: 'sequential',\n colorPalette: DEFAULT_SEQUENTIAL_LEGEND_COLOR_PALETTE,\n position: DEFAULT_MAP_POSITION,\n ratio: DEFAULT_MAP_LEGEND_RATIO,\n ...child.props,\n min: child.props.min ?? legendDomain[0],\n max: child.props.max ?? legendDomain[1],\n },\n };\n } else if (isSlot(child, CategoricalLegend)) {\n slots = {\n ...slots,\n legend: {\n type: 'categorical',\n position: DEFAULT_MAP_POSITION,\n ...child.props,\n },\n };\n } else if (isSlot(child, ThresholdLegend)) {\n const getDomainValue = (index: number, legendDomainValue: number) =>\n Number.isFinite(legendDomainValue)\n ? legendDomainValue\n : child.props.ranges?.at(index)?.to ?? legendDomainValue;\n\n const ranges = replaceInfiniteValuesInRanges(child.props.ranges, [\n getDomainValue(0, legendDomain[0]),\n getDomainValue(-1, legendDomain[1]),\n ]);\n\n slots = {\n ...slots,\n legend: {\n type: 'threshold',\n position: DEFAULT_MAP_POSITION,\n ratio: DEFAULT_MAP_LEGEND_RATIO,\n ...child.props,\n ranges,\n },\n };\n } else if (isSlot(child, Toolbar)) {\n slotMapToolbarConfig = {
|
|
5
|
-
"mappings": "AAAA,SAAS,eAAe;AACxB,SAAS,gBAAgC;AAEzC,SAAS,oBAAoB;AAE7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB,SAAS,qCAAqC;AAC9C,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAC5B,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,eAAe;
|
|
4
|
+
"sourcesContent": ["import { isEmpty } from 'lodash-es';\nimport { Children, type ReactNode } from 'react';\n\nimport { ChartToolbar } from '@dynatrace/strato-components-preview/charts';\n\nimport {\n DEFAULT_BASE_LAYER_RULES,\n DEFAULT_MAP_LEGEND_RATIO,\n DEFAULT_MAP_POSITION,\n DEFAULT_SEQUENTIAL_LEGEND_COLOR_PALETTE,\n} from '../constants.js';\nimport { isSlot } from './is-slot.js';\nimport { replaceInfiniteValuesInRanges } from './replace-infinite-values-in-ranges.js';\nimport { BaseLayer } from '../slots/BaseLayer.js';\nimport { CategoricalLegend } from '../slots/CategoricalLegend.js';\nimport { ChartInteractions } from '../slots/ChartInteractions.js';\nimport { DownloadCSV } from '../slots/DownloadCSV.js';\nimport { SequentialLegend } from '../slots/SequentialLegend.js';\nimport { ThresholdLegend } from '../slots/ThresholdLegend.js';\nimport { sanitizeProps, Toolbar } from '../slots/Toolbar.js';\nimport { Zoom } from '../slots/Zoom.js';\nimport type { MapConfig } from '../types/configuration.js';\nimport type {\n ChartInteractionsConfig,\n MapToolbarConfig,\n} from '../types/toolbar.js';\n\n/**\n * Generate map config based on slots\n * @param children - Map children\n * @param legendDomain - Domain containing min and max value relevant for legend\n * @returns Map slot config\n */\nexport const iterateConfigSlots = (\n children: ReactNode,\n legendDomain: [number, number],\n) => {\n let slots: MapConfig = {\n toolbar: undefined,\n interactions: undefined,\n legend: undefined,\n baseLayer: DEFAULT_BASE_LAYER_RULES,\n };\n\n let slotMapToolbarConfig: MapToolbarConfig = {};\n\n Children.forEach(children, (child) => {\n if (isSlot(child, ChartInteractions)) {\n const { children, ...previousInteractions } = child.props;\n\n const interactions = iterateChartInteractionsSlots(children);\n\n slots = {\n ...slots,\n interactions: {\n ...previousInteractions,\n ...interactions,\n },\n };\n } else if (isSlot(child, ChartToolbar)) {\n const { children, ...toolbar } = child.props;\n const childrenToolbar = iterateChartToolbarSlots(children);\n\n slots = {\n ...slots,\n toolbar: {\n ...toolbar,\n ...childrenToolbar,\n },\n };\n } else if (isSlot(child, SequentialLegend)) {\n slots = {\n ...slots,\n legend: {\n type: 'sequential',\n colorPalette: DEFAULT_SEQUENTIAL_LEGEND_COLOR_PALETTE,\n position: DEFAULT_MAP_POSITION,\n ratio: DEFAULT_MAP_LEGEND_RATIO,\n ...child.props,\n min: child.props.min ?? legendDomain[0],\n max: child.props.max ?? legendDomain[1],\n },\n };\n } else if (isSlot(child, CategoricalLegend)) {\n slots = {\n ...slots,\n legend: {\n type: 'categorical',\n position: DEFAULT_MAP_POSITION,\n ...child.props,\n },\n };\n } else if (isSlot(child, ThresholdLegend)) {\n const getDomainValue = (index: number, legendDomainValue: number) =>\n Number.isFinite(legendDomainValue)\n ? legendDomainValue\n : child.props.ranges?.at(index)?.to ?? legendDomainValue;\n\n const ranges = replaceInfiniteValuesInRanges(child.props.ranges, [\n getDomainValue(0, legendDomain[0]),\n getDomainValue(-1, legendDomain[1]),\n ]);\n\n slots = {\n ...slots,\n legend: {\n type: 'threshold',\n position: DEFAULT_MAP_POSITION,\n ratio: DEFAULT_MAP_LEGEND_RATIO,\n ...child.props,\n ranges,\n },\n };\n } else if (isSlot(child, Toolbar)) {\n slotMapToolbarConfig = {\n ...slotMapToolbarConfig,\n ...sanitizeProps(child.props),\n };\n } else if (isSlot(child, DownloadCSV)) {\n slotMapToolbarConfig = {\n ...slotMapToolbarConfig,\n downloadCSV: { enabled: true },\n };\n } else if (isSlot(child, Zoom)) {\n slotMapToolbarConfig = {\n ...slotMapToolbarConfig,\n zoom: { enabled: true },\n };\n } else if (isSlot(child, BaseLayer)) {\n slots = {\n ...slots,\n baseLayer: {\n ...slots.baseLayer,\n ...child.props,\n },\n };\n }\n });\n if (!isEmpty(slotMapToolbarConfig)) {\n slots.toolbar = { ...slots.toolbar, ...slotMapToolbarConfig };\n }\n\n return slots;\n};\n\nconst iterateChartInteractionsSlots = (children: ReactNode) => {\n let interactions: ChartInteractionsConfig = {};\n\n Children.forEach(children, (childInteractions) => {\n if (isSlot(childInteractions, ChartInteractions.Zoom)) {\n interactions = { ...interactions, zoom: { enabled: true } };\n } else if (isSlot(childInteractions, ChartInteractions.ZoomToFit)) {\n interactions = { ...interactions, zoomToFit: { enabled: true } };\n }\n });\n\n return interactions;\n};\n\n/**\n * Generates chart config based on slots\n * @param children - CharInteraction children\n * @returns ChartInteraction slot config\n */\nconst iterateChartToolbarSlots = (children: ReactNode) => {\n let toolbar = {};\n\n Children.forEach(children, (childToolbar) => {\n if (isSlot(childToolbar, ChartToolbar.DownloadData)) {\n toolbar = {\n ...toolbar,\n downloadCSV: { enabled: true },\n };\n }\n });\n\n return toolbar;\n};\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["children"]
|
|
7
7
|
}
|
|
@@ -40,6 +40,7 @@ var import_use_map_loading = require("../hooks/use-map-loading.js");
|
|
|
40
40
|
var import_use_map_performance = require("../hooks/use-map-performance.js");
|
|
41
41
|
var import_use_overlay_events = require("../hooks/use-overlay-events.js");
|
|
42
42
|
var import_use_tooltip_event_listeners = require("../hooks/use-tooltip-event-listeners.js");
|
|
43
|
+
var import_use_webgl_context_error = require("../hooks/use-webgl-context-error.js");
|
|
43
44
|
var import_default_style = require("../map-styles/default-style.js");
|
|
44
45
|
var import_imperative_handler_provider = require("../providers/imperative-handler.provider.js");
|
|
45
46
|
var import_get_color_from_token = require("../utils/get-color-from-token.js");
|
|
@@ -90,9 +91,24 @@ const MapSource = () => {
|
|
|
90
91
|
)
|
|
91
92
|
] });
|
|
92
93
|
};
|
|
93
|
-
const MapInteractions = ({
|
|
94
|
+
const MapInteractions = ({
|
|
95
|
+
children,
|
|
96
|
+
onContextLostError
|
|
97
|
+
}) => {
|
|
98
|
+
const [contextLostError, setContextLostError] = (0, import_react.useState)(null);
|
|
94
99
|
(0, import_use_hover_interaction.useHoverInteraction)();
|
|
95
100
|
(0, import_use_active_interaction.useActiveInteraction)();
|
|
101
|
+
(0, import_use_webgl_context_error.useWebGLContextError)(() => {
|
|
102
|
+
onContextLostError?.();
|
|
103
|
+
setContextLostError(
|
|
104
|
+
new Error(
|
|
105
|
+
"Too many active maps. This is a browser limitation. Try reducing the number of map instances."
|
|
106
|
+
)
|
|
107
|
+
);
|
|
108
|
+
});
|
|
109
|
+
if (contextLostError) {
|
|
110
|
+
throw contextLostError;
|
|
111
|
+
}
|
|
96
112
|
return children;
|
|
97
113
|
};
|
|
98
114
|
const MapContent = (0, import_react.forwardRef)((props, forwardedRef) => {
|
|
@@ -103,6 +119,7 @@ const MapContent = (0, import_react.forwardRef)((props, forwardedRef) => {
|
|
|
103
119
|
mapStyle = import_default_style.defaultStyle,
|
|
104
120
|
onViewStateChange,
|
|
105
121
|
onMapLoad,
|
|
122
|
+
onContextLostError,
|
|
106
123
|
...remaining
|
|
107
124
|
} = props;
|
|
108
125
|
const loading = (0, import_use_map_loading.useMapLoading)();
|
|
@@ -165,15 +182,15 @@ const MapContent = (0, import_react.forwardRef)((props, forwardedRef) => {
|
|
|
165
182
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
166
183
|
import_react_maplibre.Map,
|
|
167
184
|
{
|
|
168
|
-
onMove: (evt) => {
|
|
169
|
-
onViewStateChange?.(evt.viewState);
|
|
170
|
-
},
|
|
171
|
-
initialViewState: calculatedInitialViewState,
|
|
172
185
|
style: {
|
|
173
186
|
width: graphWidth,
|
|
174
187
|
height: `${graphHeight}px`,
|
|
175
188
|
...style
|
|
176
189
|
},
|
|
190
|
+
onMove: (evt) => {
|
|
191
|
+
onViewStateChange?.(evt.viewState);
|
|
192
|
+
},
|
|
193
|
+
initialViewState: calculatedInitialViewState,
|
|
177
194
|
mapStyle,
|
|
178
195
|
dragRotate: false,
|
|
179
196
|
fadeDuration: 0,
|
|
@@ -212,7 +229,7 @@ const MapContent = (0, import_react.forwardRef)((props, forwardedRef) => {
|
|
|
212
229
|
children: [
|
|
213
230
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MapSource, {}),
|
|
214
231
|
loading ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
215
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MapInteractions, { children }),
|
|
232
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(MapInteractions, { onContextLostError, children }),
|
|
216
233
|
shouldRenderToolbar ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_MapToolbar.MapToolbar, {}) : null
|
|
217
234
|
] })
|
|
218
235
|
]
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var use_webgl_context_error_exports = {};
|
|
20
|
+
__export(use_webgl_context_error_exports, {
|
|
21
|
+
useWebGLContextError: () => useWebGLContextError
|
|
22
|
+
});
|
|
23
|
+
module.exports = __toCommonJS(use_webgl_context_error_exports);
|
|
24
|
+
var import_react_maplibre = require("@vis.gl/react-maplibre");
|
|
25
|
+
var import_react = require("react");
|
|
26
|
+
const useWebGLContextError = (onContextLost) => {
|
|
27
|
+
const { current: mapRef } = (0, import_react_maplibre.useMap)();
|
|
28
|
+
(0, import_react.useEffect)(() => {
|
|
29
|
+
const canvas = mapRef?.getMap()?.getCanvas();
|
|
30
|
+
if (!canvas) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const handleContextLost = () => {
|
|
34
|
+
onContextLost?.();
|
|
35
|
+
};
|
|
36
|
+
canvas.addEventListener("webglcontextlost", handleContextLost);
|
|
37
|
+
return () => {
|
|
38
|
+
canvas.removeEventListener("webglcontextlost", handleContextLost);
|
|
39
|
+
};
|
|
40
|
+
}, [mapRef, onContextLost]);
|
|
41
|
+
};
|
package/map/slots/Toolbar.d.ts
CHANGED
package/map/slots/Toolbar.js
CHANGED
|
@@ -18,8 +18,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var Toolbar_exports = {};
|
|
20
20
|
__export(Toolbar_exports, {
|
|
21
|
-
Toolbar: () => Toolbar
|
|
21
|
+
Toolbar: () => Toolbar,
|
|
22
|
+
sanitizeProps: () => sanitizeProps
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(Toolbar_exports);
|
|
25
|
+
var import_lodash_es = require("lodash");
|
|
26
|
+
const allowedProps = ["placement", "hidden", "draggable"];
|
|
27
|
+
const sanitizeProps = (externalProps) => {
|
|
28
|
+
return (0, import_lodash_es.pick)(externalProps, allowedProps);
|
|
29
|
+
};
|
|
24
30
|
const Toolbar = (props) => null;
|
|
25
31
|
Toolbar.displayName = "MapToolbar";
|
package/map/types/map-view.d.ts
CHANGED
|
@@ -78,6 +78,13 @@ export interface MapViewBaseProps extends DataTestId, StylingProps, MaskingProps
|
|
|
78
78
|
truncationMode?: TruncationMode;
|
|
79
79
|
/** Map View formatter options */
|
|
80
80
|
formatter?: Formatter | FormatOptions<Unit, ConvertibleUnit>;
|
|
81
|
+
/**
|
|
82
|
+
* Callback fired when the map context is lost.
|
|
83
|
+
* Browsers have a limit of active WebGL canvas contexts.
|
|
84
|
+
* The map will automatically show an error state, but this callback
|
|
85
|
+
* allows consumers to perform additional actions (e.g., analytics, custom UI).
|
|
86
|
+
*/
|
|
87
|
+
onContextLostError?: () => void;
|
|
81
88
|
}
|
|
82
89
|
/**
|
|
83
90
|
* Props to configure a Map
|
|
@@ -103,7 +103,10 @@ const iterateConfigSlots = (children, legendDomain) => {
|
|
|
103
103
|
}
|
|
104
104
|
};
|
|
105
105
|
} else if ((0, import_is_slot.isSlot)(child, import_Toolbar.Toolbar)) {
|
|
106
|
-
slotMapToolbarConfig = {
|
|
106
|
+
slotMapToolbarConfig = {
|
|
107
|
+
...slotMapToolbarConfig,
|
|
108
|
+
...(0, import_Toolbar.sanitizeProps)(child.props)
|
|
109
|
+
};
|
|
107
110
|
} else if ((0, import_is_slot.isSlot)(child, import_DownloadCSV.DownloadCSV)) {
|
|
108
111
|
slotMapToolbarConfig = {
|
|
109
112
|
...slotMapToolbarConfig,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynatrace/strato-geo",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -58,10 +58,10 @@
|
|
|
58
58
|
"react-dom": "^18.0.0",
|
|
59
59
|
"react-intl": "^6.0.8 || ^7.0.0",
|
|
60
60
|
"react-is": "^18.0.0",
|
|
61
|
-
"@dynatrace/strato-components": "^1.
|
|
62
|
-
"@dynatrace/strato-components-preview": "^2.
|
|
63
|
-
"@dynatrace/strato-design-tokens": "^1.
|
|
64
|
-
"@dynatrace/strato-icons": "^1.
|
|
61
|
+
"@dynatrace/strato-components": "^1.16.0",
|
|
62
|
+
"@dynatrace/strato-components-preview": "^2.14.1",
|
|
63
|
+
"@dynatrace/strato-design-tokens": "^1.3.1",
|
|
64
|
+
"@dynatrace/strato-icons": "^1.12.0"
|
|
65
65
|
},
|
|
66
66
|
"sideEffects": [
|
|
67
67
|
"./map/styles/react-mapgl-styles.css",
|