@deck.gl/widgets 9.3.7 → 9.4.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.
@@ -0,0 +1,186 @@
1
+ // deck.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {View} from '@deck.gl/core';
6
+
7
+ /** Discriminated plain-object layout tree accepted by the view layout compiler. */
8
+ export type ViewLayout =
9
+ | ColumnViewLayout
10
+ | RowViewLayout
11
+ | SplitViewLayout
12
+ | OverlayViewLayout
13
+ | SpacerViewLayout;
14
+
15
+ /** CSS-like length accepted by the view layout builder. */
16
+ export type ViewLayoutLength = number | string;
17
+
18
+ /** Insets applied inside an allocated child rectangle before compiling its contents. */
19
+ export type ViewLayoutInsets = {
20
+ /** Top inset in pixels. */
21
+ top?: number;
22
+ /** Right inset in pixels. */
23
+ right?: number;
24
+ /** Bottom inset in pixels. */
25
+ bottom?: number;
26
+ /** Left inset in pixels. */
27
+ left?: number;
28
+ };
29
+
30
+ /** A raw deck.gl view or nested layout object allowed inside `children`. */
31
+ export type ViewLayoutChild = ViewLayout | View | null | false | undefined;
32
+
33
+ /** Common layout metadata shared by every authored layout item. */
34
+ export type ViewLayoutBaseProps = {
35
+ /** Optional width expression resolved against the current parent bounds. */
36
+ width?: ViewLayoutLength;
37
+ /** Optional height expression resolved against the current parent bounds. */
38
+ height?: ViewLayoutLength;
39
+ /** Minimum size in pixels along the parent stack axis. */
40
+ minPixels?: number;
41
+ /** Maximum size in pixels along the parent stack axis. */
42
+ maxPixels?: number;
43
+ /** Optional insets applied after parent layout allocation. */
44
+ inset?: ViewLayoutInsets;
45
+ };
46
+
47
+ /** Optional split metadata for a row or column with two or more children. */
48
+ export type ViewLayoutSplitProps = {
49
+ /** Stable id for user-adjustable splits between child items. */
50
+ splitId?: string;
51
+ /** Initial ratio of the first child's share over the stack axis for two-child splits. */
52
+ initialSplit?: number;
53
+ /** Minimum split ratio. */
54
+ minSplit?: number;
55
+ /** Maximum split ratio. */
56
+ maxSplit?: number;
57
+ };
58
+
59
+ /** One horizontal layout container that splits width among its children. */
60
+ export type RowViewLayout = ViewLayoutBaseProps &
61
+ ViewLayoutSplitProps & {
62
+ /** Discriminator for horizontal stack layout. */
63
+ type: 'row';
64
+ /** Ordered child items or raw deck views. */
65
+ children: readonly ViewLayoutChild[];
66
+ };
67
+
68
+ /** One vertical layout container that splits height among its children. */
69
+ export type ColumnViewLayout = ViewLayoutBaseProps &
70
+ ViewLayoutSplitProps & {
71
+ /** Discriminator for vertical stack layout. */
72
+ type: 'column';
73
+ /** Ordered child items or raw deck views. */
74
+ children: readonly ViewLayoutChild[];
75
+ };
76
+
77
+ /** Split layout container using the same orientation/views shape as SplitterWidgetViewLayout. */
78
+ export type SplitViewLayout = ViewLayoutBaseProps &
79
+ ViewLayoutSplitProps & {
80
+ /** Split axis. Horizontal splits width; vertical splits height. */
81
+ orientation: 'horizontal' | 'vertical';
82
+ /** Ordered child items or raw deck views. */
83
+ views: readonly ViewLayoutChild[];
84
+ };
85
+
86
+ export type ViewLayoutWithChildren =
87
+ | ColumnViewLayout
88
+ | RowViewLayout
89
+ | SplitViewLayout
90
+ | OverlayViewLayout;
91
+
92
+ /** One overlay container that gives each child the same parent bounds. */
93
+ export type OverlayViewLayout = ViewLayoutBaseProps & {
94
+ /** Discriminator for overlay layout. */
95
+ type: 'overlay';
96
+ /** Ordered child items or raw deck views. */
97
+ children: readonly ViewLayoutChild[];
98
+ };
99
+
100
+ /** One empty slot used to reserve fixed or flexible space in a stack. */
101
+ export type SpacerViewLayout = ViewLayoutBaseProps & {
102
+ /** Discriminator for an empty spacer item. */
103
+ type: 'spacer';
104
+ };
105
+
106
+ const VIEW_LAYOUT_TYPES = new Set(['row', 'column', 'overlay', 'spacer']);
107
+ const VIEW_LAYOUT_ORIENTATIONS = new Set(['horizontal', 'vertical']);
108
+
109
+ /** Returns true when a child is a plain view layout object instead of a deck.gl View. */
110
+ export function isViewLayout(child: ViewLayoutChild): child is ViewLayout {
111
+ return Boolean(
112
+ child &&
113
+ typeof child === 'object' &&
114
+ !(child instanceof View) &&
115
+ (('type' in child && VIEW_LAYOUT_TYPES.has(String(child.type))) ||
116
+ ('orientation' in child && VIEW_LAYOUT_ORIENTATIONS.has(String(child.orientation))))
117
+ );
118
+ }
119
+
120
+ /** Resolves the canonical layout type for either the type/children or orientation/views syntax. */
121
+ export function getViewLayoutType(item: ViewLayout): 'row' | 'column' | 'overlay' | 'spacer' {
122
+ if ('orientation' in item) {
123
+ return item.orientation === 'horizontal' ? 'row' : 'column';
124
+ }
125
+ return item.type;
126
+ }
127
+
128
+ /** Resolves child entries for either the type/children or orientation/views syntax. */
129
+ export function getViewLayoutChildren(item: ViewLayoutWithChildren): readonly ViewLayoutChild[] {
130
+ return 'views' in item ? item.views : item.children;
131
+ }
132
+
133
+ /**
134
+ * Validates one discriminated-union plain object before compiling it.
135
+ *
136
+ * @param item - Candidate layout item.
137
+ */
138
+ export function assertViewLayout(item: ViewLayout): void {
139
+ if (!item || typeof item !== 'object') {
140
+ throw new Error('ViewLayout must be an object.');
141
+ }
142
+
143
+ const type = getViewLayoutType(item);
144
+ switch (type) {
145
+ case 'row':
146
+ case 'column':
147
+ case 'overlay': {
148
+ const children = getViewLayoutChildren(item as ViewLayoutWithChildren);
149
+ if (!Array.isArray(children)) {
150
+ throw new Error('ViewLayout requires a children or views array.');
151
+ }
152
+ if (isSplitLayoutItem(item) && item.splitId) {
153
+ if (children.filter(Boolean).length < 2) {
154
+ throw new Error('ViewLayout with splitId requires at least two children.');
155
+ }
156
+ }
157
+ children.forEach(assertViewLayoutChild);
158
+ break;
159
+ }
160
+ case 'spacer':
161
+ break;
162
+ default:
163
+ throw new Error(`Unsupported view layout item: ${String(type)}`);
164
+ }
165
+ }
166
+
167
+ function isSplitLayoutItem(
168
+ item: ViewLayout
169
+ ): item is RowViewLayout | ColumnViewLayout | SplitViewLayout {
170
+ const type = getViewLayoutType(item);
171
+ return type === 'row' || type === 'column';
172
+ }
173
+
174
+ function assertViewLayoutChild(child: ViewLayoutChild): void {
175
+ if (!child) {
176
+ return;
177
+ }
178
+ if (isViewLayout(child)) {
179
+ assertViewLayout(child);
180
+ return;
181
+ }
182
+ if (child instanceof View) {
183
+ return;
184
+ }
185
+ throw new Error('ViewLayout children must be deck.gl View instances or layout objects.');
186
+ }
@@ -21,6 +21,10 @@ export type ZoomWidgetProps = WidgetProps & {
21
21
  zoomOutLabel?: string;
22
22
  /** Zoom transition duration in ms. 0 disables the transition */
23
23
  transitionDuration?: number;
24
+ /** Zoom level delta applied by each button click.
25
+ * @default 1
26
+ */
27
+ zoomStep?: number;
24
28
  /** Which axes to apply zoom to. One of 'X', 'Y' or 'all'.
25
29
  * Only effective if the current view is OrthographicView.
26
30
  */
@@ -50,6 +54,7 @@ export class ZoomWidget extends Widget<ZoomWidgetProps> {
50
54
  placement: 'top-left',
51
55
  orientation: 'vertical',
52
56
  transitionDuration: 200,
57
+ zoomStep: 1,
53
58
  zoomInLabel: 'Zoom In',
54
59
  zoomOutLabel: 'Zoom Out',
55
60
  zoomAxis: 'all',
@@ -164,13 +169,13 @@ export class ZoomWidget extends Widget<ZoomWidgetProps> {
164
169
 
165
170
  handleZoomIn() {
166
171
  for (const viewId of this.viewIds) {
167
- this.handleZoom(viewId, 1);
172
+ this.handleZoom(viewId, this.props.zoomStep);
168
173
  }
169
174
  }
170
175
 
171
176
  handleZoomOut() {
172
177
  for (const viewId of this.viewIds) {
173
- this.handleZoom(viewId, -1);
178
+ this.handleZoom(viewId, -this.props.zoomStep);
174
179
  }
175
180
  }
176
181
  }