@deck.gl/widgets 9.2.10 → 9.3.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/compass-widget.js +5 -5
  2. package/dist/compass-widget.js.map +1 -1
  3. package/dist/context-menu-widget.d.ts +23 -18
  4. package/dist/context-menu-widget.d.ts.map +1 -1
  5. package/dist/context-menu-widget.js +44 -48
  6. package/dist/context-menu-widget.js.map +1 -1
  7. package/dist/dist.dev.js +2533 -420
  8. package/dist/fullscreen-widget.js +1 -1
  9. package/dist/fullscreen-widget.js.map +1 -1
  10. package/dist/geocoder-widget.d.ts +2 -4
  11. package/dist/geocoder-widget.d.ts.map +1 -1
  12. package/dist/geocoder-widget.js +16 -20
  13. package/dist/geocoder-widget.js.map +1 -1
  14. package/dist/gimbal-widget.d.ts +0 -3
  15. package/dist/gimbal-widget.d.ts.map +1 -1
  16. package/dist/gimbal-widget.js +4 -22
  17. package/dist/gimbal-widget.js.map +1 -1
  18. package/dist/index.cjs +921 -370
  19. package/dist/index.cjs.map +4 -4
  20. package/dist/index.d.ts +5 -3
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +4 -3
  23. package/dist/index.js.map +1 -1
  24. package/dist/info-widget.d.ts +38 -17
  25. package/dist/info-widget.d.ts.map +1 -1
  26. package/dist/info-widget.js +40 -130
  27. package/dist/info-widget.js.map +1 -1
  28. package/dist/lib/components/dropdown-menu.d.ts +10 -4
  29. package/dist/lib/components/dropdown-menu.d.ts.map +1 -1
  30. package/dist/lib/components/dropdown-menu.js +12 -7
  31. package/dist/lib/components/dropdown-menu.js.map +1 -1
  32. package/dist/lib/components/icon-menu.d.ts.map +1 -1
  33. package/dist/lib/components/icon-menu.js +2 -3
  34. package/dist/lib/components/icon-menu.js.map +1 -1
  35. package/dist/lib/components/popover.d.ts +30 -0
  36. package/dist/lib/components/popover.d.ts.map +1 -0
  37. package/dist/lib/components/popover.js +93 -0
  38. package/dist/lib/components/popover.js.map +1 -0
  39. package/dist/lib/components/range-input.d.ts +26 -0
  40. package/dist/lib/components/range-input.d.ts.map +1 -0
  41. package/dist/lib/components/range-input.js +261 -0
  42. package/dist/lib/components/range-input.js.map +1 -0
  43. package/dist/lib/components/user-content.d.ts +8 -0
  44. package/dist/lib/components/user-content.d.ts.map +1 -0
  45. package/dist/lib/components/user-content.js +15 -0
  46. package/dist/lib/components/user-content.js.map +1 -0
  47. package/dist/popup-widget.d.ts +63 -0
  48. package/dist/popup-widget.d.ts.map +1 -0
  49. package/dist/popup-widget.js +70 -0
  50. package/dist/popup-widget.js.map +1 -0
  51. package/dist/reset-view-widget.d.ts +1 -1
  52. package/dist/reset-view-widget.d.ts.map +1 -1
  53. package/dist/reset-view-widget.js +12 -11
  54. package/dist/reset-view-widget.js.map +1 -1
  55. package/dist/scrollbar-widget.d.ts +68 -0
  56. package/dist/scrollbar-widget.d.ts.map +1 -0
  57. package/dist/scrollbar-widget.js +181 -0
  58. package/dist/scrollbar-widget.js.map +1 -0
  59. package/dist/stats-widget.d.ts +4 -0
  60. package/dist/stats-widget.d.ts.map +1 -1
  61. package/dist/stats-widget.js +3 -3
  62. package/dist/stats-widget.js.map +1 -1
  63. package/dist/stylesheet.css +244 -29
  64. package/dist/theme-widget.d.ts.map +1 -1
  65. package/dist/theme-widget.js +7 -5
  66. package/dist/theme-widget.js.map +1 -1
  67. package/dist/themes.d.ts +30 -0
  68. package/dist/themes.d.ts.map +1 -1
  69. package/dist/themes.js +28 -4
  70. package/dist/themes.js.map +1 -1
  71. package/dist/timeline-widget.d.ts +25 -6
  72. package/dist/timeline-widget.d.ts.map +1 -1
  73. package/dist/timeline-widget.js +46 -18
  74. package/dist/timeline-widget.js.map +1 -1
  75. package/dist/zoom-widget.d.ts +2 -8
  76. package/dist/zoom-widget.d.ts.map +1 -1
  77. package/dist/zoom-widget.js +23 -18
  78. package/dist/zoom-widget.js.map +1 -1
  79. package/dist.min.js +2 -2
  80. package/package.json +4 -3
  81. package/src/compass-widget.tsx +5 -5
  82. package/src/context-menu-widget.tsx +86 -76
  83. package/src/fullscreen-widget.tsx +1 -1
  84. package/src/geocoder-widget.tsx +17 -24
  85. package/src/gimbal-widget.tsx +4 -26
  86. package/src/index.ts +11 -6
  87. package/src/info-widget.tsx +93 -157
  88. package/src/lib/components/dropdown-menu.tsx +42 -20
  89. package/src/lib/components/icon-menu.tsx +3 -4
  90. package/src/lib/components/popover.tsx +167 -0
  91. package/src/lib/components/range-input.tsx +432 -0
  92. package/src/lib/components/user-content.tsx +30 -0
  93. package/src/popup-widget.tsx +163 -0
  94. package/src/reset-view-widget.tsx +12 -11
  95. package/src/scrollbar-widget.tsx +288 -0
  96. package/src/stats-widget.tsx +10 -4
  97. package/src/stylesheet.css +244 -29
  98. package/src/theme-widget.tsx +7 -5
  99. package/src/themes.ts +35 -4
  100. package/src/timeline-widget.tsx +96 -33
  101. package/src/zoom-widget.tsx +25 -21
  102. package/dist/lib/components/grouped-icon-button.d.ts +0 -10
  103. package/dist/lib/components/grouped-icon-button.d.ts.map +0 -1
  104. package/dist/lib/components/grouped-icon-button.js +0 -7
  105. package/dist/lib/components/grouped-icon-button.js.map +0 -1
  106. package/dist/lib/components/simple-menu.d.ts +0 -16
  107. package/dist/lib/components/simple-menu.d.ts.map +0 -1
  108. package/dist/lib/components/simple-menu.js +0 -30
  109. package/dist/lib/components/simple-menu.js.map +0 -1
  110. package/src/lib/components/grouped-icon-button.tsx +0 -27
  111. package/src/lib/components/simple-menu.tsx +0 -52
