• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

visgl / deck.gl / 12799532385

16 Jan 2025 12:27AM UTC coverage: 91.636% (-0.04%) from 91.676%
12799532385

push

github

web-flow
feat(react) Support for JSX Widgets in React (#9278)

* Add DeckGLContext

  * chore(react) all children are provided a DeckContext by default

* Add useWidget hook

* chore(main) export react components for each widget

* React widgets should warn when pure-js widgets are used

* Widgets should be removed when JSX unmounts

* chore(react) widgets should be reset when omitted in react

* chore(react) widget prop warning shouldn't warn for empty array

* chore(react) use consistent naming between react and purejs widgets

* Should use @deck.gl/react for all widget imports

---------

Signed-off-by: Chris Gervang <chris@gervang.com>

6689 of 7324 branches covered (91.33%)

Branch coverage included in aggregate %.

44 of 82 new or added lines in 5 files covered. (53.66%)

54087 of 58999 relevant lines covered (91.67%)

14877.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

15.0
/modules/react/src/utils/use-widget.ts
1
import {useContext, useMemo, useEffect} from 'react';
1✔
2
import {DeckGlContext} from './deckgl-context';
1✔
3
import {log, type Widget, _deepEqual as deepEqual} from '@deck.gl/core';
1✔
4

1✔
5
export function useWidget<T extends Widget, PropsT extends {}>(
1✔
NEW
6
  WidgetClass: {new (props: PropsT): T},
×
NEW
7
  props: PropsT
×
NEW
8
): T {
×
NEW
9
  const context = useContext(DeckGlContext);
×
NEW
10
  const {widgets, deck} = context;
×
NEW
11
  useEffect(() => {
×
NEW
12
    // warn if the user supplied a pure-js widget, since it will be ignored
×
NEW
13
    // NOTE: This effect runs once per widget. Context widgets and deck widget props are synced after first effect runs.
×
NEW
14
    const internalWidgets = deck?.props.widgets;
×
NEW
15
    if (widgets?.length && internalWidgets?.length && !deepEqual(internalWidgets, widgets, 1)) {
×
NEW
16
      log.warn('"widgets" prop will be ignored because React widgets are in use.')();
×
NEW
17
    }
×
NEW
18

×
NEW
19
    return () => {
×
NEW
20
      // Remove widget from context when it is unmounted
×
NEW
21
      const index = widgets?.indexOf(widget);
×
NEW
22
      if (index && index !== -1) {
×
NEW
23
        widgets?.splice(index, 1);
×
NEW
24
        deck?.setProps({widgets});
×
NEW
25
      }
×
NEW
26
    };
×
NEW
27
  }, []);
×
NEW
28
  const widget = useMemo(() => new WidgetClass(props), [WidgetClass]);
×
NEW
29

×
NEW
30
  // Hook rebuilds widgets on every render: [] then [FirstWidget] then [FirstWidget, SecondWidget]
×
NEW
31
  widgets?.push(widget);
×
NEW
32
  widget.setProps(props);
×
NEW
33

×
NEW
34
  useEffect(() => {
×
NEW
35
    deck?.setProps({widgets});
×
NEW
36
  }, [widgets]);
×
NEW
37

×
NEW
38
  return widget;
×
NEW
39
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc