Skip to content

Commit a9e001c

Browse files
committed
Initial commit
0 parents  commit a9e001c

File tree

229 files changed

+781067
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

229 files changed

+781067
-0
lines changed

.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
SKIP_PREFLIGHT_CHECK=true

.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
#/dist
5+
/storybook-static
6+
/node_modules
7+
/.pnp
8+
.pnp.js
9+
10+
# testing
11+
/coverage
12+
13+
# production
14+
/build
15+
/src/__image_snapshots__
16+
17+
/public/catalogue/
18+
19+
/.idea
20+
# misc
21+
.DS_Store
22+
.env.local
23+
.env.development.local
24+
.env.test.local
25+
.env.production.local
26+
.eslintcache
27+
28+
npm-debug.log*
29+
yarn-debug.log*
30+
yarn-error.log*
31+
32+
*.swp
33+
*.swo
34+
35+
36+
/docs
37+
!/docs/server.js

.storybook/main.js

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
module.exports = {
2+
stories: ["../src/**/*.stories.mdx", "../src/**/*.stories.@(js|jsx|ts|tsx)"],
3+
addons: [
4+
"@storybook/addon-links",
5+
"@storybook/addon-essentials",
6+
"@storybook/preset-create-react-app",
7+
],
8+
webpackFinal: async (config, { configType }) => {
9+
// split into more chunks
10+
config.optimization = {
11+
splitChunks: {
12+
chunks: "all",
13+
minSize: 30 * 1024, // 30KB
14+
maxSize: 1024 * 1024, // 1MB
15+
},
16+
};
17+
18+
return config;
19+
},
20+
};

.storybook/manager.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { addons } from "@storybook/addons";
2+
import wheregroupTheme from "./wheregroupTheme";
3+
4+
addons.setConfig({
5+
theme: wheregroupTheme,
6+
});

.storybook/mapcomponents_logo.png

7.76 KB
Loading

.storybook/preview.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from "react";
2+
3+
//import { MapComponentsProvider } from "react-map-components-core";
4+
//import { MapLibreMap } from "react-map-components-maplibre";
5+
6+
//export const decorators = [
7+
// (Story) => (
8+
// <MapComponentsProvider>
9+
// <Story />
10+
// <MapLibreMap
11+
// options={{
12+
// //style: "mapbox://styles/mapbox/light-v10",
13+
// //center: [-87.62712, 41.89033],
14+
// zoom: 14.5,
15+
// //pitch: 45,
16+
// style: "https://wms.wheregroup.com/tileserver/style/osm-bright.json",
17+
// //style:"https://wms.wheregroup.com/tileserver/style/osm-liberty.json",
18+
// //center: [8.607, 53.1409349],
19+
// // zoom: 13,
20+
// center: [7.0851268, 50.73884],
21+
// // maxBounds: [
22+
// // [1.40625, 43.452919],
23+
// // [17.797852, 55.973798],
24+
// // ],
25+
// }}
26+
// />
27+
// </MapComponentsProvider>
28+
// ),
29+
//];
30+
31+
export const parameters = {
32+
actions: { argTypesRegex: "^on[A-Z].*" },
33+
};

.storybook/wheregroupTheme.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { create } from "@storybook/theming";
2+
import logo from "./mapcomponents_logo.png";
3+
4+
export default create({
5+
base: "light",
6+
brandTitle: "WhereGroup GmbH",
7+
brandUrl: "https://wheregroup.com",
8+
brandImage: logo,
9+
});

