Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve docs and hooks-example for useMap and MapProvider #2118

Merged
merged 7 commits into from
Dec 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions docs/api-reference/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ function App() {
</TabItem>
</Tabs>


## Properties

Aside from the props listed below, the `Map` component supports all parameters of the `Map` class constructor ([Mapbox](https://docs.mapbox.com/mapbox-gl-js/api/map/) | [Maplibre](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/)). Beware that this is not an exhaustive list of all props. Different base map libraries may offer different options and default values. When in doubt, refer to your base map library's documentation.
Expand All @@ -64,6 +63,10 @@ Aside from the props listed below, the `Map` component supports all parameters o

Map container id.

Required when [`MapProvider`](./map-provider.md)s are used. Used to reference the map with [`useMap`](./use-map.md).

Make sure to pick a name that has no conflict with other imports (there are no checks or errors in this case).

#### `style`: CSSProperties {#style}

Default: `{position: 'relative', width: '100%', height: '100%'}`
Expand Down Expand Up @@ -116,7 +119,6 @@ Enable diffing when `mapStyle` changes. If `false`, force a 'full' update, remov
Terrain property of the style. Must conform to the [Terrain Style Specification](https://docs.mapbox.com/mapbox-gl-js/style-spec/terrain/).
If `undefined` is provided, removes terrain from the map.


### Camera options

#### `initialViewState`: object {#initialviewstate}
Expand Down Expand Up @@ -461,13 +463,14 @@ Called when one of the map's sources loads or changes, including if a tile belon

### Other options

The following props, along with any options of the `Map` class ([Mapbox](https://docs.mapbox.com/mapbox-gl-js/api/map/) | [Maplibre](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/)) not listed above, can be specified to construct the underlying `Map` instance.
The following props, along with any options of the `Map` class ([Mapbox](https://docs.mapbox.com/mapbox-gl-js/api/map/) | [Maplibre](https://maplibre.org/maplibre-gl-js/docs/API/type-aliases/MapOptions/)) not listed above, can be specified to construct the underlying `Map` instance.

Note: props in this section are not reactive. They are only used once when the Map instance is constructed.

#### `mapLib`: any {#maplib}

Default:

- `import('mapbox-gl')` if imported from `react-map-gl`
- `import('maplibre-gl')` if imported from `react-map-gl/maplibre`

Expand Down Expand Up @@ -499,7 +502,7 @@ function App() {
Or to load a pre-bundled version of the library:

```html title="index.html"
<script src="https://api.mapbox.com/mapbox-gl-js/v2.4.0/mapbox-gl.js" ></script>
<script src="https://api.mapbox.com/mapbox-gl-js/v2.4.0/mapbox-gl.js"></script>
```

```tsx title="app.tsx"
Expand All @@ -511,7 +514,6 @@ function App() {
}
```


#### `mapboxAccessToken`: string {#mapboxaccesstoken}

Token used to access the Mapbox data service. See [about map tokens](../get-started/mapbox-tokens.md).
Expand Down Expand Up @@ -561,8 +563,6 @@ The number of web workers instantiated on a page with mapbox-gl maps.

Provides an interface for loading mapbox-gl's WebWorker bundle from a self-hosted URL. This is useful if your site needs to operate in a strict CSP (Content Security Policy) environment wherein you are not allowed to load JavaScript code from a Blob URL, which is default behavior.



## Methods

Imperative methods are accessible via a [React ref](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) or the [useMap](./use-map.md) hook.
Expand Down Expand Up @@ -592,7 +592,6 @@ function App() {
</TabItem>
<TabItem value="maplibre" label="Maplibre">


```tsx
import * as React from 'react';
import {useRef, useCallback} from 'react';
Expand All @@ -612,7 +611,6 @@ function App() {
}
```


</TabItem>
</Tabs>

Expand All @@ -624,8 +622,6 @@ You can still access the hidden members via `getMap()`:

Returns the native `Map` ([Mapbox](https://docs.mapbox.com/mapbox-gl-js/api/map/) | [Maplibre](https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/)) instance associated with this component.



## Source

[map.tsx](https://github.com/visgl/react-map-gl/tree/7.0-release/src/components/map.tsx)
10 changes: 7 additions & 3 deletions docs/api-reference/use-map.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# useMap

The `useMap` hook allows a custom component to reference the [Map](./map.md) that contains it.
The `useMap` hook allows a component to reference the [Map](./map.md) that contains it.

When used with [MapProvider](./map-provider.md), this hook can also reference maps that are rendered outside of the current map component's direct render tree.

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
Expand Down Expand Up @@ -60,7 +62,7 @@ function NavigateButton() {
</Tabs>


When used with the [MapProvider](./map-provider.md), this hook can also reference maps that are rendered outside of the current component's direct render tree.
When used with the [MapProvider](./map-provider.md), this hook can also reference maps that are rendered outside of the current component's direct render tree as long as both trees are part of the current `<MapProvider>`.


<Tabs groupId="map-library">
Expand All @@ -70,6 +72,8 @@ When used with the [MapProvider](./map-provider.md), this hook can also referenc
import {MapProvider, Map, useMap} from 'react-map-gl';

function Root() {
// Note: `useMap` will not work in <Root>, only children of <MapProvider> can use `useMap`

return (
<MapProvider>
<Map id="myMapA" ... />
Expand Down Expand Up @@ -131,7 +135,7 @@ See a full example [here](https://github.com/visgl/react-map-gl/tree/7.0-release

The hook returns an object that contains all mounted maps under the closest `MapProvider`. The keys are each map's [id](./map.md#id) and the values are the [MapRef](./types.md#mapref).

If the hook is used inside a decendent of a `Map` component, the returned object also contains a `current` field that references the containing map.
If the hook is used inside a decendent of a `Map` component, the returned object additionally contains a `current` field that references the containing map.

## Source

Expand Down
2 changes: 2 additions & 0 deletions examples/get-started/hook/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import Map from './map';
import Controls from './controls';

function Root() {
// Note: `useMap` will not work here, only child components of `MapProvider` or `Map` can use `useMap`

return (
<MapProvider>
<Controls />
Expand Down
30 changes: 26 additions & 4 deletions examples/get-started/hook/controls.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,34 @@ import {useCallback, useState, useEffect} from 'react';
import {useMap} from 'react-map-gl';

export default function Controls() {
const {mymap} = useMap();
/**
* ## This is how `useMap` works:
* ```
* const maps = useMap();
* console.log('Controls useMap()', maps);
* ```
* ### First render:
* ```
* {
* "current": undefined
* }
* ```
* ### Second render:
* ```
* {
* "current": undefined,
* "mymap": {...} // See https://visgl.github.io/react-map-gl/docs/api-reference/types#mapref
* }
* ```
*/

const {mymap} = useMap(); // `mymap` is the id in <Map id="mymap" />

const [inputValue, setInputValue] = useState('');
const [hasError, setError] = useState(false);

useEffect(() => {
if (!mymap) {
return undefined;
}
if (!mymap) return undefined;

const onMove = () => {
const {lng, lat} = mymap.getCenter();
Expand All @@ -31,6 +51,8 @@ export default function Controls() {
}, []);

const onSubmit = useCallback(() => {
if (!mymap) return;

const [lng, lat] = inputValue.split(',').map(Number);
if (Math.abs(lng) <= 180 && Math.abs(lat) <= 85) {
mymap.easeTo({
Expand Down
24 changes: 24 additions & 0 deletions examples/get-started/hook/controls2.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// import {useMap} from 'react-map-gl';

export default function Controls2() {
/**
* ## This is how `useMap` works:
* This component does nothing. It's purpose is to demo `useMap`.
* When a component is a child of `<Map>`, `useMap` has a `current` field that references the containing map.
* See https://visgl.github.io/react-map-gl/docs/api-reference/use-map
* See https://visgl.github.io/react-map-gl/docs/api-reference/types#mapref
* ```
* const maps = useMap();
* console.log('Controls2 useMap()', maps);
* ```
* ### First render:
* ```
* {
* "current": {...}, // this is the same as `mymap`
* "mymap": {...}
* }
* ```
*/

return null;
}
27 changes: 25 additions & 2 deletions examples/get-started/hook/map.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,35 @@
import * as React from 'react';
import Map from 'react-map-gl';
// import {useMap} from 'react-map-gl';

import 'mapbox-gl/dist/mapbox-gl.css';
import Controls2 from './controls2';

const MAPBOX_TOKEN = ''; // Set your mapbox token here

export default function MapView() {
/**
* ## This is how `useMap` works:
* ```
* const maps = useMap();
* console.log('MapView useMap()', maps);
* ```
* ### First render:
* ```
* {
* "current": undefined
* }
* Second render:
* {
* "current": undefined,
* "mymap": {...} // See https://visgl.github.io/react-map-gl/docs/api-reference/types#mapref
* }
* ```
*/

return (
<Map
id="mymap"
id="mymap" // relevant for `useMap`, see control.js, controls2.js
initialViewState={{
longitude: -122.4,
latitude: 37.8,
Expand All @@ -17,6 +38,8 @@ export default function MapView() {
style={{width: 800, height: 600}}
mapStyle="mapbox://styles/mapbox/streets-v9"
mapboxAccessToken={MAPBOX_TOKEN}
/>
>
<Controls2 />
</Map>
);
}
Loading