Skip to content

Commit a1300ab

Browse files
authored
chore(widgets): Join Widget and WidgetImpl, clean up widgets (#9576)
1 parent 00465d0 commit a1300ab

File tree

36 files changed

+665
-909
lines changed

36 files changed

+665
-909
lines changed

docs/api-reference/core/widget.md

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,15 @@ A widget is a UI component that can interact with deck.gl's cameras and layers.
99

1010
You may find many ready-to-use widgets in the `@deck.gl/widgets` module.
1111

12-
A widget is expected to implement the `Widget` interface. Here is a custom widget that shows a spinner while layers are loading:
12+
The `Widget` class is not used directly by an app. It is a base class used to define new widgets.
13+
14+
15+
A widget should inherit the `Widget` class. Here is a custom widget that shows a spinner while layers are loading:
1316

1417
```ts
1518
import {Deck, Widget} from '@deck.gl/core';
1619

17-
class LoadingIndicator implements Widget {
20+
class LoadingIndicator extends Widget {
1821
element?: HTMLDivElement;
1922
size: number;
2023

@@ -24,18 +27,15 @@ class LoadingIndicator implements Widget {
2427
this.size = options.size;
2528
}
2629

27-
onAdd() {
28-
const el = document.createElement('div');
30+
onRenderHTML(el: HTMLElement) {
2931
el.className = 'spinner';
3032
el.style.width = `${this.size}px`;
3133
// TODO - create animation for .spinner in the CSS stylesheet
32-
this.element = el;
33-
return el;
3434
}
3535

3636
onRedraw({layers}) {
3737
const isVisible = layers.some(layer => !layer.isLoaded);
38-
this.element.style.display = isVisible ? 'block' : 'none';
38+
this.rootElement.style.display = isVisible ? 'block' : 'none';
3939
}
4040
}
4141

@@ -80,6 +80,25 @@ Widget positioning within the view. One of:
8080

8181
### Methods
8282

83+
#### `setProps` {#setprops}
84+
85+
Optional. Called to update widget options.
86+
87+
#### `updateHTML` {#updatehtml}
88+
89+
Updates the widget. Normally called automatically.
90+
91+
92+
### Lifecycle Methods
93+
94+
The following methods are available when implementing a new widget.
95+
96+
#### `constructor`
97+
98+
Supply the props and default props to the base class.
99+
100+
#### `onRenderHTML`
101+
83102
#### `onAdd` {#onadd}
84103

85104
Required. Called when the widget is added to a Deck instance.
@@ -96,10 +115,6 @@ Returns an optional UI element that should be appended to the Deck container.
96115

97116
Optional. Called when the widget is removed.
98117

99-
#### `setProps` {#setprops}
100-
101-
Optional. Called to update widget options.
102-
103118
#### `onViewportChange` {#onviewportchange}
104119

105120
Op†ional. Called when the containing view is changed. If `viewId: null`, will be called if any viewport changes.

examples/get-started/pure-js/widgets/app.js

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@ import {
99
ZoomWidget,
1010
FullscreenWidget,
1111
DarkGlassTheme,
12-
LightGlassTheme,
13-
TimelineWidget
12+
LightGlassTheme
1413
} from '@deck.gl/widgets';
1514
import '@deck.gl/widgets/stylesheet.css';
1615

@@ -78,15 +77,6 @@ new Deck({
7877
widgets: [
7978
new ZoomWidget({style: widgetTheme}),
8079
new CompassWidget({style: widgetTheme}),
81-
new FullscreenWidget({style: widgetTheme}),
82-
new TimelineWidget({
83-
style: widgetTheme,
84-
domain: [0, 24],
85-
step: 1,
86-
value: 0,
87-
playInterval: 1000,
88-
// eslint-disable-next-line no-console, no-undef
89-
onTimeChange: time => console.log('Time:', time)
90-
})
80+
new FullscreenWidget({style: widgetTheme})
9181
]
9282
});

modules/aggregation-layers/src/screen-grid-layer/screen-grid-cell-layer.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import {Texture} from '@luma.gl/core';
66
import {Model, Geometry} from '@luma.gl/engine';
7-
import {Layer, picking, UpdateParameters, DefaultProps, Color} from '@deck.gl/core';
7+
import {Layer, picking, UpdateParameters, Color} from '@deck.gl/core';
88
import {createColorRangeTexture, updateColorRangeTexture} from '../common/utils/color-utils';
99
import vs from './screen-grid-layer-vertex.glsl';
1010
import fs from './screen-grid-layer-fragment.glsl';

modules/carto/src/layers/schema/spatialjson-utils.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {bigIntToHex} from 'quadbin';
66
import {BinaryPointFeature} from '@loaders.gl/schema';
77

88
export type IndexScheme = 'h3' | 'quadbin';
9-
type TypedArray = Float32Array | Float64Array;
109

1110
export type Indices = {value: BigUint64Array};
1211
export type NumericProps = BinaryPointFeature['numericProps'];

modules/carto/src/layers/vector-tile-layer.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// Copyright (c) vis.gl contributors
44

55
import {registerLoaders} from '@loaders.gl/core';
6-
import {BinaryFeatureCollection, BinaryPointFeature} from '@loaders.gl/schema';
6+
import {BinaryPointFeature} from '@loaders.gl/schema';
77
import CartoPropertiesTileLoader from './schema/carto-properties-tile-loader';
88
import CartoVectorTileLoader from './schema/carto-vector-tile-loader';
99
registerLoaders([CartoPropertiesTileLoader, CartoVectorTileLoader]);
@@ -13,7 +13,6 @@ import {ClipExtension, CollisionFilterExtension} from '@deck.gl/extensions';
1313
import {
1414
MVTLayer,
1515
MVTLayerProps,
16-
TileLayer,
1716
_getURLFromTemplate,
1817
_Tile2DHeader,
1918
_TileLoadProps as TileLoadProps,

modules/carto/src/utils.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,7 @@
22
// SPDX-License-Identifier: MIT
33
// Copyright (c) vis.gl contributors
44

5-
import {
6-
BinaryAttribute,
7-
BinaryFeature,
8-
BinaryFeatureCollection,
9-
BinaryPointFeature
10-
} from '@loaders.gl/schema';
5+
import {BinaryFeatureCollection, BinaryPointFeature} from '@loaders.gl/schema';
116
import {log} from '@deck.gl/core';
127
import type {Properties, NumericProps} from './layers/schema/spatialjson-utils';
138

modules/core/src/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ export type {Effect, EffectContext, PreRenderOptions, PostRenderOptions} from '.
129129
export type {PickingUniforms, ProjectProps, ProjectUniforms} from './shaderlib/index';
130130
export type {DefaultProps} from './lifecycle/prop-types';
131131
export type {LayersPassRenderOptions} from './passes/layers-pass';
132-
export type {Widget} from './lib/widget';
132+
export {Widget} from './lib/widget';
133+
export type {WidgetProps} from './lib/widget';
133134
export type {WidgetPlacement} from './lib/widget-manager';
134135
export type {LightingEffectProps} from './effects/lighting/lighting-effect';
135136
export type {AmbientLightOptions} from './effects/lighting/ambient-light';

modules/core/src/lib/deck.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import DeckRenderer from './deck-renderer';
1010
import DeckPicker from './deck-picker';
1111
import {Widget} from './widget';
1212
import {WidgetManager} from './widget-manager';
13-
import Tooltip from './tooltip';
13+
import {TooltipWidget} from './tooltip-widget';
1414
import log from '../utils/log';
1515
import {deepEqual} from '../utils/deep-equal';
1616
import typedArrayManager from '../utils/typed-array-manager';
@@ -41,7 +41,7 @@ import type {ViewStateChangeParameters, InteractionState} from '../controllers/c
4141
import type {PickingInfo} from './picking/pick-info';
4242
import type {PickByPointOptions, PickByRectOptions} from './deck-picker';
4343
import type {LayersList} from './layer-manager';
44-
import type {TooltipContent} from './tooltip';
44+
import type {TooltipContent} from './tooltip-widget';
4545
import type {ViewStateMap, AnyViewStateOf, ViewOrViews, ViewStateObject} from './view-manager';
4646
import {CreateDeviceProps} from '@luma.gl/core';
4747

@@ -295,7 +295,7 @@ export default class Deck<ViewsT extends ViewOrViews = null> {
295295
protected deckPicker: DeckPicker | null = null;
296296
protected eventManager: EventManager | null = null;
297297
protected widgetManager: WidgetManager | null = null;
298-
protected tooltip: Tooltip | null = null;
298+
protected tooltip: TooltipWidget | null = null;
299299
protected animationLoop: AnimationLoop | null = null;
300300

301301
/** Internal view state if no callback is supplied */
@@ -1026,7 +1026,7 @@ export default class Deck<ViewsT extends ViewOrViews = null> {
10261026
deck: this,
10271027
parentElement: this.canvas?.parentElement
10281028
});
1029-
this.widgetManager.addDefault(new Tooltip());
1029+
this.widgetManager.addDefault(new TooltipWidget());
10301030

10311031
this.setProps(this.props);
10321032

modules/core/src/lib/layer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1253,6 +1253,7 @@ export default abstract class Layer<PropsT extends {} = {}> extends Component<
12531253
// Private methods
12541254

12551255
/** Called after updateState to perform common tasks */
1256+
// eslint-disable-next-line complexity
12561257
protected _postUpdate(updateParams: UpdateParameters<Layer<PropsT>>, forceUpdate: boolean) {
12571258
const {props, oldProps} = updateParams;
12581259

modules/core/src/lib/tooltip.ts renamed to modules/core/src/lib/tooltip-widget.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,10 @@
22
// SPDX-License-Identifier: MIT
33
// Copyright (c) vis.gl contributors
44

5-
import type {Widget} from './widget';
5+
import {Widget, WidgetProps} from './widget';
66
import type {WidgetPlacement} from './widget-manager';
77
import type {PickingInfo} from './picking/pick-info';
88
import type Viewport from '../viewports/viewport';
9-
import type Deck from './deck';
109

1110
/* global document */
1211
const defaultStyle: Partial<CSSStyleDeclaration> = {
@@ -31,32 +30,34 @@ export type TooltipContent =
3130
style?: Partial<CSSStyleDeclaration>;
3231
};
3332

34-
export default class Tooltip implements Widget {
33+
export type TooltipWidgetProps = WidgetProps;
34+
35+
export class TooltipWidget extends Widget<TooltipWidgetProps> {
36+
static defaultProps: Required<TooltipWidgetProps> = {
37+
...Widget.defaultProps
38+
};
39+
3540
id = 'default-tooltip';
3641
placement: WidgetPlacement = 'fill';
37-
props = {};
42+
className = 'deck-tooltip';
43+
3844
isVisible: boolean = false;
39-
deck?: Deck<any>;
40-
element?: HTMLDivElement;
4145
lastViewport?: Viewport;
4246

43-
onAdd({deck}: {deck: Deck<any>}): HTMLDivElement {
47+
constructor(props: TooltipWidgetProps = {}) {
48+
super(props, TooltipWidget.defaultProps);
49+
this.setProps(props);
50+
}
51+
52+
// TODO(ib) - does this really need to be overridden?
53+
onCreateRootElement() {
4454
const el = document.createElement('div');
45-
el.className = 'deck-tooltip';
55+
el.className = this.className;
4656
Object.assign(el.style, defaultStyle);
47-
48-
this.deck = deck;
49-
this.element = el;
50-
5157
return el;
5258
}
5359

54-
onRemove() {
55-
this.deck = undefined;
56-
this.element = undefined;
57-
}
58-
59-
setProps() {}
60+
onRenderHTML(rootElement: HTMLElement): void {}
6061

6162
onViewportChange(viewport: Viewport) {
6263
if (this.isVisible && viewport.id === this.lastViewport?.id && viewport !== this.lastViewport) {
@@ -77,7 +78,7 @@ export default class Tooltip implements Widget {
7778
}
7879

7980
setTooltip(displayInfo: TooltipContent, x?: number, y?: number): void {
80-
const el = this.element;
81+
const el = this.rootElement;
8182
if (!el) {
8283
return;
8384
}

0 commit comments

Comments
 (0)