-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
docs(react) React widgets and useWidget
hook documentation
#9309
Changes from all commits
a97034d
0ab5523
027397d
baaee31
15f82d3
1ef41db
6f69171
4b34f32
4cad33f
a2d0277
d4ba0ec
5a099f6
149c736
be81d52
95d7a18
edc1129
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
# @deck.gl/react | ||
|
||
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. | ||
|
||
This module contains the following: | ||
|
||
### React Components | ||
|
||
- [\<DeckGL/>](./deckgl.md) | ||
- Widgets in the [`@deck.gl/widgets`](../widgets/overview.md) module are re-exported as React components in this module. | ||
- e.g. `import { ZoomWidget } from '@deck.gl/react';` | ||
|
||
### React Hooks | ||
|
||
- [useWidget](./use-widget.md) | ||
|
||
## Installation | ||
|
||
### Install from NPM | ||
|
||
```bash | ||
npm install deck.gl | ||
# or | ||
npm install @deck.gl/core @deck.gl/react | ||
``` | ||
|
||
```jsx | ||
import DeckGL from '@deck.gl/react'; | ||
|
||
<DeckGL initialViewState={{longitude: -122.45, latitude: 37.78, zoom: 12}}/> | ||
``` | ||
|
||
## Using React-wrapped Widgets | ||
|
||
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: | ||
|
||
```diff | ||
-import { ZoomWidget } from '@deck.gl/widgets'; | ||
+import { ZoomWidget } from '@deck.gl/react'; | ||
|
||
-<DeckGL widgets={[new ZoomWidget({})]}> | ||
+<DeckGL> | ||
+ <ZoomWidget/> | ||
</DeckGL> | ||
``` | ||
|
||
React props are passed to the widget: | ||
|
||
```diff | ||
-new ZoomWidget({ id: 'zoom', placement: 'top-right' }) | ||
+<ZoomWidget id='zoom' placement='top-right'/> | ||
``` | ||
|
||
### Authoring Custom Widgets with React | ||
|
||
Learn how author your own custom widgets in React with the `useWidget` hook by reading the [Custom Widget Developer Guide](../../developer-guide/custom-widgets). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# useWidget | ||
|
||
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. | ||
|
||
## Usage | ||
|
||
```tsx | ||
// React wrapper usage | ||
import DeckGL, {useWidget} from '@deck.gl/react'; | ||
import {CompassWidget as UniversalCompassWidget, type CompassWidgetProps} from '@deck.gl/react'; | ||
|
||
const CompassWidget = (props: CompassWidgetProps) => { | ||
const widget = useWidget(UniversalCompassWidget, props); | ||
return null; | ||
} | ||
|
||
<DeckGL> | ||
<CompassWidget/> | ||
</DeckGL> | ||
``` | ||
|
||
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. | ||
|
||
```tsx | ||
import React, {useMemo} from 'react'; | ||
import type {Widget} from '@deck.gl/core'; | ||
import DeckGL, {useWidget} from '@deck.gl/react'; | ||
import {createPortal} from 'react-dom'; | ||
|
||
class MyWidget implements Widget { | ||
constructor(props) { | ||
this.props = { ...props }; | ||
} | ||
|
||
onAdd() { | ||
return this.props.element; // HTMLDivElement | ||
} | ||
} | ||
|
||
const MyReactWidget = (props) => { | ||
const element = useMemo(() => document.createElement('div'), []); | ||
const widget = useWidget(MyWidget, {...props, element}); | ||
return createPortal( | ||
<div>Hello World</div>, | ||
element | ||
); | ||
}; | ||
|
||
<DeckGL> | ||
<MyReactWidget/> | ||
</DeckGL> | ||
``` | ||
|
||
See a full example [here](../../developer-guide/custom-widgets/react-widgets.md). | ||
|
||
## Signature | ||
|
||
```tsx | ||
useWidget<T extends Widget, PropsT extends {}>( | ||
WidgetClass: {new (props: PropsT): T}, | ||
props: PropsT | ||
): T | ||
``` | ||
|
||
The hook creates an [`Widget`](../core/widget.md) instance, adds it to deck.gl, and removes it upon unmount. | ||
|
||
Parameters: | ||
|
||
- `WidgetClass`: `{new (props: PropsT): T}` - called to create an instance of the control. | ||
- `props`: `PropsT` - props passed into the widget constructor on creation and `widget.setProps` on render. | ||
|
||
Returns: | ||
|
||
[`Widget`](../core/widget.md) - the widget instance of `WidgetClass`. | ||
|
||
## Source | ||
|
||
[modules/react/src/utils/use-widget.ts](https://github.com/visgl/deck.gl/blob/master/modules/react/src/utils/use-widget.ts) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -49,15 +49,16 @@ The vis.gl community maintains two React libraries that seamlessly work with dec | |
- `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). | ||
- `@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). | ||
|
||
## Using JSX Layers and Views | ||
## Using JSX Layers, Views, and Widgets | ||
|
||
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. | ||
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. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it is worth mentioning that the basic JSX support is very limited and link to new sections like React Widgets pages. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is done below already with:
The relevant section for JSX is under "## Children" |
||
|
||
```jsx | ||
import React from 'react'; | ||
import DeckGL from '@deck.gl/react'; | ||
import {MapViewState} from '@deck.gl/core'; | ||
import {LineLayer} from '@deck.gl/layers'; | ||
import {ZoomWidget} from '@deck.gl/react'; | ||
import {Map} from 'react-map-gl'; | ||
|
||
const INITIAL_VIEW_STATE: MapViewState = { | ||
|
@@ -83,6 +84,8 @@ function App() { | |
</MapView> | ||
|
||
<FirstPersonView width="50%" x="50%" fovy={50} /> | ||
|
||
<ZoomWidget/> | ||
</DeckGL> | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be good to do an audit for this and use maplibre since it doesn't need a token.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea - Add a bullet to our v9.1 tracker task?