Skip to content

Commit 198af4e

Browse files
docs(react) React widgets and useWidget hook documentation (#9309)
* docs(react) React widgets and useWidget hook documentation * Should use portal to render react into non-react dom element https://react.dev/reference/react-dom/createPortal#rendering-react-components-into-non-react-dom-nodes * add(react) overview docs for react module --------- Co-authored-by: Ib Green <7025232+ibgreen@users.noreply.github.com>
1 parent c1cacac commit 198af4e

File tree

6 files changed

+171
-16
lines changed

6 files changed

+171
-16
lines changed

docs/api-reference/react/deckgl.md

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,23 @@ const App = (data) => (
2323
);
2424
```
2525

26-
Like any React component, `DeckGL` can accept child components. Child components are often maps (e.g. the `StaticMap` component from react-map-gl), but can be any React components.
26+
Like any React component, `DeckGL` can accept child components. Typical React components include:
27+
28+
- Base maps such as the [`Map`](https://visgl.github.io/react-map-gl/docs/api-reference/map) component from `react-map-gl`, which can synchronize with deck.gl's view state.
29+
- [Widgets](./overview.md#using-react-wrapped-widgets), which can display and control deck.gl state.
2730

2831
```js
2932
import DeckGL from '@deck.gl/react';
30-
import {StaticMap} from 'react-map-gl';
33+
import {Map} from 'react-map-gl/maplibre';
34+
import 'maplibre-gl/dist/maplibre-gl.css';
3135

3236
const App = (data) => (
3337
<DeckGL
3438
initialViewState={{longitude: -122.45, latitude: 37.78, zoom: 12}}
3539
controller={true}
3640
layers={[new ScatterplotLayer({data})]}
3741
>
38-
<StaticMap
39-
mapStyle="mapbox://styles/mapbox/dark-v9"
40-
mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN} />
42+
<Map mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json" />
4143
</DeckGL>
4244
);
4345