README.md

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
# MapComponents MapLibre
2+
3+
## Getting started
4+
5+
1. Clone the repository
6+
2. ```cd``` into the folder and
7+
3. Run ```yarn``` to install all dependencies.
8+
4. Run ```yarn storybook``` to start the storybook server. It will watch files for changes and hot-reload affected components. If cleanup functions are incomplete it can be required to reload the browser.
9+
10+
### Create a new component
11+
12+
2. Run ```yarn create-component {component-name}``` to create a new Map-component based on ./src/components/MlComponentTemplate/. It must start with a capital letter because it is a react component and preferably start with the prefix "Ml" if it is a MapLibre component, to follow the naming conventions of this repository.
13+
2. The new component should become available within your storybook webinterface. Start the component development inside the component file (former MlComponentTemplate.js) and see the changes reflected in your browser.
14+
3. Once the component is ready to be published to the MapComponents catalogue, remove the ```_``` from the meta.json file ({component_name}.meta_.json) and it will be included in the next release.
15+
16+
### Create a new example application
17+
18+
1. Follow all steps of "Create a new component"
19+
2. Change the value of the property "type" in {component_name}.meta.json to "application"
20+
21+
## Anatomy of a MapComponent
22+
23+
A MapComponent is a react component that accepts at least 1 attribute "mapId" and is expected to retrieve and directly manipulate a maplibre-gl instance from mapContext.
24+
An example implementation of basic required functions for the maplibre instance retrieval process using the functions getMap, mapExists provided by mapContext, both accepting "mapId" (string) as parameter, can be seen in ./components/MlBasicCompontent.js. For components with a basic functionality it may be sufficient to make use of the MlBasicComponent and just provide the attributes "mapId" (string), "mapIsReady" (function), "cleanup" (function) as can be seen in ./components/MlDeckGlLayer/MlDeckGlLayer.
25+
If no attribute mapId is provided the map component is expected to work with the map instance provided by mapContext at ```mapContext.map```.
26+
27+
28+
### File structure
29+
30+
```
31+
./src/components/{component_name}/
32+
├── {component_name}.doc.de.md
33+
├── {component_name}.meta.json
34+
├── {component_name}.js
35+
├── {component_name}.test.js
36+
└── {component_name}.stories.js
37+
```
38+
39+
### {component_name}.js
40+
41+
React component implementation
42+
43+
#### Common conventions
44+
45+
##### Cleanup functions
46+
47+
To make sure a component cleans up the MapLibre instance after it has been removed from reactDOM declare a reference to the map instance using the useRef hook.
48+
49+
**- Reference declaration**
50+
51+
```
52+
const mapRef = useRef(null);
53+
```
54+
55+
**- Component cleanup function**
56+
57+
After everything has been undone it is important to set the map reference (mapRef.current) to null.
58+
59+
```
60+
useEffect(() => {
61+
return () => {
62+
// This is the cleanup function, it is called when this react component is removed from reactDOM
63+
if (mapRef.current) {
64+
if (mapRef.current.style && mapRef.current.getLayer(layerId)) {
65+
mapRef.current.removeLayer(layerId);
66+
}
67+
if (mapRef.current.style && mapRef.current.getSource(layerSourceId)) {
68+
mapRef.current.removeSource(layerSourceId);
69+
}
70+
71+
mapRef.current = null;
72+
}
73+
};
74+
}, []);
75+
```
76+
77+
**- Reference population**
78+
79+
This happens within the effect where the targeted (through props.mapId) map instance is discovered for the first time.
80+
81+
```
82+
mapRef.current = mapContext.getMap(props.mapId);
83+
```
84+
85+
### {component_name}.meta.json
86+
87+
Additional meta data regarding the component, this file is required for the component to become listed in the catalogue
88+
89+
```
90+
{
91+
"name": "{component_name}", // must be identical to the react component name (string)
92+
"title": "", // german component title (string)
93+
"description": "", // german short description (string)
94+
"tags": [ "Map add-on" ], // list of tags (Array<string>)
95+
"category": "add-ons", // category (string)
96+
"type": "component", // type "component" or "application" (string)
97+
}
98+
```
99+
100+
### {component_name}.doc.de.md
101+
102+
Description text, that is shown on the catalogue component detail page below the main image
103+
104+
### {component_name}.stories.js
105+
106+
Example implementation of a component in context with all required dependent components to showcase the basic functionality of a single component. Decorators to choose from are located in ./src/decorators/. During development the command ```yarn storybook``` will start a server (localhost:6006) with live reload functionality. In case of example applications the stories are used as a wrapper to make the application available in the storybook build that is later used to access working demos from within the catalogue.
107+
108+
Storybook stories are also used to generate screenshots of each component. The command ```yarn test``` will run automated jest tests. To make a component screenshot appear in the catalogue manually create a png like ./public/thumbnails/{component_name}.png and push it to the repository, it will be included in the catalogue in the next catalogue deployment.
109+
110+
More information on writing storybook stories for react components: https://storybook.js.org/docs/react/get-started/browse-stories
111+
112+
## LoadingOverlay and LoadingOverlayProvider (currently located in ./ui_components/)
113+
114+
The loading overlay component is added in the storybook decorator.
115+
Without any further configuration it will listen for new MapLibre instances registered in MapContext and fade out once all of them have fired an "IDLE" event. For more precise control the LoadingOverlayContext provides a ```loadingOverlayContext.setControlled(true)``` function that will, if called with true as first parameter, switch the LoadingOverlay to manual control. Once the application has loaded completely call the ```loadingOverlayContext.setLoadingDone(true)``` function to trigger the LoadingOverlay Component to fade out.
116+
117+
For decorator integration examples check the storybook decorators located in ./decorators/.
118+
For controlled LoadingOverlay examples please see MlLaermkarte (story & component).

babel.config.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"presets": [
3+
"@babel/preset-env",
4+
"@babel/preset-react"
5+
]
6+
}

jest.config.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"setupFiles": ["<rootDir>/src/test/setupTests.js"],
3+
"testRegex": "/*.test.js$",
4+
"collectCoverage": true,
5+
"coverageReporters": ["lcov"],
6+
"coverageDirectory": "test-coverage",
7+
"coverageThreshold": {
8+
"global": {
9+
"branches": 0,
10+
"functions": 0,
11+
"lines": 0,
12+
"statements": 0
13+
}
14+
},
15+
"moduleDirectories": ["node_modules", "src"]
16+
}

jsdoc.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"tags": {
3+
"allowUnknownTags": [
4+
"pailhead"
5+
]
6+
},
7+
"recurseDepth": 10,
8+
"plugins": [
9+
"node_modules/better-docs/typescript"
10+
],
11+
"source": {
12+
"include": ["./src/"]
13+
}
14+
}

0 commit comments

Comments
 (0)