glimpse-sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +80 -0
- package/dist/src/app.d.ts +53 -0
- package/dist/src/app.js +187 -0
- package/dist/src/events.d.ts +36 -0
- package/dist/src/events.js +37 -0
- package/dist/src/index.d.ts +4 -0
- package/dist/src/index.js +4 -0
- package/dist/src/protocol.d.ts +43 -0
- package/dist/src/protocol.js +58 -0
- package/dist/src/widgets.d.ts +351 -0
- package/dist/src/widgets.js +626 -0
- package/package.json +53 -0
- package/src/app.ts +241 -0
- package/src/events.ts +85 -0
- package/src/index.ts +57 -0
- package/src/protocol.ts +73 -0
- package/src/widgets.ts +820 -0
package/src/widgets.ts
ADDED
|
@@ -0,0 +1,820 @@
|
|
|
1
|
+
import { Icon, MenuItem } from "./protocol.js";
|
|
2
|
+
|
|
3
|
+
export type Align = "fill" | "start" | "end" | "center" | "baseline";
|
|
4
|
+
export type Orientation = "horizontal" | "vertical";
|
|
5
|
+
export type Variant = "normal" | "muted" | "accent" | "success" | "warning" | "danger";
|
|
6
|
+
|
|
7
|
+
export interface WidgetNode {
|
|
8
|
+
toProtocol(): Record<string, unknown>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface CommonProps {
|
|
12
|
+
id?: string;
|
|
13
|
+
visible?: boolean;
|
|
14
|
+
hexpand?: boolean;
|
|
15
|
+
vexpand?: boolean;
|
|
16
|
+
halign?: Align;
|
|
17
|
+
valign?: Align;
|
|
18
|
+
tooltip?: string;
|
|
19
|
+
variant?: Variant;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function applyCommonProps(
|
|
23
|
+
payload: Record<string, unknown>,
|
|
24
|
+
props: CommonProps,
|
|
25
|
+
): Record<string, unknown> {
|
|
26
|
+
if (props.id !== undefined) payload.id = props.id;
|
|
27
|
+
if (props.visible !== undefined) payload.visible = props.visible;
|
|
28
|
+
if (props.hexpand !== undefined) payload.hexpand = props.hexpand;
|
|
29
|
+
if (props.vexpand !== undefined) payload.vexpand = props.vexpand;
|
|
30
|
+
if (props.halign !== undefined) payload.halign = props.halign;
|
|
31
|
+
if (props.valign !== undefined) payload.valign = props.valign;
|
|
32
|
+
if (props.tooltip !== undefined) payload.tooltip = props.tooltip;
|
|
33
|
+
if (props.variant !== undefined) payload.variant = props.variant;
|
|
34
|
+
return payload;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
abstract class WidgetBase implements WidgetNode {
|
|
38
|
+
protected constructor(protected readonly common: CommonProps = {}) {}
|
|
39
|
+
|
|
40
|
+
protected withCommon(payload: Record<string, unknown>): Record<string, unknown> {
|
|
41
|
+
return applyCommonProps(payload, this.common);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
abstract toProtocol(): Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export class Label extends WidgetBase {
|
|
48
|
+
constructor(
|
|
49
|
+
public readonly text: string,
|
|
50
|
+
private readonly options: CommonProps & {
|
|
51
|
+
wrap?: boolean;
|
|
52
|
+
xalign?: number;
|
|
53
|
+
selectable?: boolean;
|
|
54
|
+
} = {},
|
|
55
|
+
) {
|
|
56
|
+
super(options);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
toProtocol(): Record<string, unknown> {
|
|
60
|
+
const payload = this.withCommon({ text: this.text });
|
|
61
|
+
if (this.options.wrap !== undefined) payload.wrap = this.options.wrap;
|
|
62
|
+
if (this.options.xalign !== undefined) payload.xalign = this.options.xalign;
|
|
63
|
+
if (this.options.selectable !== undefined) payload.selectable = this.options.selectable;
|
|
64
|
+
return { type: "label", data: payload };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export class Image extends WidgetBase {
|
|
69
|
+
constructor(
|
|
70
|
+
public readonly icon: Icon,
|
|
71
|
+
private readonly options: CommonProps & { pixel_size?: number } = {},
|
|
72
|
+
) {
|
|
73
|
+
super(options);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
toProtocol(): Record<string, unknown> {
|
|
77
|
+
const payload = this.withCommon({ icon: this.icon.toProtocol() });
|
|
78
|
+
if (this.options.pixel_size !== undefined) payload.pixel_size = this.options.pixel_size;
|
|
79
|
+
return { type: "image", data: payload };
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class IconWidget extends WidgetBase {
|
|
84
|
+
constructor(
|
|
85
|
+
public readonly icon: Icon,
|
|
86
|
+
private readonly options: CommonProps & { pixel_size?: number } = {},
|
|
87
|
+
) {
|
|
88
|
+
super(options);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
toProtocol(): Record<string, unknown> {
|
|
92
|
+
const payload = this.withCommon({ icon: this.icon.toProtocol() });
|
|
93
|
+
if (this.options.pixel_size !== undefined) payload.pixel_size = this.options.pixel_size;
|
|
94
|
+
return { type: "icon", data: payload };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export class Progress extends WidgetBase {
|
|
99
|
+
constructor(
|
|
100
|
+
private readonly options: CommonProps & {
|
|
101
|
+
value: number;
|
|
102
|
+
max?: number;
|
|
103
|
+
show_text?: boolean;
|
|
104
|
+
text?: string;
|
|
105
|
+
},
|
|
106
|
+
) {
|
|
107
|
+
super(options);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
toProtocol(): Record<string, unknown> {
|
|
111
|
+
const payload = this.withCommon({
|
|
112
|
+
value: this.options.value,
|
|
113
|
+
max: this.options.max ?? 1,
|
|
114
|
+
});
|
|
115
|
+
if (this.options.show_text !== undefined) payload.show_text = this.options.show_text;
|
|
116
|
+
if (this.options.text !== undefined) payload.text = this.options.text;
|
|
117
|
+
return { type: "progress", data: payload };
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export class Button extends WidgetBase {
|
|
122
|
+
constructor(
|
|
123
|
+
private readonly options: CommonProps & {
|
|
124
|
+
label?: string;
|
|
125
|
+
icon?: Icon;
|
|
126
|
+
child?: TreeNode;
|
|
127
|
+
} = {},
|
|
128
|
+
) {
|
|
129
|
+
super(options);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
toProtocol(): Record<string, unknown> {
|
|
133
|
+
const payload = this.withCommon({});
|
|
134
|
+
if (this.options.label !== undefined) payload.label = this.options.label;
|
|
135
|
+
if (this.options.icon !== undefined) payload.icon = this.options.icon.toProtocol();
|
|
136
|
+
if (this.options.child !== undefined) payload.child = this.options.child.toProtocol();
|
|
137
|
+
return { type: "button", data: payload };
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export class Switch extends WidgetBase {
|
|
142
|
+
constructor(
|
|
143
|
+
private readonly options: CommonProps & {
|
|
144
|
+
label?: string;
|
|
145
|
+
active?: boolean;
|
|
146
|
+
} = {},
|
|
147
|
+
) {
|
|
148
|
+
super(options);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
toProtocol(): Record<string, unknown> {
|
|
152
|
+
const payload = this.withCommon({ active: this.options.active ?? false });
|
|
153
|
+
if (this.options.label !== undefined) payload.label = this.options.label;
|
|
154
|
+
return { type: "switch", data: payload };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export class Scale extends WidgetBase {
|
|
159
|
+
constructor(
|
|
160
|
+
private readonly options: CommonProps & {
|
|
161
|
+
min?: number;
|
|
162
|
+
max?: number;
|
|
163
|
+
step?: number;
|
|
164
|
+
value?: number;
|
|
165
|
+
orientation?: Orientation;
|
|
166
|
+
draw_value?: boolean;
|
|
167
|
+
} = {},
|
|
168
|
+
) {
|
|
169
|
+
super(options);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
toProtocol(): Record<string, unknown> {
|
|
173
|
+
const payload = this.withCommon({
|
|
174
|
+
min: this.options.min ?? 0,
|
|
175
|
+
max: this.options.max ?? 1,
|
|
176
|
+
step: this.options.step ?? 0.1,
|
|
177
|
+
value: this.options.value ?? 0,
|
|
178
|
+
});
|
|
179
|
+
if (this.options.orientation !== undefined) payload.orientation = this.options.orientation;
|
|
180
|
+
if (this.options.draw_value !== undefined) payload.draw_value = this.options.draw_value;
|
|
181
|
+
return { type: "scale", data: payload };
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
export class Checkbox extends WidgetBase {
|
|
186
|
+
constructor(
|
|
187
|
+
private readonly options: CommonProps & {
|
|
188
|
+
label?: string;
|
|
189
|
+
active?: boolean;
|
|
190
|
+
} = {},
|
|
191
|
+
) {
|
|
192
|
+
super(options);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
toProtocol(): Record<string, unknown> {
|
|
196
|
+
const payload = this.withCommon({ active: this.options.active ?? false });
|
|
197
|
+
if (this.options.label !== undefined) payload.label = this.options.label;
|
|
198
|
+
return { type: "checkbox", data: payload };
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
export class DropdownItem {
|
|
203
|
+
constructor(
|
|
204
|
+
public readonly id: string,
|
|
205
|
+
public readonly label: string,
|
|
206
|
+
) {}
|
|
207
|
+
|
|
208
|
+
toProtocol(): Record<string, unknown> {
|
|
209
|
+
return { id: this.id, label: this.label };
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export class Dropdown extends WidgetBase {
|
|
214
|
+
constructor(
|
|
215
|
+
private readonly options: CommonProps & {
|
|
216
|
+
items?: DropdownItem[];
|
|
217
|
+
selected?: number;
|
|
218
|
+
} = {},
|
|
219
|
+
) {
|
|
220
|
+
super(options);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
toProtocol(): Record<string, unknown> {
|
|
224
|
+
const payload = this.withCommon({
|
|
225
|
+
items: (this.options.items ?? []).map((item) => item.toProtocol()),
|
|
226
|
+
});
|
|
227
|
+
if (this.options.selected !== undefined) payload.selected = this.options.selected;
|
|
228
|
+
return { type: "dropdown", data: payload };
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
export class Separator extends WidgetBase {
|
|
233
|
+
constructor(private readonly options: CommonProps & { orientation?: Orientation } = {}) {
|
|
234
|
+
super(options);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
toProtocol(): Record<string, unknown> {
|
|
238
|
+
const payload = this.withCommon({});
|
|
239
|
+
if (this.options.orientation !== undefined) payload.orientation = this.options.orientation;
|
|
240
|
+
return { type: "separator", data: payload };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
export class Scroll extends WidgetBase {
|
|
245
|
+
constructor(
|
|
246
|
+
private readonly child: TreeNode,
|
|
247
|
+
options: CommonProps = {},
|
|
248
|
+
) {
|
|
249
|
+
super(options);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
toProtocol(): Record<string, unknown> {
|
|
253
|
+
return { type: "scroll", data: this.withCommon({ child: this.child.toProtocol() }) };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export class GridChild {
|
|
258
|
+
constructor(
|
|
259
|
+
public readonly row: number,
|
|
260
|
+
public readonly column: number,
|
|
261
|
+
public readonly child: TreeNode,
|
|
262
|
+
public readonly width: number = 1,
|
|
263
|
+
public readonly height: number = 1,
|
|
264
|
+
) {}
|
|
265
|
+
|
|
266
|
+
toProtocol(): Record<string, unknown> {
|
|
267
|
+
return {
|
|
268
|
+
row: this.row,
|
|
269
|
+
column: this.column,
|
|
270
|
+
width: this.width,
|
|
271
|
+
height: this.height,
|
|
272
|
+
child: this.child.toProtocol(),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
export class Grid extends WidgetBase {
|
|
278
|
+
constructor(
|
|
279
|
+
private readonly options: CommonProps & {
|
|
280
|
+
children?: GridChild[];
|
|
281
|
+
row_spacing?: number;
|
|
282
|
+
column_spacing?: number;
|
|
283
|
+
} = {},
|
|
284
|
+
) {
|
|
285
|
+
super(options);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
toProtocol(): Record<string, unknown> {
|
|
289
|
+
return {
|
|
290
|
+
type: "grid",
|
|
291
|
+
data: this.withCommon({
|
|
292
|
+
row_spacing: this.options.row_spacing ?? 0,
|
|
293
|
+
column_spacing: this.options.column_spacing ?? 0,
|
|
294
|
+
children: (this.options.children ?? []).map((child) => child.toProtocol()),
|
|
295
|
+
}),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
export class Hero extends WidgetBase {
|
|
301
|
+
constructor(
|
|
302
|
+
private readonly options: CommonProps & {
|
|
303
|
+
title: string;
|
|
304
|
+
subtitle: string;
|
|
305
|
+
icon?: Icon;
|
|
306
|
+
},
|
|
307
|
+
) {
|
|
308
|
+
super(options);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
toProtocol(): Record<string, unknown> {
|
|
312
|
+
const payload = this.withCommon({
|
|
313
|
+
title: this.options.title,
|
|
314
|
+
subtitle: this.options.subtitle,
|
|
315
|
+
});
|
|
316
|
+
if (this.options.icon !== undefined) payload.icon = this.options.icon.toProtocol();
|
|
317
|
+
return { type: "hero", data: payload };
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
export class Card extends WidgetBase {
|
|
322
|
+
constructor(
|
|
323
|
+
private readonly options: CommonProps & {
|
|
324
|
+
children?: TreeNode[];
|
|
325
|
+
} = {},
|
|
326
|
+
) {
|
|
327
|
+
super(options);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
toProtocol(): Record<string, unknown> {
|
|
331
|
+
return {
|
|
332
|
+
type: "card",
|
|
333
|
+
data: this.withCommon({
|
|
334
|
+
children: (this.options.children ?? []).map((child) => child.toProtocol()),
|
|
335
|
+
}),
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
export class Header {
|
|
341
|
+
constructor(
|
|
342
|
+
public readonly title: string,
|
|
343
|
+
public readonly subtitle = "",
|
|
344
|
+
) {}
|
|
345
|
+
|
|
346
|
+
toProtocol(): Record<string, unknown> {
|
|
347
|
+
const payload: Record<string, unknown> = { title: this.title };
|
|
348
|
+
if (this.subtitle !== "") payload.subtitle = this.subtitle;
|
|
349
|
+
return payload;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export class Section extends WidgetBase {
|
|
354
|
+
constructor(
|
|
355
|
+
private readonly options: CommonProps & {
|
|
356
|
+
title?: string;
|
|
357
|
+
subtitle?: string;
|
|
358
|
+
header?: Header;
|
|
359
|
+
body?: TreeNode[];
|
|
360
|
+
children?: TreeNode[];
|
|
361
|
+
},
|
|
362
|
+
) {
|
|
363
|
+
super(options);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
toProtocol(): Record<string, unknown> {
|
|
367
|
+
const header =
|
|
368
|
+
this.options.header ??
|
|
369
|
+
(this.options.title === undefined
|
|
370
|
+
? undefined
|
|
371
|
+
: new Header(this.options.title, this.options.subtitle ?? ""));
|
|
372
|
+
const body = this.options.body ?? this.options.children ?? [];
|
|
373
|
+
return {
|
|
374
|
+
type: "section",
|
|
375
|
+
data: this.withCommon({
|
|
376
|
+
...(header === undefined ? {} : { header: header.toProtocol() }),
|
|
377
|
+
body: body.map((child) => child.toProtocol()),
|
|
378
|
+
}),
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
export class Collapsible extends WidgetBase {
|
|
384
|
+
constructor(
|
|
385
|
+
private readonly options: CommonProps & {
|
|
386
|
+
title?: string;
|
|
387
|
+
subtitle?: string;
|
|
388
|
+
header?: Header;
|
|
389
|
+
expanded?: boolean;
|
|
390
|
+
body?: TreeNode[];
|
|
391
|
+
children?: TreeNode[];
|
|
392
|
+
},
|
|
393
|
+
) {
|
|
394
|
+
super(options);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
toProtocol(): Record<string, unknown> {
|
|
398
|
+
const header =
|
|
399
|
+
this.options.header ??
|
|
400
|
+
(this.options.title === undefined
|
|
401
|
+
? undefined
|
|
402
|
+
: new Header(this.options.title, this.options.subtitle ?? ""));
|
|
403
|
+
const body = this.options.body ?? this.options.children ?? [];
|
|
404
|
+
return {
|
|
405
|
+
type: "collapsible",
|
|
406
|
+
data: this.withCommon({
|
|
407
|
+
...(header === undefined ? {} : { header: header.toProtocol() }),
|
|
408
|
+
expanded: this.options.expanded ?? false,
|
|
409
|
+
body: body.map((child) => child.toProtocol()),
|
|
410
|
+
}),
|
|
411
|
+
};
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export class Item extends WidgetBase {
|
|
416
|
+
constructor(
|
|
417
|
+
private readonly options: CommonProps & {
|
|
418
|
+
left?: TreeNode;
|
|
419
|
+
label?: string;
|
|
420
|
+
right?: TreeNode;
|
|
421
|
+
clickable?: boolean;
|
|
422
|
+
menu?: MenuItem[];
|
|
423
|
+
} = {},
|
|
424
|
+
) {
|
|
425
|
+
super(options);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
toProtocol(): Record<string, unknown> {
|
|
429
|
+
const payload = this.withCommon({
|
|
430
|
+
label: this.options.label ?? "",
|
|
431
|
+
clickable: this.options.clickable ?? false,
|
|
432
|
+
menu: (this.options.menu ?? []).map((item) => item.toProtocol()),
|
|
433
|
+
});
|
|
434
|
+
if (this.options.left !== undefined) payload.left = this.options.left.toProtocol();
|
|
435
|
+
if (this.options.right !== undefined) payload.right = this.options.right.toProtocol();
|
|
436
|
+
return { type: "item", data: payload };
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
export class CollapsibleItem extends WidgetBase {
|
|
441
|
+
constructor(
|
|
442
|
+
private readonly options: CommonProps & {
|
|
443
|
+
left?: TreeNode;
|
|
444
|
+
label?: string;
|
|
445
|
+
right?: TreeNode;
|
|
446
|
+
expanded?: boolean;
|
|
447
|
+
body?: TreeNode[];
|
|
448
|
+
children?: TreeNode[];
|
|
449
|
+
} = {},
|
|
450
|
+
) {
|
|
451
|
+
super(options);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
toProtocol(): Record<string, unknown> {
|
|
455
|
+
const payload = this.withCommon({
|
|
456
|
+
label: this.options.label ?? "",
|
|
457
|
+
expanded: this.options.expanded ?? false,
|
|
458
|
+
body: (this.options.body ?? this.options.children ?? []).map((child) => child.toProtocol()),
|
|
459
|
+
});
|
|
460
|
+
if (this.options.left !== undefined) payload.left = this.options.left.toProtocol();
|
|
461
|
+
if (this.options.right !== undefined) payload.right = this.options.right.toProtocol();
|
|
462
|
+
return { type: "collapsible_item", data: payload };
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
export class Meter extends WidgetBase {
|
|
467
|
+
constructor(
|
|
468
|
+
private readonly options: CommonProps & {
|
|
469
|
+
icon?: Icon;
|
|
470
|
+
label?: string;
|
|
471
|
+
value: number;
|
|
472
|
+
min?: number;
|
|
473
|
+
max?: number;
|
|
474
|
+
step?: number;
|
|
475
|
+
text?: string;
|
|
476
|
+
interactive?: boolean;
|
|
477
|
+
},
|
|
478
|
+
) {
|
|
479
|
+
super(options);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
toProtocol(): Record<string, unknown> {
|
|
483
|
+
const payload = this.withCommon({
|
|
484
|
+
label: this.options.label ?? "",
|
|
485
|
+
value: this.options.value,
|
|
486
|
+
min: this.options.min ?? 0,
|
|
487
|
+
max: this.options.max ?? 1,
|
|
488
|
+
step: this.options.step ?? 0.01,
|
|
489
|
+
interactive: this.options.interactive ?? false,
|
|
490
|
+
});
|
|
491
|
+
if (this.options.icon !== undefined) payload.icon = this.options.icon.toProtocol();
|
|
492
|
+
if (this.options.text !== undefined) payload.text = this.options.text;
|
|
493
|
+
return { type: "meter", data: payload };
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
export class Copyable extends WidgetBase {
|
|
498
|
+
constructor(
|
|
499
|
+
private readonly options: CommonProps & {
|
|
500
|
+
label?: string;
|
|
501
|
+
value: string;
|
|
502
|
+
},
|
|
503
|
+
) {
|
|
504
|
+
super(options);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
toProtocol(): Record<string, unknown> {
|
|
508
|
+
return {
|
|
509
|
+
type: "copyable",
|
|
510
|
+
data: this.withCommon({
|
|
511
|
+
label: this.options.label ?? "",
|
|
512
|
+
value: this.options.value,
|
|
513
|
+
}),
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
export class ToastAction {
|
|
519
|
+
constructor(
|
|
520
|
+
public readonly id: string,
|
|
521
|
+
public readonly label: string,
|
|
522
|
+
) {}
|
|
523
|
+
|
|
524
|
+
toProtocol(): Record<string, unknown> {
|
|
525
|
+
return { id: this.id, label: this.label };
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
export class Toast extends WidgetBase {
|
|
530
|
+
constructor(
|
|
531
|
+
private readonly options: CommonProps & {
|
|
532
|
+
icon?: Icon;
|
|
533
|
+
title: string;
|
|
534
|
+
message?: string;
|
|
535
|
+
action?: ToastAction;
|
|
536
|
+
},
|
|
537
|
+
) {
|
|
538
|
+
super(options);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
toProtocol(): Record<string, unknown> {
|
|
542
|
+
const payload = this.withCommon({
|
|
543
|
+
title: this.options.title,
|
|
544
|
+
message: this.options.message ?? "",
|
|
545
|
+
});
|
|
546
|
+
if (this.options.icon !== undefined) payload.icon = this.options.icon.toProtocol();
|
|
547
|
+
if (this.options.action !== undefined) payload.action = this.options.action.toProtocol();
|
|
548
|
+
return { type: "toast", data: payload };
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
export class ActionRow extends WidgetBase {
|
|
553
|
+
constructor(
|
|
554
|
+
private readonly options: CommonProps & {
|
|
555
|
+
title: string;
|
|
556
|
+
subtitle?: string;
|
|
557
|
+
meta?: string;
|
|
558
|
+
icon?: Icon;
|
|
559
|
+
},
|
|
560
|
+
) {
|
|
561
|
+
super(options);
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
toProtocol(): Record<string, unknown> {
|
|
565
|
+
const payload = this.withCommon({
|
|
566
|
+
title: this.options.title,
|
|
567
|
+
subtitle: this.options.subtitle ?? "",
|
|
568
|
+
meta: this.options.meta ?? "",
|
|
569
|
+
});
|
|
570
|
+
if (this.options.icon !== undefined) payload.icon = this.options.icon.toProtocol();
|
|
571
|
+
return { type: "action_row", data: payload };
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export class Row extends WidgetBase {
|
|
576
|
+
constructor(
|
|
577
|
+
private readonly options: CommonProps & {
|
|
578
|
+
spacing?: number;
|
|
579
|
+
children?: TreeNode[];
|
|
580
|
+
} = {},
|
|
581
|
+
) {
|
|
582
|
+
super(options);
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
toProtocol(): Record<string, unknown> {
|
|
586
|
+
return {
|
|
587
|
+
type: "row",
|
|
588
|
+
data: this.withCommon({
|
|
589
|
+
spacing: this.options.spacing ?? 0,
|
|
590
|
+
children: (this.options.children ?? []).map((child) => child.toProtocol()),
|
|
591
|
+
}),
|
|
592
|
+
};
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
export class Column extends WidgetBase {
|
|
597
|
+
constructor(
|
|
598
|
+
private readonly options: CommonProps & {
|
|
599
|
+
spacing?: number;
|
|
600
|
+
children?: TreeNode[];
|
|
601
|
+
} = {},
|
|
602
|
+
) {
|
|
603
|
+
super(options);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
toProtocol(): Record<string, unknown> {
|
|
607
|
+
return {
|
|
608
|
+
type: "column",
|
|
609
|
+
data: this.withCommon({
|
|
610
|
+
spacing: this.options.spacing ?? 0,
|
|
611
|
+
children: (this.options.children ?? []).map((child) => child.toProtocol()),
|
|
612
|
+
}),
|
|
613
|
+
};
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
export class ActionMenuItem {
|
|
618
|
+
constructor(
|
|
619
|
+
public readonly options: {
|
|
620
|
+
id: string;
|
|
621
|
+
label: string;
|
|
622
|
+
icon?: Icon;
|
|
623
|
+
visible?: boolean;
|
|
624
|
+
checked?: boolean;
|
|
625
|
+
selectable?: boolean;
|
|
626
|
+
},
|
|
627
|
+
) {}
|
|
628
|
+
|
|
629
|
+
toProtocol(): Record<string, unknown> {
|
|
630
|
+
const payload: Record<string, unknown> = {
|
|
631
|
+
id: this.options.id,
|
|
632
|
+
label: this.options.label,
|
|
633
|
+
};
|
|
634
|
+
if (this.options.icon !== undefined) payload.icon = this.options.icon.toProtocol();
|
|
635
|
+
if (this.options.visible !== undefined) payload.visible = this.options.visible;
|
|
636
|
+
if (this.options.checked !== undefined) payload.checked = this.options.checked;
|
|
637
|
+
if (this.options.selectable !== undefined) payload.selectable = this.options.selectable;
|
|
638
|
+
return payload;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
export class ActionMenu extends WidgetBase {
|
|
643
|
+
constructor(
|
|
644
|
+
private readonly options: CommonProps & {
|
|
645
|
+
header?: string;
|
|
646
|
+
items?: ActionMenuItem[];
|
|
647
|
+
} = {},
|
|
648
|
+
) {
|
|
649
|
+
super(options);
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
toProtocol(): Record<string, unknown> {
|
|
653
|
+
const payload = this.withCommon({
|
|
654
|
+
items: (this.options.items ?? []).map((item) => item.toProtocol()),
|
|
655
|
+
});
|
|
656
|
+
if (this.options.header !== undefined) payload.header = this.options.header;
|
|
657
|
+
return { type: "action_menu", data: payload };
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
export class Spinner extends WidgetBase {
|
|
662
|
+
constructor(
|
|
663
|
+
private readonly options: CommonProps & {
|
|
664
|
+
spinning?: boolean;
|
|
665
|
+
} = {},
|
|
666
|
+
) {
|
|
667
|
+
super(options);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
toProtocol(): Record<string, unknown> {
|
|
671
|
+
return {
|
|
672
|
+
type: "spinner",
|
|
673
|
+
data: this.withCommon({ spinning: this.options.spinning ?? true }),
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
export class DetailGridItem {
|
|
679
|
+
constructor(
|
|
680
|
+
public readonly key: string,
|
|
681
|
+
public readonly value: string,
|
|
682
|
+
) {}
|
|
683
|
+
|
|
684
|
+
toProtocol(): Record<string, unknown> {
|
|
685
|
+
return { key: this.key, value: this.value };
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
export class DetailGrid extends WidgetBase {
|
|
690
|
+
constructor(
|
|
691
|
+
private readonly options: CommonProps & {
|
|
692
|
+
rows?: DetailGridItem[];
|
|
693
|
+
} = {},
|
|
694
|
+
) {
|
|
695
|
+
super(options);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
toProtocol(): Record<string, unknown> {
|
|
699
|
+
return {
|
|
700
|
+
type: "detail_grid",
|
|
701
|
+
data: this.withCommon({
|
|
702
|
+
rows: (this.options.rows ?? []).map((row) => row.toProtocol()),
|
|
703
|
+
}),
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
export class EmptyState extends WidgetBase {
|
|
709
|
+
constructor(
|
|
710
|
+
private readonly options: CommonProps & {
|
|
711
|
+
title: string;
|
|
712
|
+
subtitle?: string;
|
|
713
|
+
},
|
|
714
|
+
) {
|
|
715
|
+
super(options);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
toProtocol(): Record<string, unknown> {
|
|
719
|
+
return {
|
|
720
|
+
type: "empty_state",
|
|
721
|
+
data: this.withCommon({
|
|
722
|
+
title: this.options.title,
|
|
723
|
+
subtitle: this.options.subtitle ?? "",
|
|
724
|
+
}),
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
export class Badge extends WidgetBase {
|
|
730
|
+
constructor(
|
|
731
|
+
private readonly options: CommonProps & {
|
|
732
|
+
label: string;
|
|
733
|
+
},
|
|
734
|
+
) {
|
|
735
|
+
super(options);
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
toProtocol(): Record<string, unknown> {
|
|
739
|
+
return {
|
|
740
|
+
type: "badge",
|
|
741
|
+
data: this.withCommon({
|
|
742
|
+
label: this.options.label,
|
|
743
|
+
}),
|
|
744
|
+
};
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
export class StatusDot extends WidgetBase {
|
|
749
|
+
constructor(options: CommonProps = {}) {
|
|
750
|
+
super(options);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
toProtocol(): Record<string, unknown> {
|
|
754
|
+
return { type: "status", data: this.withCommon({}) };
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
export class Box extends WidgetBase {
|
|
759
|
+
constructor(
|
|
760
|
+
private readonly options: CommonProps & {
|
|
761
|
+
orientation?: Orientation;
|
|
762
|
+
spacing?: number;
|
|
763
|
+
children?: TreeNode[];
|
|
764
|
+
} = {},
|
|
765
|
+
) {
|
|
766
|
+
super(options);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
static vertical(children: TreeNode[], spacing = 0, options: CommonProps = {}): Box {
|
|
770
|
+
return new Box({ ...options, orientation: "vertical", spacing, children });
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
static horizontal(children: TreeNode[], spacing = 0, options: CommonProps = {}): Box {
|
|
774
|
+
return new Box({ ...options, orientation: "horizontal", spacing, children });
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
toProtocol(): Record<string, unknown> {
|
|
778
|
+
return {
|
|
779
|
+
type: "box",
|
|
780
|
+
data: this.withCommon({
|
|
781
|
+
orientation: this.options.orientation ?? "vertical",
|
|
782
|
+
spacing: this.options.spacing ?? 0,
|
|
783
|
+
children: (this.options.children ?? []).map((child) => child.toProtocol()),
|
|
784
|
+
}),
|
|
785
|
+
};
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
export type TreeNode =
|
|
790
|
+
| Hero
|
|
791
|
+
| Card
|
|
792
|
+
| Section
|
|
793
|
+
| Collapsible
|
|
794
|
+
| Item
|
|
795
|
+
| CollapsibleItem
|
|
796
|
+
| Meter
|
|
797
|
+
| Copyable
|
|
798
|
+
| Toast
|
|
799
|
+
| ActionRow
|
|
800
|
+
| ActionMenu
|
|
801
|
+
| DetailGrid
|
|
802
|
+
| EmptyState
|
|
803
|
+
| Badge
|
|
804
|
+
| StatusDot
|
|
805
|
+
| Box
|
|
806
|
+
| Row
|
|
807
|
+
| Column
|
|
808
|
+
| Grid
|
|
809
|
+
| Scroll
|
|
810
|
+
| Progress
|
|
811
|
+
| Separator
|
|
812
|
+
| Spinner
|
|
813
|
+
| Label
|
|
814
|
+
| IconWidget
|
|
815
|
+
| Image
|
|
816
|
+
| Button
|
|
817
|
+
| Switch
|
|
818
|
+
| Scale
|
|
819
|
+
| Dropdown
|
|
820
|
+
| Checkbox;
|