@deck.gl/core
Version:
deck.gl core library
97 lines • 3.71 kB
JavaScript
// deck.gl
// SPDX-License-Identifier: MIT
// Copyright (c) vis.gl contributors
import { deepEqual } from "../utils/deep-equal.js";
import { applyStyles, removeStyles } from "../utils/apply-styles.js";
export class Widget {
constructor(props) {
/**
* The view id that this widget is being attached to. Default `null`.
* If assigned, this widget will only respond to events occurred inside the specific view that matches this id.
*/
this.viewId = null;
this.props = {
// @ts-expect-error `defaultProps` may not exist on constructor
...this.constructor.defaultProps,
...props
};
// @ts-expect-error TODO(ib) - why is id considered optional even though we use Required<>
this.id = this.props.id;
}
/** Called to update widget options */
setProps(props) {
const oldProps = this.props;
const el = this.rootElement;
// Update className and style
if (el && oldProps.className !== props.className) {
if (oldProps.className)
el.classList.remove(oldProps.className);
if (props.className)
el.classList.add(props.className);
}
// Update style
if (el && !deepEqual(oldProps.style, props.style, 1)) {
removeStyles(el, oldProps.style);
applyStyles(el, props.style);
}
Object.assign(this.props, props);
// Update the HTML to match the new props
this.updateHTML();
}
/** Update the HTML to reflect latest props and state */
updateHTML() {
if (this.rootElement) {
this.onRenderHTML(this.rootElement);
}
}
// @note empty method calls have an overhead in V8 but it is very low, ~1ns
/**
* Common utility to create the root DOM element for this widget
* Configures the top-level styles and adds basic class names for theming
* @returns an UI element that should be appended to the Deck container
*/
onCreateRootElement() {
const CLASS_NAMES = [
// Add class names for theming
'deck-widget',
this.className,
// plus any app-supplied class name
this.props.className
];
const element = document.createElement('div');
CLASS_NAMES.filter((cls) => typeof cls === 'string' && cls.length > 0).forEach(className => element.classList.add(className));
applyStyles(element, this.props.style);
return element;
}
/** Internal API called by Deck when the widget is first added to a Deck instance */
_onAdd(params) {
return this.onAdd(params) ?? this.onCreateRootElement();
}
/** Overridable by subclass - called when the widget is first added to a Deck instance
* @returns an optional UI element that should be appended to the Deck container
*/
onAdd(params) { }
/** Called when the widget is removed */
onRemove() { }
// deck integration - Event hooks
/** Called when the containing view is changed */
onViewportChange(viewport) { }
/** Called when the containing view is redrawn */
onRedraw(params) { }
/** Called when a hover event occurs */
onHover(info, event) { }
/** Called when a click event occurs */
onClick(info, event) { }
/** Called when a drag event occurs */
onDrag(info, event) { }
/** Called when a dragstart event occurs */
onDragStart(info, event) { }
/** Called when a dragend event occurs */
onDragEnd(info, event) { }
}
Widget.defaultProps = {
id: 'widget',
style: {},
className: ''
};
//# sourceMappingURL=widget.js.map