@@ -55,7 +57,10 @@ A [Context.Provider](https://reactjs.org/docs/context.html#contextprovider) comp
5557

5658
- `viewport` ([Viewport](../core/viewport.md)) - the current viewport
5759
- `container` (DOMElement) - the DOM element containing the deck canvas
58-
- `eventManager` ([EventManager](https://uber-web.github.io/mjolnir.js/docs/api-reference/event-manager))
60+
- `eventManager` ([EventManager](https://visgl.github.io/mjolnir.js/docs/api-reference/event-manager))
61+
- `onViewStateChange` ([onViewStateChange](../core/deck.md#onviewstatechange)) - the view state change handler
62+
- `deck` ([Deck](../core/deck.md)) - the current deck instance, if present
63+
- `widgets` ([Widget](../core/widget.md)[]) - the current jsx widgets, if any
5964

6065
```jsx
6166
/// Example using react-map-gl v6 controls with deck.gl
@@ -81,7 +86,7 @@ The following semantics of the standard React `children` property are considered
8186
It is possible to use JSX syntax to create deck.gl layers as React children of the `DeckGL` React components, instead of providing them as ES6 class instances to the `layers` prop.
8287

8388
```jsx
84-
<DeckGL {...viewState}>
89+
<DeckGL initialViewState={...viewState}>
8590
<LineLayer id="line-layer" data={data} />
8691
<DeckGL />
8792
```
@@ -96,7 +101,7 @@ It is possible to use JSX syntax to create deck.gl views as React children of th
96101
```jsx
97102
<DeckGL initialViewState={...viewState} layers={layers} >
98103
<MapView id="map" width="50%" controller={true} >
99-
<StaticMap mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN} />
104+
<Map mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json" />
100105
</MapView>
101106
<FirstPersonView width="50%" x="50%" fovy={50} />
102107
<DeckGL />
@@ -112,11 +117,22 @@ If a certain view id is used in both JSX views and the `views` prop, the view in
112117

113118
<DeckGL initialViewState={...viewState} layers={layers} views={views} >
114119
<View id="map">
115-
<StaticMap mapboxApiAccessToken={MAPBOX_ACCESS_TOKEN} />
120+
<Map mapStyle="https://basemaps.cartocdn.com/gl/positron-gl-style/style.json" />
116121
</View>
117122
<DeckGL />
118123
```
119124

125+
#### JSX Widgets
126+
127+
It is possible to use JSX syntax to create deck.gl widgets as React children of the `DeckGL` React components, instead of providing them as ES6 class instances to the `widgets` props.
128+
129+
```jsx
130+
<DeckGL initialViewState={...viewState}>
131+
<ZoomWidget id="zoom-widget" placement="top-right" />
132+
<DeckGL />
133+
```
134+
135+
Learn how to use widgets in JSX by reading [Using React-wrapped widgets](./overview.md#using-react-wrapped-widgets).
120136

121137
#### Position Children in Views
122138

docs/api-reference/react/overview.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# @deck.gl/react
2+
3+
This module integrates deck.gl with React. First-time deck.gl developers may find it helpful to read [Using deck.gl with React](../../get-started/using-with-react.md) before getting started.
4+
5+
This module contains the following:
6+
7+
### React Components
8+
9+
- [\<DeckGL/>](./deckgl.md)
10+
- Widgets in the [`@deck.gl/widgets`](../widgets/overview.md) module are re-exported as React components in this module.
11+
- e.g. `import { ZoomWidget } from '@deck.gl/react';`
12+
13+
### React Hooks
14+
15+
- [useWidget](./use-widget.md)
16+
17+
## Installation
18+
19+
### Install from NPM
20+
21+
```bash
22+
npm install deck.gl
23+
# or
24+
npm install @deck.gl/core @deck.gl/react
25+
```
26+
27+
```jsx
28+
import DeckGL from '@deck.gl/react';
29+
30+
<DeckGL initialViewState={{longitude: -122.45, latitude: 37.78, zoom: 12}}/>
31+
```
32+
33+
## Using React-wrapped Widgets
34+
35+
Here's a typical example of how to switch from using pure-js widgets in the [`@deck.gl/widgets`](../widgets/overview.md) module to their React-equivalent:
36+
37+
```diff
38+
-import { ZoomWidget } from '@deck.gl/widgets';
39+
+import { ZoomWidget } from '@deck.gl/react';
40+
41+
-<DeckGL widgets={[new ZoomWidget({})]}>
42+
+<DeckGL>
43+
+ <ZoomWidget/>
44+
</DeckGL>
45+
```
46+
47+
React props are passed to the widget:
48+
49+
```diff
50+
-new ZoomWidget({ id: 'zoom', placement: 'top-right' })
51+
+<ZoomWidget id='zoom' placement='top-right'/>
52+
```
53+
54+
### Authoring Custom Widgets with React
55+
56+
Learn how author your own custom widgets in React with the `useWidget` hook by reading the [Custom Widget Developer Guide](../../developer-guide/custom-widgets).
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# useWidget
2+
3+
The `useWidget` hook is used to create React wrappers for normal (non-React) deck.gl widgets, or to create custom widgets with UI rendered by React.
4+
5+
## Usage
6+
7+
```tsx
8+
// React wrapper usage
9+
import DeckGL, {useWidget} from '@deck.gl/react';
10+
import {CompassWidget as UniversalCompassWidget, type CompassWidgetProps} from '@deck.gl/react';
11+
12+
const CompassWidget = (props: CompassWidgetProps) => {
13+
const widget = useWidget(UniversalCompassWidget, props);
14+
return null;
15+
}
16+
17+
<DeckGL>
18+
<CompassWidget/>
19+
</DeckGL>
20+
```
21+
22+
For a custom widget, React can be used to implement the UI itself. A widget class is used to hook into deck.gl apis, and a React [`portal`](https://react.dev/reference/react-dom/createPortal) is utilized to render the widget UI along-side other widgets.
23+
24+
```tsx
25+
import React, {useMemo} from 'react';
26+
import type {Widget} from '@deck.gl/core';
27+
import DeckGL, {useWidget} from '@deck.gl/react';
28+
import {createPortal} from 'react-dom';
29+
30+
class MyWidget implements Widget {
31+
constructor(props) {
32+
this.props = { ...props };
33+
}
34+
35+
onAdd() {
36+
return this.props.element; // HTMLDivElement
37+
}
38+
}
39+
40+
const MyReactWidget = (props) => {
41+
const element = useMemo(() => document.createElement('div'), []);
42+
const widget = useWidget(MyWidget, {...props, element});
43+
return createPortal(
44+
<div>Hello World</div>,
45+
element
46+
);
47+
};
48+
49+
<DeckGL>
50+
<MyReactWidget/>
51+
</DeckGL>
52+
```
53+
54+
See a full example [here](../../developer-guide/custom-widgets/react-widgets.md).
55+
56+
## Signature
57+
58+
```tsx
59+
useWidget<T extends Widget, PropsT extends {}>(
60+
WidgetClass: {new (props: PropsT): T},
61+
props: PropsT
62+
): T
63+
```
64+
65+
The hook creates an [`Widget`](../core/widget.md) instance, adds it to deck.gl, and removes it upon unmount.
66+
67+
Parameters:
68+
69+
- `WidgetClass`: `{new (props: PropsT): T}` - called to create an instance of the control.
70+
- `props`: `PropsT` - props passed into the widget constructor on creation and `widget.setProps` on render.
71+
72+
Returns:
73+
74+
[`Widget`](../core/widget.md) - the widget instance of `WidgetClass`.
75+
76+
## Source
77+
78+
[modules/react/src/utils/use-widget.ts](https://github.com/visgl/deck.gl/blob/master/modules/react/src/utils/use-widget.ts)

docs/get-started/using-with-react.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,16 @@ The vis.gl community maintains two React libraries that seamlessly work with dec
4949
- `react-map-gl` - a React wrapper for [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/guides) and [MapLibre GL JS](https://maplibre.org/maplibre-gl-js/docs/). Several integration options are discussed in [using with Mapbox](../developer-guide/base-maps/using-with-mapbox.md).
5050
- `@vis.gl/react-google-maps` - a React wrapper for [Google Maps JavaScript API](https://developers.google.com/maps/documentation/javascript). See [using with Google Maps](../developer-guide/base-maps/using-with-google-maps.md).
5151

52-
## Using JSX Layers and Views
52+
## Using JSX Layers, Views, and Widgets
5353

54-
It is possible to use JSX syntax to create deck.gl layers and views as React children of the `DeckGL` React components, instead of providing them as ES6 class instances to the `layers` prop. There are no performance advantages to this syntax but it can allow for a more consistent, React-like coding style.
54+
It is possible to use JSX syntax to create deck.gl layers, views, and widgets as React children of the `DeckGL` React components, instead of providing them as ES6 class instances to the `layers`, `views`, or `widgets` prop, respectively. There are no performance advantages to this syntax but it can allow for a more consistent, React-like coding style.
5555

5656
```jsx
5757
import React from 'react';
5858
import DeckGL from '@deck.gl/react';
5959
import {MapViewState} from '@deck.gl/core';
6060
import {LineLayer} from '@deck.gl/layers';
61+
import {ZoomWidget} from '@deck.gl/react';
6162
import {Map} from 'react-map-gl';
6263

6364
const INITIAL_VIEW_STATE: MapViewState = {
@@ -83,6 +84,8 @@ function App() {
8384
</MapView>
8485

8586
<FirstPersonView width="50%" x="50%" fovy={50} />
87+
88+
<ZoomWidget/>
8689
</DeckGL>
8790
);
8891
}

docs/table-of-contents.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,9 @@
293293
"type": "category",
294294
"label": "@deck.gl/react",
295295
"items": [
296-
"api-reference/react/deckgl"
296+
"api-reference/react/overview",
297+
"api-reference/react/deckgl",
298+
"api-reference/react/use-widget"
297299
]
298300
},
299301
{

docs/whats-new.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ Release date: TBD (targeting December 2024)
3939
### React Widgets
4040

4141
deck.gl v9.0 added support for widgets, with v9.1 users can now create React components with the same level of deep deck.gl integration.
42-
- All the official deck.gl widgets can now be easily wrapped into React components with the new `useWidget` hook.
43-
- Pre-wrapped React components for existing widget are available from the `@deck.gl/react` package.
44-
- To try it out, check out our new [getting started example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/react/widgets) for using widgets in React.
42+
- All the official deck.gl widgets can now be easily wrapped into React components with the new [`useWidget`](./api-reference/react/use-widget.md) hook.
43+
- Pre-wrapped React components for existing widget are available from the [`@deck.gl/react`](./api-reference/react/overview.md) package.
44+
- To try it out, check out our [React getting started example](https://github.com/visgl/deck.gl/tree/master/examples/get-started/react/basic) for using widgets in React.
4545

4646
### Widgets Developer Guide
4747

48-
deck.gl v9.1 provides the ability to for applications to write React component that integrate with deck.gl using the widget interface. Learn how to write such React components with our new [Custom Widgets Developer Guide](./docs/developer-guide/custom-widgets).
48+
deck.gl v9.1 provides the ability to for applications to write React component that integrate with deck.gl using the widget interface. Learn how to write such React components with our new [Custom Widgets Developer Guide](./developer-guide/custom-widgets).
4949

5050
### Aggregation layers upgrade
5151

0 commit comments

Comments
 (0)