@mapcomponents/deck-gl 0.0.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.
- package/.babelrc +22 -0
- package/.editorconfig +19 -0
- package/.eslintignore +12 -0
- package/.eslintrc.js +30 -0
- package/.prettierignore +11 -0
- package/.prettierrc.json +6 -0
- package/.storybook/.babelrc +26 -0
- package/.storybook/main.js +40 -0
- package/.storybook/manager.js +6 -0
- package/.storybook/mapcomponents_logo.png +0 -0
- package/.storybook/preview.js +33 -0
- package/.storybook/style.css +15 -0
- package/.storybook/wheregroupTheme.js +9 -0
- package/CHANGELOG.md +1 -0
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/config/env.js +106 -0
- package/config/jest/babelTransform.js +29 -0
- package/config/jest/cssTransform.js +14 -0
- package/config/jest/fileTransform.js +40 -0
- package/config/paths.js +75 -0
- package/coverage/clover.xml +6 -0
- package/coverage/coverage-final.json +1 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +101 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +196 -0
- package/coverage/lcov.info +0 -0
- package/cypress/support/commands.ts +37 -0
- package/cypress/support/component-index.html +12 -0
- package/cypress/support/component.ts +46 -0
- package/cypress.config.ts +101 -0
- package/dist/components/MlHexagonMap/MlHexagonMap.d.ts +19 -0
- package/dist/components/MlHexagonMap/MlHexagonMap.stories.d.ts +14 -0
- package/dist/contexts/DeckGlContext.d.ts +15 -0
- package/dist/decorators/MapContextDecorator.d.ts +2 -0
- package/dist/hooks/useDeckGl.d.ts +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.esm.js +105 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/setupTests.d.ts +13 -0
- package/dist/stories/components/Readme.d.ts +2 -0
- package/dist/util/BubbleForInstructions.d.ts +2 -0
- package/dist/util/Instructions.d.ts +14 -0
- package/dist/util/index.d.ts +3 -0
- package/dist/util/layerRemovalTest.d.ts +2 -0
- package/dist/util/sourceRemovalTest.d.ts +2 -0
- package/eslintErrorTest.js +10 -0
- package/package.json +199 -0
- package/public/assets/3D/godzilla_simple.glb +0 -0
- package/public/assets/3D/hexa.json +4 -0
- package/public/assets/3D/laerm_points.json +1 -0
- package/public/assets/dop.png +0 -0
- package/public/assets/historic.png +0 -0
- package/public/assets/marker.png +0 -0
- package/public/assets/osm.png +0 -0
- package/public/assets/sample.gpx +716 -0
- package/public/assets/sample1.gpx +3003 -0
- package/public/assets/sample2.gpx +1264 -0
- package/public/assets/sample3.gpx +912 -0
- package/public/assets/wg-marker.png +0 -0
- package/public/catalogue/.gitkeep +0 -0
- package/public/catalogue/mc_meta.json +1 -0
- package/public/favicon.ico +0 -0
- package/public/index.html +39 -0
- package/public/logo.png +0 -0
- package/public/manifest.json +25 -0
- package/public/robots.txt +3 -0
- package/public/thumbnails/MapLibreMap.png +0 -0
- package/public/thumbnails/MlCameraFollowPath.png +0 -0
- package/public/thumbnails/MlCreatePdfButton.png +0 -0
- package/public/thumbnails/MlCreatePdfForm.png +0 -0
- package/public/thumbnails/MlDeckGlLayer.png +0 -0
- package/public/thumbnails/MlDeckGlTerrainLayer.png +0 -0
- package/public/thumbnails/MlDemoDashboard.png +0 -0
- package/public/thumbnails/MlFeatureEditor.png +0 -0
- package/public/thumbnails/MlFillExtrusionLayer.png +0 -0
- package/public/thumbnails/MlFollowGps.png +0 -0
- package/public/thumbnails/MlGeoJsonLayer.png +0 -0
- package/public/thumbnails/MlGpxViewer.png +0 -0
- package/public/thumbnails/MlHillshadeLayer.png +0 -0
- package/public/thumbnails/MlIconLayer.png +0 -0
- package/public/thumbnails/MlLaermkarte.png +0 -0
- package/public/thumbnails/MlLayerMagnify.png +0 -0
- package/public/thumbnails/MlLayerSwipe.png +0 -0
- package/public/thumbnails/MlMapDrawTools.png +0 -0
- package/public/thumbnails/MlMeasureTool.png +0 -0
- package/public/thumbnails/MlMobilerImker.png +0 -0
- package/public/thumbnails/MlNavigationCompass.png +0 -0
- package/public/thumbnails/MlNavigationTools.png +0 -0
- package/public/thumbnails/MlOsmLayer.png +0 -0
- package/public/thumbnails/MlScaleReference.png +0 -0
- package/public/thumbnails/MlSketchTool.png +0 -0
- package/public/thumbnails/MlSpatialElevationProfile.png +0 -0
- package/public/thumbnails/MlThreeJsLayer.png +0 -0
- package/public/thumbnails/MlTransitionGeoJsonLayer.png +0 -0
- package/public/thumbnails/MlVectorTileLayer.png +0 -0
- package/public/thumbnails/MlWanderApp.png +0 -0
- package/public/thumbnails/MlWmsLayer.png +0 -0
- package/public/thumbnails/MlWmsLoader.png +0 -0
- package/public/thumbnails/useCameraFollowPath.png +0 -0
- package/rollup.config.js +67 -0
- package/scripts/build-catalogue-markdown-docs.js +28 -0
- package/scripts/build-catalogue-meta.js +42 -0
- package/scripts/create-map-component.sh +36 -0
- package/scripts/test.js +53 -0
- package/src/@types/assets/index.d.ts +20 -0
- package/src/App.css +0 -0
- package/src/components/MlHexagonMap/MlHexagonMap.meta_.json +14 -0
- package/src/components/MlHexagonMap/MlHexagonMap.stories.tsx +29 -0
- package/src/components/MlHexagonMap/MlHexagonMap.tsx +143 -0
- package/src/contexts/DeckGlContext.tsx +66 -0
- package/src/custom.d.ts +4 -0
- package/src/decorators/MapContextDecorator.js +41 -0
- package/src/decorators/style.css +34 -0
- package/src/hooks/useDeckGl.tsx +24 -0
- package/src/index.ts +2 -0
- package/src/setupTests.js +113 -0
- package/src/stories/components/Readme.js +7 -0
- package/src/util/BubbleForInstructions.js +48 -0
- package/src/util/Instructions.tsx +60 -0
- package/src/util/index.js +4 -0
- package/src/util/layerRemovalTest.js +121 -0
- package/src/util/sourceRemovalTest.js +113 -0
- package/tsconfig.json +34 -0
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import React, { ReactNode, useEffect, useRef, useState } from 'react';
|
|
2
|
+
import { useMap } from '@mapcomponents/react-maplibre';
|
|
3
|
+
import { Deck, Layer } from '@deck.gl/core/typed';
|
|
4
|
+
import { MapboxLayer } from '@deck.gl/mapbox/typed';
|
|
5
|
+
|
|
6
|
+
export interface DeckGlContextType {
|
|
7
|
+
deckGl: Deck | undefined;
|
|
8
|
+
deckGlLayerArray: Layer[];
|
|
9
|
+
setDeckGlLayerArray: React.Dispatch<React.SetStateAction<Layer[]>>;
|
|
10
|
+
}
|
|
11
|
+
interface DeckGlContextProviderProps {
|
|
12
|
+
mapId: string;
|
|
13
|
+
children: ReactNode;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const layerId = 'deckgl-layer';
|
|
17
|
+
const DeckGlContext = React.createContext({} as DeckGlContextType);
|
|
18
|
+
|
|
19
|
+
const DeckGlContextProvider = ({ mapId, children }: DeckGlContextProviderProps) => {
|
|
20
|
+
const mapHook = useMap({ mapId });
|
|
21
|
+
|
|
22
|
+
const [deckGl, setDeckGl] = useState<Deck | undefined>(undefined);
|
|
23
|
+
const layerRef = useRef<MapboxLayer<Layer> | undefined>(undefined);
|
|
24
|
+
const [deckGlLayerArray, setDeckGlLayerArray] = useState([]);
|
|
25
|
+
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
if (!mapHook.map) return;
|
|
28
|
+
|
|
29
|
+
const deck = new Deck({
|
|
30
|
+
gl: mapHook.map.painter.context.gl,
|
|
31
|
+
layers: [],
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
layerRef.current = new MapboxLayer({
|
|
35
|
+
id: layerId,
|
|
36
|
+
deck: deck,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
mapHook.map.addLayer(layerRef.current);
|
|
42
|
+
|
|
43
|
+
setDeckGl(deck);
|
|
44
|
+
return () => {
|
|
45
|
+
mapHook.map?.removeLayer(layerId);
|
|
46
|
+
layerRef.current = undefined;
|
|
47
|
+
};
|
|
48
|
+
}, [mapHook.map]);
|
|
49
|
+
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (!deckGl) return;
|
|
52
|
+
deckGl.setProps({
|
|
53
|
+
layers: [...deckGlLayerArray],
|
|
54
|
+
});
|
|
55
|
+
}, [deckGlLayerArray, deckGl]);
|
|
56
|
+
|
|
57
|
+
const value = {
|
|
58
|
+
deckGl,
|
|
59
|
+
deckGlLayerArray,
|
|
60
|
+
setDeckGlLayerArray,
|
|
61
|
+
};
|
|
62
|
+
return <DeckGlContext.Provider value={value}>{children}</DeckGlContext.Provider>;
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export { DeckGlContextProvider };
|
|
66
|
+
export default DeckGlContext;
|
package/src/custom.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
MapComponentsProvider,
|
|
5
|
+
MapLibreMap,
|
|
6
|
+
MlNavigationTools,
|
|
7
|
+
getTheme,
|
|
8
|
+
} from '@mapcomponents/react-maplibre';
|
|
9
|
+
import './style.css';
|
|
10
|
+
import { ThemeProvider as MUIThemeProvider } from '@mui/material/styles';
|
|
11
|
+
|
|
12
|
+
const decorators = [
|
|
13
|
+
(Story, context) => {
|
|
14
|
+
const theme = useMemo(() => getTheme(context?.globals?.theme), [context?.globals?.theme]);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className="fullscreen_map">
|
|
18
|
+
<MapComponentsProvider>
|
|
19
|
+
<MUIThemeProvider theme={theme}>
|
|
20
|
+
<Story />
|
|
21
|
+
<MapLibreMap
|
|
22
|
+
options={{
|
|
23
|
+
zoom: 14.5,
|
|
24
|
+
style: 'https://wms.wheregroup.com/tileserver/style/osm-bright.json',
|
|
25
|
+
center: [7.0851268, 50.73884],
|
|
26
|
+
}}
|
|
27
|
+
mapId="map_1"
|
|
28
|
+
/>
|
|
29
|
+
<MlNavigationTools
|
|
30
|
+
sx={{ bottom: '25px', right: '5px' }}
|
|
31
|
+
showZoomButtons={false}
|
|
32
|
+
mapId="map_1"
|
|
33
|
+
/>
|
|
34
|
+
</MUIThemeProvider>
|
|
35
|
+
</MapComponentsProvider>
|
|
36
|
+
</div>
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
];
|
|
40
|
+
|
|
41
|
+
export default decorators;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#root {
|
|
2
|
+
background-color: #000;
|
|
3
|
+
position: absolute;
|
|
4
|
+
min-height: 400px;
|
|
5
|
+
top: 0;
|
|
6
|
+
bottom: 0;
|
|
7
|
+
left: 0;
|
|
8
|
+
right: 0;
|
|
9
|
+
}
|
|
10
|
+
.docs-story {
|
|
11
|
+
min-height: 400px;
|
|
12
|
+
display: flex;
|
|
13
|
+
align-items: stretch;
|
|
14
|
+
}
|
|
15
|
+
.docs-story > div:first-child {
|
|
16
|
+
width: 100%;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.App {
|
|
20
|
+
position: absolute;
|
|
21
|
+
top: 0;
|
|
22
|
+
right: 0;
|
|
23
|
+
bottom: 0;
|
|
24
|
+
left: 0;
|
|
25
|
+
}
|
|
26
|
+
.fullscreen_map .mapContainer {
|
|
27
|
+
position: absolute;
|
|
28
|
+
top: 0;
|
|
29
|
+
right: 0;
|
|
30
|
+
left: 0;
|
|
31
|
+
bottom: 0;
|
|
32
|
+
z-index: 100;
|
|
33
|
+
}
|
|
34
|
+
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import DeckGlContext from '../contexts/DeckGlContext';
|
|
2
|
+
import { useContext } from 'react';
|
|
3
|
+
import { Layer } from '@deck.gl/core/typed';
|
|
4
|
+
|
|
5
|
+
function useDeckGl() {
|
|
6
|
+
const deckGlContext = useContext(DeckGlContext);
|
|
7
|
+
const layerArray = deckGlContext.deckGlLayerArray;
|
|
8
|
+
|
|
9
|
+
function addLayer(layer: Layer) {
|
|
10
|
+
const newDeckGLLayerArray = [...layerArray];
|
|
11
|
+
newDeckGLLayerArray.push(layer);
|
|
12
|
+
deckGlContext.setDeckGlLayerArray(newDeckGLLayerArray);
|
|
13
|
+
}
|
|
14
|
+
function removeLayer(layer: Layer) {
|
|
15
|
+
const newDeckGLLayerArray = layerArray.filter((l) => l !== layer);
|
|
16
|
+
deckGlContext.setDeckGlLayerArray(newDeckGLLayerArray);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
addLayer,
|
|
20
|
+
removeLayer,
|
|
21
|
+
layerArray,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
export default useDeckGl;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
import 'jest-enzyme';
|
|
3
|
+
import Adapter from '@wojtekmaj/enzyme-adapter-react-17';
|
|
4
|
+
|
|
5
|
+
import { configure } from 'enzyme';
|
|
6
|
+
|
|
7
|
+
var uuid_regex = '[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}';
|
|
8
|
+
export { uuid_regex };
|
|
9
|
+
|
|
10
|
+
// MapLibre-gl mockup
|
|
11
|
+
var mockMapLibreMethods = {
|
|
12
|
+
on: jest.fn(),
|
|
13
|
+
off: jest.fn(),
|
|
14
|
+
addControl: jest.fn(),
|
|
15
|
+
removeControl: jest.fn(),
|
|
16
|
+
fitBounds: jest.fn(),
|
|
17
|
+
hasControl: jest.fn(() => true),
|
|
18
|
+
getCanvas: () => document.createElement('canvas'),
|
|
19
|
+
getContainer: () => ({
|
|
20
|
+
style: {},
|
|
21
|
+
}),
|
|
22
|
+
};
|
|
23
|
+
export { mockMapLibreMethods };
|
|
24
|
+
|
|
25
|
+
jest.mock('maplibre-gl/dist/maplibre-gl', () => {
|
|
26
|
+
const originalModule = jest.requireActual('maplibre-gl/dist/maplibre-gl');
|
|
27
|
+
|
|
28
|
+
return {
|
|
29
|
+
...originalModule,
|
|
30
|
+
GeolocateControl: jest.fn(),
|
|
31
|
+
Map: function () {
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
33
|
+
var self = this;
|
|
34
|
+
this.layers = [];
|
|
35
|
+
this.sources = [];
|
|
36
|
+
this.style = { sourceCaches: {} };
|
|
37
|
+
|
|
38
|
+
let styleFunctions = {
|
|
39
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
40
|
+
addSource: (id, source) => {
|
|
41
|
+
if (typeof id.id !== 'undefined') {
|
|
42
|
+
self.sources.push(id);
|
|
43
|
+
self.style.sourceCaches[id] = {};
|
|
44
|
+
} else if (typeof id !== 'undefined') {
|
|
45
|
+
self.sources.push(id);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
getSource: (id) => {
|
|
49
|
+
if (self.sources.indexOf(id) !== -1) {
|
|
50
|
+
return { setData: jest.fn() };
|
|
51
|
+
}
|
|
52
|
+
return false;
|
|
53
|
+
},
|
|
54
|
+
removeSource: (id) => {
|
|
55
|
+
const sourcePosition = self.sources.indexOf(id);
|
|
56
|
+
if (sourcePosition !== -1) {
|
|
57
|
+
self.sources.splice(sourcePosition, 1);
|
|
58
|
+
delete self.style.sourceCaches[id];
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
addLayer: (layer) => {
|
|
62
|
+
if (typeof layer.id !== 'undefined') {
|
|
63
|
+
self.layers.push(layer.id);
|
|
64
|
+
if (typeof layer.source !== 'undefined' && typeof layer.source === 'object') {
|
|
65
|
+
self.sources.push(layer.id);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
getLayer: (id) => {
|
|
70
|
+
if (self.layers.indexOf(id) !== -1) {
|
|
71
|
+
return {};
|
|
72
|
+
}
|
|
73
|
+
return false;
|
|
74
|
+
},
|
|
75
|
+
removeLayer: (id) => {
|
|
76
|
+
const layerPosition = self.layers.indexOf(id);
|
|
77
|
+
if (layerPosition !== -1) {
|
|
78
|
+
self.layers.splice(layerPosition, 1);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
...styleFunctions,
|
|
85
|
+
once: (eventName, callback) => {
|
|
86
|
+
callback();
|
|
87
|
+
},
|
|
88
|
+
remove: jest.fn(),
|
|
89
|
+
setLayerZoomRange: jest.fn(),
|
|
90
|
+
setLayoutProperty: jest.fn(),
|
|
91
|
+
addImage: jest.fn(),
|
|
92
|
+
loadImage: jest.fn(),
|
|
93
|
+
removeImage: jest.fn(),
|
|
94
|
+
hasImage: jest.fn(),
|
|
95
|
+
project: jest.fn(),
|
|
96
|
+
setZoom: jest.fn(),
|
|
97
|
+
setPitch: jest.fn(),
|
|
98
|
+
setCenter: jest.fn(),
|
|
99
|
+
style: { ...styleFunctions },
|
|
100
|
+
layers: this.layers,
|
|
101
|
+
sources: this.sources,
|
|
102
|
+
_update: jest.fn(),
|
|
103
|
+
...mockMapLibreMethods,
|
|
104
|
+
};
|
|
105
|
+
},
|
|
106
|
+
NavigationControl: jest.fn(),
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
configure({ adapter: new Adapter() });
|
|
111
|
+
|
|
112
|
+
window.URL.createObjectURL = function () {};
|
|
113
|
+
window.HTMLCanvasElement.prototype.getContext = () => {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReplyAllIcon from '@mui/icons-material/ReplyAll';
|
|
3
|
+
import { Box, Typography } from '@mui/material';
|
|
4
|
+
|
|
5
|
+
function BubbleForInstruction(props) {
|
|
6
|
+
return (
|
|
7
|
+
<>
|
|
8
|
+
<Box
|
|
9
|
+
sx={{
|
|
10
|
+
width: '475px',
|
|
11
|
+
height: '475px',
|
|
12
|
+
position: 'fixed',
|
|
13
|
+
display: 'block',
|
|
14
|
+
borderRadius: '360px',
|
|
15
|
+
bgcolor: 'primary.main',
|
|
16
|
+
right: props.bubbleRight,
|
|
17
|
+
bottom: props.bubbleBottom,
|
|
18
|
+
left: props.bubbleLeft,
|
|
19
|
+
top: props.bubbleTop,
|
|
20
|
+
zIndex: props.zIndex,
|
|
21
|
+
}}
|
|
22
|
+
>
|
|
23
|
+
<Typography
|
|
24
|
+
variant="h5"
|
|
25
|
+
sx={{
|
|
26
|
+
marginTop: props.textMarginTop,
|
|
27
|
+
marginLeft: props.textMarginLeft,
|
|
28
|
+
color: 'text.contrast',
|
|
29
|
+
textAlign: 'left',
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
<b>{props.children}</b>
|
|
33
|
+
</Typography>
|
|
34
|
+
<ReplyAllIcon
|
|
35
|
+
sx={{
|
|
36
|
+
color: 'text.contrast',
|
|
37
|
+
fontSize: '80px',
|
|
38
|
+
position: 'absolute',
|
|
39
|
+
transform: props.iconTransform,
|
|
40
|
+
marginTop: props.iconMarginTop,
|
|
41
|
+
marginLeft: props.iconMarginLeft,
|
|
42
|
+
}}
|
|
43
|
+
/>
|
|
44
|
+
</Box>
|
|
45
|
+
</>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
export default BubbleForInstruction;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, { useEffect, useState, useRef } from 'react';
|
|
2
|
+
import {Fade, SxProps} from '@mui/material';
|
|
3
|
+
import BubbleStyle from './BubbleForInstructions';
|
|
4
|
+
|
|
5
|
+
interface StepObject {
|
|
6
|
+
duration: number;
|
|
7
|
+
props: SxProps;
|
|
8
|
+
content: JSX.Element;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface InstructionProps {
|
|
12
|
+
steps: Array<StepObject>;
|
|
13
|
+
open: boolean;
|
|
14
|
+
callback?: () => void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const Instructions = (props: InstructionProps) => {
|
|
18
|
+
const [activeStep, setActiveStep] = useState<number>();
|
|
19
|
+
const initializedRef = useRef(false);
|
|
20
|
+
|
|
21
|
+
const activateStep = (stepId?: number | undefined) => {
|
|
22
|
+
let _nextStep: number | undefined = typeof stepId === 'undefined' ? 0 : stepId + 1;
|
|
23
|
+
if (typeof _nextStep !== 'undefined') {
|
|
24
|
+
if (_nextStep > props.steps.length + 1) {
|
|
25
|
+
_nextStep = undefined;
|
|
26
|
+
} else {
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
activateStep(_nextStep);
|
|
29
|
+
}, props.steps[_nextStep].duration);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
setActiveStep(_nextStep);
|
|
33
|
+
};
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
if (props.open && !initializedRef.current) {
|
|
36
|
+
initializedRef.current = true;
|
|
37
|
+
activateStep();
|
|
38
|
+
}
|
|
39
|
+
if (!props.open) {
|
|
40
|
+
initializedRef.current = false;
|
|
41
|
+
setActiveStep(undefined);
|
|
42
|
+
}
|
|
43
|
+
}, [props.open]);
|
|
44
|
+
|
|
45
|
+
return (
|
|
46
|
+
<>
|
|
47
|
+
{typeof activeStep !== 'undefined' && (
|
|
48
|
+
<Fade in={true} timeout={150}>
|
|
49
|
+
<div>
|
|
50
|
+
<BubbleStyle {...props.steps[activeStep].props}>
|
|
51
|
+
{props.steps[activeStep].content}
|
|
52
|
+
</BubbleStyle>
|
|
53
|
+
</div>
|
|
54
|
+
</Fade>
|
|
55
|
+
)}
|
|
56
|
+
</>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default Instructions;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import React, { useContext, useState } from "react";
|
|
2
|
+
import { mount } from "enzyme";
|
|
3
|
+
import { MapContext, MapComponentsProvider } from "../index";
|
|
4
|
+
import MapLibreMap from "./../components/MapLibreMap/MapLibreMap";
|
|
5
|
+
|
|
6
|
+
const layerRemovalTest = (
|
|
7
|
+
ComponentName,
|
|
8
|
+
Component,
|
|
9
|
+
regexLayerNameTest,
|
|
10
|
+
humanReadableLayerName,
|
|
11
|
+
beforeWrapperInit,
|
|
12
|
+
afterWrapperInit,
|
|
13
|
+
createWrapperFunction
|
|
14
|
+
) => {
|
|
15
|
+
const TestComponent = (props) => {
|
|
16
|
+
const [layerVisible, setLayerVisible] = useState(true);
|
|
17
|
+
const [refreshTrigger, setRefreshTrigger] = useState(0);
|
|
18
|
+
const mapContext = useContext(MapContext);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
<MapLibreMap />
|
|
23
|
+
|
|
24
|
+
{layerVisible && Component}
|
|
25
|
+
|
|
26
|
+
<button
|
|
27
|
+
className="toggle_layer_visible"
|
|
28
|
+
onClick={() => {
|
|
29
|
+
setLayerVisible(!layerVisible);
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
toggle layer visible
|
|
33
|
+
</button>
|
|
34
|
+
<button
|
|
35
|
+
className="trigger_refresh"
|
|
36
|
+
onClick={() => {
|
|
37
|
+
setRefreshTrigger(refreshTrigger + 1);
|
|
38
|
+
}}
|
|
39
|
+
>
|
|
40
|
+
refresh
|
|
41
|
+
</button>
|
|
42
|
+
<div className="layers_json">
|
|
43
|
+
{mapContext.map &&
|
|
44
|
+
refreshTrigger &&
|
|
45
|
+
JSON.stringify(mapContext.map.map.layers)}
|
|
46
|
+
</div>
|
|
47
|
+
</>
|
|
48
|
+
);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const createWrapper =
|
|
52
|
+
(typeof createWrapperFunction === "function" && createWrapperFunction) ||
|
|
53
|
+
(() =>
|
|
54
|
+
mount(
|
|
55
|
+
<MapComponentsProvider>
|
|
56
|
+
<TestComponent />
|
|
57
|
+
</MapComponentsProvider>
|
|
58
|
+
));
|
|
59
|
+
|
|
60
|
+
describe(ComponentName, () => {
|
|
61
|
+
it(
|
|
62
|
+
"should add a Layer with the id '" +
|
|
63
|
+
humanReadableLayerName +
|
|
64
|
+
"' to the MapLibre instance",
|
|
65
|
+
async () => {
|
|
66
|
+
if (typeof beforeWrapperInit === "function") {
|
|
67
|
+
await beforeWrapperInit();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const wrapper = createWrapper(TestComponent);
|
|
71
|
+
|
|
72
|
+
if (typeof afterWrapperInit === "function") {
|
|
73
|
+
await afterWrapperInit();
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
wrapper.find(".trigger_refresh").simulate("click");
|
|
77
|
+
|
|
78
|
+
// debug helper
|
|
79
|
+
//console.log('layer removal test')
|
|
80
|
+
//console.log(wrapper.find(".layers_json").text());
|
|
81
|
+
//console.log(regexLayerNameTest.toString());
|
|
82
|
+
//console.log(regexLayerNameTest.test(wrapper.find(".layers_json").text()));
|
|
83
|
+
expect(regexLayerNameTest.test(wrapper.find(".layers_json").text())).toEqual(
|
|
84
|
+
true
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
it(
|
|
90
|
+
"should remove a Layer with the id '" +
|
|
91
|
+
humanReadableLayerName +
|
|
92
|
+
"' from the MapLibre instance",
|
|
93
|
+
async () => {
|
|
94
|
+
if (typeof beforeWrapperInit === "function") {
|
|
95
|
+
await beforeWrapperInit();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const wrapper = createWrapper(TestComponent);
|
|
99
|
+
|
|
100
|
+
if (typeof afterWrapperInit === "function") {
|
|
101
|
+
await afterWrapperInit();
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
wrapper.find(".trigger_refresh").simulate("click");
|
|
105
|
+
|
|
106
|
+
expect(regexLayerNameTest.test(wrapper.find(".layers_json").text())).toEqual(
|
|
107
|
+
true
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
wrapper.find(".toggle_layer_visible").simulate("click");
|
|
111
|
+
wrapper.find(".trigger_refresh").simulate("click");
|
|
112
|
+
|
|
113
|
+
expect(regexLayerNameTest.test(wrapper.find(".layers_json").text())).toEqual(
|
|
114
|
+
false
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
);
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
export default layerRemovalTest;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import React, { useContext, useState } from "react";
|
|
2
|
+
import { mount, configure } from "enzyme";
|
|
3
|
+
import { MapContext, MapComponentsProvider } from "../index";
|
|
4
|
+
import MapLibreMap from "./../components/MapLibreMap/MapLibreMap";
|
|
5
|
+
|
|
6
|
+
const sourceRemovalTest = (
|
|
7
|
+
ComponentName,
|
|
8
|
+
Component,
|
|
9
|
+
regexLayerNameTest,
|
|
10
|
+
humanReadableLayerName,
|
|
11
|
+
beforeWrapperInit,
|
|
12
|
+
afterWrapperInit
|
|
13
|
+
) => {
|
|
14
|
+
const TestComponent = (props) => {
|
|
15
|
+
const [layerVisible, setLayerVisible] = useState(true);
|
|
16
|
+
const [refreshTrigger, setRefreshTrigger] = useState(0);
|
|
17
|
+
const mapContext = useContext(MapContext);
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
<MapLibreMap />
|
|
22
|
+
|
|
23
|
+
{layerVisible && Component}
|
|
24
|
+
|
|
25
|
+
<button
|
|
26
|
+
className="toggle_layer_visible"
|
|
27
|
+
onClick={() => {
|
|
28
|
+
setLayerVisible(!layerVisible);
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
toggle layer visible
|
|
32
|
+
</button>
|
|
33
|
+
<button
|
|
34
|
+
className="trigger_refresh"
|
|
35
|
+
onClick={() => {
|
|
36
|
+
setRefreshTrigger(refreshTrigger + 1);
|
|
37
|
+
}}
|
|
38
|
+
>
|
|
39
|
+
refresh
|
|
40
|
+
</button>
|
|
41
|
+
<div className="sources_json">
|
|
42
|
+
{mapContext.map &&
|
|
43
|
+
refreshTrigger &&
|
|
44
|
+
JSON.stringify(mapContext.map.map.sources)}
|
|
45
|
+
</div>
|
|
46
|
+
</>
|
|
47
|
+
);
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const createWrapper = () =>
|
|
51
|
+
mount(
|
|
52
|
+
<MapComponentsProvider>
|
|
53
|
+
<TestComponent />
|
|
54
|
+
</MapComponentsProvider>
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
describe(ComponentName, () => {
|
|
58
|
+
it(
|
|
59
|
+
"should add a Source with the id '" +
|
|
60
|
+
humanReadableLayerName +
|
|
61
|
+
"' to the MapLibre instance",
|
|
62
|
+
async () => {
|
|
63
|
+
if (typeof beforeWrapperInit === "function") {
|
|
64
|
+
await beforeWrapperInit();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const wrapper = createWrapper();
|
|
68
|
+
|
|
69
|
+
if (typeof afterWrapperInit === "function") {
|
|
70
|
+
await afterWrapperInit();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
wrapper.find(".trigger_refresh").simulate("click");
|
|
74
|
+
|
|
75
|
+
expect(
|
|
76
|
+
regexLayerNameTest.test(wrapper.find(".sources_json").text())
|
|
77
|
+
).toEqual(true);
|
|
78
|
+
}
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
it(
|
|
82
|
+
"should remove a Source with the id '" +
|
|
83
|
+
humanReadableLayerName +
|
|
84
|
+
"' from the MapLibre instance",
|
|
85
|
+
async () => {
|
|
86
|
+
if (typeof beforeWrapperInit === "function") {
|
|
87
|
+
await beforeWrapperInit();
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const wrapper = createWrapper();
|
|
91
|
+
|
|
92
|
+
if (typeof afterWrapperInit === "function") {
|
|
93
|
+
await afterWrapperInit();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
wrapper.find(".trigger_refresh").simulate("click");
|
|
97
|
+
|
|
98
|
+
expect(
|
|
99
|
+
regexLayerNameTest.test(wrapper.find(".sources_json").text())
|
|
100
|
+
).toEqual(true);
|
|
101
|
+
|
|
102
|
+
wrapper.find(".toggle_layer_visible").simulate("click");
|
|
103
|
+
wrapper.find(".trigger_refresh").simulate("click");
|
|
104
|
+
|
|
105
|
+
expect(
|
|
106
|
+
regexLayerNameTest.test(wrapper.find(".sources_json").text())
|
|
107
|
+
).toEqual(false);
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export default sourceRemovalTest;
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"checkJs": false,
|
|
4
|
+
"esModuleInterop": true,
|
|
5
|
+
"importHelpers": false,
|
|
6
|
+
"isolatedModules": true,
|
|
7
|
+
"resolveJsonModule": true,
|
|
8
|
+
"skipLibCheck": true,
|
|
9
|
+
"sourceMap": true,
|
|
10
|
+
"strict": false,
|
|
11
|
+
"types": ["node", "jest", "geojson", "cypress"],
|
|
12
|
+
"typeRoots": ["./src/@types", "./node_modules/@types"],
|
|
13
|
+
"outDir": "build/esm",
|
|
14
|
+
"module": "esnext",
|
|
15
|
+
"target": "es5",
|
|
16
|
+
"lib": ["es6", "dom", "es2016", "es2017"],
|
|
17
|
+
"jsx": "react",
|
|
18
|
+
"declaration": true,
|
|
19
|
+
"declarationDir": "./dist",
|
|
20
|
+
"moduleResolution": "node",
|
|
21
|
+
"noUnusedLocals": true,
|
|
22
|
+
"noUnusedParameters": true,
|
|
23
|
+
"noImplicitReturns": true,
|
|
24
|
+
"noImplicitThis": true,
|
|
25
|
+
"noImplicitAny": true,
|
|
26
|
+
"strictNullChecks": true,
|
|
27
|
+
"suppressImplicitAnyIndexErrors": true,
|
|
28
|
+
"allowSyntheticDefaultImports": true,
|
|
29
|
+
"allowJs": true,
|
|
30
|
+
"baseUrl": "."
|
|
31
|
+
},
|
|
32
|
+
"include": ["src", "src/custom.d.tsx"],
|
|
33
|
+
"exclude": ["node_modules", "lib"]
|
|
34
|
+
}
|