package/dist/index.cjs CHANGED
@@ -27,8 +27,10 @@ __export(dist_exports, {
27
27
  GimbalWidget: () => GimbalWidget,
28
28
  LightGlassTheme: () => LightGlassTheme,
29
29
  LightTheme: () => LightTheme,
30
+ PopupWidget: () => PopupWidget,
30
31
  ResetViewWidget: () => ResetViewWidget,
31
32
  ScreenshotWidget: () => ScreenshotWidget,
33
+ ScrollbarWidget: () => ScrollbarWidget,
32
34
  ZoomWidget: () => ZoomWidget,
33
35
  _ButtonGroup: () => ButtonGroup,
34
36
  _ContextMenuWidget: () => ContextMenuWidget,
@@ -38,13 +40,13 @@ __export(dist_exports, {
38
40
  _FpsWidget: () => FpsWidget,
39
41
  _GeocoderWidget: () => GeocoderWidget,
40
42
  _GoogleGeocoder: () => GoogleGeocoder,
41
- _GroupedIconButton: () => GroupedIconButton,
42
43
  _IconButton: () => IconButton,
43
44
  _IconMenu: () => IconMenu,
44
45
  _InfoWidget: () => InfoWidget,
45
46
  _LoadingWidget: () => LoadingWidget,
46
47
  _MapboxGeocoder: () => MapboxGeocoder,
47
48
  _OpenCageGeocoder: () => OpenCageGeocoder,
49
+ _RangeInput: () => RangeInput,
48
50
  _ScaleWidget: () => ScaleWidget,
49
51
  _SimpleMenu: () => SimpleMenu,
50
52
  _SplitterWidget: () => SplitterWidget,
@@ -67,11 +69,11 @@ var ButtonGroup = (props) => {
67
69
  return (0, import_jsx_runtime.jsx)("div", { className: `deck-widget-button-group ${orientation}`, children });
68
70
  };
69
71
 
70
- // dist/lib/components/grouped-icon-button.js
72
+ // dist/lib/components/icon-button.js
71
73
  var import_jsx_runtime2 = require("preact/jsx-runtime");
72
- var GroupedIconButton = (props) => {
74
+ var IconButton = (props) => {
73
75
  const { className = "", label, onClick, children } = props;
74
- return (0, import_jsx_runtime2.jsx)("button", { className: `deck-widget-icon-button ${className}`, type: "button", onClick, title: label, children: children ? children : (0, import_jsx_runtime2.jsx)("div", { className: "deck-widget-icon" }) });
76
+ return (0, import_jsx_runtime2.jsx)("div", { className: "deck-widget-button", children: (0, import_jsx_runtime2.jsx)("button", { className: `deck-widget-icon-button ${className}`, type: "button", onClick, title: label, children: children ? children : (0, import_jsx_runtime2.jsx)("div", { className: "deck-widget-icon" }) }) });
75
77
  };
76
78
 
77
79
  // dist/zoom-widget.js
@@ -80,7 +82,6 @@ var ZoomWidget = class extends import_core.Widget {
80
82
  super(props);
81
83
  this.className = "deck-widget-zoom";
82
84
  this.placement = "top-left";
83
- this.viewports = {};
84
85
  this.setProps(this.props);
85
86
  }
86
87
  setProps(props) {
@@ -89,16 +90,22 @@ var ZoomWidget = class extends import_core.Widget {
89
90
  super.setProps(props);
90
91
  }
91
92
  onRenderHTML(rootElement) {
92
- const ui = (0, import_jsx_runtime3.jsxs)(ButtonGroup, { orientation: this.props.orientation, children: [(0, import_jsx_runtime3.jsx)(GroupedIconButton, { onClick: () => this.handleZoomIn(), label: this.props.zoomInLabel, className: "deck-widget-zoom-in" }), (0, import_jsx_runtime3.jsx)(GroupedIconButton, { onClick: () => this.handleZoomOut(), label: this.props.zoomOutLabel, className: "deck-widget-zoom-out" })] });
93
+ const ui = (0, import_jsx_runtime3.jsxs)(ButtonGroup, { orientation: this.props.orientation, children: [(0, import_jsx_runtime3.jsx)(IconButton, { onClick: () => this.handleZoomIn(), label: this.props.zoomInLabel, className: "deck-widget-zoom-in" }), (0, import_jsx_runtime3.jsx)(IconButton, { onClick: () => this.handleZoomOut(), label: this.props.zoomOutLabel, className: "deck-widget-zoom-out" })] });
93
94
  (0, import_preact.render)(ui, rootElement);
94
95
  }
95
- onViewportChange(viewport) {
96
- this.viewports[viewport.id] = viewport;
97
- }
98
- handleZoom(viewport, nextZoom) {
99
- const viewId = this.viewId || (viewport == null ? void 0 : viewport.id) || "default-view";
96
+ handleZoom(viewId, nextZoom) {
97
+ const viewState = this.getViewState(viewId);
98
+ if (viewState) {
99
+ const { minZoom, maxZoom } = viewState;
100
+ if (Number.isFinite(minZoom)) {
101
+ nextZoom = Math.max(minZoom, nextZoom);
102
+ }
103
+ if (Number.isFinite(maxZoom)) {
104
+ nextZoom = Math.min(maxZoom, nextZoom);
105
+ }
106
+ }
100
107
  const nextViewState = {
101
- ...viewport,
108
+ ...viewState,
102
109
  zoom: nextZoom
103
110
  };
104
111
  if (this.props.transitionDuration > 0) {
@@ -110,19 +117,21 @@ var ZoomWidget = class extends import_core.Widget {
110
117
  this.setViewState(viewId, nextViewState);
111
118
  }
112
119
  handleZoomIn() {
113
- for (const viewport of Object.values(this.viewports)) {
114
- this.handleZoom(viewport, viewport.zoom + 1);
120
+ var _a;
121
+ const viewIds = this.viewId ? [this.viewId] : ((_a = this.deck) == null ? void 0 : _a.getViews().map((v) => v.id)) ?? [];
122
+ for (const viewId of viewIds) {
123
+ const viewState = this.getViewState(viewId);
124
+ this.handleZoom(viewId, viewState.zoom + 1);
115
125
  }
116
126
  }
117
127
  handleZoomOut() {
118
- for (const viewport of Object.values(this.viewports)) {
119
- this.handleZoom(viewport, viewport.zoom - 1);
128
+ var _a;
129
+ const viewIds = this.viewId ? [this.viewId] : ((_a = this.deck) == null ? void 0 : _a.getViews().map((v) => v.id)) ?? [];
130
+ for (const viewId of viewIds) {
131
+ const viewState = this.getViewState(viewId);
132
+ this.handleZoom(viewId, viewState.zoom - 1);
120
133
  }
121
134
  }
122
- /** @todo - move to deck or widget manager */
123
- setViewState(viewId, viewState) {
124
- this.deck._onViewStateChange({ viewId, viewState, interactionState: {} });
125
- }
126
135
  };
127
136
  ZoomWidget.defaultProps = {
128
137
  ...import_core.Widget.defaultProps,
@@ -136,18 +145,9 @@ ZoomWidget.defaultProps = {
136
145
  };
137
146
 
138
147
  // dist/reset-view-widget.js
139
- var import_jsx_runtime5 = require("preact/jsx-runtime");
148
+ var import_jsx_runtime4 = require("preact/jsx-runtime");
140
149
  var import_preact2 = require("preact");
141
150
  var import_core2 = require("@deck.gl/core");
142
-
143
- // dist/lib/components/icon-button.js
144
- var import_jsx_runtime4 = require("preact/jsx-runtime");
145
- var IconButton = (props) => {
146
- const { className = "", label, onClick, children } = props;
147
- return (0, import_jsx_runtime4.jsx)("div", { className: "deck-widget-button", children: (0, import_jsx_runtime4.jsx)("button", { className: `deck-widget-icon-button ${className}`, type: "button", onClick, title: label, children: children ? children : (0, import_jsx_runtime4.jsx)("div", { className: "deck-widget-icon" }) }) });
148
- };
149
-
150
- // dist/reset-view-widget.js
151
151
  var ResetViewWidget = class extends import_core2.Widget {
152
152
  constructor(props = {}) {
153
153
  super(props);
@@ -161,22 +161,25 @@ var ResetViewWidget = class extends import_core2.Widget {
161
161
  super.setProps(props);
162
162
  }
163
163
  onRenderHTML(rootElement) {
164
- (0, import_preact2.render)((0, import_jsx_runtime5.jsx)(IconButton, { className: "deck-widget-reset-focus", label: this.props.label, onClick: this.handleClick.bind(this) }), rootElement);
164
+ (0, import_preact2.render)((0, import_jsx_runtime4.jsx)(IconButton, { className: "deck-widget-reset-focus", label: this.props.label, onClick: this.handleClick.bind(this) }), rootElement);
165
165
  }
166
166
  handleClick() {
167
167
  var _a;
168
168
  const initialViewState = this.props.initialViewState || ((_a = this.deck) == null ? void 0 : _a.props.initialViewState);
169
- this.setViewState(initialViewState);
169
+ this.resetViewState(initialViewState);
170
170
  }
171
- setViewState(viewState) {
172
- const viewId = this.props.viewId || "default-view";
173
- const nextViewState = {
174
- ...viewId !== "default-view" ? viewState == null ? void 0 : viewState[viewId] : viewState
175
- // only works for geospatial?
176
- // transitionDuration: this.props.transitionDuration,
177
- // transitionInterpolator: new FlyToInterpolator()
178
- };
179
- this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
171
+ resetViewState(viewState) {
172
+ var _a;
173
+ const viewIds = this.viewId ? [this.viewId] : ((_a = this.deck) == null ? void 0 : _a.getViews().map((v) => v.id)) ?? [];
174
+ for (const viewId of viewIds) {
175
+ const nextViewState = {
176
+ ...(viewState == null ? void 0 : viewState[viewId]) ?? viewState
177
+ // only works for geospatial?
178
+ // transitionDuration: this.props.transitionDuration,
179
+ // transitionInterpolator: new FlyToInterpolator()
180
+ };
181
+ this.setViewState(viewId, nextViewState);
182
+ }
180
183
  }
181
184
  };
182
185
  ResetViewWidget.defaultProps = {
@@ -189,7 +192,7 @@ ResetViewWidget.defaultProps = {
189
192
  };
190
193
 
191
194
  // dist/gimbal-widget.js
192
- var import_jsx_runtime6 = require("preact/jsx-runtime");
195
+ var import_jsx_runtime5 = require("preact/jsx-runtime");
193
196
  var import_core3 = require("@deck.gl/core");
194
197
  var import_preact3 = require("preact");
195
198
  var GimbalWidget = class extends import_core3.Widget {
@@ -210,21 +213,21 @@ var GimbalWidget = class extends import_core3.Widget {
210
213
  const viewId = this.viewId || ((_a = Object.values(this.viewports)[0]) == null ? void 0 : _a.id) || "default-view";
211
214
  const widgetViewport = this.viewports[viewId];
212
215
  const { rotationOrbit, rotationX } = this.getNormalizedRotation(widgetViewport);
213
- const ui = (0, import_jsx_runtime6.jsx)("div", { className: "deck-widget-button", style: { perspective: 100, pointerEvents: "auto" }, children: (0, import_jsx_runtime6.jsxs)("button", { type: "button", onClick: () => {
216
+ const ui = (0, import_jsx_runtime5.jsx)("div", { className: "deck-widget-button", style: { perspective: 100, pointerEvents: "auto" }, children: (0, import_jsx_runtime5.jsxs)("button", { type: "button", onClick: () => {
214
217
  for (const viewport of Object.values(this.viewports)) {
215
218
  this.resetOrbitView(viewport);
216
219
  }
217
- }, title: this.props.label, style: { position: "relative", width: 26, height: 26 }, children: [(0, import_jsx_runtime6.jsx)("svg", { className: "gimbal-outer-ring", width: "100%", height: "100%", viewBox: "0 0 26 26", style: {
220
+ }, title: this.props.label, style: { position: "relative", width: 26, height: 26 }, children: [(0, import_jsx_runtime5.jsx)("svg", { className: "gimbal-outer-ring", width: "100%", height: "100%", viewBox: "0 0 26 26", style: {
218
221
  position: "absolute",
219
222
  top: 0,
220
223
  left: 0,
221
224
  transform: `rotateY(${rotationOrbit}deg)`
222
- }, children: (0, import_jsx_runtime6.jsx)("circle", { cx: "13", cy: "13", r: "10", stroke: "var(--icon-gimbal-outer-color, rgb(68, 92, 204))", strokeWidth: this.props.strokeWidth, fill: "none" }) }), (0, import_jsx_runtime6.jsx)("svg", { className: "gimbal-inner-ring", width: "100%", height: "100%", viewBox: "0 0 26 26", style: {
225
+ }, children: (0, import_jsx_runtime5.jsx)("circle", { cx: "13", cy: "13", r: "10", stroke: "var(--icon-gimbal-outer-color, rgb(68, 92, 204))", strokeWidth: this.props.strokeWidth, fill: "none" }) }), (0, import_jsx_runtime5.jsx)("svg", { className: "gimbal-inner-ring", width: "100%", height: "100%", viewBox: "0 0 26 26", style: {
223
226
  position: "absolute",
224
227
  top: 0,
225
228
  left: 0,
226
229
  transform: `rotateX(${rotationX}deg)`
227
- }, children: (0, import_jsx_runtime6.jsx)("circle", { cx: "13", cy: "13", r: "7", stroke: "var(--icon-gimbal-inner-color, rgb(240, 92, 68))", strokeWidth: this.props.strokeWidth, fill: "none" }) })] }) });
230
+ }, children: (0, import_jsx_runtime5.jsx)("circle", { cx: "13", cy: "13", r: "7", stroke: "var(--icon-gimbal-inner-color, rgb(240, 92, 68))", strokeWidth: this.props.strokeWidth, fill: "none" }) })] }) });
228
231
  (0, import_preact3.render)(ui, rootElement);
229
232
  }
230
233
  onViewportChange(viewport) {
@@ -232,7 +235,7 @@ var GimbalWidget = class extends import_core3.Widget {
232
235
  this.updateHTML();
233
236
  }
234
237
  resetOrbitView(viewport) {
235
- const viewId = this.getViewId(viewport);
238
+ const viewId = this.viewId || (viewport == null ? void 0 : viewport.id) || "OrbitView";
236
239
  const viewState = this.getViewState(viewId);
237
240
  if ("rotationOrbit" in viewState || "rotationX" in viewState) {
238
241
  const nextViewState = {
@@ -244,11 +247,12 @@ var GimbalWidget = class extends import_core3.Widget {
244
247
  transitionProps: ["rotationOrbit", "rotationX"]
245
248
  })
246
249
  };
247
- this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
250
+ this.setViewState(viewId, nextViewState);
248
251
  }
249
252
  }
250
253
  getNormalizedRotation(viewport) {
251
- const viewState = this.getViewState(this.getViewId(viewport));
254
+ const viewId = this.viewId || (viewport == null ? void 0 : viewport.id) || "OrbitView";
255
+ const viewState = this.getViewState(viewId);
252
256
  const [rz, rx] = this.getRotation(viewState);
253
257
  const rotationOrbit = normalizeAndClampAngle(rz);
254
258
  const rotationX = normalizeAndClampAngle(rx);
@@ -260,24 +264,6 @@ var GimbalWidget = class extends import_core3.Widget {
260
264
  }
261
265
  return [0, 0];
262
266
  }
263
- // Move to Widget/WidgetManager?
264
- getViewId(viewport) {
265
- const viewId = this.viewId || (viewport == null ? void 0 : viewport.id) || "OrbitView";
266
- return viewId;
267
- }
268
- getViewState(viewId) {
269
- const viewManager = this.getViewManager();
270
- const viewState = viewId && viewManager.getViewState(viewId) || viewManager.viewState;
271
- return viewState;
272
- }
273
- getViewManager() {
274
- var _a;
275
- const viewManager = (_a = this.deck) == null ? void 0 : _a.viewManager;
276
- if (!viewManager) {
277
- throw new Error("wigdet must be added to a deck instance");
278
- }
279
- return viewManager;
280
- }
281
267
  };
282
268
  GimbalWidget.defaultProps = {
283
269
  ...import_core3.Widget.defaultProps,
@@ -303,7 +289,7 @@ function normalizeAndClampAngle(angle) {
303
289
  }
304
290
 
305
291
  // dist/compass-widget.js
306
- var import_jsx_runtime7 = require("preact/jsx-runtime");
292
+ var import_jsx_runtime6 = require("preact/jsx-runtime");
307
293
  var import_core4 = require("@deck.gl/core");
308
294
  var import_preact4 = require("preact");
309
295
  var CompassWidget = class extends import_core4.Widget {
@@ -321,14 +307,14 @@ var CompassWidget = class extends import_core4.Widget {
321
307
  }
322
308
  onRenderHTML(rootElement) {
323
309
  var _a;
324
- const viewId = this.viewId || ((_a = Object.values(this.viewports)[0]) == null ? void 0 : _a.id) || "default-view";
310
+ const viewId = this.viewId || ((_a = Object.values(this.viewports)[0]) == null ? void 0 : _a.id);
325
311
  const widgetViewport = this.viewports[viewId];
326
312
  const [rz, rx] = this.getRotation(widgetViewport);
327
- const ui = (0, import_jsx_runtime7.jsx)("div", { className: "deck-widget-button", style: { perspective: 100 }, children: (0, import_jsx_runtime7.jsx)("button", { type: "button", onClick: () => {
313
+ const ui = (0, import_jsx_runtime6.jsx)("div", { className: "deck-widget-button", style: { perspective: 100 }, children: (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => {
328
314
  for (const viewport of Object.values(this.viewports)) {
329
315
  this.handleCompassReset(viewport);
330
316
  }
331
- }, title: this.props.label, style: { transform: `rotateX(${rx}deg)` }, children: (0, import_jsx_runtime7.jsx)("svg", { fill: "none", width: "100%", height: "100%", viewBox: "0 0 26 26", children: (0, import_jsx_runtime7.jsxs)("g", { transform: `rotate(${rz},13,13)`, children: [(0, import_jsx_runtime7.jsx)("path", { d: "M10 13.0001L12.9999 5L15.9997 13.0001H10Z", fill: "var(--icon-compass-north-color, rgb(240, 92, 68))" }), (0, import_jsx_runtime7.jsx)("path", { d: "M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z", fill: "var(--icon-compass-south-color, rgb(204, 204, 204))" })] }) }) }) });
317
+ }, title: this.props.label, style: { transform: `rotateX(${rx}deg)` }, children: (0, import_jsx_runtime6.jsx)("svg", { fill: "none", width: "100%", height: "100%", viewBox: "0 0 26 26", children: (0, import_jsx_runtime6.jsxs)("g", { transform: `rotate(${rz},13,13)`, children: [(0, import_jsx_runtime6.jsx)("path", { d: "M10 13.0001L12.9999 5L15.9997 13.0001H10Z", fill: "var(--icon-compass-north-color, rgb(240, 92, 68))" }), (0, import_jsx_runtime6.jsx)("path", { d: "M16.0002 12.9999L13.0004 21L10.0005 12.9999H16.0002Z", fill: "var(--icon-compass-south-color, rgb(204, 204, 204))" })] }) }) }) });
332
318
  (0, import_preact4.render)(ui, rootElement);
333
319
  }
334
320
  onViewportChange(viewport) {
@@ -346,16 +332,17 @@ var CompassWidget = class extends import_core4.Widget {
346
332
  return [0, 0];
347
333
  }
348
334
  handleCompassReset(viewport) {
349
- const viewId = this.viewId || viewport.id || "default-view";
335
+ const viewId = this.viewId || viewport.id;
350
336
  if (viewport instanceof import_core4.WebMercatorViewport) {
337
+ const viewState = this.getViewState(viewId);
351
338
  const nextViewState = {
352
- ...viewport,
339
+ ...viewState,
353
340
  bearing: 0,
354
341
  ...this.getRotation(viewport)[0] === 0 ? { pitch: 0 } : {},
355
342
  transitionDuration: this.props.transitionDuration,
356
343
  transitionInterpolator: new import_core4.FlyToInterpolator()
357
344
  };
358
- this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
345
+ this.setViewState(viewId, nextViewState);
359
346
  }
360
347
  }
361
348
  };
@@ -369,7 +356,7 @@ CompassWidget.defaultProps = {
369
356
  };
370
357
 
371
358
  // dist/scale-widget.js
372
- var import_jsx_runtime8 = require("preact/jsx-runtime");
359
+ var import_jsx_runtime7 = require("preact/jsx-runtime");
373
360
  var import_preact5 = require("preact");
374
361
  var import_core5 = require("@deck.gl/core");
375
362
  var ScaleWidget = class extends import_core5.Widget {
@@ -391,7 +378,7 @@ var ScaleWidget = class extends import_core5.Widget {
391
378
  const lineOffsetX = 50;
392
379
  const svgWidth = lineOffsetX + this.scaleWidth;
393
380
  const tickHeight = 10;
394
- (0, import_preact5.render)((0, import_jsx_runtime8.jsxs)("svg", { className: "deck-widget-scale", width: svgWidth, height: 30, style: { overflow: "visible", background: "transparent" }, onClick: this.handleClick.bind(this), children: [(0, import_jsx_runtime8.jsx)("text", { x: lineOffsetX + 5, y: "10", textAnchor: "end", alignmentBaseline: "middle", style: { fontSize: "16px", fill: "black", fontWeight: "bold", fontFamily: "sans-serif" }, children: this.scaleText }), (0, import_jsx_runtime8.jsx)("line", { x1: lineOffsetX, y1: "15", x2: lineOffsetX + this.scaleWidth, y2: "15", stroke: "black", strokeWidth: "6" }), (0, import_jsx_runtime8.jsx)("line", { x1: lineOffsetX, y1: "15", x2: lineOffsetX, y2: 15 - tickHeight, stroke: "black", strokeWidth: "6" }), (0, import_jsx_runtime8.jsx)("line", { x1: lineOffsetX + this.scaleWidth, y1: "15", x2: lineOffsetX + this.scaleWidth, y2: 15 - tickHeight, stroke: "black", strokeWidth: "6" })] }), rootElement);
381
+ (0, import_preact5.render)((0, import_jsx_runtime7.jsxs)("svg", { className: "deck-widget-scale", width: svgWidth, height: 30, style: { overflow: "visible", background: "transparent" }, onClick: this.handleClick.bind(this), children: [(0, import_jsx_runtime7.jsx)("text", { x: lineOffsetX + 5, y: "10", textAnchor: "end", alignmentBaseline: "middle", style: { fontSize: "16px", fill: "black", fontWeight: "bold", fontFamily: "sans-serif" }, children: this.scaleText }), (0, import_jsx_runtime7.jsx)("line", { x1: lineOffsetX, y1: "15", x2: lineOffsetX + this.scaleWidth, y2: "15", stroke: "black", strokeWidth: "6" }), (0, import_jsx_runtime7.jsx)("line", { x1: lineOffsetX, y1: "15", x2: lineOffsetX, y2: 15 - tickHeight, stroke: "black", strokeWidth: "6" }), (0, import_jsx_runtime7.jsx)("line", { x1: lineOffsetX + this.scaleWidth, y1: "15", x2: lineOffsetX + this.scaleWidth, y2: 15 - tickHeight, stroke: "black", strokeWidth: "6" })] }), rootElement);
395
382
  }
396
383
  onViewportChange(viewport) {
397
384
  if (!("latitude" in viewport))
@@ -454,13 +441,13 @@ function computeScaleCandidate(metersPerPixel) {
454
441
  }
455
442
 
456
443
  // dist/geocoder-widget.js
457
- var import_jsx_runtime10 = require("preact/jsx-runtime");
444
+ var import_jsx_runtime9 = require("preact/jsx-runtime");
458
445
  var import_core6 = require("@deck.gl/core");
459
446
  var import_core7 = require("@deck.gl/core");
460
447
  var import_preact6 = require("preact");
461
448
 
462
449
  // dist/lib/components/dropdown-menu.js
463
- var import_jsx_runtime9 = require("preact/jsx-runtime");
450
+ var import_jsx_runtime8 = require("preact/jsx-runtime");
464
451
  var import_hooks = require("preact/hooks");
465
452
  function getMenuItemValue(item) {
466
453
  return typeof item === "string" ? item : item.value;
@@ -473,11 +460,13 @@ function getMenuItemIcon(item) {
473
460
  }
474
461
  var DropdownMenu = (props) => {
475
462
  const [isOpen, setIsOpen] = (0, import_hooks.useState)(false);
463
+ return (0, import_jsx_runtime8.jsx)(SimpleMenu, { ...props, style: { ...props.style, position: "absolute" }, isOpen, onClose: () => setIsOpen(false), trigger: (0, import_jsx_runtime8.jsx)("button", { className: "deck-widget-dropdown-button", onClick: () => setIsOpen(!isOpen), children: (0, import_jsx_runtime8.jsx)("span", { className: `deck-widget-dropdown-icon ${isOpen ? "open" : ""}` }) }) });
464
+ };
465
+ var SimpleMenu = (props) => {
476
466
  const dropdownRef = (0, import_hooks.useRef)(null);
477
- const toggleDropdown = () => setIsOpen(!isOpen);
478
467
  const handleClickOutside = (event) => {
479
468
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
480
- setIsOpen(false);
469
+ props.onClose();
481
470
  }
482
471
  };
483
472
  (0, import_hooks.useEffect)(() => {
@@ -486,16 +475,19 @@ var DropdownMenu = (props) => {
486
475
  document.removeEventListener("mousedown", handleClickOutside);
487
476
  };
488
477
  }, []);
489
- const handleSelect = (item) => {
490
- props.onSelect(getMenuItemValue(item));
491
- setIsOpen(false);
478
+ const handleSelect = (value) => {
479
+ if (value) {
480
+ props.onSelect(value);
481
+ props.onClose();
482
+ }
492
483
  };
493
484
  if (props.menuItems.length === 0) {
494
485
  return null;
495
486
  }
496
- return (0, import_jsx_runtime9.jsxs)("div", { className: "deck-widget-dropdown-container", ref: dropdownRef, style: props.style, children: [(0, import_jsx_runtime9.jsx)("button", { className: "deck-widget-dropdown-button", onClick: toggleDropdown, children: (0, import_jsx_runtime9.jsx)("span", { className: `deck-widget-dropdown-icon ${isOpen ? "open" : ""}` }) }), isOpen && (0, import_jsx_runtime9.jsx)("ul", { className: "deck-widget-dropdown-menu", children: props.menuItems.map((item) => {
487
+ return (0, import_jsx_runtime8.jsxs)("div", { className: "deck-widget-dropdown-container", ref: dropdownRef, children: [props.trigger, props.isOpen && (0, import_jsx_runtime8.jsx)("ul", { className: "deck-widget-dropdown-menu", style: props.style, children: props.menuItems.map((item, i) => {
488
+ const value = getMenuItemValue(item);
497
489
  const icon = getMenuItemIcon(item);
498
- return (0, import_jsx_runtime9.jsxs)("li", { className: "deck-widget-dropdown-item", onClick: () => handleSelect(item), children: [icon && (0, import_jsx_runtime9.jsx)("span", { className: "deck-widget-dropdown-item-icon", style: { maskImage: `url("${icon}")`, WebkitMaskImage: `url("${icon}")` } }), getMenuItemLabel(item)] }, getMenuItemValue(item));
490
+ return (0, import_jsx_runtime8.jsxs)("li", { className: `deck-widget-dropdown-item ${value ? "" : "disabled"}`, onClick: () => handleSelect(value), children: [icon && (0, import_jsx_runtime8.jsx)("span", { className: "deck-widget-dropdown-item-icon", style: { maskImage: `url("${icon}")`, WebkitMaskImage: `url("${icon}")` } }), getMenuItemLabel(item)] }, i);
499
491
  }) })] });
500
492
  };
501
493
 
@@ -731,7 +723,7 @@ var GeocoderWidget = class extends import_core6.Widget {
731
723
  try {
732
724
  const coordinates = await CurrentLocationGeocoder.geocode();
733
725
  if (coordinates) {
734
- this.setViewState(coordinates);
726
+ this.flyTo(coordinates);
735
727
  }
736
728
  } catch (error) {
737
729
  this.geocodeHistory.errorText = error instanceof Error ? error.message : "Location error";
@@ -748,10 +740,9 @@ var GeocoderWidget = class extends import_core6.Widget {
748
740
  this.updateHTML();
749
741
  }
750
742
  if (coordinates) {
751
- this.setViewState(coordinates);
743
+ this.flyTo(coordinates);
752
744
  }
753
745
  };
754
- this.viewports = {};
755
746
  this.setProps(this.props);
756
747
  }
757
748
  setProps(props) {
@@ -765,7 +756,7 @@ var GeocoderWidget = class extends import_core6.Widget {
765
756
  }
766
757
  onRenderHTML(rootElement) {
767
758
  const menuItems = this.props._geolocation ? [CURRENT_LOCATION_ITEM, ...this.geocodeHistory.addressHistory] : [...this.geocodeHistory.addressHistory];
768
- (0, import_preact6.render)((0, import_jsx_runtime10.jsxs)("div", { className: "deck-widget-geocoder", children: [(0, import_jsx_runtime10.jsx)("input", {
759
+ (0, import_preact6.render)((0, import_jsx_runtime9.jsxs)("div", { className: "deck-widget-geocoder", children: [(0, import_jsx_runtime9.jsx)("input", {
769
760
  className: "deck-widget-geocoder-input",
770
761
  type: "text",
771
762
  placeholder: this.isGettingLocation ? "Finding your location..." : this.geocoder.placeholderLocation ?? "Enter address or location",
@@ -776,24 +767,23 @@ var GeocoderWidget = class extends import_core6.Widget {
776
767
  return this.setInput(((_a = e.target) == null ? void 0 : _a.value) || "");
777
768
  },
778
769
  onKeyPress: this.handleKeyPress
779
- }), (0, import_jsx_runtime10.jsx)(DropdownMenu, { menuItems, onSelect: this.handleSelect }), this.geocodeHistory.errorText && (0, import_jsx_runtime10.jsx)("div", { className: "deck-widget-geocoder-error", children: this.geocodeHistory.errorText })] }), rootElement);
770
+ }), (0, import_jsx_runtime9.jsx)(DropdownMenu, { menuItems, onSelect: this.handleSelect }), this.geocodeHistory.errorText && (0, import_jsx_runtime9.jsx)("div", { className: "deck-widget-geocoder-error", children: this.geocodeHistory.errorText })] }), rootElement);
780
771
  }
781
- // TODO - MOVE TO WIDGETIMPL?
782
- setViewState(viewState) {
783
- const viewId = this.props.viewId || (viewState == null ? void 0 : viewState.id) || "default-view";
784
- const viewport = this.viewports[viewId] || {};
785
- const nextViewState = {
786
- ...viewport,
787
- ...viewState
788
- };
789
- if (this.props.transitionDuration > 0) {
790
- nextViewState.transitionDuration = this.props.transitionDuration;
791
- nextViewState.transitionInterpolator = "latitude" in nextViewState ? new import_core7.FlyToInterpolator() : new import_core7.LinearInterpolator();
772
+ flyTo(viewState) {
773
+ var _a;
774
+ const viewIds = this.viewId ? [this.viewId] : ((_a = this.deck) == null ? void 0 : _a.getViews().map((v) => v.id)) ?? [];
775
+ for (const viewId of viewIds) {
776
+ const currentViewState = this.getViewState(viewId);
777
+ const nextViewState = {
778
+ ...currentViewState,
779
+ ...viewState
780
+ };
781
+ if (this.props.transitionDuration > 0) {
782
+ nextViewState.transitionDuration = this.props.transitionDuration;
783
+ nextViewState.transitionInterpolator = "latitude" in nextViewState ? new import_core7.FlyToInterpolator() : new import_core7.LinearInterpolator();
784
+ }
785
+ this.setViewState(viewId, nextViewState);
792
786
  }
793
- this.deck._onViewStateChange({ viewId, viewState: nextViewState, interactionState: {} });
794
- }
795
- onViewportChange(viewport) {
796
- this.viewports[viewport.id] = viewport;
797
787
  }
798
788
  };
799
789
  GeocoderWidget.defaultProps = {
@@ -829,7 +819,7 @@ function getGeocoder(props) {
829
819
  }
830
820
 
831
821
  // dist/fullscreen-widget.js
832
- var import_jsx_runtime11 = require("preact/jsx-runtime");
822
+ var import_jsx_runtime10 = require("preact/jsx-runtime");
833
823
  var import_core8 = require("@deck.gl/core");
834
824
  var import_preact7 = require("preact");
835
825
  var FullscreenWidget = class extends import_core8.Widget {
@@ -847,7 +837,7 @@ var FullscreenWidget = class extends import_core8.Widget {
847
837
  document.removeEventListener("fullscreenchange", this.onFullscreenChange.bind(this));
848
838
  }
849
839
  onRenderHTML(rootElement) {
850
- (0, import_preact7.render)((0, import_jsx_runtime11.jsx)(IconButton, { onClick: () => {
840
+ (0, import_preact7.render)((0, import_jsx_runtime10.jsx)(IconButton, { onClick: () => {
851
841
  this.handleClick().catch((err) => import_core8.log.error(err)());
852
842
  }, label: this.fullscreen ? this.props.exitLabel : this.props.enterLabel, className: this.fullscreen ? "deck-widget-fullscreen-exit" : "deck-widget-fullscreen-enter" }), rootElement);
853
843
  }
@@ -857,8 +847,8 @@ var FullscreenWidget = class extends import_core8.Widget {
857
847
  super.setProps(props);
858
848
  }
859
849
  getContainer() {
860
- var _a, _b;
861
- return this.props.container || ((_b = (_a = this.deck) == null ? void 0 : _a.getCanvas()) == null ? void 0 : _b.parentElement);
850
+ var _a, _b, _c;
851
+ return this.props.container || ((_a = this.deck) == null ? void 0 : _a.props.parent) || ((_c = (_b = this.deck) == null ? void 0 : _b.getCanvas()) == null ? void 0 : _c.parentElement);
862
852
  }
863
853
  onFullscreenChange() {
864
854
  const prevFullscreen = this.fullscreen;
@@ -907,7 +897,7 @@ FullscreenWidget.defaultProps = {
907
897
  };
908
898
 
909
899
  // dist/splitter-widget.js
910
- var import_jsx_runtime12 = require("preact/jsx-runtime");
900
+ var import_jsx_runtime11 = require("preact/jsx-runtime");
911
901
  var import_preact8 = require("preact");
912
902
  var import_hooks2 = require("preact/hooks");
913
903
  var import_core9 = require("@deck.gl/core");
@@ -927,7 +917,7 @@ var SplitterWidget = class extends import_core9.Widget {
927
917
  rootElement.style.width = "100%";
928
918
  rootElement.style.height = "100%";
929
919
  rootElement.style.margin = "0px";
930
- (0, import_preact8.render)((0, import_jsx_runtime12.jsx)(Splitter, { orientation: this.props.orientation, initialSplit: this.props.initialSplit, onChange: this.props.onChange, onDragStart: this.props.onDragStart, onDragEnd: this.props.onDragEnd }), rootElement);
920
+ (0, import_preact8.render)((0, import_jsx_runtime11.jsx)(Splitter, { orientation: this.props.orientation, initialSplit: this.props.initialSplit, onChange: this.props.onChange, onDragStart: this.props.onDragStart, onDragEnd: this.props.onDragEnd }), rootElement);
931
921
  }
932
922
  };
933
923
  SplitterWidget.defaultProps = {
@@ -1007,16 +997,16 @@ function Splitter({ orientation, initialSplit, onChange, onDragStart, onDragEnd
1007
997
  right: 0,
1008
998
  bottom: 0
1009
999
  };
1010
- return (0, import_jsx_runtime12.jsx)("div", { ref: containerRef, style: containerStyle, children: (0, import_jsx_runtime12.jsx)("div", { style: splitterStyle, onMouseDown: handleDragStart }) });
1000
+ return (0, import_jsx_runtime11.jsx)("div", { ref: containerRef, style: containerStyle, children: (0, import_jsx_runtime11.jsx)("div", { style: splitterStyle, onMouseDown: handleDragStart }) });
1011
1001
  }
1012
1002
 
1013
1003
  // dist/view-selector-widget.js
1014
- var import_jsx_runtime14 = require("preact/jsx-runtime");
1004
+ var import_jsx_runtime13 = require("preact/jsx-runtime");
1015
1005
  var import_preact9 = require("preact");
1016
1006
  var import_core10 = require("@deck.gl/core");
1017
1007
 
1018
1008
  // dist/lib/components/icon-menu.js
1019
- var import_jsx_runtime13 = require("preact/jsx-runtime");
1009
+ var import_jsx_runtime12 = require("preact/jsx-runtime");
1020
1010
  var import_hooks3 = require("preact/hooks");
1021
1011
  function IconMenu(props) {
1022
1012
  const [menuOpen, setMenuOpen] = (0, import_hooks3.useState)(false);
@@ -1042,7 +1032,7 @@ function IconMenu(props) {
1042
1032
  const selectedMenuItem = props.menuItems.find((item) => item.value === selectedItem);
1043
1033
  const label = props.label || (selectedMenuItem == null ? void 0 : selectedMenuItem.label) || "";
1044
1034
  const icon = props.icon || (selectedMenuItem == null ? void 0 : selectedMenuItem.icon);
1045
- return (0, import_jsx_runtime13.jsxs)("div", { style: { position: "relative", display: "inline-block" }, ref: containerRef, children: [(0, import_jsx_runtime13.jsx)(IconButton, { className: props.className, label, onClick: handleButtonClick, children: icon }), menuOpen && (0, import_jsx_runtime13.jsx)("div", { className: "deck-widget-icon-menu", children: (0, import_jsx_runtime13.jsx)(ButtonGroup, { orientation: "vertical", children: props.menuItems.map((item) => (0, import_jsx_runtime13.jsx)(GroupedIconButton, { label: item.label, onClick: () => handleSelectItem(item.value), children: item.icon }, item.value)) }) })] });
1035
+ return (0, import_jsx_runtime12.jsxs)("div", { style: { position: "relative", display: "inline-block" }, ref: containerRef, children: [(0, import_jsx_runtime12.jsx)(IconButton, { className: props.className, label, onClick: handleButtonClick, children: icon }), menuOpen && (0, import_jsx_runtime12.jsx)("div", { className: "deck-widget-icon-menu", children: (0, import_jsx_runtime12.jsx)(ButtonGroup, { orientation: "vertical", children: props.menuItems.map((item) => (0, import_jsx_runtime12.jsx)(IconButton, { label: item.label, onClick: () => handleSelectItem(item.value), children: item.icon }, item.value)) }) })] });
1046
1036
  }
1047
1037
 
1048
1038
  // dist/view-selector-widget.js
@@ -1065,7 +1055,7 @@ var ViewSelectorWidget = class extends import_core10.Widget {
1065
1055
  super.setProps(props);
1066
1056
  }
1067
1057
  onRenderHTML(rootElement) {
1068
- (0, import_preact9.render)((0, import_jsx_runtime14.jsx)(IconMenu, { className: "deck-widget-view-selector", menuItems: MENU_ITEMS.map((item) => ({
1058
+ (0, import_preact9.render)((0, import_jsx_runtime13.jsx)(IconMenu, { className: "deck-widget-view-selector", menuItems: MENU_ITEMS.map((item) => ({
1069
1059
  ...item,
1070
1060
  icon: item.icon()
1071
1061
  })), initialItem: this.props.initialViewMode, onItemSelected: this.handleSelectMode }), rootElement);
@@ -1083,9 +1073,9 @@ ViewSelectorWidget.defaultProps = {
1083
1073
  };
1084
1074
  var ICON_STYLE = { width: "24px", height: "24px" };
1085
1075
  var ICONS = {
1086
- single: () => (0, import_jsx_runtime14.jsx)("svg", { width: "24", height: "24", style: ICON_STYLE, children: (0, import_jsx_runtime14.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" }) }),
1087
- "split-horizontal": () => (0, import_jsx_runtime14.jsxs)("svg", { width: "24", height: "24", style: ICON_STYLE, children: [(0, import_jsx_runtime14.jsx)("rect", { x: "4", y: "4", width: "16", height: "7", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" }), (0, import_jsx_runtime14.jsx)("rect", { x: "4", y: "13", width: "16", height: "7", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" })] }),
1088
- "split-vertical": () => (0, import_jsx_runtime14.jsxs)("svg", { width: "24", height: "24", style: ICON_STYLE, children: [(0, import_jsx_runtime14.jsx)("rect", { x: "4", y: "4", width: "7", height: "16", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" }), (0, import_jsx_runtime14.jsx)("rect", { x: "13", y: "4", width: "7", height: "16", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" })] })
1076
+ single: () => (0, import_jsx_runtime13.jsx)("svg", { width: "24", height: "24", style: ICON_STYLE, children: (0, import_jsx_runtime13.jsx)("rect", { x: "4", y: "4", width: "16", height: "16", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" }) }),
1077
+ "split-horizontal": () => (0, import_jsx_runtime13.jsxs)("svg", { width: "24", height: "24", style: ICON_STYLE, children: [(0, import_jsx_runtime13.jsx)("rect", { x: "4", y: "4", width: "16", height: "7", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" }), (0, import_jsx_runtime13.jsx)("rect", { x: "4", y: "13", width: "16", height: "7", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" })] }),
1078
+ "split-vertical": () => (0, import_jsx_runtime13.jsxs)("svg", { width: "24", height: "24", style: ICON_STYLE, children: [(0, import_jsx_runtime13.jsx)("rect", { x: "4", y: "4", width: "7", height: "16", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" }), (0, import_jsx_runtime13.jsx)("rect", { x: "13", y: "4", width: "7", height: "16", stroke: "var(--button-icon-hover, rgb(24, 24, 26))", fill: "none", strokeWidth: "2" })] })
1089
1079
  };
1090
1080
  var MENU_ITEMS = [
1091
1081
  { value: "single", icon: ICONS.single, label: "Single View" },
@@ -1094,312 +1084,839 @@ var MENU_ITEMS = [
1094
1084
  ];
1095
1085
 
1096
1086
  // dist/info-widget.js
1097
- var import_jsx_runtime15 = require("preact/jsx-runtime");
1087
+ var import_jsx_runtime16 = require("preact/jsx-runtime");
1098
1088
  var import_core11 = require("@deck.gl/core");
1099
1089
  var import_preact10 = require("preact");
1090
+
1091
+ // dist/lib/components/popover.js
1092
+ var import_jsx_runtime14 = require("preact/jsx-runtime");
1093
+ var import_hooks4 = require("preact/hooks");
1094
+ var import_dom = require("@floating-ui/dom");
1095
+ var Popover = ({ x, y, placement = "right", offset: pixelOffset = 0, arrow: arrowSize = false, arrowColor = "white", children }) => {
1096
+ const anchorRef = (0, import_hooks4.useRef)(null);
1097
+ const contentRef = (0, import_hooks4.useRef)(null);
1098
+ const arrowRef = (0, import_hooks4.useRef)(null);
1099
+ const updaterRef = (0, import_hooks4.useRef)();
1100
+ updaterRef.current = () => {
1101
+ if (!anchorRef.current || !contentRef.current)
1102
+ return;
1103
+ const arrowWidth = Array.isArray(arrowSize) ? arrowSize[0] : arrowSize || 0;
1104
+ const arrowHeight = Array.isArray(arrowSize) ? arrowSize[1] : arrowSize || 0;
1105
+ const padding = pixelOffset + Math.max(arrowHeight, arrowWidth);
1106
+ const middleware = placement.includes("-") ? [(0, import_dom.offset)(padding), (0, import_dom.flip)(), (0, import_dom.shift)()] : [(0, import_dom.offset)(padding), (0, import_dom.shift)(), (0, import_dom.flip)()];
1107
+ if (arrowRef.current)
1108
+ middleware.push((0, import_dom.arrow)({ element: arrowRef.current }));
1109
+ (0, import_dom.computePosition)(anchorRef.current, contentRef.current, {
1110
+ placement,
1111
+ strategy: "fixed",
1112
+ middleware
1113
+ }).then((popoverPos) => {
1114
+ if (contentRef.current) {
1115
+ Object.assign(contentRef.current.style, {
1116
+ left: `${popoverPos.x}px`,
1117
+ top: `${popoverPos.y}px`
1118
+ });
1119
+ }
1120
+ const arrowData = popoverPos.middlewareData.arrow;
1121
+ if (arrowData && arrowRef.current) {
1122
+ const arrowStyle = createArrow(arrowWidth, arrowHeight, arrowColor, popoverPos.placement);
1123
+ arrowStyle.transform = `translate(${arrowData.x || 0}px, ${arrowData.y || 0}px)`;
1124
+ Object.assign(arrowRef.current.style, arrowStyle);
1125
+ }
1126
+ });
1127
+ };
1128
+ (0, import_hooks4.useMemo)(() => {
1129
+ var _a;
1130
+ (_a = updaterRef.current) == null ? void 0 : _a.call(updaterRef);
1131
+ }, [placement, arrowSize, pixelOffset]);
1132
+ (0, import_hooks4.useEffect)(() => {
1133
+ if (contentRef.current) {
1134
+ contentRef.current.style.visibility = "visible";
1135
+ }
1136
+ const cleanup = (0, import_dom.autoUpdate)(anchorRef.current, contentRef.current, () => {
1137
+ var _a;
1138
+ return (_a = updaterRef.current) == null ? void 0 : _a.call(updaterRef);
1139
+ });
1140
+ return () => {
1141
+ cleanup();
1142
+ };
1143
+ }, []);
1144
+ return (0, import_jsx_runtime14.jsx)("div", { style: { position: "absolute", left: x, top: y }, ref: anchorRef, children: (0, import_jsx_runtime14.jsxs)("div", { className: "deck-widget deck-widget-popover", style: { position: "fixed", visibility: "hidden", pointerEvents: "none" }, ref: contentRef, children: [Boolean(arrowSize) && (0, import_jsx_runtime14.jsx)("div", { className: "deck-widget-popover-arrow", style: { position: "absolute" }, ref: arrowRef }), children] }) });
1145
+ };
1146
+ function createArrow(width, height, color, placement) {
1147
+ const result = {
1148
+ width: 0,
1149
+ height: 0,
1150
+ top: "",
1151
+ bottom: "",
1152
+ left: "",
1153
+ right: ""
1154
+ };
1155
+ if (placement.startsWith("bottom")) {
1156
+ result.borderLeft = `${width / 2}px solid transparent`;
1157
+ result.borderRight = `${width / 2}px solid transparent`;
1158
+ result.borderBottom = `${height}px solid ${color}`;
1159
+ result.borderTop = "";
1160
+ result.top = `${-height}px`;
1161
+ } else if (placement.startsWith("top")) {
1162
+ result.borderLeft = `${width / 2}px solid transparent`;
1163
+ result.borderRight = `${width / 2}px solid transparent`;
1164
+ result.borderTop = `${height}px solid ${color}`;
1165
+ result.borderBottom = "";
1166
+ result.bottom = `${-height}px`;
1167
+ } else if (placement.startsWith("right")) {
1168
+ result.borderTop = `${width / 2}px solid transparent`;
1169
+ result.borderBottom = `${width / 2}px solid transparent`;
1170
+ result.borderRight = `${height}px solid ${color}`;
1171
+ result.borderLeft = "";
1172
+ result.left = `${-height}px`;
1173
+ } else if (placement.startsWith("left")) {
1174
+ result.borderTop = `${width / 2}px solid transparent`;
1175
+ result.borderBottom = `${width / 2}px solid transparent`;
1176
+ result.borderLeft = `${height}px solid ${color}`;
1177
+ result.borderRight = "";
1178
+ result.right = `${-height}px`;
1179
+ }
1180
+ return result;
1181
+ }
1182
+
1183
+ // dist/lib/components/user-content.js
1184
+ var import_jsx_runtime15 = require("preact/jsx-runtime");
1185
+ var import_hooks5 = require("preact/hooks");
1186
+ var UserContent = ({ text, html, element, ...props }) => {
1187
+ const containerRef = (0, import_hooks5.useRef)(null);
1188
+ (0, import_hooks5.useEffect)(() => {
1189
+ if (containerRef.current && element) {
1190
+ containerRef.current.append(element);
1191
+ }
1192
+ return () => {
1193
+ element == null ? void 0 : element.remove();
1194
+ };
1195
+ }, [element]);
1196
+ return (0, import_jsx_runtime15.jsx)("div", { ref: containerRef, ...props, dangerouslySetInnerHTML: html ? { __html: html } : void 0, children: text });
1197
+ };
1198
+
1199
+ // dist/info-widget.js
1100
1200
  var InfoWidget = class extends import_core11.Widget {
1101
1201
  constructor(props) {
1102
1202
  super(props);
1103
1203
  this.className = "deck-widget-info";
1104
1204
  this.placement = "fill";
1205
+ this.tooltip = null;
1105
1206
  this.setProps(this.props);
1106
1207
  }
1107
1208
  setProps(props) {
1108
1209
  this.viewId = props.viewId ?? this.viewId;
1109
1210
  super.setProps(props);
1110
1211
  }
1111
- onCreateRootElement() {
1112
- const element = super.onCreateRootElement();
1113
- const style = { margin: "0px", top: "0px", left: "0px", position: "absolute" };
1114
- Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));
1115
- return element;
1212
+ onAdd({ deck }) {
1213
+ this.deck = deck;
1116
1214
  }
1117
1215
  onViewportChange(viewport) {
1118
1216
  this.viewport = viewport;
1119
1217
  this.updateHTML();
1120
1218
  }
1121
1219
  onHover(info) {
1122
- if (this.props.mode === "hover" && this.props.getTooltip) {
1123
- const tooltip = this.props.getTooltip(info, this);
1124
- this.setProps({
1125
- visible: tooltip !== null,
1126
- ...tooltip,
1127
- style: { zIndex: "1", ...tooltip == null ? void 0 : tooltip.style }
1128
- });
1220
+ if (this.props.mode === "hover") {
1221
+ this.tooltip = this._getTooltip(info);
1129
1222
  }
1130
1223
  }
1131
1224
  onClick(info) {
1132
- var _a, _b;
1133
- if (this.props.mode === "click" && this.props.getTooltip) {
1134
- const tooltip = this.props.getTooltip(info, this);
1135
- this.setProps({
1136
- visible: tooltip !== null,
1137
- ...tooltip
1138
- });
1139
- return tooltip !== null;
1225
+ if (this.props.mode === "click") {
1226
+ this.tooltip = this._getTooltip(info);
1140
1227
  }
1141
- return ((_b = (_a = this.props).onClick) == null ? void 0 : _b.call(_a, this, info)) || false;
1142
1228
  }
1143
- onAdd({ deck, viewId }) {
1144
- this.deck = deck;
1145
- if (!viewId) {
1146
- this.viewport = deck.getViewports()[0];
1147
- } else {
1148
- this.viewport = deck.getViewports().find((viewport) => viewport.id === viewId);
1149
- }
1229
+ _getTooltip(info) {
1230
+ if (!this.props.getTooltip)
1231
+ return null;
1232
+ const content = this.props.getTooltip(info, this) ?? null;
1233
+ if (content === null)
1234
+ return null;
1235
+ const normalizedTooltip = typeof content === "string" ? { text: content } : content;
1236
+ const position = normalizedTooltip.position || info.coordinate;
1237
+ if (!position)
1238
+ return null;
1239
+ return {
1240
+ position,
1241
+ text: "",
1242
+ html: "",
1243
+ element: null,
1244
+ className: "",
1245
+ style: {},
1246
+ ...normalizedTooltip
1247
+ };
1150
1248
  }
1151
1249
  onRenderHTML(rootElement) {
1152
- if (!this.viewport) {
1250
+ if (!this.viewport || this.tooltip === null) {
1251
+ (0, import_preact10.render)(null, rootElement);
1153
1252
  return;
1154
1253
  }
1155
- const [longitude, latitude] = this.props.position;
1156
- const [x, y] = this.viewport.project([longitude, latitude]);
1157
- const minOffset = this.props.minOffset || 0;
1158
- const gap = 10;
1159
- const arrowHeight = 8;
1160
- const arrowWidth = 16;
1161
- const isAbove = y > this.viewport.height / 2;
1162
- const background = this.props.style && this.props.style.background || "rgba(255,255,255,0.9)";
1163
- const ui = this.props.visible ? (0, import_jsx_runtime15.jsxs)("div", { className: "popup-container", style: { position: "absolute", left: 0, top: 0 }, children: [(0, import_jsx_runtime15.jsx)("div", { className: "popup-content", style: {
1164
- background,
1165
- padding: "10px",
1166
- position: "relative",
1167
- // Include any additional styles
1168
- ...this.props.style
1169
- }, children: this.props.text }), (0, import_jsx_runtime15.jsx)("div", { className: "popup-arrow", style: { position: "absolute", width: "0px", height: "0px" } })] }) : null;
1254
+ const style = {
1255
+ ...this.props.style,
1256
+ ...this.tooltip.style
1257
+ };
1258
+ const [x, y] = this.viewport.project(this.tooltip.position);
1259
+ const ui = (0, import_jsx_runtime16.jsx)(Popover, { x, y, placement: this.props.placement, arrow: this.props.arrow, arrowColor: "var(--menu-background, #fff)", offset: this.props.offset, children: (0, import_jsx_runtime16.jsx)(UserContent, { className: `deck-widget-popup-content ${this.tooltip.className} ${this.props.className}`, style, html: this.tooltip.html, text: this.tooltip.text, element: this.tooltip.element }) });
1170
1260
  (0, import_preact10.render)(ui, rootElement);
1171
- requestAnimationFrame(() => {
1172
- if (!this.props.visible || !rootElement.firstChild || !this.viewport)
1173
- return;
1174
- const container = rootElement.firstChild;
1175
- const contentEl = container.querySelector(".popup-content");
1176
- const arrowEl = container.querySelector(".popup-arrow");
1177
- if (!contentEl || !arrowEl)
1178
- return;
1179
- const contentRect = contentEl.getBoundingClientRect();
1180
- const popupWidth = contentRect.width;
1181
- const popupHeight = contentRect.height;
1182
- let computedLeft = x - popupWidth / 2;
1183
- let computedTop;
1184
- if (isAbove) {
1185
- computedTop = y - gap - arrowHeight - popupHeight;
1186
- } else {
1187
- computedTop = y + gap + arrowHeight;
1188
- }
1189
- if (computedLeft < minOffset) {
1190
- computedLeft = minOffset;
1191
- }
1192
- if (computedLeft + popupWidth > this.viewport.width - minOffset) {
1193
- computedLeft = this.viewport.width - minOffset - popupWidth;
1194
- }
1195
- if (isAbove) {
1196
- if (computedTop < minOffset) {
1197
- computedTop = minOffset;
1198
- }
1199
- } else if (computedTop + popupHeight + arrowHeight > this.viewport.height - minOffset) {
1200
- computedTop = this.viewport.height - minOffset - popupHeight - arrowHeight;
1201
- }
1202
- container.style.left = `${computedLeft}px`;
1203
- container.style.top = `${computedTop}px`;
1204
- container.style.transform = "";
1205
- let arrowLeft = x - computedLeft - arrowWidth / 2;
1206
- arrowLeft = Math.max(arrowLeft, 0);
1207
- arrowLeft = Math.min(arrowLeft, popupWidth - arrowWidth);
1208
- if (isAbove) {
1209
- arrowEl.style.left = `${arrowLeft}px`;
1210
- arrowEl.style.bottom = `-${arrowHeight}px`;
1211
- arrowEl.style.top = "";
1212
- arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;
1213
- arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;
1214
- arrowEl.style.borderTop = `${arrowHeight}px solid ${background}`;
1215
- arrowEl.style.borderBottom = "";
1216
- } else {
1217
- arrowEl.style.left = `${arrowLeft}px`;
1218
- arrowEl.style.top = `-${arrowHeight}px`;
1219
- arrowEl.style.bottom = "";
1220
- arrowEl.style.borderLeft = `${arrowWidth / 2}px solid transparent`;
1221
- arrowEl.style.borderRight = `${arrowWidth / 2}px solid transparent`;
1222
- arrowEl.style.borderBottom = `${arrowHeight}px solid ${background}`;
1223
- arrowEl.style.borderTop = "";
1224
- }
1225
- });
1226
1261
  }
1227
1262
  };
1228
1263
  InfoWidget.defaultProps = {
1229
1264
  ...import_core11.Widget.defaultProps,
1230
1265
  id: "info",
1231
- position: [0, 0],
1232
- text: "",
1233
- visible: false,
1234
- minOffset: 0,
1235
1266
  viewId: null,
1236
1267
  mode: "hover",
1237
1268
  getTooltip: void 0,
1238
- onClick: void 0
1269
+ placement: "right",
1270
+ offset: 10,
1271
+ arrow: 10
1239
1272
  };
1240
1273
 
1241
- // dist/context-menu-widget.js
1274
+ // dist/popup-widget.js
1242
1275
  var import_jsx_runtime17 = require("preact/jsx-runtime");
1243
1276
  var import_core12 = require("@deck.gl/core");
1244
1277
  var import_preact11 = require("preact");
1245
-
1246
- // dist/lib/components/simple-menu.js
1247
- var import_jsx_runtime16 = require("preact/jsx-runtime");
1248
- var MENU_STYLE = {
1249
- position: "absolute",
1250
- top: "100%",
1251
- left: 0,
1252
- background: "white",
1253
- border: "1px solid #ccc",
1254
- borderRadius: "4px",
1255
- marginTop: "var(--menu-gap, 4px)",
1256
- zIndex: 100
1257
- };
1258
- var MENU_ITEM_STYLE = {
1259
- background: "white",
1260
- border: "none",
1261
- padding: "4px",
1262
- cursor: "pointer",
1263
- pointerEvents: "auto"
1278
+ var PopupWidget = class extends import_core12.Widget {
1279
+ constructor(props) {
1280
+ super(props);
1281
+ this.className = "deck-widget-popup";
1282
+ this.placement = "fill";
1283
+ this.setProps(this.props);
1284
+ this.isOpen = this.props.defaultIsOpen;
1285
+ }
1286
+ setProps(props) {
1287
+ this.viewId = props.viewId ?? this.viewId;
1288
+ super.setProps(props);
1289
+ }
1290
+ onAdd({ deck }) {
1291
+ this.deck = deck;
1292
+ }
1293
+ onViewportChange(viewport) {
1294
+ this.viewport = viewport;
1295
+ this.updateHTML();
1296
+ }
1297
+ onClick() {
1298
+ if (this.props.closeOnClickOutside) {
1299
+ this._setIsOpen(false);
1300
+ }
1301
+ }
1302
+ _setIsOpen(isOpen) {
1303
+ var _a, _b;
1304
+ if (this.isOpen === isOpen)
1305
+ return;
1306
+ this.isOpen = isOpen;
1307
+ (_b = (_a = this.props).onOpenChange) == null ? void 0 : _b.call(_a, isOpen);
1308
+ this.updateHTML();
1309
+ }
1310
+ onRenderHTML(rootElement) {
1311
+ if (!this.viewport) {
1312
+ (0, import_preact11.render)(null, rootElement);
1313
+ return;
1314
+ }
1315
+ const { marker, content, style } = this.props;
1316
+ const [x, y] = this.viewport.project(this.props.position);
1317
+ const ui = (0, import_jsx_runtime17.jsxs)("div", { children: [marker && (0, import_jsx_runtime17.jsx)("div", { style: { position: "absolute", left: x, top: y, pointerEvents: "all", cursor: "pointer" }, children: (0, import_jsx_runtime17.jsx)(UserContent, { ...marker, onClick: () => this._setIsOpen(true) }) }), this.isOpen && (0, import_jsx_runtime17.jsx)(Popover, { x, y, placement: this.props.placement, arrow: this.props.arrow, arrowColor: "var(--menu-background, #fff)", offset: this.props.offset, children: (0, import_jsx_runtime17.jsxs)("div", { className: `deck-widget-popup-content ${this.props.className}`, style, children: [this.props.closeButton && (0, import_jsx_runtime17.jsx)("div", { className: "deck-widget-popup-controls", style: { width: "100%", display: "flex", justifyContent: "end" }, children: (0, import_jsx_runtime17.jsx)(IconButton, { className: "deck-widget-popup-close-button", onClick: () => this._setIsOpen(false) }) }), (0, import_jsx_runtime17.jsx)(UserContent, { ...typeof content === "string" ? { text: content } : content })] }) })] });
1318
+ (0, import_preact11.render)(ui, rootElement);
1319
+ }
1264
1320
  };
1265
- var SimpleMenu = (props) => {
1266
- const { menuItems, onItemSelected, position, style } = props;
1267
- const styleOverride = {
1268
- ...MENU_STYLE,
1269
- ...style,
1270
- left: `${position.x}px`,
1271
- top: `${position.y}px`
1272
- };
1273
- return (0, import_jsx_runtime16.jsx)("div", { style: styleOverride, children: menuItems.map(({ key, label }) => (0, import_jsx_runtime16.jsx)("button", { style: { ...MENU_ITEM_STYLE, display: "block" }, onClick: (_) => onItemSelected(key), children: label }, key)) });
1321
+ PopupWidget.defaultProps = {
1322
+ ...import_core12.Widget.defaultProps,
1323
+ id: "info",
1324
+ viewId: null,
1325
+ position: [0, 0],
1326
+ marker: null,
1327
+ defaultIsOpen: true,
1328
+ content: "",
1329
+ placement: "right",
1330
+ offset: 10,
1331
+ arrow: 10,
1332
+ closeButton: true,
1333
+ closeOnClickOutside: false,
1334
+ onOpenChange: () => {
1335
+ }
1274
1336
  };
1275
1337
 
1276
1338
  // dist/context-menu-widget.js
1277
- var MOUSE_BUTTON_RIGHT = 2;
1278
- var MOUSE_WHICH_RIGHT = 3;
1279
- var ContextMenuWidget = class extends import_core12.Widget {
1339
+ var import_jsx_runtime18 = require("preact/jsx-runtime");
1340
+ var import_core13 = require("@deck.gl/core");
1341
+ var import_preact12 = require("preact");
1342
+ var ContextMenuWidget = class extends import_core13.Widget {
1280
1343
  constructor(props) {
1281
1344
  super(props);
1282
1345
  this.className = "deck-widget-context-menu";
1283
1346
  this.placement = "fill";
1284
- this.pickInfo = null;
1285
- this.pickInfo = null;
1347
+ this.menu = null;
1286
1348
  this.setProps(this.props);
1287
1349
  }
1288
1350
  onAdd({ deck }) {
1289
- var _a, _b;
1290
- const element = document.createElement("div");
1291
- element.classList.add("deck-widget", "deck-widget-context-menu");
1292
- const style = {
1293
- margin: "0px",
1294
- top: "0px",
1295
- left: "0px",
1296
- position: "absolute",
1297
- pointerEvents: "auto"
1351
+ var _a;
1352
+ (_a = deck.getCanvas()) == null ? void 0 : _a.addEventListener("contextmenu", (event) => this.handleContextMenu(event));
1353
+ }
1354
+ handleContextMenu(srcEvent) {
1355
+ var _a;
1356
+ const targetRect = srcEvent.target.getBoundingClientRect();
1357
+ const x = srcEvent.clientX - targetRect.x;
1358
+ const y = srcEvent.clientY - targetRect.y;
1359
+ const pickInfo = ((_a = this.deck) == null ? void 0 : _a.pickObject({ x, y })) || {
1360
+ x,
1361
+ y,
1362
+ picked: false,
1363
+ layer: null,
1364
+ color: null,
1365
+ index: -1,
1366
+ pixelRatio: 1
1298
1367
  };
1299
- Object.entries(style).forEach(([key, value]) => element.style.setProperty(key, value));
1300
- (_a = deck.getCanvas()) == null ? void 0 : _a.addEventListener("click", () => this.hide());
1301
- (_b = deck.getCanvas()) == null ? void 0 : _b.addEventListener("contextmenu", (event) => this.handleContextMenu(event));
1302
- return element;
1368
+ const menuItems = this.props.getMenuItems(pickInfo, this) || [];
1369
+ this.menu = menuItems.length > 0 ? {
1370
+ items: menuItems,
1371
+ pickInfo
1372
+ } : null;
1373
+ srcEvent.preventDefault();
1374
+ this.updateHTML();
1303
1375
  }
1304
1376
  onRenderHTML(rootElement) {
1305
- const { visible, position, menuItems } = this.props;
1306
- const ui = visible && menuItems.length ? (0, import_jsx_runtime17.jsx)(SimpleMenu, { menuItems, onItemSelected: (key) => this.props.onMenuItemSelected(key, this.pickInfo), position, style: { pointerEvents: "auto" } }) : null;
1307
- (0, import_preact11.render)(ui, rootElement);
1308
- }
1309
- handleContextMenu(srcEvent) {
1310
- var _a, _b, _c;
1311
- if (srcEvent && (srcEvent.button === MOUSE_BUTTON_RIGHT || srcEvent.which === MOUSE_WHICH_RIGHT)) {
1312
- this.pickInfo = ((_a = this.deck) == null ? void 0 : _a.pickObject({
1313
- x: srcEvent.clientX,
1314
- y: srcEvent.clientY
1315
- })) || null;
1316
- const menuItems = this.pickInfo && ((_c = (_b = this.props).getMenuItems) == null ? void 0 : _c.call(_b, this.pickInfo, this)) || [];
1317
- const visible = menuItems.length > 0;
1318
- this.setProps({
1319
- visible,
1320
- position: { x: srcEvent.clientX, y: srcEvent.clientY },
1321
- menuItems
1322
- });
1323
- this.updateHTML();
1324
- srcEvent.preventDefault();
1325
- return visible;
1377
+ if (!this.menu) {
1378
+ (0, import_preact12.render)(null, rootElement);
1379
+ return;
1326
1380
  }
1327
- return false;
1381
+ const { items, pickInfo } = this.menu;
1382
+ const style = {
1383
+ pointerEvents: "auto",
1384
+ position: "static",
1385
+ ...this.props.style
1386
+ };
1387
+ const ui = (0, import_jsx_runtime18.jsx)(Popover, { x: pickInfo.x, y: pickInfo.y, placement: this.props.placement, arrow: this.props.arrow, arrowColor: "var(--menu-background, #fff)", offset: this.props.offset, children: (0, import_jsx_runtime18.jsx)(SimpleMenu, { menuItems: items, onSelect: (value) => this.props.onMenuItemSelected(value, pickInfo), style, isOpen: true, onClose: () => this.hide() }) });
1388
+ (0, import_preact12.render)(ui, rootElement);
1328
1389
  }
1329
1390
  hide() {
1330
- this.setProps({ visible: false });
1391
+ this.menu = null;
1392
+ this.updateHTML();
1331
1393
  }
1332
1394
  };
1333
1395
  ContextMenuWidget.defaultProps = {
1334
- ...import_core12.Widget.defaultProps,
1396
+ ...import_core13.Widget.defaultProps,
1335
1397
  id: "context",
1336
1398
  viewId: null,
1337
- visible: false,
1338
- position: { x: 0, y: 0 },
1339
1399
  getMenuItems: void 0,
1340
- menuItems: [],
1341
- // eslint-disable-next-line no-console
1342
- onMenuItemSelected: (key, pickInfo) => console.log("Context menu item selected:", key, pickInfo)
1400
+ onMenuItemSelected: () => {
1401
+ },
1402
+ placement: "bottom-start",
1403
+ offset: 10,
1404
+ arrow: false
1343
1405
  };
1344
1406
 
1407
+ // dist/scrollbar-widget.js
1408
+ var import_jsx_runtime20 = require("preact/jsx-runtime");
1409
+ var import_core14 = require("@deck.gl/core");
1410
+ var import_preact13 = require("preact");
1411
+
1412
+ // dist/lib/components/range-input.js
1413
+ var import_jsx_runtime19 = require("preact/jsx-runtime");
1414
+ var import_hooks6 = require("preact/hooks");
1415
+ var wheelListenerOptions = { passive: false };
1416
+ var clamp = (value, min, max) => {
1417
+ if (value < min) {
1418
+ return min;
1419
+ }
1420
+ if (value > max) {
1421
+ return max;
1422
+ }
1423
+ return value;
1424
+ };
1425
+ var getTrackDimension = (track, vertical) => {
1426
+ if (!track || !track.firstElementChild) {
1427
+ return [0, 0];
1428
+ }
1429
+ const rect = track.firstElementChild.getBoundingClientRect();
1430
+ if (vertical) {
1431
+ return [rect.top, rect.height];
1432
+ }
1433
+ return vertical ? [rect.top, rect.height] : [rect.left, rect.width];
1434
+ };
1435
+ var getEffectiveStep = (step, range) => {
1436
+ if (typeof step === "number" && !Number.isNaN(step) && step > 0) {
1437
+ return step;
1438
+ }
1439
+ return Math.max(1, range / 10 || 1);
1440
+ };
1441
+ var getEffectivePage = (pageSize, rangeSize) => {
1442
+ if (typeof pageSize === "number" && !Number.isNaN(pageSize) && pageSize > 0) {
1443
+ return pageSize;
1444
+ }
1445
+ return Math.max(1, rangeSize || 1);
1446
+ };
1447
+ function RangeInput(props) {
1448
+ const { className = "", min, max, step, value, orientation, pageSize, stepButtons = false, startButtonAriaLabel, endButtonAriaLabel, eventTarget, decorations = [], onChange } = props;
1449
+ const vertical = orientation !== "horizontal";
1450
+ const rootRef = (0, import_hooks6.useRef)(null);
1451
+ const trackRef = (0, import_hooks6.useRef)(null);
1452
+ const thumbRef = (0, import_hooks6.useRef)(null);
1453
+ const dragStateRef = (0, import_hooks6.useRef)(null);
1454
+ const [trackLength, setTrackLength] = (0, import_hooks6.useState)(0);
1455
+ const range = max - min;
1456
+ const rangeSize = Math.max(0, value[1] - value[0]);
1457
+ const maxStart = Math.max(0, range - rangeSize);
1458
+ const clampedStart = clamp(value[0], min, min + maxStart);
1459
+ const { thumbLength, thumbOffset } = (0, import_hooks6.useMemo)(() => {
1460
+ if (trackLength <= 0 || range <= 0) {
1461
+ return { thumbLength: 0, thumbOffset: 0 };
1462
+ }
1463
+ if (range <= rangeSize) {
1464
+ return { thumbLength: 1, thumbOffset: 0 };
1465
+ }
1466
+ const nextThumbLength = rangeSize / range;
1467
+ const travel = Math.max(0, 1 - nextThumbLength);
1468
+ const ratio = maxStart <= 0 ? 0 : clamp((clampedStart - min) / maxStart, 0, 1);
1469
+ return {
1470
+ thumbLength: Math.max(0, Math.min(nextThumbLength, 1)),
1471
+ thumbOffset: travel * ratio
1472
+ };
1473
+ }, [trackLength, range, rangeSize, maxStart, clampedStart, min]);
1474
+ const emitRange = (0, import_hooks6.useCallback)((nextStart) => {
1475
+ if (!onChange) {
1476
+ return;
1477
+ }
1478
+ const clamped = clamp(nextStart, min, min + maxStart);
1479
+ onChange([clamped, clamped + rangeSize]);
1480
+ }, [onChange, min, maxStart, rangeSize]);
1481
+ const handleStepNegative = (0, import_hooks6.useCallback)((event) => {
1482
+ event.stopPropagation();
1483
+ emitRange(clampedStart - getEffectiveStep(step, range));
1484
+ }, [emitRange, clampedStart, step, range]);
1485
+ const handleStepPositive = (0, import_hooks6.useCallback)((event) => {
1486
+ event.stopPropagation();
1487
+ emitRange(clampedStart + getEffectiveStep(step, range));
1488
+ }, [emitRange, clampedStart, step, range]);
1489
+ const handleTrackClick = (0, import_hooks6.useCallback)((event) => {
1490
+ if (event.button !== 0) {
1491
+ return;
1492
+ }
1493
+ const target = event.target;
1494
+ if ((target == null ? void 0 : target.dataset.scrollbarThumb) === "true") {
1495
+ return;
1496
+ }
1497
+ const track = trackRef.current;
1498
+ if (!track) {
1499
+ return;
1500
+ }
1501
+ event.preventDefault();
1502
+ event.stopPropagation();
1503
+ const [trackStart] = getTrackDimension(track, vertical);
1504
+ const coordinate = vertical ? event.clientY - trackStart : event.clientX - trackStart;
1505
+ const span = Math.max(1, 1 - thumbLength) * trackLength;
1506
+ const thumbCenter = thumbLength / 2 * trackLength;
1507
+ const ratio = span <= 0 ? 0 : clamp((coordinate - thumbCenter) / span, 0, 1);
1508
+ emitRange(min + ratio * maxStart);
1509
+ }, [vertical, trackLength, thumbLength, emitRange, min, maxStart]);
1510
+ const handleThumbPointerDown = (event) => {
1511
+ if (event.button !== 0) {
1512
+ return;
1513
+ }
1514
+ const track = trackRef.current;
1515
+ if (!track) {
1516
+ return;
1517
+ }
1518
+ dragStateRef.current = {
1519
+ pointerId: event.pointerId,
1520
+ startCoord: vertical ? event.clientY : event.clientX,
1521
+ startRatio: thumbOffset,
1522
+ min,
1523
+ max,
1524
+ maxStart
1525
+ };
1526
+ event.currentTarget.setPointerCapture(event.pointerId);
1527
+ event.preventDefault();
1528
+ event.stopPropagation();
1529
+ };
1530
+ const handleThumbPointerMove = (0, import_hooks6.useCallback)((event) => {
1531
+ const state = dragStateRef.current;
1532
+ if (!state || state.pointerId !== event.pointerId) {
1533
+ return;
1534
+ }
1535
+ const [trackStart, trackLength2] = getTrackDimension(trackRef.current, vertical);
1536
+ const coordinate = vertical ? event.clientY : event.clientX;
1537
+ const delta = coordinate - state.startCoord;
1538
+ const ratio = state.startRatio + delta / trackLength2;
1539
+ const nextStart = clamp(ratio * (state.max - state.min), 0, state.maxStart) + state.min;
1540
+ emitRange(nextStart);
1541
+ event.preventDefault();
1542
+ }, [emitRange, vertical]);
1543
+ const handleThumbPointerUp = (0, import_hooks6.useCallback)((event) => {
1544
+ var _a;
1545
+ const state = dragStateRef.current;
1546
+ if (state && state.pointerId === event.pointerId) {
1547
+ dragStateRef.current = null;
1548
+ (_a = thumbRef.current) == null ? void 0 : _a.releasePointerCapture(event.pointerId);
1549
+ event.preventDefault();
1550
+ }
1551
+ }, []);
1552
+ const handleKeyDown = (0, import_hooks6.useCallback)((event) => {
1553
+ switch (event.key) {
1554
+ case "ArrowUp":
1555
+ case "ArrowLeft":
1556
+ if (vertical && event.key === "ArrowUp" || !vertical && event.key === "ArrowLeft") {
1557
+ emitRange(clampedStart - getEffectiveStep(step, range));
1558
+ event.preventDefault();
1559
+ }
1560
+ break;
1561
+ case "ArrowDown":
1562
+ case "ArrowRight":
1563
+ if (vertical && event.key === "ArrowDown" || !vertical && event.key === "ArrowRight") {
1564
+ emitRange(clampedStart + getEffectiveStep(step, range));
1565
+ event.preventDefault();
1566
+ }
1567
+ break;
1568
+ case "PageUp":
1569
+ emitRange(clampedStart - getEffectivePage(pageSize, rangeSize));
1570
+ event.preventDefault();
1571
+ break;
1572
+ case "PageDown":
1573
+ emitRange(clampedStart + getEffectivePage(pageSize, rangeSize));
1574
+ event.preventDefault();
1575
+ break;
1576
+ case "Home":
1577
+ emitRange(min);
1578
+ event.preventDefault();
1579
+ break;
1580
+ case "End":
1581
+ emitRange(min + maxStart);
1582
+ event.preventDefault();
1583
+ break;
1584
+ default:
1585
+ break;
1586
+ }
1587
+ }, [vertical, emitRange, clampedStart, step, range, pageSize, rangeSize, min, maxStart]);
1588
+ const handleWheel = (0, import_hooks6.useCallback)((event) => {
1589
+ event.preventDefault();
1590
+ event.stopPropagation();
1591
+ if (maxStart === 0) {
1592
+ return;
1593
+ }
1594
+ let delta = vertical ? event.deltaY : event.deltaX;
1595
+ if (!vertical && delta === 0) {
1596
+ delta = event.deltaY;
1597
+ }
1598
+ if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {
1599
+ delta *= getEffectiveStep(step, range);
1600
+ } else if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
1601
+ delta *= getEffectivePage(pageSize, rangeSize);
1602
+ }
1603
+ if (delta === 0) {
1604
+ return;
1605
+ }
1606
+ emitRange(clampedStart + delta);
1607
+ }, [emitRange, clampedStart, maxStart, vertical, step, range, pageSize, rangeSize]);
1608
+ (0, import_hooks6.useLayoutEffect)(() => {
1609
+ setTrackLength(getTrackDimension(trackRef.current, vertical)[1]);
1610
+ }, [vertical]);
1611
+ (0, import_hooks6.useLayoutEffect)(() => {
1612
+ const track = trackRef.current;
1613
+ if (!track) {
1614
+ return void 0;
1615
+ }
1616
+ const update = () => {
1617
+ setTrackLength(getTrackDimension(track, vertical)[1]);
1618
+ };
1619
+ update();
1620
+ if (typeof ResizeObserver !== "undefined") {
1621
+ const observer = new ResizeObserver(update);
1622
+ observer.observe(track);
1623
+ return () => observer.disconnect();
1624
+ }
1625
+ if (typeof window !== "undefined") {
1626
+ window.addEventListener("resize", update);
1627
+ return () => window.removeEventListener("resize", update);
1628
+ }
1629
+ return void 0;
1630
+ }, [vertical]);
1631
+ (0, import_hooks6.useEffect)(() => {
1632
+ const eventRoot = eventTarget ?? rootRef.current;
1633
+ if (!eventRoot)
1634
+ return void 0;
1635
+ eventRoot.addEventListener("keydown", handleKeyDown);
1636
+ eventRoot.addEventListener("wheel", handleWheel, wheelListenerOptions);
1637
+ return () => {
1638
+ eventRoot.removeEventListener("keydown", handleKeyDown);
1639
+ eventRoot.removeEventListener("wheel", handleWheel, wheelListenerOptions);
1640
+ };
1641
+ }, [eventTarget, handleKeyDown, handleWheel]);
1642
+ const decorationElements = (0, import_hooks6.useMemo)(() => {
1643
+ if (!decorations.length || range <= 0) {
1644
+ return [];
1645
+ }
1646
+ return decorations.map((decoration, index) => {
1647
+ const [start, end] = decoration.position;
1648
+ const startRatio = (start - min) / range;
1649
+ const endRatio = (end - min) / range;
1650
+ const offsetPct = Math.round(startRatio * 1e3) / 10;
1651
+ const sizePct = Math.max(0, Math.round((endRatio - startRatio) * 1e3) / 10);
1652
+ const style = vertical ? {
1653
+ left: "0",
1654
+ width: "100%",
1655
+ top: `${offsetPct}%`,
1656
+ height: `${sizePct}%`
1657
+ } : {
1658
+ top: "0",
1659
+ height: "100%",
1660
+ left: `${offsetPct}%`,
1661
+ width: `${sizePct}%`
1662
+ };
1663
+ return (0, import_jsx_runtime19.jsx)("div", { className: "deck-widget-range__decoration", style, children: decoration.element }, `decoration-${index}`);
1664
+ });
1665
+ }, [decorations, range, min, vertical]);
1666
+ return (0, import_jsx_runtime19.jsxs)("div", { ref: rootRef, tabIndex: 0, role: "scrollbar", "aria-valuemin": min, "aria-valuemax": min + maxStart, "aria-valuenow": clampedStart, "aria-orientation": orientation, className: `${className} deck-widget-range deck-widget-range--${orientation} ${maxStart === 0 ? "deck-widget-range--disabled" : ""}`, children: [stepButtons && (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "deck-widget-range__button deck-widget-range__button--start", "aria-label": startButtonAriaLabel, disabled: clampedStart <= min, onClick: handleStepNegative, children: (0, import_jsx_runtime19.jsx)("span", { className: "deck-widget-icon" }) }), (0, import_jsx_runtime19.jsxs)("div", { className: "deck-widget-range__track", ref: trackRef, onClick: handleTrackClick, children: [(0, import_jsx_runtime19.jsx)("div", { className: "deck-widget-range__decorations", children: decorationElements }), (0, import_jsx_runtime19.jsx)("div", { className: "deck-widget-range__thumb", "data-scrollbar-thumb": "true", ref: thumbRef, style: vertical ? { height: `${thumbLength * 100}%`, top: `${thumbOffset * 100}%` } : { width: `${thumbLength * 100}%`, left: `${thumbOffset * 100}%` }, onPointerDown: handleThumbPointerDown, onPointerMove: handleThumbPointerMove, onPointerUp: handleThumbPointerUp, onPointerCancel: handleThumbPointerUp })] }), stepButtons && (0, import_jsx_runtime19.jsx)("button", { type: "button", className: "deck-widget-range__button deck-widget-range__button--end", "aria-label": endButtonAriaLabel, disabled: clampedStart >= min + maxStart, onClick: handleStepPositive, children: (0, import_jsx_runtime19.jsx)("span", { className: "deck-widget-icon" }) })] });
1667
+ }
1668
+
1669
+ // dist/scrollbar-widget.js
1670
+ var clamp2 = (value, min, max) => {
1671
+ if (value < min) {
1672
+ return min;
1673
+ }
1674
+ if (value > max) {
1675
+ return max;
1676
+ }
1677
+ return value;
1678
+ };
1679
+ var ScrollbarWidget = class extends import_core14.Widget {
1680
+ constructor(props) {
1681
+ const resolved = {
1682
+ ...ScrollbarWidget.defaultProps,
1683
+ ...props
1684
+ };
1685
+ super(resolved);
1686
+ this.className = "deck-widget-scrollbar";
1687
+ this.placement = "fill";
1688
+ this.contentSize = 0;
1689
+ this.viewportSize = 0;
1690
+ this.scrollOffset = 0;
1691
+ this.handleRangeChange = (nextValue) => {
1692
+ this.emitScroll(nextValue[0]);
1693
+ };
1694
+ this.viewId = resolved.viewId ?? null;
1695
+ }
1696
+ onViewportChange(viewport) {
1697
+ this.viewport = viewport;
1698
+ this.onRenderHTML();
1699
+ }
1700
+ onRenderHTML() {
1701
+ const element = this.rootElement;
1702
+ if (!element) {
1703
+ return;
1704
+ }
1705
+ element.dataset.placement = this.props.placement;
1706
+ const viewport = this.viewport;
1707
+ this.updateViewport(viewport);
1708
+ const clampedOffset = this.getClampedOffset();
1709
+ const wheelTarget = this.getWheelEventTarget(this.props.captureWheel ? "global" : "local");
1710
+ const decorations = this.getDecorations(viewport);
1711
+ const isVertical = this.isVertical();
1712
+ const startLabel = this.props.startButtonAriaLabel ?? (isVertical ? "Scroll up" : "Scroll left");
1713
+ const endLabel = this.props.endButtonAriaLabel ?? (isVertical ? "Scroll down" : "Scroll right");
1714
+ const ui = (0, import_jsx_runtime20.jsx)(RangeInput, { min: 0, max: Math.max(0, this.contentSize), step: this.getEffectiveStep(), pageSize: this.getEffectivePage(), value: [clampedOffset, clampedOffset + this.viewportSize], orientation: this.props.orientation, stepButtons: true, startButtonAriaLabel: startLabel, endButtonAriaLabel: endLabel, eventTarget: wheelTarget, decorations, onChange: this.handleRangeChange });
1715
+ (0, import_preact13.render)(ui, element);
1716
+ }
1717
+ onRemove() {
1718
+ if (this.rootElement) {
1719
+ (0, import_preact13.render)(null, this.rootElement);
1720
+ }
1721
+ super.onRemove();
1722
+ }
1723
+ updateViewport(viewport) {
1724
+ if (!viewport) {
1725
+ this.contentSize = 0;
1726
+ this.scrollOffset = 0;
1727
+ this.viewportSize = 0;
1728
+ return;
1729
+ }
1730
+ const { contentBounds } = this.props;
1731
+ const isVertical = this.isVertical();
1732
+ const projectedBounds = contentBounds ? projectBounds(contentBounds, viewport, isVertical) : [0, 0];
1733
+ this.contentSize = projectedBounds[1] - projectedBounds[0];
1734
+ this.scrollOffset = -projectedBounds[0];
1735
+ this.viewportSize = isVertical ? viewport.height : viewport.width;
1736
+ }
1737
+ getDecorations(viewport) {
1738
+ const { decorations = [], contentBounds } = this.props;
1739
+ if (!viewport || !contentBounds || decorations.length === 0) {
1740
+ return [];
1741
+ }
1742
+ const isVertical = this.isVertical();
1743
+ const [contentStart] = projectBounds(contentBounds, viewport, isVertical);
1744
+ return decorations.map((decoration) => {
1745
+ const [start, end] = projectBounds(decoration.contentBounds, viewport, isVertical);
1746
+ const onClick = decoration.onClick ? (e) => {
1747
+ var _a;
1748
+ const handled = (_a = decoration.onClick) == null ? void 0 : _a.call(decoration, e);
1749
+ if (handled) {
1750
+ e.stopPropagation();
1751
+ e.preventDefault();
1752
+ }
1753
+ } : void 0;
1754
+ return {
1755
+ position: [start - contentStart, end - contentStart],
1756
+ element: (0, import_jsx_runtime20.jsx)("div", { style: {
1757
+ pointerEvents: onClick ? "all" : "none",
1758
+ width: "100%",
1759
+ height: "100%",
1760
+ backgroundColor: decoration.color
1761
+ }, title: decoration.title, onClick })
1762
+ };
1763
+ });
1764
+ }
1765
+ getWheelEventTarget(mode) {
1766
+ var _a, _b, _c;
1767
+ if (mode === null)
1768
+ return null;
1769
+ if (mode === "local")
1770
+ return this.rootElement;
1771
+ return ((_a = this.deck) == null ? void 0 : _a.props.parent) || ((_c = (_b = this.deck) == null ? void 0 : _b.getCanvas()) == null ? void 0 : _c.parentElement) || this.rootElement;
1772
+ }
1773
+ getMaxScroll() {
1774
+ return Math.max(0, this.contentSize - this.viewportSize);
1775
+ }
1776
+ getClampedOffset() {
1777
+ const maxScroll = this.getMaxScroll();
1778
+ return clamp2(this.scrollOffset, 0, maxScroll);
1779
+ }
1780
+ isVertical() {
1781
+ return this.props.orientation !== "horizontal";
1782
+ }
1783
+ getEffectiveStep() {
1784
+ if (typeof this.props.stepSize === "number" && !Number.isNaN(this.props.stepSize)) {
1785
+ return this.props.stepSize;
1786
+ }
1787
+ return Math.max(1, this.viewportSize / 10 || 1);
1788
+ }
1789
+ getEffectivePage() {
1790
+ if (typeof this.props.pageSize === "number" && !Number.isNaN(this.props.pageSize)) {
1791
+ return this.props.pageSize;
1792
+ }
1793
+ return this.viewportSize;
1794
+ }
1795
+ emitScroll(next) {
1796
+ const maxScroll = this.getMaxScroll();
1797
+ const target = clamp2(Math.round(next), 0, maxScroll);
1798
+ const viewport = this.viewport;
1799
+ if (viewport && target !== this.getClampedOffset()) {
1800
+ const pixel = viewport.project(viewport.position);
1801
+ if (this.isVertical()) {
1802
+ pixel[1] -= target - this.scrollOffset;
1803
+ } else {
1804
+ pixel[0] -= target - this.scrollOffset;
1805
+ }
1806
+ const { target: newTarget } = viewport.panByPosition(viewport.position, pixel);
1807
+ this.deck._onViewStateChange({
1808
+ viewId: viewport.id,
1809
+ viewState: {
1810
+ ...this.getViewState(viewport.id),
1811
+ target: newTarget
1812
+ },
1813
+ interactionState: {}
1814
+ });
1815
+ }
1816
+ }
1817
+ };
1818
+ ScrollbarWidget.defaultProps = {
1819
+ ...import_core14.Widget.defaultProps,
1820
+ contentBounds: null,
1821
+ placement: "top-right",
1822
+ viewId: null,
1823
+ orientation: "vertical",
1824
+ stepSize: null,
1825
+ pageSize: null,
1826
+ startButtonAriaLabel: "",
1827
+ endButtonAriaLabel: "",
1828
+ captureWheel: false,
1829
+ decorations: []
1830
+ };
1831
+ function projectBounds(bounds, viewport, isVertical) {
1832
+ return bounds.map(([x, y]) => viewport.project([x, y, 0])).reduce((range, [x, y]) => {
1833
+ const value = isVertical ? y : x;
1834
+ range[0] = Math.min(range[0], value);
1835
+ range[1] = Math.max(range[1], value);
1836
+ return range;
1837
+ }, [Infinity, -Infinity]);
1838
+ }
1839
+
1345
1840
  // dist/timeline-widget.js
1346
- var import_jsx_runtime18 = require("preact/jsx-runtime");
1347
- var import_core13 = require("@deck.gl/core");
1348
- var import_preact12 = require("preact");
1349
- var TimelineWidget = class extends import_core13.Widget {
1841
+ var import_jsx_runtime21 = require("preact/jsx-runtime");
1842
+ var import_core15 = require("@deck.gl/core");
1843
+ var import_preact14 = require("preact");
1844
+ var TimelineWidget = class extends import_core15.Widget {
1350
1845
  constructor(props = {}) {
1846
+ var _a;
1351
1847
  super(props);
1352
1848
  this.id = "timeline";
1353
1849
  this.className = "deck-widget-timeline";
1354
- this.placement = "bottom-left";
1850
+ this.placement = "fill";
1355
1851
  this.playing = false;
1356
1852
  this.timerId = null;
1357
1853
  this.handlePlayPause = () => {
1358
1854
  if (this.playing) {
1359
1855
  this.stop();
1360
1856
  } else {
1361
- this.start();
1857
+ this.play();
1362
1858
  }
1363
1859
  };
1364
- this.handleSliderChange = (e) => {
1365
- const input = e.target;
1366
- const val = Number(input.value);
1367
- this.currentTime = val;
1368
- this.props.onTimeChange(val);
1860
+ this.handleTimeChange = ([value]) => {
1861
+ var _a2;
1862
+ this.currentTime = value;
1863
+ (_a2 = this.props.timeline) == null ? void 0 : _a2.setTime(value);
1864
+ this.props.onTimeChange(value);
1369
1865
  this.updateHTML();
1370
1866
  };
1371
1867
  this.tick = () => {
1372
- const [min, max] = this.props.timeRange;
1373
- let next = this.currentTime + this.props.step;
1374
- if (next > max) {
1375
- next = min;
1868
+ const { timeRange: [min, max], step, loop } = this.props;
1869
+ if (step > 0) {
1870
+ let next = Math.floor(this.currentTime / step) * step + step;
1871
+ if (next > max) {
1872
+ if (this.currentTime < max) {
1873
+ next = max;
1874
+ } else if (loop) {
1875
+ next = min;
1876
+ } else {
1877
+ next = max;
1878
+ this.playing = false;
1879
+ }
1880
+ }
1881
+ this.currentTime = next;
1882
+ this.props.onTimeChange(next);
1883
+ this.updateHTML();
1376
1884
  }
1377
- this.currentTime = next;
1378
- this.props.onTimeChange(next);
1379
- this.updateHTML();
1380
1885
  if (this.playing) {
1381
1886
  this.timerId = window.setTimeout(this.tick, this.props.playInterval);
1887
+ } else {
1888
+ this.timerId = null;
1382
1889
  }
1383
1890
  };
1384
1891
  this.currentTime = this.props.initialTime ?? this.props.timeRange[0];
1892
+ (_a = this.props.timeline) == null ? void 0 : _a.setTime(this.currentTime);
1385
1893
  this.setProps(this.props);
1386
1894
  }
1387
1895
  setProps(props) {
1388
- this.placement = props.placement ?? this.placement;
1389
1896
  this.viewId = props.viewId ?? this.viewId;
1390
1897
  super.setProps(props);
1391
1898
  }
1392
1899
  onAdd() {
1393
1900
  this.playing = false;
1394
1901
  this.timerId = null;
1902
+ if (this.props.autoPlay)
1903
+ this.play();
1395
1904
  }
1396
1905
  onRemove() {
1397
1906
  this.stop();
1398
1907
  }
1399
1908
  onRenderHTML(rootElement) {
1400
- (0, import_preact12.render)((0, import_jsx_runtime18.jsxs)("div", { style: { display: "flex", alignItems: "center", pointerEvents: "auto" }, children: [(0, import_jsx_runtime18.jsx)(IconButton, { label: this.playing ? "Pause" : "Play", onClick: this.handlePlayPause, children: (0, import_jsx_runtime18.jsx)("div", { className: "text", children: this.playing ? "\u23F8" : "\u25B6" }) }), (0, import_jsx_runtime18.jsx)("input", { type: "range", className: "timeline-slider", min: this.props.timeRange[0], max: this.props.timeRange[1], step: this.props.step, value: this.currentTime, onInput: this.handleSliderChange })] }), rootElement);
1909
+ const { timeRange, step, formatLabel } = this.props;
1910
+ const currentTime = this.currentTime;
1911
+ rootElement.dataset.placement = this.props.placement;
1912
+ (0, import_preact14.render)((0, import_jsx_runtime21.jsxs)("div", { className: "deck-widget-button-group", children: [this.playing ? (0, import_jsx_runtime21.jsx)(IconButton, { label: "Pause", className: "deck-widget-timeline-pause", onClick: this.handlePlayPause }) : (0, import_jsx_runtime21.jsx)(IconButton, { label: "Play", className: "deck-widget-timeline-play", onClick: this.handlePlayPause }), (0, import_jsx_runtime21.jsx)(RangeInput, { min: timeRange[0], max: timeRange[1], orientation: "horizontal", step, value: [currentTime, currentTime], onChange: this.handleTimeChange, decorations: [
1913
+ {
1914
+ position: [currentTime, currentTime + step],
1915
+ element: (0, import_jsx_runtime21.jsx)("div", { className: "deck-widget-timeline-label deck-widget-timeline-label--current", children: formatLabel(currentTime) })
1916
+ }
1917
+ ] })] }), rootElement);
1401
1918
  }
1402
- start() {
1919
+ play() {
1403
1920
  this.playing = true;
1404
1921
  this.updateHTML();
1405
1922
  this.tick();
@@ -1414,23 +1931,27 @@ var TimelineWidget = class extends import_core13.Widget {
1414
1931
  }
1415
1932
  };
1416
1933
  TimelineWidget.defaultProps = {
1417
- ...import_core13.Widget.defaultProps,
1934
+ ...import_core15.Widget.defaultProps,
1418
1935
  id: "timeline",
1419
1936
  placement: "bottom-left",
1420
1937
  viewId: null,
1938
+ timeline: null,
1421
1939
  timeRange: [0, 100],
1422
1940
  step: 1,
1423
1941
  initialTime: void 0,
1424
1942
  onTimeChange: () => {
1425
1943
  },
1426
- playInterval: 1e3
1944
+ autoPlay: false,
1945
+ loop: false,
1946
+ playInterval: 1e3,
1947
+ formatLabel: String
1427
1948
  };
1428
1949
 
1429
1950
  // dist/screenshot-widget.js
1430
- var import_jsx_runtime19 = require("preact/jsx-runtime");
1431
- var import_preact13 = require("preact");
1432
- var import_core14 = require("@deck.gl/core");
1433
- var ScreenshotWidget = class extends import_core14.Widget {
1951
+ var import_jsx_runtime22 = require("preact/jsx-runtime");
1952
+ var import_preact15 = require("preact");
1953
+ var import_core16 = require("@deck.gl/core");
1954
+ var ScreenshotWidget = class extends import_core16.Widget {
1434
1955
  constructor(props = {}) {
1435
1956
  super(props);
1436
1957
  this.className = "deck-widget-screenshot";
@@ -1443,7 +1964,7 @@ var ScreenshotWidget = class extends import_core14.Widget {
1443
1964
  super.setProps(props);
1444
1965
  }
1445
1966
  onRenderHTML(rootElement) {
1446
- (0, import_preact13.render)((0, import_jsx_runtime19.jsx)(IconButton, { className: "deck-widget-camera", label: this.props.label, onClick: this.handleClick.bind(this) }), rootElement);
1967
+ (0, import_preact15.render)((0, import_jsx_runtime22.jsx)(IconButton, { className: "deck-widget-camera", label: this.props.label, onClick: this.handleClick.bind(this) }), rootElement);
1447
1968
  }
1448
1969
  handleClick() {
1449
1970
  if (this.props.onCapture) {
@@ -1470,7 +1991,7 @@ var ScreenshotWidget = class extends import_core14.Widget {
1470
1991
  }
1471
1992
  };
1472
1993
  ScreenshotWidget.defaultProps = {
1473
- ...import_core14.Widget.defaultProps,
1994
+ ...import_core16.Widget.defaultProps,
1474
1995
  id: "screenshot",
1475
1996
  placement: "top-left",
1476
1997
  viewId: null,
@@ -1481,10 +2002,10 @@ ScreenshotWidget.defaultProps = {
1481
2002
  };
1482
2003
 
1483
2004
  // dist/theme-widget.js
1484
- var import_jsx_runtime20 = require("preact/jsx-runtime");
1485
- var import_core15 = require("@deck.gl/core");
1486
- var import_core16 = require("@deck.gl/core");
1487
- var import_preact14 = require("preact");
2005
+ var import_jsx_runtime23 = require("preact/jsx-runtime");
2006
+ var import_core17 = require("@deck.gl/core");
2007
+ var import_core18 = require("@deck.gl/core");
2008
+ var import_preact16 = require("preact");
1488
2009
 
1489
2010
  // dist/themes.js
1490
2011
  var LightTheme = {
@@ -1507,7 +2028,13 @@ var LightTheme = {
1507
2028
  "--menu-border": "unset",
1508
2029
  "--menu-shadow": "0px 0px 8px 0px rgba(0, 0, 0, 0.25)",
1509
2030
  "--menu-text": "rgb(24, 24, 26, 1)",
1510
- "--menu-item-hover": "rgba(0, 0, 0, 0.08)"
2031
+ "--menu-item-hover": "rgba(0, 0, 0, 0.08)",
2032
+ "--range-step-button-size": "24px",
2033
+ "--range-track-size": "16px",
2034
+ "--range-thumb-size": "10px",
2035
+ "--range-track-color": "#d8d8e5",
2036
+ "--range-thumb-color": "#616166",
2037
+ "--range-decoration-active-color": "#f8dd50"
1511
2038
  };
1512
2039
  var DarkTheme = {
1513
2040
  "--widget-margin": "12px",
@@ -1529,7 +2056,13 @@ var DarkTheme = {
1529
2056
  "--menu-border": "unset",
1530
2057
  "--menu-shadow": "0px 0px 8px 0px rgba(0, 0, 0, 0.25)",
1531
2058
  "--menu-text": "rgb(215, 214, 229, 1)",
1532
- "--menu-item-hover": "rgba(255, 255, 255, 0.1)"
2059
+ "--menu-item-hover": "rgba(255, 255, 255, 0.1)",
2060
+ "--range-step-button-size": "24px",
2061
+ "--range-track-size": "16px",
2062
+ "--range-thumb-size": "10px",
2063
+ "--range-track-color": "#2c2c30",
2064
+ "--range-thumb-color": "#9e9da8",
2065
+ "--range-decoration-active-color": "#dd7d2c"
1533
2066
  };
1534
2067
  var LightGlassTheme = {
1535
2068
  "--widget-margin": "12px",
@@ -1551,7 +2084,13 @@ var LightGlassTheme = {
1551
2084
  "--menu-border": "1px solid rgba(255, 255, 255, 0.6)",
1552
2085
  "--menu-shadow": "0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset",
1553
2086
  "--menu-text": "rgb(24, 24, 26, 1)",
1554
- "--menu-item-hover": "rgba(0, 0, 0, 0.08)"
2087
+ "--menu-item-hover": "rgba(0, 0, 0, 0.08)",
2088
+ "--range-step-button-size": "24px",
2089
+ "--range-track-size": "16px",
2090
+ "--range-thumb-size": "10px",
2091
+ "--range-track-color": "rgba(215, 214, 229, 0.3)",
2092
+ "--range-thumb-color": "rgba(97, 97, 102, 1)",
2093
+ "--range-decoration-active-color": "rgba(255, 215, 0, 0.6)"
1555
2094
  };
1556
2095
  var DarkGlassTheme = {
1557
2096
  "--widget-margin": "12px",
@@ -1573,11 +2112,17 @@ var DarkGlassTheme = {
1573
2112
  "--menu-border": "1px solid rgba(18, 18, 20, 0.75)",
1574
2113
  "--menu-shadow": "0px 0px 8px 0px rgba(0, 0, 0, 0.25), 0px 0px 8px 0px rgba(0, 0, 0, 0.1) inset",
1575
2114
  "--menu-text": "rgb(215, 214, 229, 1)",
1576
- "--menu-item-hover": "rgba(255, 255, 255, 0.1)"
2115
+ "--menu-item-hover": "rgba(255, 255, 255, 0.1)",
2116
+ "--range-step-button-size": "24px",
2117
+ "--range-track-size": "16px",
2118
+ "--range-thumb-size": "10px",
2119
+ "--range-track-color": "rgba(24, 24, 26, 0.3)",
2120
+ "--range-thumb-color": "rgba(158, 157, 168, 1)",
2121
+ "--range-decoration-active-color": "rgba(255, 145, 0, 0.6)"
1577
2122
  };
1578
2123
 
1579
2124
  // dist/theme-widget.js
1580
- var ThemeWidget = class extends import_core16.Widget {
2125
+ var ThemeWidget = class extends import_core18.Widget {
1581
2126
  constructor(props = {}) {
1582
2127
  super(props);
1583
2128
  this.className = "deck-widget-theme";
@@ -1594,22 +2139,22 @@ var ThemeWidget = class extends import_core16.Widget {
1594
2139
  super.setProps(props);
1595
2140
  switch (this.themeMode) {
1596
2141
  case "light":
1597
- if (props.lightModeTheme && !(0, import_core15._deepEqual)(props.lightModeTheme, lightModeTheme, 1)) {
2142
+ if (props.lightModeTheme && !(0, import_core17._deepEqual)(props.lightModeTheme, lightModeTheme, 1)) {
1598
2143
  this._setThemeMode("light");
1599
2144
  }
1600
2145
  break;
1601
2146
  case "dark":
1602
- if (props.darkModeTheme && !(0, import_core15._deepEqual)(props.darkModeTheme, darkModeTheme, 1)) {
2147
+ if (props.darkModeTheme && !(0, import_core17._deepEqual)(props.darkModeTheme, darkModeTheme, 1)) {
1603
2148
  this._setThemeMode("dark");
1604
2149
  }
1605
2150
  break;
1606
2151
  default:
1607
- import_core15.log.warn(`Invalid theme mode ${this.themeMode}`)();
2152
+ import_core17.log.warn(`Invalid theme mode ${this.themeMode}`)();
1608
2153
  }
1609
2154
  }
1610
2155
  onRenderHTML(rootElement) {
1611
2156
  const { lightModeLabel, darkModeLabel } = this.props;
1612
- (0, import_preact14.render)((0, import_jsx_runtime20.jsx)(IconButton, { onClick: this._handleClick.bind(this), label: this.themeMode === "dark" ? darkModeLabel : lightModeLabel, className: this.themeMode === "dark" ? "deck-widget-moon" : "deck-widget-sun" }), rootElement);
2157
+ (0, import_preact16.render)((0, import_jsx_runtime23.jsx)(IconButton, { onClick: this._handleClick.bind(this), label: this.themeMode === "dark" ? darkModeLabel : lightModeLabel, className: this.themeMode === "dark" ? "deck-widget-moon" : "deck-widget-sun" }), rootElement);
1613
2158
  }
1614
2159
  onAdd() {
1615
2160
  this._setThemeMode(this.themeMode);
@@ -1624,20 +2169,26 @@ var ThemeWidget = class extends import_core16.Widget {
1624
2169
  const container = (_a = this.rootElement) == null ? void 0 : _a.closest(".deck-widget-container");
1625
2170
  if (container) {
1626
2171
  const themeStyle = themeMode === "dark" ? this.props.darkModeTheme : this.props.lightModeTheme;
1627
- (0, import_core15._applyStyles)(container, themeStyle);
2172
+ (0, import_core17._applyStyles)(container, themeStyle);
1628
2173
  const label = this.themeMode === "dark" ? this.props.darkModeLabel : this.props.lightModeLabel;
1629
- import_core15.log.log(1, `Switched theme to ${label}`, themeStyle)();
2174
+ import_core17.log.log(1, `Switched theme to ${label}`, themeStyle)();
1630
2175
  this.updateHTML();
1631
2176
  }
1632
2177
  }
1633
2178
  /** Read browser preference */
1634
2179
  _getInitialThemeMode() {
1635
2180
  const { initialThemeMode } = this.props;
1636
- return initialThemeMode === "auto" ? window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light" : initialThemeMode;
2181
+ if (initialThemeMode !== "auto") {
2182
+ return initialThemeMode;
2183
+ }
2184
+ if (typeof window === "undefined") {
2185
+ return "light";
2186
+ }
2187
+ return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
1637
2188
  }
1638
2189
  };
1639
2190
  ThemeWidget.defaultProps = {
1640
- ...import_core16.Widget.defaultProps,
2191
+ ...import_core18.Widget.defaultProps,
1641
2192
  id: "theme",
1642
2193
  placement: "top-left",
1643
2194
  viewId: null,
@@ -1649,10 +2200,10 @@ ThemeWidget.defaultProps = {
1649
2200
  };
1650
2201
 
1651
2202
  // dist/loading-widget.js
1652
- var import_jsx_runtime21 = require("preact/jsx-runtime");
1653
- var import_preact15 = require("preact");
1654
- var import_core17 = require("@deck.gl/core");
1655
- var LoadingWidget = class extends import_core17.Widget {
2203
+ var import_jsx_runtime24 = require("preact/jsx-runtime");
2204
+ var import_preact17 = require("preact");
2205
+ var import_core19 = require("@deck.gl/core");
2206
+ var LoadingWidget = class extends import_core19.Widget {
1656
2207
  constructor(props = {}) {
1657
2208
  super(props);
1658
2209
  this.className = "deck-widget-loading";
@@ -1666,9 +2217,9 @@ var LoadingWidget = class extends import_core17.Widget {
1666
2217
  super.setProps(props);
1667
2218
  }
1668
2219
  onRenderHTML(rootElement) {
1669
- (0, import_preact15.render)(
2220
+ (0, import_preact17.render)(
1670
2221
  // TODO(ibgreen) - this should not be a button, but styling is so nested that it is easier to reuse this component.
1671
- this.loading && (0, import_jsx_runtime21.jsx)(IconButton, { className: "deck-widget-spinner", label: this.props.label, onClick: this.handleClick.bind(this) }),
2222
+ this.loading && (0, import_jsx_runtime24.jsx)(IconButton, { className: "deck-widget-spinner", label: this.props.label, onClick: this.handleClick.bind(this) }),
1672
2223
  rootElement
1673
2224
  );
1674
2225
  }
@@ -1684,7 +2235,7 @@ var LoadingWidget = class extends import_core17.Widget {
1684
2235
  }
1685
2236
  };
1686
2237
  LoadingWidget.defaultProps = {
1687
- ...import_core17.Widget.defaultProps,
2238
+ ...import_core19.Widget.defaultProps,
1688
2239
  id: "loading",
1689
2240
  placement: "top-left",
1690
2241
  viewId: null,
@@ -1692,10 +2243,10 @@ LoadingWidget.defaultProps = {
1692
2243
  };
1693
2244
 
1694
2245
  // dist/fps-widget.js
1695
- var import_jsx_runtime22 = require("preact/jsx-runtime");
1696
- var import_core18 = require("@deck.gl/core");
1697
- var import_preact16 = require("preact");
1698
- var FpsWidget = class extends import_core18.Widget {
2246
+ var import_jsx_runtime25 = require("preact/jsx-runtime");
2247
+ var import_core20 = require("@deck.gl/core");
2248
+ var import_preact18 = require("preact");
2249
+ var FpsWidget = class extends import_core20.Widget {
1699
2250
  constructor(props = {}) {
1700
2251
  super(props);
1701
2252
  this.className = "deck-widget-fps";
@@ -1714,7 +2265,7 @@ var FpsWidget = class extends import_core18.Widget {
1714
2265
  }
1715
2266
  onRenderHTML(rootElement) {
1716
2267
  const fps = this._getFps();
1717
- (0, import_preact16.render)((0, import_jsx_runtime22.jsx)(IconButton, { children: (0, import_jsx_runtime22.jsxs)("div", { className: "text", children: ["FPS", (0, import_jsx_runtime22.jsx)("br", {}), fps] }) }), rootElement);
2268
+ (0, import_preact18.render)((0, import_jsx_runtime25.jsx)(IconButton, { children: (0, import_jsx_runtime25.jsxs)("div", { className: "text", children: ["FPS", (0, import_jsx_runtime25.jsx)("br", {}), fps] }) }), rootElement);
1718
2269
  }
1719
2270
  _animate() {
1720
2271
  const fps = this._getFps();
@@ -1730,19 +2281,17 @@ var FpsWidget = class extends import_core18.Widget {
1730
2281
  }
1731
2282
  };
1732
2283
  FpsWidget.defaultProps = {
1733
- ...import_core18.Widget.defaultProps,
2284
+ ...import_core20.Widget.defaultProps,
1734
2285
  id: "fps",
1735
2286
  placement: "top-left",
1736
2287
  viewId: null
1737
2288
  };
1738
2289
 
1739
2290
  // dist/stats-widget.js
1740
- var import_jsx_runtime23 = require("preact/jsx-runtime");
1741
- var import_core19 = require("@deck.gl/core");
1742
- var import_core20 = require("@luma.gl/core");
1743
- var import_preact17 = require("preact");
1744
- var RIGHT_ARROW = "\u25B6";
1745
- var DOWN_ARROW = "\u2B07";
2291
+ var import_jsx_runtime26 = require("preact/jsx-runtime");
2292
+ var import_core21 = require("@deck.gl/core");
2293
+ var import_core22 = require("@luma.gl/core");
2294
+ var import_preact19 = require("preact");
1746
2295
  var DEFAULT_COUNT_FORMATTER = (stat) => `${stat.name}: ${stat.count}`;
1747
2296
  function formatTime(time) {
1748
2297
  return time < 1e3 ? `${time.toFixed(2)}ms` : `${(time / 1e3).toFixed(2)}s`;
@@ -1758,7 +2307,7 @@ var DEFAULT_FORMATTERS = {
1758
2307
  fps: (stat) => `${stat.name}: ${Math.round(stat.getHz())}fps`,
1759
2308
  memory: (stat) => `${stat.name}: ${formatMemory(stat.count)}`
1760
2309
  };
1761
- var StatsWidget = class extends import_core19.Widget {
2310
+ var StatsWidget = class extends import_core21.Widget {
1762
2311
  constructor(props = {}) {
1763
2312
  super(props);
1764
2313
  this.className = "deck-widget-stats";
@@ -1771,6 +2320,7 @@ var StatsWidget = class extends import_core19.Widget {
1771
2320
  };
1772
2321
  this._formatters = { ...DEFAULT_FORMATTERS };
1773
2322
  this._resetOnUpdate = { ...this.props.resetOnUpdate };
2323
+ this.collapsed = !props.defaultIsExpanded;
1774
2324
  this.setProps(props);
1775
2325
  }
1776
2326
  setProps(props) {
@@ -1802,11 +2352,11 @@ var StatsWidget = class extends import_core19.Widget {
1802
2352
  stat.reset();
1803
2353
  }
1804
2354
  lines.forEach((line, i) => {
1805
- items.push((0, import_jsx_runtime23.jsx)("div", { style: { whiteSpace: "pre" }, children: line }, `${stat.name}-${i}`));
2355
+ items.push((0, import_jsx_runtime26.jsx)("div", { style: { whiteSpace: "pre" }, children: line }, `${stat.name}-${i}`));
1806
2356
  });
1807
2357
  });
1808
2358
  }
1809
- (0, import_preact17.render)((0, import_jsx_runtime23.jsxs)("div", { className: "deck-widget-stats-container", style: { cursor: "default" }, children: [(0, import_jsx_runtime23.jsxs)("div", { className: "deck-widget-stats-header", style: { cursor: "pointer", pointerEvents: "auto" }, onClick: this._toggleCollapsed, children: [collapsed ? RIGHT_ARROW : DOWN_ARROW, " ", title] }), !collapsed && (0, import_jsx_runtime23.jsx)("div", { className: "deck-widget-stats-content", children: items })] }), rootElement);
2359
+ (0, import_preact19.render)((0, import_jsx_runtime26.jsxs)("div", { className: "deck-widget-stats-container", style: { cursor: "default" }, children: [(0, import_jsx_runtime26.jsxs)("div", { className: "deck-widget-stats-header", style: { cursor: "pointer", pointerEvents: "auto" }, onClick: this._toggleCollapsed, children: [(0, import_jsx_runtime26.jsx)("b", { children: title }), (0, import_jsx_runtime26.jsx)("button", { className: "deck-widget-dropdown-button", children: (0, import_jsx_runtime26.jsx)("span", { className: `deck-widget-dropdown-icon ${collapsed ? "" : "open"}` }) })] }), !collapsed && (0, import_jsx_runtime26.jsx)("div", { className: "deck-widget-stats-content", children: items })] }), rootElement);
1810
2360
  }
1811
2361
  onRedraw() {
1812
2362
  const framesPerUpdate = Math.max(1, this.props.framesPerUpdate || 1);
@@ -1821,7 +2371,7 @@ var StatsWidget = class extends import_core19.Widget {
1821
2371
  const metrics = ((_a = this.deck) == null ? void 0 : _a.metrics) ?? {};
1822
2372
  return Object.entries(metrics);
1823
2373
  case "luma":
1824
- return Array.from(import_core20.luma.stats.stats.values())[0];
2374
+ return Array.from(import_core22.luma.stats.stats.values())[0];
1825
2375
  case "device":
1826
2376
  const device = (_b = this.deck) == null ? void 0 : _b.device;
1827
2377
  const stats = device == null ? void 0 : device.statsManager.stats.values();
@@ -1843,10 +2393,11 @@ var StatsWidget = class extends import_core19.Widget {
1843
2393
  }
1844
2394
  };
1845
2395
  StatsWidget.defaultProps = {
1846
- ...import_core19.Widget.defaultProps,
2396
+ ...import_core21.Widget.defaultProps,
1847
2397
  type: "deck",
1848
2398
  placement: "top-left",
1849
2399
  viewId: null,
2400
+ defaultIsExpanded: false,
1850
2401
  stats: void 0,
1851
2402
  title: "Stats",
1852
2403
  framesPerUpdate: 1,