Skip to content

Commit 4319bd3

Browse files
initial commit
Co-Authored-By: Sabrina Jodexnis <[email protected]>
0 parents  commit 4319bd3

File tree

137 files changed

+31622
-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.

137 files changed

+31622
-0
lines changed

.eslintrc.js

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
// @ts-check
2+
module.exports = {
3+
plugins: ['react', 'import', 'react-hooks', '@typescript-eslint'],
4+
extends: ['prettier', 'plugin:@typescript-eslint/recommended'],
5+
parser: '@typescript-eslint/parser',
6+
env: {
7+
node: true,
8+
browser: true,
9+
es6: true
10+
},
11+
globals: {
12+
google: true
13+
},
14+
ignorePatterns: ['node_modules', '**/dist*/**/*.js'],
15+
16+
parserOptions: {
17+
ecmaVersion: 2020,
18+
sourceType: 'module'
19+
},
20+
rules: {
21+
'no-continue': 'off',
22+
'no-console': ['error', {allow: ['warn', 'error']}]
23+
},
24+
overrides: [
25+
{
26+
files: ['examples/**/*'],
27+
rules: {
28+
'no-process-env': 'off'
29+
}
30+
},
31+
{
32+
files: ['./{src,examples}/*.{ts,mts,cts,tsx}'],
33+
rules: {
34+
// Some of JS rules don't always work correctly in TS and
35+
// hence need to be reimported as TS rules
36+
'no-redeclare': 'off',
37+
'no-shadow': 'off',
38+
'no-use-before-define': 'off',
39+
'no-dupe-class-members': 'off',
40+
41+
// typescript does a good job tracking return types
42+
'consistent-return': 'off',
43+
44+
'no-undef': 'off',
45+
'react-hooks/rules-of-hooks': 'error',
46+
'react-hooks/exhaustive-deps': 'warn',
47+
48+
// We use function hoisting to put exports at top of file
49+
'@typescript-eslint/no-use-before-define': 'off',
50+
'@typescript-eslint/no-dupe-class-members': ['error'],
51+
52+
// We encourage explicit typing, e.g `field: string = ''`
53+
'@typescript-eslint/no-inferrable-types': 'off'
54+
},
55+
parserOptions: {project: ['**/tsconfig.json']}
56+
},
57+
{
58+
files: ['**/__tests__/**/*.{ts,tsx}'],
59+
rules: {
60+
'@typescript-eslint/no-empty-function': 'off',
61+
'@typescript-eslint/no-non-null-assertion': 'off'
62+
}
63+
}
64+
]
65+
};

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/node_modules
2+
/dist
3+
/examples/**/package-lock.json
4+
/examples/**/node_modules

.npmignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.vscode
2+
node_modules
3+
dist
4+
docs
5+
src
6+
tsconfig.json

.ocularrc.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const {resolve} = require('path');
2+
3+
const config = {
4+
lint: {
5+
paths: ['src', 'test', 'examples']
6+
},
7+
8+
typescript: {
9+
project: 'tsconfig.json'
10+
},
11+
12+
aliases: {
13+
'react-map-gl/test': resolve('./test'),
14+
'react-map-gl': resolve('./src')
15+
},
16+
17+
browserTest: {
18+
server: {wait: 5000}
19+
},
20+
21+
entry: {
22+
test: 'test/node.js',
23+
'test-browser': 'test/browser.js',
24+
size: ['test/size/all.js', 'test/size/map.js']
25+
}
26+
};
27+
28+
module.exports = config;

.prettierignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
dist
3+
.npmignore
4+
CHANGELOG.md

.prettierrc

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"printWidth": 80,
3+
"tabWidth": 2,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": true,
7+
"trailingComma": "none",
8+
"bracketSpacing": false,
9+
"bracketSameLine": true,
10+
"arrowParens": "avoid"
11+
}

