glimpse-sdk 0.8.0 → 0.9.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/src/widgets.ts DELETED
@@ -1,491 +0,0 @@
1
- export type InlineHandler = (event: unknown) => void | Promise<void>;
2
- export class InlineHandlerRegistry {
3
- readonly handlers = new Map<string, InlineHandler>();
4
-
5
- generatedId(event: "click" | "toggle" | "change", path: number[]): string {
6
- const suffix = path.length === 0 ? "root" : path.join(".");
7
- return `__glimpse:${event}:${suffix}`;
8
- }
9
-
10
- targetId(event: "click" | "toggle" | "change", id: string | undefined, path: number[]): string {
11
- return id ?? this.generatedId(event, path);
12
- }
13
-
14
- add(event: "click" | "toggle" | "change", id: string, handler: InlineHandler): void {
15
- this.handlers.set(`${event}:${id}`, handler);
16
- }
17
- }
18
-
19
- export type BadgeKind = "default" | "success" | "warning" | "error" | "accent";
20
- export type StatusDotStatus = "neutral" | "success" | "warning" | "error" | "accent";
21
- export type PagerAppearance = "dots" | "numbers";
22
- export type PopoverSize = "small" | "medium" | "large" | "wide";
23
-
24
- export interface ProtocolNode {
25
- type: string;
26
- data: Record<string, unknown>;
27
- }
28
-
29
- export interface CommonOptions {
30
- visible?: boolean;
31
- tooltip?: string;
32
- css_classes?: string[];
33
- styles?: Record<string, string>;
34
- }
35
-
36
- export abstract class WidgetBase {
37
- protected constructor(protected readonly common: CommonOptions = {}) {}
38
- abstract readonly type: string;
39
- abstract data(): Record<string, unknown>;
40
- bindHandlers(_registry: InlineHandlerRegistry, _path: number[]): void {}
41
-
42
- toProtocol(): ProtocolNode {
43
- return { type: this.type, data: this.data() };
44
- }
45
-
46
- protected commonData(): Record<string, unknown> {
47
- const out: Record<string, unknown> = {};
48
- if (this.common.visible !== undefined) out.visible = this.common.visible;
49
- if (this.common.tooltip !== undefined) out.tooltip = this.common.tooltip;
50
- if (this.common.css_classes?.length) out.css_classes = this.common.css_classes;
51
- if (this.common.styles && Object.keys(this.common.styles).length > 0) out.styles = this.common.styles;
52
- return out;
53
- }
54
- }
55
-
56
- const child = (node?: TreeNode): ProtocolNode | undefined => node?.toProtocol();
57
- const children = (nodes: TreeNode[]): ProtocolNode[] => nodes.map((node) => node.toProtocol());
58
-
59
- export class Label extends WidgetBase {
60
- readonly type = "label";
61
- private readonly options: CommonOptions & { label: string; xalign?: number; wrap?: boolean };
62
- constructor(options: string | CommonOptions & { label: string; xalign?: number; wrap?: boolean }) {
63
- const normalized = typeof options === "string" ? { label: options } : options;
64
- super(normalized);
65
- this.options = normalized;
66
- }
67
- data(): Record<string, unknown> {
68
- const out: Record<string, unknown> = { ...this.commonData(), label: this.options.label };
69
- if (this.options.xalign !== undefined) out.xalign = this.options.xalign;
70
- if (this.options.wrap !== undefined) out.wrap = this.options.wrap;
71
- return out;
72
- }
73
- }
74
-
75
- export class Header extends WidgetBase {
76
- readonly type = "header";
77
- constructor(private readonly options: CommonOptions & { label: string }) { super(options); }
78
- data(): Record<string, unknown> { return { ...this.commonData(), label: this.options.label }; }
79
- }
80
-
81
- export class Hero extends WidgetBase {
82
- readonly type = "hero";
83
- constructor(private readonly options: CommonOptions & { title: string; subtitle?: string; id?: string; icon?: string; icon_size?: number; toggle?: boolean; toggle_sensitive?: boolean; separator?: boolean; trailing?: TreeNode; on_toggle?: InlineHandler }) { super(options); }
84
- data(): Record<string, unknown> {
85
- const out: Record<string, unknown> = { ...this.commonData(), title: this.options.title, subtitle: this.options.subtitle ?? "" };
86
- for (const key of ["id", "icon", "icon_size", "toggle", "toggle_sensitive", "separator"] as const) {
87
- if (this.options[key] !== undefined) out[key] = this.options[key];
88
- }
89
- const trailing = child(this.options.trailing);
90
- if (trailing) out.trailing = trailing;
91
- return out;
92
- }
93
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
94
- if (this.options.on_toggle) {
95
- this.options.id = registry.targetId("toggle", this.options.id, path);
96
- registry.add("toggle", this.options.id, this.options.on_toggle);
97
- }
98
- this.options.trailing?.bindHandlers(registry, [...path, 0]);
99
- }
100
- }
101
-
102
- export class Badge extends WidgetBase {
103
- readonly type = "badge";
104
- constructor(private readonly options: CommonOptions & { label: string; kind?: BadgeKind }) { super(options); }
105
- data(): Record<string, unknown> { return { ...this.commonData(), label: this.options.label, kind: this.options.kind ?? "default" }; }
106
- }
107
-
108
- export class StatusDot extends WidgetBase {
109
- readonly type = "status_dot";
110
- constructor(private readonly options: CommonOptions & { status?: StatusDotStatus } = {}) { super(options); }
111
- data(): Record<string, unknown> { return { ...this.commonData(), status: this.options.status ?? "neutral" }; }
112
- }
113
-
114
- export class PanelIndicator extends WidgetBase {
115
- readonly type = "panel_indicator";
116
- constructor(private readonly options: CommonOptions & { id?: string; icon?: string; label?: string; active?: boolean; checked?: boolean; needs_attention?: boolean; extra?: TreeNode; on_click?: InlineHandler }) { super(options); }
117
- data(): Record<string, unknown> {
118
- const out: Record<string, unknown> = { ...this.commonData(), active: this.options.active ?? false, checked: this.options.checked ?? false, needs_attention: this.options.needs_attention ?? false };
119
- for (const key of ["id", "icon", "label"] as const) if (this.options[key] !== undefined) out[key] = this.options[key];
120
- const extra = child(this.options.extra);
121
- if (extra) out.extra = extra;
122
- return out;
123
- }
124
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
125
- if (this.options.id && this.options.on_click) registry.add("click", this.options.id, this.options.on_click);
126
- this.options.extra?.bindHandlers(registry, [...path, 0]);
127
- }
128
- }
129
-
130
- export class EmptyState extends WidgetBase {
131
- readonly type = "empty_state";
132
- constructor(private readonly options: CommonOptions & { title: string; subtitle?: string }) { super(options); }
133
- data(): Record<string, unknown> {
134
- const out: Record<string, unknown> = { ...this.commonData(), title: this.options.title };
135
- if (this.options.subtitle !== undefined) out.subtitle = this.options.subtitle;
136
- return out;
137
- }
138
- }
139
-
140
- export class Spinner extends WidgetBase {
141
- readonly type = "spinner";
142
- constructor(private readonly options: CommonOptions & { spinning?: boolean } = {}) { super(options); }
143
- data(): Record<string, unknown> { return { ...this.commonData(), spinning: this.options.spinning ?? true }; }
144
- }
145
-
146
- export class Meter extends WidgetBase {
147
- readonly type = "meter";
148
- constructor(private readonly options: CommonOptions & { id?: string; icon?: string; label?: string; value?: number; min?: number; max?: number; step?: number; text?: string; interactive?: boolean; on_change?: InlineHandler } = {}) { super(options); }
149
- data(): Record<string, unknown> {
150
- const out: Record<string, unknown> = {
151
- ...this.commonData(),
152
- label: this.options.label ?? "",
153
- value: this.options.value ?? 0,
154
- min: this.options.min ?? 0,
155
- max: this.options.max ?? 1,
156
- step: this.options.step ?? 0.01,
157
- interactive: this.options.interactive ?? this.options.on_change !== undefined,
158
- };
159
- for (const key of ["id", "icon", "text"] as const) if (this.options[key] !== undefined) out[key] = this.options[key];
160
- return out;
161
- }
162
- bindHandlers(registry: InlineHandlerRegistry, _path: number[]): void {
163
- if (this.options.id && this.options.on_change) registry.add("change", this.options.id, this.options.on_change);
164
- }
165
- }
166
-
167
- export class Separator extends WidgetBase {
168
- readonly type = "separator";
169
- constructor(common: CommonOptions = {}) { super(common); }
170
- data(): Record<string, unknown> { return this.commonData(); }
171
- }
172
-
173
- export class Scroll extends WidgetBase {
174
- readonly type = "scroll";
175
- constructor(private readonly options: CommonOptions & { child: TreeNode }) { super(options); }
176
- data(): Record<string, unknown> { return { ...this.commonData(), child: this.options.child.toProtocol() }; }
177
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
178
- this.options.child.bindHandlers(registry, [...path, 0]);
179
- }
180
- }
181
-
182
- abstract class ChildrenWidget extends WidgetBase {
183
- constructor(common: CommonOptions & { children?: TreeNode[] } = {}) { super(common); this.kids = common.children ?? []; }
184
- protected readonly kids: TreeNode[];
185
- data(): Record<string, unknown> { return { ...this.commonData(), children: children(this.kids) }; }
186
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
187
- this.kids.forEach((kid, index) => kid.bindHandlers(registry, [...path, index]));
188
- }
189
- }
190
-
191
- export class Row extends ChildrenWidget { readonly type = "row"; }
192
- export class Column extends ChildrenWidget { readonly type = "column"; }
193
- export class BoxedList extends ChildrenWidget { readonly type = "boxed_list"; }
194
- export class ButtonRow extends ChildrenWidget { readonly type = "button_row"; }
195
-
196
- export class CircleBox extends WidgetBase {
197
- readonly type = "circle_box";
198
- constructor(private readonly options: CommonOptions & { color: string }) { super(options); }
199
- data(): Record<string, unknown> {
200
- const out = this.commonData();
201
- out.color = this.options.color;
202
- return out;
203
- }
204
- }
205
-
206
- export class Container extends ChildrenWidget {
207
- readonly type = "container";
208
- }
209
-
210
- export class PopoverShell extends ChildrenWidget {
211
- readonly type = "popover_shell";
212
- constructor(private readonly options: CommonOptions & { children?: TreeNode[]; size?: PopoverSize; footer?: TreeNode[]; footer_visible?: boolean } = {}) { super(options); }
213
- data(): Record<string, unknown> {
214
- const out: Record<string, unknown> = { ...super.data(), size: this.options.size ?? "medium" };
215
- if ((this.options.footer ?? []).length > 0) out.footer = children(this.options.footer ?? []);
216
- if (this.options.footer_visible) out.footer_visible = this.options.footer_visible;
217
- return out;
218
- }
219
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
220
- super.bindHandlers(registry, path);
221
- (this.options.footer ?? []).forEach((kid, index) => kid.bindHandlers(registry, [...path, this.kids.length + index]));
222
- }
223
- }
224
-
225
- export class Tile extends WidgetBase {
226
- readonly type: string = "tile";
227
- constructor(protected readonly options: CommonOptions & { primary: string; id?: string; secondary?: string; left_icon?: string; left?: TreeNode; right?: TreeNode; on_click?: InlineHandler }) { super(options); }
228
- data(): Record<string, unknown> {
229
- const out: Record<string, unknown> = { ...this.commonData(), primary: this.options.primary };
230
- for (const key of ["id", "secondary", "left_icon"] as const) if (this.options[key] !== undefined) out[key] = this.options[key];
231
- const left = child(this.options.left);
232
- const right = child(this.options.right);
233
- if (left) out.left = left;
234
- if (right) out.right = right;
235
- return out;
236
- }
237
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
238
- if (this.options.on_click) {
239
- this.options.id = registry.targetId("click", this.options.id, path);
240
- registry.add("click", this.options.id, this.options.on_click);
241
- }
242
- this.options.left?.bindHandlers(registry, [...path, 0]);
243
- this.options.right?.bindHandlers(registry, [...path, 1]);
244
- }
245
- }
246
-
247
- export class SegmentedTile extends Tile {
248
- readonly type = "segmented_tile";
249
- constructor(protected readonly options: ConstructorParameters<typeof Tile>[0] & { child?: TreeNode; expanded?: boolean; on_toggle?: InlineHandler }) { super(options); }
250
- data(): Record<string, unknown> {
251
- const out = super.data();
252
- const nested = child(this.options.child);
253
- if (nested) out.child = nested;
254
- out.expanded = this.options.expanded ?? false;
255
- return out;
256
- }
257
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
258
- super.bindHandlers(registry, path);
259
- if (this.options.on_toggle) {
260
- this.options.id = registry.targetId("toggle", this.options.id, path);
261
- registry.add("toggle", this.options.id, this.options.on_toggle);
262
- }
263
- this.options.child?.bindHandlers(registry, [...path, 2]);
264
- }
265
- }
266
-
267
- export class SwitchTile extends WidgetBase {
268
- readonly type = "switch_tile";
269
- constructor(private readonly options: CommonOptions & { id: string; primary: string; secondary?: string; left_icon?: string; left?: TreeNode; active?: boolean; on_toggle?: InlineHandler }) { super(options); }
270
- data(): Record<string, unknown> {
271
- const out: Record<string, unknown> = { ...this.commonData(), id: this.options.id, primary: this.options.primary, active: this.options.active ?? false };
272
- for (const key of ["secondary", "left_icon"] as const) if (this.options[key] !== undefined) out[key] = this.options[key];
273
- const left = child(this.options.left);
274
- if (left) out.left = left;
275
- return out;
276
- }
277
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
278
- if (this.options.on_toggle) registry.add("toggle", this.options.id, this.options.on_toggle);
279
- this.options.left?.bindHandlers(registry, [...path, 0]);
280
- }
281
- }
282
-
283
- export class ExpanderTile extends WidgetBase {
284
- readonly type = "expander_tile";
285
- constructor(private readonly options: CommonOptions & { primary: string; id?: string; secondary?: string; left_icon?: string; left?: TreeNode; child?: TreeNode; expanded?: boolean; on_toggle?: InlineHandler }) { super(options); }
286
- data(): Record<string, unknown> {
287
- const out: Record<string, unknown> = { ...this.commonData(), primary: this.options.primary, expanded: this.options.expanded ?? false };
288
- for (const key of ["id", "secondary", "left_icon"] as const) if (this.options[key] !== undefined) out[key] = this.options[key];
289
- const left = child(this.options.left);
290
- const nested = child(this.options.child);
291
- if (left) out.left = left;
292
- if (nested) out.child = nested;
293
- return out;
294
- }
295
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
296
- if (this.options.on_toggle) {
297
- this.options.id = registry.targetId("toggle", this.options.id, path);
298
- registry.add("toggle", this.options.id, this.options.on_toggle);
299
- }
300
- this.options.left?.bindHandlers(registry, [...path, 0]);
301
- this.options.child?.bindHandlers(registry, [...path, 1]);
302
- }
303
- }
304
-
305
- export class SliderTile extends WidgetBase {
306
- readonly type = "slider_tile";
307
- constructor(private readonly options: CommonOptions & { id: string; label?: string; left_icon?: string; left?: TreeNode; value?: number; min?: number; max?: number; step?: number; page?: number; digits?: number; snap_step?: number; on_change?: InlineHandler }) { super(options); }
308
- data(): Record<string, unknown> {
309
- const out: Record<string, unknown> = { ...this.commonData(), id: this.options.id, value: this.options.value ?? 0, min: this.options.min ?? 0, max: this.options.max ?? 1, step: this.options.step ?? 0.01, page: this.options.page ?? 0.1, digits: this.options.digits ?? 0 };
310
- for (const key of ["label", "left_icon", "snap_step"] as const) if (this.options[key] !== undefined) out[key] = this.options[key];
311
- const left = child(this.options.left);
312
- if (left) out.left = left;
313
- return out;
314
- }
315
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
316
- if (this.options.on_change) registry.add("change", this.options.id, this.options.on_change);
317
- this.options.left?.bindHandlers(registry, [...path, 0]);
318
- }
319
- }
320
-
321
- export class ChoiceTile extends WidgetBase {
322
- readonly type = "choice_tile";
323
- constructor(private readonly options: CommonOptions & { primary: string; id?: string; secondary?: string; left_icon?: string; left?: TreeNode; selected?: boolean; on_click?: InlineHandler }) { super(options); }
324
- data(): Record<string, unknown> {
325
- const out: Record<string, unknown> = { ...this.commonData(), primary: this.options.primary, selected: this.options.selected ?? false };
326
- for (const key of ["id", "secondary", "left_icon"] as const) if (this.options[key] !== undefined) out[key] = this.options[key];
327
- const left = child(this.options.left);
328
- if (left) out.left = left;
329
- return out;
330
- }
331
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
332
- if (this.options.on_click) {
333
- this.options.id = registry.targetId("click", this.options.id, path);
334
- registry.add("click", this.options.id, this.options.on_click);
335
- }
336
- this.options.left?.bindHandlers(registry, [...path, 0]);
337
- }
338
- }
339
-
340
- export class Choice {
341
- constructor(public readonly options: { id: string; primary: string; secondary?: string; icon?: string }) {}
342
- toProtocol(): Record<string, unknown> {
343
- const out: Record<string, unknown> = { id: this.options.id, primary: this.options.primary };
344
- if (this.options.secondary !== undefined) out.secondary = this.options.secondary;
345
- if (this.options.icon !== undefined) out.icon = this.options.icon;
346
- return out;
347
- }
348
- }
349
-
350
- export class ChoiceList extends WidgetBase {
351
- readonly type = "choice_list";
352
- constructor(private readonly options: CommonOptions & { id: string; choices?: Choice[]; active?: string; on_change?: InlineHandler }) { super(options); }
353
- data(): Record<string, unknown> {
354
- const out: Record<string, unknown> = { ...this.commonData(), id: this.options.id, choices: (this.options.choices ?? []).map((choice) => choice.toProtocol()) };
355
- if (this.options.active !== undefined) out.active = this.options.active;
356
- return out;
357
- }
358
- bindHandlers(registry: InlineHandlerRegistry, _path: number[]): void {
359
- if (this.options.on_change) registry.add("change", this.options.id, this.options.on_change);
360
- }
361
- }
362
-
363
- export class KeyValueGrid extends WidgetBase {
364
- readonly type = "key_value_grid";
365
- constructor(private readonly options: CommonOptions & { rows?: { key: string; value: string }[] } = {}) { super(options); }
366
- data(): Record<string, unknown> { return { ...this.commonData(), rows: this.options.rows ?? [] }; }
367
- }
368
-
369
- export class PagerItem extends WidgetBase {
370
- readonly type = "pager_item";
371
- constructor(private readonly options: CommonOptions & { id: number; label?: string; appearance?: PagerAppearance; active?: boolean; inactive?: boolean; occupied?: boolean; urgent?: boolean; on_click?: InlineHandler }) { super(options); }
372
- data(): Record<string, unknown> { return { ...this.commonData(), id: this.options.id, label: this.options.label ?? "", appearance: this.options.appearance ?? "dots", active: this.options.active ?? false, inactive: this.options.inactive ?? false, occupied: this.options.occupied ?? false, urgent: this.options.urgent ?? false }; }
373
- bindHandlers(registry: InlineHandlerRegistry, _path: number[]): void { if (this.options.on_click) registry.add("click", String(this.options.id), this.options.on_click); }
374
- }
375
-
376
- export class PagerStrip extends WidgetBase {
377
- readonly type = "pager_strip";
378
- constructor(private readonly options: CommonOptions & { id?: string; items?: PagerItem[]; placeholder?: boolean; on_change?: InlineHandler } = {}) { super(options); }
379
- data(): Record<string, unknown> {
380
- const out: Record<string, unknown> = { ...this.commonData(), placeholder: this.options.placeholder ?? false, items: (this.options.items ?? []).map((item) => item.data()) };
381
- if (this.options.id !== undefined) out.id = this.options.id;
382
- return out;
383
- }
384
- bindHandlers(registry: InlineHandlerRegistry, path: number[]): void {
385
- if (this.options.id && this.options.on_change) registry.add("change", this.options.id, this.options.on_change);
386
- (this.options.items ?? []).forEach((item, index) => item.bindHandlers(registry, [...path, index]));
387
- }
388
- }
389
-
390
- abstract class ActiveIndicator extends WidgetBase {
391
- constructor(protected readonly options: CommonOptions & { active?: boolean } = {}) { super(options); }
392
- data(): Record<string, unknown> { return { ...this.commonData(), active: this.options.active ?? false }; }
393
- }
394
-
395
- export class CameraIndicator extends ActiveIndicator { readonly type = "camera_indicator"; }
396
- export class MicIndicator extends ActiveIndicator { readonly type = "mic_indicator"; }
397
- export class MutedIndicator extends ActiveIndicator { readonly type = "muted_indicator"; }
398
- export class LocationIndicator extends ActiveIndicator { readonly type = "location_indicator"; }
399
-
400
- export class ScreenCastIndicator extends ActiveIndicator {
401
- readonly type = "screencast_indicator";
402
- constructor(protected readonly options: CommonOptions & { active?: boolean; timer_text?: string } = {}) { super(options); }
403
- data(): Record<string, unknown> {
404
- const out = super.data();
405
- if (this.options.timer_text !== undefined) out.timer_text = this.options.timer_text;
406
- return out;
407
- }
408
- }
409
-
410
- export class Calendar extends WidgetBase {
411
- readonly type = "calendar";
412
- constructor(private readonly options: CommonOptions & { selected_date: string; id?: string; event_days?: string[]; on_change?: InlineHandler }) { super(options); }
413
- data(): Record<string, unknown> {
414
- const out: Record<string, unknown> = { ...this.commonData(), selected_date: this.options.selected_date, event_days: this.options.event_days ?? [] };
415
- if (this.options.id !== undefined) out.id = this.options.id;
416
- return out;
417
- }
418
- bindHandlers(registry: InlineHandlerRegistry, _path: number[]): void { if (this.options.id && this.options.on_change) registry.add("change", this.options.id, this.options.on_change); }
419
- }
420
-
421
- export class BatteryHero extends WidgetBase {
422
- readonly type = "battery_hero";
423
- constructor(private readonly options: CommonOptions & { icon: string; percentage: string; fraction: number; state: string }) { super(options); }
424
- data(): Record<string, unknown> { return { ...this.commonData(), icon: this.options.icon, percentage: this.options.percentage, fraction: this.options.fraction, state: this.options.state }; }
425
- }
426
-
427
- export class DateHero extends WidgetBase {
428
- readonly type = "date_hero";
429
- constructor(private readonly options: CommonOptions & { weekday: string; date: string }) { super(options); }
430
- data(): Record<string, unknown> { return { ...this.commonData(), weekday: this.options.weekday, date: this.options.date }; }
431
- }
432
-
433
- export class EventItem {
434
- constructor(public readonly options: { id: string; title: string; start: string; end?: string; location?: string; all_day?: boolean }) {}
435
- toProtocol(): Record<string, unknown> {
436
- const out: Record<string, unknown> = { id: this.options.id, title: this.options.title, start: this.options.start, end: this.options.end ?? "", all_day: this.options.all_day ?? false };
437
- if (this.options.location !== undefined) out.location = this.options.location;
438
- return out;
439
- }
440
- }
441
-
442
- export class Events extends WidgetBase {
443
- readonly type = "events";
444
- constructor(private readonly options: CommonOptions & { date: string; events?: EventItem[]; loading?: boolean }) { super(options); }
445
- data(): Record<string, unknown> { return { ...this.commonData(), date: this.options.date, loading: this.options.loading ?? false, events: (this.options.events ?? []).map((event) => event.toProtocol()) }; }
446
- }
447
-
448
- export class WeatherForecastItem {
449
- constructor(public readonly options: { day_name: string; icon: string; condition: string; temperatures: string; is_today?: boolean }) {}
450
- toProtocol(): Record<string, unknown> { return { day_name: this.options.day_name, icon: this.options.icon, condition: this.options.condition, temperatures: this.options.temperatures, is_today: this.options.is_today ?? false }; }
451
- }
452
-
453
- export class WeatherForecastList extends WidgetBase {
454
- readonly type = "weather_forecast_list";
455
- constructor(private readonly options: CommonOptions & { items?: WeatherForecastItem[] } = {}) { super(options); }
456
- data(): Record<string, unknown> { return { ...this.commonData(), items: (this.options.items ?? []).map((item) => item.toProtocol()) }; }
457
- }
458
-
459
- export class WeatherHourlyItem {
460
- constructor(public readonly options: { time: string; icon: string; temperature: string }) {}
461
- toProtocol(): Record<string, unknown> { return { time: this.options.time, icon: this.options.icon, temperature: this.options.temperature }; }
462
- }
463
-
464
- export class WeatherHourlyStrip extends WidgetBase {
465
- readonly type = "weather_hourly_strip";
466
- constructor(private readonly options: CommonOptions & { items?: WeatherHourlyItem[] } = {}) { super(options); }
467
- data(): Record<string, unknown> { return { ...this.commonData(), items: (this.options.items ?? []).map((item) => item.toProtocol()) }; }
468
- }
469
-
470
- export class WorldClockRow {
471
- constructor(public readonly options: { name: string; timezone: string; time: string; offset: string; day_label?: string }) {}
472
- toProtocol(): Record<string, unknown> {
473
- const out: Record<string, unknown> = { name: this.options.name, timezone: this.options.timezone, time: this.options.time, offset: this.options.offset };
474
- if (this.options.day_label !== undefined) out.day_label = this.options.day_label;
475
- return out;
476
- }
477
- }
478
-
479
- export class WorldClock extends WidgetBase {
480
- readonly type = "world_clock";
481
- constructor(private readonly options: CommonOptions & { rows?: WorldClockRow[] } = {}) { super(options); }
482
- data(): Record<string, unknown> { return { ...this.commonData(), rows: (this.options.rows ?? []).map((row) => row.toProtocol()) }; }
483
- }
484
-
485
- export type TreeNode =
486
- | Row | Column | Container | CircleBox | BoxedList | PopoverShell
487
- | Label | Header | Hero | Badge | StatusDot | PanelIndicator | EmptyState | Spinner | Meter | Separator | Scroll
488
- | Tile | SegmentedTile | ButtonRow | SwitchTile | ExpanderTile | SliderTile | ChoiceTile | ChoiceList | KeyValueGrid
489
- | PagerItem | PagerStrip
490
- | CameraIndicator | MicIndicator | MutedIndicator | ScreenCastIndicator | LocationIndicator
491
- | Calendar | BatteryHero | DateHero | Events | WeatherForecastList | WeatherHourlyStrip | WorldClock;