@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.
- package/dist/compass-widget.js +5 -5
- package/dist/compass-widget.js.map +1 -1
- package/dist/context-menu-widget.d.ts +23 -18
- package/dist/context-menu-widget.d.ts.map +1 -1
- package/dist/context-menu-widget.js +44 -48
- package/dist/context-menu-widget.js.map +1 -1
- package/dist/dist.dev.js +2533 -420
- package/dist/fullscreen-widget.js +1 -1
- package/dist/fullscreen-widget.js.map +1 -1
- package/dist/geocoder-widget.d.ts +2 -4
- package/dist/geocoder-widget.d.ts.map +1 -1
- package/dist/geocoder-widget.js +16 -20
- package/dist/geocoder-widget.js.map +1 -1
- package/dist/gimbal-widget.d.ts +0 -3
- package/dist/gimbal-widget.d.ts.map +1 -1
- package/dist/gimbal-widget.js +4 -22
- package/dist/gimbal-widget.js.map +1 -1
- package/dist/index.cjs +921 -370
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/index.js.map +1 -1
- package/dist/info-widget.d.ts +38 -17
- package/dist/info-widget.d.ts.map +1 -1
- package/dist/info-widget.js +40 -130
- package/dist/info-widget.js.map +1 -1
- package/dist/lib/components/dropdown-menu.d.ts +10 -4
- package/dist/lib/components/dropdown-menu.d.ts.map +1 -1
- package/dist/lib/components/dropdown-menu.js +12 -7
- package/dist/lib/components/dropdown-menu.js.map +1 -1
- package/dist/lib/components/icon-menu.d.ts.map +1 -1
- package/dist/lib/components/icon-menu.js +2 -3
- package/dist/lib/components/icon-menu.js.map +1 -1
- package/dist/lib/components/popover.d.ts +30 -0
- package/dist/lib/components/popover.d.ts.map +1 -0
- package/dist/lib/components/popover.js +93 -0
- package/dist/lib/components/popover.js.map +1 -0
- package/dist/lib/components/range-input.d.ts +26 -0
- package/dist/lib/components/range-input.d.ts.map +1 -0
- package/dist/lib/components/range-input.js +261 -0
- package/dist/lib/components/range-input.js.map +1 -0
- package/dist/lib/components/user-content.d.ts +8 -0
- package/dist/lib/components/user-content.d.ts.map +1 -0
- package/dist/lib/components/user-content.js +15 -0
- package/dist/lib/components/user-content.js.map +1 -0
- package/dist/popup-widget.d.ts +63 -0
- package/dist/popup-widget.d.ts.map +1 -0
- package/dist/popup-widget.js +70 -0
- package/dist/popup-widget.js.map +1 -0
- package/dist/reset-view-widget.d.ts +1 -1
- package/dist/reset-view-widget.d.ts.map +1 -1
- package/dist/reset-view-widget.js +12 -11
- package/dist/reset-view-widget.js.map +1 -1
- package/dist/scrollbar-widget.d.ts +68 -0
- package/dist/scrollbar-widget.d.ts.map +1 -0
- package/dist/scrollbar-widget.js +181 -0
- package/dist/scrollbar-widget.js.map +1 -0
- package/dist/stats-widget.d.ts +4 -0
- package/dist/stats-widget.d.ts.map +1 -1
- package/dist/stats-widget.js +3 -3
- package/dist/stats-widget.js.map +1 -1
- package/dist/stylesheet.css +244 -29
- package/dist/theme-widget.d.ts.map +1 -1
- package/dist/theme-widget.js +7 -5
- package/dist/theme-widget.js.map +1 -1
- package/dist/themes.d.ts +30 -0
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +28 -4
- package/dist/themes.js.map +1 -1
- package/dist/timeline-widget.d.ts +25 -6
- package/dist/timeline-widget.d.ts.map +1 -1
- package/dist/timeline-widget.js +46 -18
- package/dist/timeline-widget.js.map +1 -1
- package/dist/zoom-widget.d.ts +2 -8
- package/dist/zoom-widget.d.ts.map +1 -1
- package/dist/zoom-widget.js +23 -18
- package/dist/zoom-widget.js.map +1 -1
- package/dist.min.js +2 -2
- package/package.json +4 -3
- package/src/compass-widget.tsx +5 -5
- package/src/context-menu-widget.tsx +86 -76
- package/src/fullscreen-widget.tsx +1 -1
- package/src/geocoder-widget.tsx +17 -24
- package/src/gimbal-widget.tsx +4 -26
- package/src/index.ts +11 -6
- package/src/info-widget.tsx +93 -157
- package/src/lib/components/dropdown-menu.tsx +42 -20
- package/src/lib/components/icon-menu.tsx +3 -4
- package/src/lib/components/popover.tsx +167 -0
- package/src/lib/components/range-input.tsx +432 -0
- package/src/lib/components/user-content.tsx +30 -0
- package/src/popup-widget.tsx +163 -0
- package/src/reset-view-widget.tsx +12 -11
- package/src/scrollbar-widget.tsx +288 -0
- package/src/stats-widget.tsx +10 -4
- package/src/stylesheet.css +244 -29
- package/src/theme-widget.tsx +7 -5
- package/src/themes.ts +35 -4
- package/src/timeline-widget.tsx +96 -33
- package/src/zoom-widget.tsx +25 -21
- package/dist/lib/components/grouped-icon-button.d.ts +0 -10
- package/dist/lib/components/grouped-icon-button.d.ts.map +0 -1
- package/dist/lib/components/grouped-icon-button.js +0 -7
- package/dist/lib/components/grouped-icon-button.js.map +0 -1
- package/dist/lib/components/simple-menu.d.ts +0 -16
- package/dist/lib/components/simple-menu.d.ts.map +0 -1
- package/dist/lib/components/simple-menu.js +0 -30
- package/dist/lib/components/simple-menu.js.map +0 -1
- package/src/lib/components/grouped-icon-button.tsx +0 -27
- package/src/lib/components/simple-menu.tsx +0 -52
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import {Widget} from '@deck.gl/core';
|
|
2
|
+
import type {Position, Viewport, WidgetPlacement, WidgetProps} from '@deck.gl/core';
|
|
3
|
+
import {render} from 'preact';
|
|
4
|
+
import {RangeInput, type RangeInputDecoration} from './lib/components/range-input';
|
|
5
|
+
|
|
6
|
+
export type ScrollbarOrientation = 'vertical' | 'horizontal';
|
|
7
|
+
|
|
8
|
+
export type ContentBounds = [min: Position, max: Position];
|
|
9
|
+
|
|
10
|
+
export type ScrollbarDecoration = {
|
|
11
|
+
contentBounds: ContentBounds;
|
|
12
|
+
color: string;
|
|
13
|
+
title?: string;
|
|
14
|
+
/** Callback when the decoration is clicked. Return `true` to mark the event as handled, and prevent the default behavior. */
|
|
15
|
+
onClick?: (evt: MouseEvent) => boolean;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const clamp = (value: number, min: number, max: number) => {
|
|
19
|
+
if (value < min) {
|
|
20
|
+
return min;
|
|
21
|
+
}
|
|
22
|
+
if (value > max) {
|
|
23
|
+
return max;
|
|
24
|
+
}
|
|
25
|
+
return value;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type ScrollbarWidgetProps = WidgetProps & {
|
|
29
|
+
/** The full extent of the scrollable content, in world coordinates.
|
|
30
|
+
* The widget relies on this value to calculate the position and size of the slider button and track.
|
|
31
|
+
* If not supplied, the scrollbar will always be hidden.
|
|
32
|
+
*/
|
|
33
|
+
contentBounds?: ContentBounds | null;
|
|
34
|
+
placement?: WidgetPlacement;
|
|
35
|
+
viewId?: string | null;
|
|
36
|
+
/** Direction of the scrollbar. `'horizontal'` scrolls the camera along the X axis, and `'vertical'` scrolls the camera along the Y axis.
|
|
37
|
+
* @default 'vertical'
|
|
38
|
+
*/
|
|
39
|
+
orientation?: ScrollbarOrientation;
|
|
40
|
+
/* Pixels scrolled when clicked on the step buttons.
|
|
41
|
+
* @default 1/10 of the viewport size
|
|
42
|
+
*/
|
|
43
|
+
stepSize?: number | null;
|
|
44
|
+
/* Pixels scrolled when clicked on the track.
|
|
45
|
+
* @default 100% of the viewport size
|
|
46
|
+
*/
|
|
47
|
+
pageSize?: number | null;
|
|
48
|
+
/** Label of the step button at the start.
|
|
49
|
+
* @default 'Scroll left' | 'Scroll up'
|
|
50
|
+
*/
|
|
51
|
+
startButtonAriaLabel?: string;
|
|
52
|
+
/** Label of the end button at the start.
|
|
53
|
+
* @default 'Scroll right' | 'Scroll down'
|
|
54
|
+
*/
|
|
55
|
+
endButtonAriaLabel?: string;
|
|
56
|
+
/** If `true`, mouse wheel events over the canvas will be intercepted by this scrollbar.
|
|
57
|
+
* Useful when simulating the native scrollbar's behavior.
|
|
58
|
+
* @default false
|
|
59
|
+
*/
|
|
60
|
+
captureWheel?: boolean;
|
|
61
|
+
/** Custom markers to overlay on the track. */
|
|
62
|
+
decorations?: ScrollbarDecoration[];
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
type ScrollbarWidgetRequiredProps = Required<ScrollbarWidgetProps>;
|
|
66
|
+
|
|
67
|
+
/** A scrollbar widget to be used with OrthographicView */
|
|
68
|
+
export class ScrollbarWidget extends Widget<ScrollbarWidgetProps> {
|
|
69
|
+
static override defaultProps: ScrollbarWidgetRequiredProps = {
|
|
70
|
+
...Widget.defaultProps,
|
|
71
|
+
contentBounds: null,
|
|
72
|
+
placement: 'top-right',
|
|
73
|
+
viewId: null,
|
|
74
|
+
orientation: 'vertical',
|
|
75
|
+
stepSize: null,
|
|
76
|
+
pageSize: null,
|
|
77
|
+
startButtonAriaLabel: '',
|
|
78
|
+
endButtonAriaLabel: '',
|
|
79
|
+
captureWheel: false,
|
|
80
|
+
decorations: []
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
override className = 'deck-widget-scrollbar';
|
|
84
|
+
|
|
85
|
+
placement: WidgetPlacement = 'fill';
|
|
86
|
+
|
|
87
|
+
private viewport?: Viewport;
|
|
88
|
+
private contentSize = 0;
|
|
89
|
+
private viewportSize = 0;
|
|
90
|
+
private scrollOffset = 0;
|
|
91
|
+
|
|
92
|
+
constructor(props: ScrollbarWidgetProps) {
|
|
93
|
+
const resolved = {
|
|
94
|
+
...ScrollbarWidget.defaultProps,
|
|
95
|
+
...props
|
|
96
|
+
} as ScrollbarWidgetRequiredProps;
|
|
97
|
+
super(resolved);
|
|
98
|
+
this.viewId = resolved.viewId ?? null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
override onViewportChange(viewport: Viewport) {
|
|
102
|
+
this.viewport = viewport;
|
|
103
|
+
this.onRenderHTML();
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
override onRenderHTML(): void {
|
|
107
|
+
const element = this.rootElement;
|
|
108
|
+
if (!element) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
element.dataset.placement = this.props.placement;
|
|
113
|
+
const viewport = this.viewport;
|
|
114
|
+
this.updateViewport(viewport);
|
|
115
|
+
|
|
116
|
+
const clampedOffset = this.getClampedOffset();
|
|
117
|
+
const wheelTarget = this.getWheelEventTarget(this.props.captureWheel ? 'global' : 'local');
|
|
118
|
+
const decorations = this.getDecorations(viewport);
|
|
119
|
+
const isVertical = this.isVertical();
|
|
120
|
+
const startLabel =
|
|
121
|
+
this.props.startButtonAriaLabel ?? (isVertical ? 'Scroll up' : 'Scroll left');
|
|
122
|
+
const endLabel = this.props.endButtonAriaLabel ?? (isVertical ? 'Scroll down' : 'Scroll right');
|
|
123
|
+
|
|
124
|
+
const ui = (
|
|
125
|
+
<RangeInput
|
|
126
|
+
min={0}
|
|
127
|
+
max={Math.max(0, this.contentSize)}
|
|
128
|
+
step={this.getEffectiveStep()}
|
|
129
|
+
pageSize={this.getEffectivePage()}
|
|
130
|
+
value={[clampedOffset, clampedOffset + this.viewportSize]}
|
|
131
|
+
orientation={this.props.orientation}
|
|
132
|
+
stepButtons
|
|
133
|
+
startButtonAriaLabel={startLabel}
|
|
134
|
+
endButtonAriaLabel={endLabel}
|
|
135
|
+
eventTarget={wheelTarget}
|
|
136
|
+
decorations={decorations}
|
|
137
|
+
onChange={this.handleRangeChange}
|
|
138
|
+
/>
|
|
139
|
+
);
|
|
140
|
+
|
|
141
|
+
render(ui, element);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
override onRemove(): void {
|
|
145
|
+
if (this.rootElement) {
|
|
146
|
+
render(null, this.rootElement);
|
|
147
|
+
}
|
|
148
|
+
super.onRemove();
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
private updateViewport(viewport?: Viewport): void {
|
|
152
|
+
if (!viewport) {
|
|
153
|
+
this.contentSize = 0;
|
|
154
|
+
this.scrollOffset = 0;
|
|
155
|
+
this.viewportSize = 0;
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const {contentBounds} = this.props;
|
|
160
|
+
const isVertical = this.isVertical();
|
|
161
|
+
const projectedBounds = contentBounds
|
|
162
|
+
? projectBounds(contentBounds, viewport, isVertical)
|
|
163
|
+
: ([0, 0] as [number, number]);
|
|
164
|
+
|
|
165
|
+
this.contentSize = projectedBounds[1] - projectedBounds[0];
|
|
166
|
+
this.scrollOffset = -projectedBounds[0];
|
|
167
|
+
this.viewportSize = isVertical ? viewport.height : viewport.width;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
private getDecorations(viewport?: Viewport): RangeInputDecoration[] {
|
|
171
|
+
const {decorations = [], contentBounds} = this.props;
|
|
172
|
+
if (!viewport || !contentBounds || decorations.length === 0) {
|
|
173
|
+
return [];
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const isVertical = this.isVertical();
|
|
177
|
+
const [contentStart] = projectBounds(contentBounds, viewport, isVertical);
|
|
178
|
+
|
|
179
|
+
return decorations.map(decoration => {
|
|
180
|
+
const [start, end] = projectBounds(decoration.contentBounds, viewport, isVertical);
|
|
181
|
+
const onClick = decoration.onClick
|
|
182
|
+
? (e: MouseEvent) => {
|
|
183
|
+
const handled = decoration.onClick?.(e);
|
|
184
|
+
if (handled) {
|
|
185
|
+
e.stopPropagation();
|
|
186
|
+
e.preventDefault();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
: undefined;
|
|
190
|
+
return {
|
|
191
|
+
position: [start - contentStart, end - contentStart],
|
|
192
|
+
element: (
|
|
193
|
+
<div
|
|
194
|
+
style={{
|
|
195
|
+
pointerEvents: onClick ? 'all' : 'none',
|
|
196
|
+
width: '100%',
|
|
197
|
+
height: '100%',
|
|
198
|
+
backgroundColor: decoration.color
|
|
199
|
+
}}
|
|
200
|
+
title={decoration.title}
|
|
201
|
+
onClick={onClick}
|
|
202
|
+
/>
|
|
203
|
+
)
|
|
204
|
+
};
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
private getWheelEventTarget(mode: 'global' | 'local' | null) {
|
|
209
|
+
if (mode === null) return null;
|
|
210
|
+
if (mode === 'local') return this.rootElement;
|
|
211
|
+
|
|
212
|
+
return this.deck?.props.parent || this.deck?.getCanvas()?.parentElement || this.rootElement;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
private getMaxScroll(): number {
|
|
216
|
+
return Math.max(0, this.contentSize - this.viewportSize);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private getClampedOffset(): number {
|
|
220
|
+
const maxScroll = this.getMaxScroll();
|
|
221
|
+
return clamp(this.scrollOffset, 0, maxScroll);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
private isVertical(): boolean {
|
|
225
|
+
return this.props.orientation !== 'horizontal';
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
private getEffectiveStep(): number {
|
|
229
|
+
if (typeof this.props.stepSize === 'number' && !Number.isNaN(this.props.stepSize)) {
|
|
230
|
+
return this.props.stepSize;
|
|
231
|
+
}
|
|
232
|
+
return Math.max(1, this.viewportSize / 10 || 1);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
private getEffectivePage(): number {
|
|
236
|
+
if (typeof this.props.pageSize === 'number' && !Number.isNaN(this.props.pageSize)) {
|
|
237
|
+
return this.props.pageSize;
|
|
238
|
+
}
|
|
239
|
+
return this.viewportSize;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
private emitScroll(next: number): void {
|
|
243
|
+
const maxScroll = this.getMaxScroll();
|
|
244
|
+
const target = clamp(Math.round(next), 0, maxScroll);
|
|
245
|
+
const viewport = this.viewport;
|
|
246
|
+
if (viewport && target !== this.getClampedOffset()) {
|
|
247
|
+
const pixel = viewport.project(viewport.position) as [number, number];
|
|
248
|
+
if (this.isVertical()) {
|
|
249
|
+
pixel[1] -= target - this.scrollOffset;
|
|
250
|
+
} else {
|
|
251
|
+
pixel[0] -= target - this.scrollOffset;
|
|
252
|
+
}
|
|
253
|
+
const {target: newTarget} = viewport.panByPosition(viewport.position, pixel);
|
|
254
|
+
|
|
255
|
+
// @ts-expect-error Using private method temporary until there's a public one
|
|
256
|
+
this.deck._onViewStateChange({
|
|
257
|
+
viewId: viewport.id,
|
|
258
|
+
viewState: {
|
|
259
|
+
...this.getViewState(viewport.id),
|
|
260
|
+
target: newTarget
|
|
261
|
+
},
|
|
262
|
+
interactionState: {}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
private handleRangeChange = (nextValue: [number, number]) => {
|
|
268
|
+
this.emitScroll(nextValue[0]);
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
function projectBounds(
|
|
273
|
+
bounds: ContentBounds,
|
|
274
|
+
viewport: Viewport,
|
|
275
|
+
isVertical: boolean
|
|
276
|
+
): [min: number, max: number] {
|
|
277
|
+
return bounds
|
|
278
|
+
.map(([x, y]) => viewport.project([x, y, 0]))
|
|
279
|
+
.reduce(
|
|
280
|
+
(range: [number, number], [x, y]) => {
|
|
281
|
+
const value = isVertical ? y : x;
|
|
282
|
+
range[0] = Math.min(range[0], value);
|
|
283
|
+
range[1] = Math.max(range[1], value);
|
|
284
|
+
return range;
|
|
285
|
+
},
|
|
286
|
+
[Infinity, -Infinity]
|
|
287
|
+
);
|
|
288
|
+
}
|
package/src/stats-widget.tsx
CHANGED
|
@@ -7,9 +7,6 @@ import {luma} from '@luma.gl/core';
|
|
|
7
7
|
import {render} from 'preact';
|
|
8
8
|
import type {Stats, Stat} from '@probe.gl/stats';
|
|
9
9
|
|
|
10
|
-
const RIGHT_ARROW = '\u25b6';
|
|
11
|
-
const DOWN_ARROW = '\u2b07';
|
|
12
|
-
|
|
13
10
|
const DEFAULT_COUNT_FORMATTER = (stat: Stat): string => `${stat.name}: ${stat.count}`;
|
|
14
11
|
|
|
15
12
|
function formatTime(time: number): string {
|
|
@@ -36,6 +33,10 @@ export type StatsWidgetProps = WidgetProps & {
|
|
|
36
33
|
viewId?: string | null;
|
|
37
34
|
/** Type of stats to display. */
|
|
38
35
|
type?: 'deck' | 'luma' | 'device' | 'custom';
|
|
36
|
+
/** Expand the stats UI by default.
|
|
37
|
+
* @default false
|
|
38
|
+
*/
|
|
39
|
+
defaultIsExpanded?: boolean;
|
|
39
40
|
/** Stats object to visualize. */
|
|
40
41
|
stats?: Stats;
|
|
41
42
|
/** Title shown in the header of the pop-up. Defaults to stats.id. */
|
|
@@ -55,6 +56,7 @@ export class StatsWidget extends Widget<StatsWidgetProps> {
|
|
|
55
56
|
type: 'deck',
|
|
56
57
|
placement: 'top-left',
|
|
57
58
|
viewId: null,
|
|
59
|
+
defaultIsExpanded: false,
|
|
58
60
|
stats: undefined!,
|
|
59
61
|
title: 'Stats',
|
|
60
62
|
framesPerUpdate: 1,
|
|
@@ -75,6 +77,7 @@ export class StatsWidget extends Widget<StatsWidgetProps> {
|
|
|
75
77
|
super(props);
|
|
76
78
|
this._formatters = {...DEFAULT_FORMATTERS};
|
|
77
79
|
this._resetOnUpdate = {...this.props.resetOnUpdate};
|
|
80
|
+
this.collapsed = !props.defaultIsExpanded;
|
|
78
81
|
this.setProps(props);
|
|
79
82
|
}
|
|
80
83
|
|
|
@@ -127,7 +130,10 @@ export class StatsWidget extends Widget<StatsWidgetProps> {
|
|
|
127
130
|
style={{cursor: 'pointer', pointerEvents: 'auto'}}
|
|
128
131
|
onClick={this._toggleCollapsed}
|
|
129
132
|
>
|
|
130
|
-
{
|
|
133
|
+
<b>{title}</b>
|
|
134
|
+
<button className="deck-widget-dropdown-button">
|
|
135
|
+
<span className={`deck-widget-dropdown-icon ${collapsed ? '' : 'open'}`} />
|
|
136
|
+
</button>
|
|
131
137
|
</div>
|
|
132
138
|
{!collapsed && <div className="deck-widget-stats-content">{items}</div>}
|
|
133
139
|
</div>,
|
package/src/stylesheet.css
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
.deck-widget {
|
|
2
2
|
margin: var(--widget-margin, 12px);
|
|
3
|
+
box-sizing: border-box;
|
|
3
4
|
}
|
|
4
5
|
|
|
5
6
|
/* Common button container styles */
|
|
@@ -29,6 +30,9 @@
|
|
|
29
30
|
padding: 1px;
|
|
30
31
|
gap: 1px;
|
|
31
32
|
}
|
|
33
|
+
.deck-widget-button-group > .deck-widget-button {
|
|
34
|
+
display: contents;
|
|
35
|
+
}
|
|
32
36
|
|
|
33
37
|
.deck-widget-button-group.vertical {
|
|
34
38
|
display: inline-flex;
|
|
@@ -201,24 +205,56 @@
|
|
|
201
205
|
|
|
202
206
|
/* Timeline widget styles */
|
|
203
207
|
.deck-widget.deck-widget-timeline {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
208
|
+
position: absolute;
|
|
209
|
+
margin: var(--widget-margin, 12px);
|
|
210
|
+
left: 0;
|
|
211
|
+
right: 0;
|
|
212
|
+
pointer-events: all;
|
|
207
213
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
margin: 0 8px;
|
|
211
|
-
flex: 1;
|
|
212
|
-
pointer-events: 'auto';
|
|
213
|
-
cursor: pointer;
|
|
214
|
+
.deck-widget.deck-widget-timeline[data-placement^=top-] {
|
|
215
|
+
top: 0;
|
|
214
216
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
color: var(--button-icon-idle, rgb(97, 97, 102));
|
|
217
|
+
.deck-widget.deck-widget-timeline[data-placement^=bottom-] {
|
|
218
|
+
bottom: 0;
|
|
218
219
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
.deck-widget.deck-widget-timeline .deck-widget-button-group {
|
|
221
|
+
box-sizing: border-box;
|
|
222
|
+
gap: var(--widget-margin, 12px);
|
|
223
|
+
padding: var(--widget-margin, 12px);
|
|
224
|
+
}
|
|
225
|
+
.deck-widget-timeline button.deck-widget-timeline-pause .deck-widget-icon {
|
|
226
|
+
mask-image: var(
|
|
227
|
+
--icon-pause,
|
|
228
|
+
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="black"><path d="M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z"/></svg>')
|
|
229
|
+
);
|
|
230
|
+
-webkit-mask-image: var(
|
|
231
|
+
--icon-pause,
|
|
232
|
+
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="black"><path d="M560-200v-560h160v560H560Zm-320 0v-560h160v560H240Z"/></svg>')
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
.deck-widget-timeline button.deck-widget-timeline-play .deck-widget-icon {
|
|
236
|
+
mask-image: var(
|
|
237
|
+
--icon-play,
|
|
238
|
+
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="black"><path d="M320-200v-560l440 280-440 280Z"/></svg>')
|
|
239
|
+
);
|
|
240
|
+
-webkit-mask-image: var(
|
|
241
|
+
--icon-play,
|
|
242
|
+
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960" fill="black"><path d="M320-200v-560l440 280-440 280Z"/></svg>')
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
.deck-widget-timeline-label {
|
|
246
|
+
position: relative;
|
|
247
|
+
pointer-events: none;
|
|
248
|
+
width: fit-content;
|
|
249
|
+
font-size: 13px;
|
|
250
|
+
color: var(--menu-text, rgb(24, 24, 26));
|
|
251
|
+
white-space: nowrap;
|
|
252
|
+
}
|
|
253
|
+
.deck-widget-timeline-label--current {
|
|
254
|
+
transform: translate(-50%, -100%);
|
|
255
|
+
border-radius: var(--button-corner-radius, 8px);
|
|
256
|
+
background: var(--menu-background, #fff);
|
|
257
|
+
padding: 4px;
|
|
222
258
|
}
|
|
223
259
|
|
|
224
260
|
/* FPS widget styles */
|
|
@@ -370,7 +406,6 @@
|
|
|
370
406
|
}
|
|
371
407
|
|
|
372
408
|
.deck-widget .deck-widget-dropdown-menu {
|
|
373
|
-
position: absolute;
|
|
374
409
|
top: calc(100% + var(--menu-gap, 4px));
|
|
375
410
|
left: 1px;
|
|
376
411
|
right: 1px;
|
|
@@ -389,14 +424,16 @@
|
|
|
389
424
|
|
|
390
425
|
.deck-widget .deck-widget-dropdown-item {
|
|
391
426
|
padding: 8px 12px;
|
|
392
|
-
cursor: pointer;
|
|
393
427
|
white-space: nowrap;
|
|
394
428
|
overflow: hidden;
|
|
429
|
+
cursor: default;
|
|
430
|
+
user-select: none;
|
|
395
431
|
text-overflow: ellipsis;
|
|
396
432
|
color: var(--menu-text, rgb(24, 24, 26));
|
|
397
433
|
}
|
|
398
434
|
|
|
399
|
-
.deck-widget .deck-widget-dropdown-item:hover {
|
|
435
|
+
.deck-widget .deck-widget-dropdown-item:not(.disabled):hover {
|
|
436
|
+
cursor: pointer;
|
|
400
437
|
background: var(--menu-item-hover, rgba(128, 128, 128, 0.15));
|
|
401
438
|
}
|
|
402
439
|
|
|
@@ -415,20 +452,198 @@
|
|
|
415
452
|
|
|
416
453
|
/* Stats styles */
|
|
417
454
|
.deck-widget-stats-container {
|
|
418
|
-
border-radius: var(--button-corner-radius,
|
|
455
|
+
border-radius: var(--button-corner-radius, 8px);
|
|
419
456
|
display: inline-flex;
|
|
420
457
|
flex-direction: column;
|
|
421
|
-
padding: 4px;
|
|
422
458
|
font-size: 0.7rem;
|
|
423
459
|
/* Approximately 14px */
|
|
424
460
|
line-height: 1.6;
|
|
425
|
-
font-family:
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
461
|
+
font-family: monospace;
|
|
462
|
+
background-color: var(--menu-background, #fff);
|
|
463
|
+
color: var(--menu-text, rgb(24, 24, 26));
|
|
464
|
+
box-shadow: var(--menu-shadow, 0px 0px 8px 0px rgba(0, 0, 0, 0.25));
|
|
465
|
+
}
|
|
466
|
+
.deck-widget-stats-header {
|
|
467
|
+
color: var(--button-icon-idle, rgba(97, 97, 102, 1));
|
|
468
|
+
padding-left: 8px;
|
|
469
|
+
display: flex;
|
|
470
|
+
align-items: center;
|
|
471
|
+
gap: 4px;
|
|
472
|
+
}
|
|
473
|
+
.deck-widget-stats-header:hover {
|
|
474
|
+
color: var(--button-icon-hover, rgb(24, 24, 26));
|
|
475
|
+
}
|
|
476
|
+
.deck-widget-stats-header .deck-widget-dropdown-button {
|
|
477
|
+
background: none;
|
|
478
|
+
border: none;
|
|
479
|
+
}
|
|
480
|
+
.deck-widget-stats-content {
|
|
481
|
+
padding: 4px 8px 8px;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/* Popup styles */
|
|
485
|
+
.deck-widget.deck-widget-popover {
|
|
486
|
+
margin: 0 !important;
|
|
487
|
+
}
|
|
488
|
+
.deck-widget-popup-content {
|
|
489
|
+
border-radius: var(--button-corner-radius, 8px);
|
|
490
|
+
background: var(--menu-background, #fff);
|
|
491
|
+
color: var(--menu-text, rgb(24, 24, 26));
|
|
492
|
+
box-shadow: var(--menu-shadow, 0px 0px 8px 0px rgba(0, 0, 0, 0.25));
|
|
493
|
+
padding: 10px;
|
|
494
|
+
}
|
|
495
|
+
.deck-widget-popup-content .deck-widget-popup-controls {
|
|
496
|
+
--button-size: 20px;
|
|
497
|
+
}
|
|
498
|
+
.deck-widget-popup-content .deck-widget-popup-controls .deck-widget-button {
|
|
499
|
+
box-shadow: none;
|
|
500
|
+
}
|
|
501
|
+
.deck-widget-popup-content button.deck-widget-popup-close-button .deck-widget-icon {
|
|
502
|
+
mask-image: var(
|
|
503
|
+
--icon-close,
|
|
504
|
+
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 -120 120 120" fill="black"><path d="m32-25-7-7 28-28-28-28 7-7 28 28 28-28 7 7-28 28 28 28-7 7-28-28-28 28Z"/></svg>')
|
|
505
|
+
);
|
|
506
|
+
-webkit-mask-image: var(
|
|
507
|
+
--icon-close,
|
|
508
|
+
url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 -120 120 120" fill="black"><path d="m32-25-7-7 28-28-28-28 7-7 28 28 28-28 7 7-28 28 28 28-7 7-28-28-28 28Z"/></svg>')
|
|
509
|
+
);
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** Range input */
|
|
513
|
+
.deck-widget-range {
|
|
514
|
+
position: relative;
|
|
515
|
+
pointer-events: all;
|
|
516
|
+
display: flex;
|
|
517
|
+
align-items: center;
|
|
518
|
+
user-select: none;
|
|
519
|
+
touch-action: none;
|
|
520
|
+
box-sizing: border-box;
|
|
521
|
+
margin: 0;
|
|
522
|
+
}
|
|
523
|
+
.deck-widget-range__track {
|
|
524
|
+
position: relative;
|
|
525
|
+
cursor: pointer;
|
|
526
|
+
flex: 1;
|
|
527
|
+
background: var(--range-track-color, #888);
|
|
528
|
+
border-radius: calc(var(--range-track-size, 16px) / 2);
|
|
529
|
+
}
|
|
530
|
+
.deck-widget-range__decorations {
|
|
531
|
+
position: absolute;
|
|
532
|
+
}
|
|
533
|
+
.deck-widget-range__decoration {
|
|
534
|
+
position: absolute;
|
|
535
|
+
}
|
|
536
|
+
.deck-widget-range__decoration:active {
|
|
537
|
+
background-color: var(--range-decoration-active-color, gold) !important;
|
|
538
|
+
}
|
|
539
|
+
.deck-widget-range__thumb {
|
|
540
|
+
position: relative;
|
|
541
|
+
box-sizing: content-box;
|
|
542
|
+
padding: calc(var(--range-thumb-size, 10px) / 2);
|
|
543
|
+
border-radius: calc(var(--range-thumb-size, 10px) / 2);
|
|
544
|
+
margin: calc(var(--range-thumb-size, 10px) * -0.5);
|
|
545
|
+
background: var(--range-thumb-color, #444);
|
|
546
|
+
}
|
|
547
|
+
.deck-widget-range__button {
|
|
548
|
+
cursor: pointer;
|
|
549
|
+
opacity: 0.4;
|
|
550
|
+
background-color: transparent;
|
|
551
|
+
width: var(--range-step-button-size, 24px);
|
|
552
|
+
height: var(--range-step-button-size, 24px);
|
|
553
|
+
background-size: cover;
|
|
554
|
+
border: none;
|
|
555
|
+
padding: 0;
|
|
556
|
+
}
|
|
557
|
+
.deck-widget-range__button:hover {
|
|
558
|
+
opacity: 1;
|
|
559
|
+
}
|
|
560
|
+
.deck-widget-range:not(.deck-widget-range--disabled) .deck-widget-range__button:disabled {
|
|
561
|
+
pointer-events: none;
|
|
562
|
+
opacity: 0.1;
|
|
563
|
+
}
|
|
564
|
+
.deck-widget-range--disabled {
|
|
565
|
+
display: none;
|
|
566
|
+
}
|
|
567
|
+
.deck-widget-range--vertical {
|
|
568
|
+
flex-direction: column;
|
|
569
|
+
height: 100%;
|
|
570
|
+
top: 0;
|
|
571
|
+
}
|
|
572
|
+
.deck-widget-range--horizontal {
|
|
573
|
+
flex-direction: row;
|
|
574
|
+
width: 100%;
|
|
575
|
+
left: 0;
|
|
576
|
+
}
|
|
577
|
+
.deck-widget-range--vertical .deck-widget-range__track {
|
|
578
|
+
width: var(--range-track-size, 16px);
|
|
579
|
+
padding-top: calc(var(--range-track-size, 16px) / 2);
|
|
580
|
+
padding-bottom: calc(var(--range-track-size, 16px) / 2);
|
|
581
|
+
height: 100%;
|
|
582
|
+
min-height: calc(var(--range-track-size, 16px) * 3);
|
|
583
|
+
}
|
|
584
|
+
.deck-widget-range--vertical .deck-widget-range__thumb {
|
|
585
|
+
width: 0;
|
|
586
|
+
left: 50%;
|
|
587
|
+
cursor: ns-resize;
|
|
588
|
+
}
|
|
589
|
+
.deck-widget-range--vertical .deck-widget-range__decorations {
|
|
590
|
+
top: calc(var(--range-track-size, 16px) / 2);
|
|
591
|
+
bottom: calc(var(--range-track-size, 16px) / 2);
|
|
592
|
+
left: 0;
|
|
593
|
+
right: 0;
|
|
594
|
+
}
|
|
595
|
+
.deck-widget-range--vertical .deck-widget-range__button--start .deck-widget-icon {
|
|
596
|
+
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 -960 960 960" fill="black"><path d="M480-528 296-344l-56-56 240-240 240 240-56 56-184-184Z"/></svg>');
|
|
597
|
+
}
|
|
598
|
+
.deck-widget-range--vertical .deck-widget-range__button--end .deck-widget-icon {
|
|
599
|
+
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 -960 960 960" fill="black"><path d="M480-344 240-584l56-56 184 184 184-184 56 56-240 240Z"/></svg>');
|
|
600
|
+
}
|
|
601
|
+
.deck-widget-range--horizontal .deck-widget-range__track {
|
|
602
|
+
height: var(--range-track-size, 16px);
|
|
603
|
+
padding-left: calc(var(--range-track-size, 16px) / 2);
|
|
604
|
+
padding-right: calc(var(--range-track-size, 16px) / 2);
|
|
605
|
+
width: 100%;
|
|
606
|
+
min-width: calc(var(--range-track-size, 16px) * 3);
|
|
607
|
+
}
|
|
608
|
+
.deck-widget-range--horizontal .deck-widget-range__thumb {
|
|
609
|
+
height: 0;
|
|
610
|
+
top: 50%;
|
|
611
|
+
cursor: ew-resize;
|
|
612
|
+
}
|
|
613
|
+
.deck-widget-range--horizontal .deck-widget-range__decorations {
|
|
614
|
+
left: calc(var(--range-track-size, 16px) / 2);
|
|
615
|
+
right: calc(var(--range-track-size, 16px) / 2);
|
|
616
|
+
top: 0;
|
|
617
|
+
bottom: 0;
|
|
618
|
+
}
|
|
619
|
+
.deck-widget-range--horizontal .deck-widget-range__button--start .deck-widget-icon {
|
|
620
|
+
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 -960 960 960" fill="black"><path d="M560-240 320-480l240-240 56 56-184 184 184 184-56 56Z"/></svg>');
|
|
621
|
+
}
|
|
622
|
+
.deck-widget-range--horizontal .deck-widget-range__button--end .deck-widget-icon {
|
|
623
|
+
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 -960 960 960" fill="black"><path d="M504-480 320-664l56-56 240 240-240 240-56-56 184-184Z"/></svg>');
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
/** Scrollbar */
|
|
627
|
+
.deck-widget-scrollbar .deck-widget-range {
|
|
628
|
+
position: absolute;
|
|
629
|
+
}
|
|
630
|
+
.deck-widget-scrollbar .deck-widget-range--vertical {
|
|
631
|
+
top: var(--range-step-button-size, 24px);
|
|
632
|
+
height: calc(100% - var(--range-step-button-size, 24px) * 2);
|
|
633
|
+
}
|
|
634
|
+
.deck-widget-scrollbar[data-placement$=-left] .deck-widget-range--vertical {
|
|
635
|
+
left: 0;
|
|
636
|
+
}
|
|
637
|
+
.deck-widget-scrollbar[data-placement$=-right] .deck-widget-range--vertical {
|
|
638
|
+
right: 0;
|
|
639
|
+
}
|
|
640
|
+
.deck-widget-scrollbar .deck-widget-range--horizontal {
|
|
641
|
+
left: var(--range-step-button-size, 24px);
|
|
642
|
+
width: calc(100% - var(--range-step-button-size, 24px) * 2);
|
|
643
|
+
}
|
|
644
|
+
.deck-widget-scrollbar[data-placement^=top-] .deck-widget-range--horizontal {
|
|
645
|
+
top: 0;
|
|
646
|
+
}
|
|
647
|
+
.deck-widget-scrollbar[data-placement^=bottom-] .deck-widget-range--horizontal {
|
|
648
|
+
bottom: 0;
|
|
434
649
|
}
|
package/src/theme-widget.tsx
CHANGED
|
@@ -116,10 +116,12 @@ export class ThemeWidget extends Widget<ThemeWidgetProps> {
|
|
|
116
116
|
/** Read browser preference */
|
|
117
117
|
_getInitialThemeMode(): 'light' | 'dark' {
|
|
118
118
|
const {initialThemeMode} = this.props;
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
if (initialThemeMode !== 'auto') {
|
|
120
|
+
return initialThemeMode;
|
|
121
|
+
}
|
|
122
|
+
if (typeof window === 'undefined') {
|
|
123
|
+
return 'light';
|
|
124
|
+
}
|
|
125
|
+
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
124
126
|
}
|
|
125
127
|
}
|