LICENSE.md

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 Vis.gl contributors
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
# Google Maps React
2+
3+
[![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/ubilabs/google-maps-react-hooks/tree/main/LICENSE)
4+
5+
A library to integrate the Google Maps JavaScript API into React Applications
6+
using simple components or hooks.
7+
8+
The hooks provide the possibility to access different Google Maps services and libraries, as well as the map instance
9+
itself inside all components that are wrapped inside the `APIProvider`.
10+
The map instance can only be accessed, if a `Map` component is used inside the `APIProvider`.
11+
12+
## Description
13+
14+
This is a Typescript / Javascript library to integrate the Google Maps Javascript API into your React application.
15+
It comes with a collection of React components to create maps, markers and infowindows, and a set of
16+
hooks to use some of the Google Maps
17+
API [Services](https://developers.google.com/maps/documentation/javascript#services)
18+
and [Libraries](https://developers.google.com/maps/documentation/javascript#libraries).
19+
20+
## Installation
21+
22+
```sh
23+
npm install @vis.gl/react-google-maps -D
24+
```
25+
26+
## Map Usage
27+
28+
Import the `APIProvider` and wrap it around all components that should have access to the map instance(s).
29+
All components that are children of the `APIProvider` can use hooks, components and access all map instance(s).
30+
31+
Add a `Map` component inside the `APIProvider` to display a map on the screen. Inside the `Map` component, it is
32+
possible to add components like a `Marker` or `InfoWindow` that can be displayed on the map. Also, all hooks can be used
33+
inside all components.
34+
35+
```tsx
36+
import React from 'react';
37+
import {APIProvider, Map, Marker, InfoWindow} from '@vis.gl/react-google-maps';
38+
39+
function App() {
40+
const position = {lat: 53.54992, lng: 10.00678};
41+
42+
return (
43+
<APIProvider googleMapsAPIKey={'YOUR API KEY HERE'}>
44+
<Map zoom={10} center={position}>
45+
<Marker position={position}>
46+
<InfoWindow>
47+
<p>I am open.</p>
48+
</InfoWindow>
49+
</Marker>
50+
</Map>
51+
</APIProvider>
52+
);
53+
}
54+
55+
export default App;
56+
```
57+
58+
## Usage of the `useGoogleMap` hook
59+
60+
The `APIProvider` is used to load the Google Maps JavaScript API at the top level of the app component and provides a
61+
context that holds all map instances that can be accessed via the `useGoogleMap` hook.
62+
63+
It is possible to use one or multiple `Map` components inside the `APIProvider`. Make sure to pass the id of the map to
64+
the `useGoogleMap` hook when using multiple maps.
65+
66+
### Hook usage with one Map component
67+
68+
The `useGoogleMap()` hook can be used to directly access the `google.maps.Map` instance created by a `<Map>` component
69+
in your application.
70+
71+
```tsx
72+
import React, {useEffect} from 'react';
73+
import {APIProvider, useGoogleMap} from '@vis.gl/react-google-maps';
74+
75+
const MyComponent = () => {
76+
const map = useGoogleMap();
77+
78+
useEffect(() => {
79+
if (!map) return;
80+
81+
// here you can interact with the imperative maps API
82+
}, [map]);
83+
84+
return <></>;
85+
};
86+
87+
const App = () => (
88+
<APIProvider apiKey={'YOUR API KEY HERE'}>
89+
<Map /* ... */></Map>
90+
91+
<MyComponent />
92+
</APIProvider>
93+
);
94+
```
95+
96+
### Hook usage with multiple Map components
97+
98+
When multiple `Map` components are used, an additional prop `id` is required for all map components (internally, the
99+
id `default` is used whenever no map-id is specified, which could lead to problems with multiple maps).
100+
101+
Inside the App component:
102+
103+
```tsx
104+
import React from 'react';
105+
import {APIProvider, Map} from '@vis.gl/react-google-maps';
106+
107+
function App() {
108+
const position = {lat: 53.54992, lng: 10.00678};
109+
110+
return (
111+
<APIProvider apiKey={'YOUR API KEY HERE'}>
112+
<Map id={'map-1'} /* ... */ />
113+
<Map id={'map-2'} /* ... */ />
114+
</APIProvider>
115+
);
116+
}
117+
118+
export default App;
119+
```
120+
121+
Inside another component, accessing the map instances:
122+
123+
```tsx
124+
import React, {useEffect} from 'react';
125+
import {useGoogleMap} from '@vis.gl/react-google-maps-hooks';
126+
127+
const MyComponent = () => {
128+
const mapOne = useGoogleMap('map-1');
129+
const mapTwo = useGoogleMap('map-2');
130+
131+
useEffect(() => {
132+
if (!mapOne || !mapTwo) return;
133+
134+
// interact with the map-instances.
135+
}, [mapOne, mapTwo]);
136+
137+
return <></>;
138+
};
139+
```
140+
141+
## Examples
142+
143+
Explore
144+
our [examples directory on GitHub](https://github.com/ubilabs/internal-google-maps-react-hooks-copy/tree/main/packages/examples)
145+
for full implementation examples.

docs/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
api-reference/web-mercator-viewport.md

docs/README.md

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Introduction
2+
3+
react-google-maps is a collection of [React](https://react.dev/) components and hooks for
4+
the Google Maps Javascript API.
5+
6+
Want to contribute? See our [Developer Guide](./contributing.md)
7+
8+
## Design Philosophy
9+
10+
react-google-maps was first provisioned by the Google Maps Platform team, in order to provide solid integrations between
11+
react and the Google Maps API inspired by the integration between react-map-gl and the map renderers based on
12+
mapbox-gl-js.
13+
14+
The stock Google Maps APIs are [imperative](https://en.wikipedia.org/wiki/Imperative_programming).
15+
That is, you instruct the map to do something, and it will execute the command at its own pace.
16+
17+
This does not scale when we have many components that need to synchronize with each other. We sometimes render two maps
18+
side by side, and when the user interacts with one, update both cameras. We draw React UI outside of the map container,
19+
that moves with the camera. We also render WebGL graphic overlays on top of the map, most notably
20+
with [deck.gl](https://deck.gl). In these use cases, in order for all components to synchronize correctly, they must
21+
have their shared states managed by React. We might store the **source of truth** in a parent component state, or Redux
22+
store, or hooks, and let it propagate down to the map as well as its peers.
23+
24+
Ultimately, in the spirit of the [reactive programming paradigm](https://en.wikipedia.org/wiki/Reactive_programming),
25+
data always flows **down**. As long as the map manages its own state, as mapbox-gl is designed to do, we risk the
26+
components going out of sync.
27+
28+
react-google-maps creates a fully reactive wrapper for mapbox-gl. The [Map](./api-reference/components/map.md) component
29+
can be fully [controlled](https://reactjs.org/docs/forms.html#controlled-components), that is, the map's camera would
30+
never deviate from the props that it's assigned.

0 commit comments

Comments
 (0)