@promptctl/rich-js 0.17.0 → 0.18.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/README.md +13 -26
- package/package.json +7 -3
- package/dist/core/box.d.ts +0 -144
- package/dist/core/box.js +0 -391
- package/dist/core/cells.d.ts +0 -148
- package/dist/core/cells.js +0 -266
- package/dist/core/color.d.ts +0 -250
- package/dist/core/color.js +0 -1029
- package/dist/core/console.d.ts +0 -156
- package/dist/core/console.js +0 -472
- package/dist/core/emoji.d.ts +0 -24
- package/dist/core/emoji.js +0 -391
- package/dist/core/export-html.d.ts +0 -24
- package/dist/core/export-html.js +0 -106
- package/dist/core/export-lines.d.ts +0 -121
- package/dist/core/export-lines.js +0 -141
- package/dist/core/highlighter.d.ts +0 -33
- package/dist/core/highlighter.js +0 -124
- package/dist/core/json.d.ts +0 -27
- package/dist/core/json.js +0 -53
- package/dist/core/markup.d.ts +0 -97
- package/dist/core/markup.js +0 -619
- package/dist/core/measure.d.ts +0 -27
- package/dist/core/measure.js +0 -61
- package/dist/core/oklch.d.ts +0 -161
- package/dist/core/oklch.js +0 -312
- package/dist/core/osc8.d.ts +0 -68
- package/dist/core/osc8.js +0 -90
- package/dist/core/pretty.d.ts +0 -141
- package/dist/core/pretty.js +0 -472
- package/dist/core/protocol.d.ts +0 -137
- package/dist/core/protocol.js +0 -101
- package/dist/core/render.d.ts +0 -84
- package/dist/core/render.js +0 -145
- package/dist/core/segment.d.ts +0 -142
- package/dist/core/segment.js +0 -433
- package/dist/core/spinnerData.d.ts +0 -10
- package/dist/core/spinnerData.js +0 -115
- package/dist/core/strip.d.ts +0 -145
- package/dist/core/strip.js +0 -308
- package/dist/core/style.d.ts +0 -144
- package/dist/core/style.js +0 -723
- package/dist/core/subscription.d.ts +0 -12
- package/dist/core/subscription.js +0 -12
- package/dist/core/text.d.ts +0 -255
- package/dist/core/text.js +0 -990
- package/dist/core/wrap.d.ts +0 -41
- package/dist/core/wrap.js +0 -127
- package/dist/host/host-stream.d.ts +0 -30
- package/dist/host/host-stream.js +0 -35
- package/dist/host/index.d.ts +0 -3
- package/dist/host/index.js +0 -2
- package/dist/host/terminal-host.d.ts +0 -143
- package/dist/host/terminal-host.js +0 -132
- package/dist/index.d.ts +0 -87
- package/dist/index.js +0 -104
- package/dist/node/prompt.d.ts +0 -21
- package/dist/node/prompt.js +0 -30
- package/dist/node/save.d.ts +0 -17
- package/dist/node/save.js +0 -21
- package/dist/node/terminal-host.d.ts +0 -84
- package/dist/node/terminal-host.js +0 -160
- package/dist/node/traceback.d.ts +0 -27
- package/dist/node/traceback.js +0 -112
- package/dist/renderables/align.d.ts +0 -16
- package/dist/renderables/align.js +0 -46
- package/dist/renderables/columns.d.ts +0 -61
- package/dist/renderables/columns.js +0 -168
- package/dist/renderables/constrain.d.ts +0 -15
- package/dist/renderables/constrain.js +0 -37
- package/dist/renderables/flexStrip.d.ts +0 -41
- package/dist/renderables/flexStrip.js +0 -200
- package/dist/renderables/group.d.ts +0 -11
- package/dist/renderables/group.js +0 -15
- package/dist/renderables/layout.d.ts +0 -92
- package/dist/renderables/layout.js +0 -315
- package/dist/renderables/live.d.ts +0 -47
- package/dist/renderables/live.js +0 -131
- package/dist/renderables/markdown.d.ts +0 -24
- package/dist/renderables/markdown.js +0 -182
- package/dist/renderables/padding.d.ts +0 -38
- package/dist/renderables/padding.js +0 -140
- package/dist/renderables/panel.d.ts +0 -116
- package/dist/renderables/panel.js +0 -322
- package/dist/renderables/progress.d.ts +0 -90
- package/dist/renderables/progress.js +0 -241
- package/dist/renderables/progressBar.d.ts +0 -31
- package/dist/renderables/progressBar.js +0 -52
- package/dist/renderables/prompt.d.ts +0 -49
- package/dist/renderables/prompt.js +0 -125
- package/dist/renderables/rule.d.ts +0 -24
- package/dist/renderables/rule.js +0 -90
- package/dist/renderables/spinner.d.ts +0 -29
- package/dist/renderables/spinner.js +0 -64
- package/dist/renderables/status.d.ts +0 -23
- package/dist/renderables/status.js +0 -60
- package/dist/renderables/syntax.d.ts +0 -35
- package/dist/renderables/syntax.js +0 -114
- package/dist/renderables/table.d.ts +0 -182
- package/dist/renderables/table.js +0 -697
- package/dist/renderables/traceback.d.ts +0 -31
- package/dist/renderables/traceback.js +0 -109
- package/dist/renderables/tree.d.ts +0 -54
- package/dist/renderables/tree.js +0 -159
- package/dist/template-bindings/color-funcs.d.ts +0 -87
- package/dist/template-bindings/color-funcs.js +0 -219
- package/dist/template-bindings/helpers.d.ts +0 -24
- package/dist/template-bindings/helpers.js +0 -48
- package/dist/template-bindings/index.d.ts +0 -107
- package/dist/template-bindings/index.js +0 -144
- package/dist/template-bindings/palette-funcs.d.ts +0 -94
- package/dist/template-bindings/palette-funcs.js +0 -151
- package/dist/template-bindings/style-funcs.d.ts +0 -28
- package/dist/template-bindings/style-funcs.js +0 -151
- package/dist/themes/buildPalette.d.ts +0 -36
- package/dist/themes/buildPalette.js +0 -56
- package/dist/themes/colorMath.d.ts +0 -82
- package/dist/themes/colorMath.js +0 -254
- package/dist/themes/colorRef.d.ts +0 -51
- package/dist/themes/colorRef.js +0 -96
- package/dist/themes/data/atom-one-dark.d.ts +0 -3
- package/dist/themes/data/atom-one-dark.js +0 -158
- package/dist/themes/data/atom-one-light.d.ts +0 -3
- package/dist/themes/data/atom-one-light.js +0 -158
- package/dist/themes/data/catppuccin-frappe.d.ts +0 -3
- package/dist/themes/data/catppuccin-frappe.js +0 -158
- package/dist/themes/data/catppuccin-latte.d.ts +0 -3
- package/dist/themes/data/catppuccin-latte.js +0 -158
- package/dist/themes/data/catppuccin-macchiato.d.ts +0 -3
- package/dist/themes/data/catppuccin-macchiato.js +0 -158
- package/dist/themes/data/catppuccin-mocha.d.ts +0 -3
- package/dist/themes/data/catppuccin-mocha.js +0 -158
- package/dist/themes/data/cyberpunk.d.ts +0 -17
- package/dist/themes/data/cyberpunk.js +0 -191
- package/dist/themes/data/default.d.ts +0 -3
- package/dist/themes/data/default.js +0 -158
- package/dist/themes/data/dracula.d.ts +0 -3
- package/dist/themes/data/dracula.js +0 -158
- package/dist/themes/data/flexoki.d.ts +0 -3
- package/dist/themes/data/flexoki.js +0 -158
- package/dist/themes/data/gruvbox.d.ts +0 -3
- package/dist/themes/data/gruvbox.js +0 -158
- package/dist/themes/data/index.d.ts +0 -35
- package/dist/themes/data/index.js +0 -64
- package/dist/themes/data/monokai.d.ts +0 -3
- package/dist/themes/data/monokai.js +0 -158
- package/dist/themes/data/nord.d.ts +0 -3
- package/dist/themes/data/nord.js +0 -158
- package/dist/themes/data/rose-pine-dawn.d.ts +0 -3
- package/dist/themes/data/rose-pine-dawn.js +0 -158
- package/dist/themes/data/rose-pine-moon.d.ts +0 -3
- package/dist/themes/data/rose-pine-moon.js +0 -158
- package/dist/themes/data/rose-pine.d.ts +0 -3
- package/dist/themes/data/rose-pine.js +0 -158
- package/dist/themes/data/solarized-dark.d.ts +0 -3
- package/dist/themes/data/solarized-dark.js +0 -158
- package/dist/themes/data/solarized-light.d.ts +0 -3
- package/dist/themes/data/solarized-light.js +0 -158
- package/dist/themes/data/svg-export.d.ts +0 -3
- package/dist/themes/data/svg-export.js +0 -158
- package/dist/themes/data/textual-ansi.d.ts +0 -3
- package/dist/themes/data/textual-ansi.js +0 -158
- package/dist/themes/data/textual-dark.d.ts +0 -3
- package/dist/themes/data/textual-dark.js +0 -158
- package/dist/themes/data/textual-light.d.ts +0 -3
- package/dist/themes/data/textual-light.js +0 -158
- package/dist/themes/data/tokyo-night.d.ts +0 -3
- package/dist/themes/data/tokyo-night.js +0 -158
- package/dist/themes/data/types.d.ts +0 -15
- package/dist/themes/data/types.js +0 -1
- package/dist/themes/palette.d.ts +0 -21
- package/dist/themes/palette.js +0 -28
- package/dist/themes/ramp.d.ts +0 -83
- package/dist/themes/ramp.js +0 -122
- package/dist/themes/registry.d.ts +0 -43
- package/dist/themes/registry.js +0 -82
- package/dist/themes/terminalThemes.d.ts +0 -54
- package/dist/themes/terminalThemes.js +0 -68
- package/dist/themes/transpose.d.ts +0 -87
- package/dist/themes/transpose.js +0 -138
- package/dist/widgets/button.d.ts +0 -49
- package/dist/widgets/button.js +0 -206
- package/dist/widgets/checkbox.d.ts +0 -41
- package/dist/widgets/checkbox.js +0 -155
- package/dist/widgets/dropdown.d.ts +0 -67
- package/dist/widgets/dropdown.js +0 -453
- package/dist/widgets/event-router.d.ts +0 -78
- package/dist/widgets/event-router.js +0 -622
- package/dist/widgets/focus-manager.d.ts +0 -26
- package/dist/widgets/focus-manager.js +0 -193
- package/dist/widgets/index.d.ts +0 -22
- package/dist/widgets/index.js +0 -15
- package/dist/widgets/screen.d.ts +0 -98
- package/dist/widgets/screen.js +0 -530
- package/dist/widgets/slider.d.ts +0 -57
- package/dist/widgets/slider.js +0 -270
- package/dist/widgets/static-item.d.ts +0 -40
- package/dist/widgets/static-item.js +0 -60
- package/dist/widgets/text-input.d.ts +0 -274
- package/dist/widgets/text-input.js +0 -1162
- package/dist/widgets/toggle.d.ts +0 -44
- package/dist/widgets/toggle.js +0 -179
- package/dist/widgets/types.d.ts +0 -108
- package/dist/widgets/types.js +0 -31
- package/dist/widgets/widget-base.d.ts +0 -42
- package/dist/widgets/widget-base.js +0 -173
package/dist/widgets/toggle.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Toggle widget — on/off switch with label and variant colour.
|
|
3
|
-
* [LAW:dataflow-not-control-flow] one Segment of fixed width every render;
|
|
4
|
-
* indicator and palette keys come from observable state via lookup tables.
|
|
5
|
-
* [LAW:one-type-per-behavior] shared infrastructure inherited from WidgetBase.
|
|
6
|
-
*
|
|
7
|
-
* Visual states:
|
|
8
|
-
* off — "[OFF] label" with muted variant background
|
|
9
|
-
* on — "[ON] label" with full variant accent background
|
|
10
|
-
* focused — underline on the segment (no width change)
|
|
11
|
-
* disabled — dimmed
|
|
12
|
-
*/
|
|
13
|
-
import { Segment } from "../core/segment.js";
|
|
14
|
-
import type { RenderOptions } from "../core/protocol.js";
|
|
15
|
-
import type { TerminalTheme } from "../core/color.js";
|
|
16
|
-
import { WidgetBase } from "./widget-base.js";
|
|
17
|
-
import type { KeyEvent, WidgetMouseEvent } from "./types.js";
|
|
18
|
-
export type ToggleVariant = "default" | "primary" | "success" | "warning" | "danger";
|
|
19
|
-
export interface ToggleOptions {
|
|
20
|
-
label: string;
|
|
21
|
-
on?: boolean;
|
|
22
|
-
id?: string;
|
|
23
|
-
disabled?: boolean;
|
|
24
|
-
theme?: TerminalTheme;
|
|
25
|
-
variant?: ToggleVariant;
|
|
26
|
-
}
|
|
27
|
-
export declare class Toggle extends WidgetBase {
|
|
28
|
-
readonly id: string;
|
|
29
|
-
readonly focusable = true;
|
|
30
|
-
accessor label: string;
|
|
31
|
-
accessor on: boolean;
|
|
32
|
-
accessor variant: ToggleVariant;
|
|
33
|
-
private accessor _theme;
|
|
34
|
-
constructor(options: ToggleOptions);
|
|
35
|
-
setTheme(theme: TerminalTheme): void;
|
|
36
|
-
handleKey(event: KeyEvent): void;
|
|
37
|
-
handleMouse(event: WidgetMouseEvent): void;
|
|
38
|
-
render(_options: RenderOptions): Iterable<Segment>;
|
|
39
|
-
measure(_options: RenderOptions): {
|
|
40
|
-
minimum: number;
|
|
41
|
-
maximum: number;
|
|
42
|
-
};
|
|
43
|
-
private resolvePalette;
|
|
44
|
-
}
|
package/dist/widgets/toggle.js
DELETED
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Toggle widget — on/off switch with label and variant colour.
|
|
3
|
-
* [LAW:dataflow-not-control-flow] one Segment of fixed width every render;
|
|
4
|
-
* indicator and palette keys come from observable state via lookup tables.
|
|
5
|
-
* [LAW:one-type-per-behavior] shared infrastructure inherited from WidgetBase.
|
|
6
|
-
*
|
|
7
|
-
* Visual states:
|
|
8
|
-
* off — "[OFF] label" with muted variant background
|
|
9
|
-
* on — "[ON] label" with full variant accent background
|
|
10
|
-
* focused — underline on the segment (no width change)
|
|
11
|
-
* disabled — dimmed
|
|
12
|
-
*/
|
|
13
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
14
|
-
var useValue = arguments.length > 2;
|
|
15
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
16
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
17
|
-
}
|
|
18
|
-
return useValue ? value : void 0;
|
|
19
|
-
};
|
|
20
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
21
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
22
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
23
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
24
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
25
|
-
var _, done = false;
|
|
26
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
27
|
-
var context = {};
|
|
28
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
29
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
30
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
31
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
32
|
-
if (kind === "accessor") {
|
|
33
|
-
if (result === void 0) continue;
|
|
34
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
35
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
36
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
37
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
38
|
-
}
|
|
39
|
-
else if (_ = accept(result)) {
|
|
40
|
-
if (kind === "field") initializers.unshift(_);
|
|
41
|
-
else descriptor[key] = _;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
45
|
-
done = true;
|
|
46
|
-
};
|
|
47
|
-
import { observable, action, observableRef } from "mobx";
|
|
48
|
-
import { Segment } from "../core/segment.js";
|
|
49
|
-
import { Style } from "../core/style.js";
|
|
50
|
-
import { ColorSpec } from "../core/color.js";
|
|
51
|
-
import { cellLen } from "../core/cells.js";
|
|
52
|
-
import { DEFAULT_TERMINAL_THEME } from "../themes/terminalThemes.js";
|
|
53
|
-
import { WidgetBase } from "./widget-base.js";
|
|
54
|
-
// onFg uses on-${accent} (WCAG-correct contrast, picked once at palette
|
|
55
|
-
// build time) so the ON state stays readable on a full accent bg. Earlier
|
|
56
|
-
// versions used text-${accent} here, which is mostly-accent and clashed
|
|
57
|
-
// with the same accent as background. offFg keeps text-${accent} because
|
|
58
|
-
// offBg is mostly-bg-tinted and the contrast holds.
|
|
59
|
-
const VARIANT_KEYS = {
|
|
60
|
-
default: { onBg: "primary", onFg: "on-primary", offBg: "surface", offFg: "foreground" },
|
|
61
|
-
primary: { onBg: "primary", onFg: "on-primary", offBg: "primary-muted", offFg: "text-primary" },
|
|
62
|
-
success: { onBg: "success", onFg: "on-success", offBg: "success-muted", offFg: "text-success" },
|
|
63
|
-
warning: { onBg: "warning", onFg: "on-warning", offBg: "warning-muted", offFg: "text-warning" },
|
|
64
|
-
danger: { onBg: "error", onFg: "on-error", offBg: "error-muted", offFg: "text-error" },
|
|
65
|
-
};
|
|
66
|
-
let Toggle = (() => {
|
|
67
|
-
let _classSuper = WidgetBase;
|
|
68
|
-
let _instanceExtraInitializers = [];
|
|
69
|
-
let _label_decorators;
|
|
70
|
-
let _label_initializers = [];
|
|
71
|
-
let _label_extraInitializers = [];
|
|
72
|
-
let _on_decorators;
|
|
73
|
-
let _on_initializers = [];
|
|
74
|
-
let _on_extraInitializers = [];
|
|
75
|
-
let _variant_decorators;
|
|
76
|
-
let _variant_initializers = [];
|
|
77
|
-
let _variant_extraInitializers = [];
|
|
78
|
-
let __theme_decorators;
|
|
79
|
-
let __theme_initializers = [];
|
|
80
|
-
let __theme_extraInitializers = [];
|
|
81
|
-
let _setTheme_decorators;
|
|
82
|
-
let _handleKey_decorators;
|
|
83
|
-
let _handleMouse_decorators;
|
|
84
|
-
return class Toggle extends _classSuper {
|
|
85
|
-
static {
|
|
86
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
87
|
-
_label_decorators = [observable];
|
|
88
|
-
_on_decorators = [observable];
|
|
89
|
-
_variant_decorators = [observableRef];
|
|
90
|
-
__theme_decorators = [observableRef];
|
|
91
|
-
_setTheme_decorators = [action];
|
|
92
|
-
_handleKey_decorators = [action];
|
|
93
|
-
_handleMouse_decorators = [action];
|
|
94
|
-
__esDecorate(this, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
|
|
95
|
-
__esDecorate(this, null, _on_decorators, { kind: "accessor", name: "on", static: false, private: false, access: { has: obj => "on" in obj, get: obj => obj.on, set: (obj, value) => { obj.on = value; } }, metadata: _metadata }, _on_initializers, _on_extraInitializers);
|
|
96
|
-
__esDecorate(this, null, _variant_decorators, { kind: "accessor", name: "variant", static: false, private: false, access: { has: obj => "variant" in obj, get: obj => obj.variant, set: (obj, value) => { obj.variant = value; } }, metadata: _metadata }, _variant_initializers, _variant_extraInitializers);
|
|
97
|
-
__esDecorate(this, null, __theme_decorators, { kind: "accessor", name: "_theme", static: false, private: false, access: { has: obj => "_theme" in obj, get: obj => obj._theme, set: (obj, value) => { obj._theme = value; } }, metadata: _metadata }, __theme_initializers, __theme_extraInitializers);
|
|
98
|
-
__esDecorate(this, null, _setTheme_decorators, { kind: "method", name: "setTheme", static: false, private: false, access: { has: obj => "setTheme" in obj, get: obj => obj.setTheme }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
99
|
-
__esDecorate(this, null, _handleKey_decorators, { kind: "method", name: "handleKey", static: false, private: false, access: { has: obj => "handleKey" in obj, get: obj => obj.handleKey }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
100
|
-
__esDecorate(this, null, _handleMouse_decorators, { kind: "method", name: "handleMouse", static: false, private: false, access: { has: obj => "handleMouse" in obj, get: obj => obj.handleMouse }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
101
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
102
|
-
}
|
|
103
|
-
id = __runInitializers(this, _instanceExtraInitializers);
|
|
104
|
-
focusable = true;
|
|
105
|
-
#label_accessor_storage = __runInitializers(this, _label_initializers, void 0);
|
|
106
|
-
get label() { return this.#label_accessor_storage; }
|
|
107
|
-
set label(value) { this.#label_accessor_storage = value; }
|
|
108
|
-
#on_accessor_storage = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, _on_initializers, void 0));
|
|
109
|
-
get on() { return this.#on_accessor_storage; }
|
|
110
|
-
set on(value) { this.#on_accessor_storage = value; }
|
|
111
|
-
#variant_accessor_storage = (__runInitializers(this, _on_extraInitializers), __runInitializers(this, _variant_initializers, void 0));
|
|
112
|
-
get variant() { return this.#variant_accessor_storage; }
|
|
113
|
-
set variant(value) { this.#variant_accessor_storage = value; }
|
|
114
|
-
#_theme_accessor_storage = (__runInitializers(this, _variant_extraInitializers), __runInitializers(this, __theme_initializers, void 0));
|
|
115
|
-
// [LAW:types-are-the-program] @observableRef so setTheme() triggers a
|
|
116
|
-
// re-render — see slider.ts.
|
|
117
|
-
get _theme() { return this.#_theme_accessor_storage; }
|
|
118
|
-
set _theme(value) { this.#_theme_accessor_storage = value; }
|
|
119
|
-
constructor(options) {
|
|
120
|
-
super();
|
|
121
|
-
__runInitializers(this, __theme_extraInitializers);
|
|
122
|
-
this.id = options.id ?? `toggle-${options.label.toLowerCase().replace(/\s+/g, "-")}`;
|
|
123
|
-
this.label = options.label;
|
|
124
|
-
this.on = options.on ?? false;
|
|
125
|
-
this.variant = options.variant ?? "default";
|
|
126
|
-
this.disabled = options.disabled ?? false;
|
|
127
|
-
this._theme = options.theme ?? DEFAULT_TERMINAL_THEME;
|
|
128
|
-
}
|
|
129
|
-
setTheme(theme) { this._theme = theme; }
|
|
130
|
-
// --- Event handlers ---
|
|
131
|
-
handleKey(event) {
|
|
132
|
-
if (this.disabled)
|
|
133
|
-
return;
|
|
134
|
-
if (event.key === "space") {
|
|
135
|
-
this.on = !this.on;
|
|
136
|
-
this.emitChange();
|
|
137
|
-
event.stop();
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
if (event.key === "enter") {
|
|
141
|
-
this.emitSubmit();
|
|
142
|
-
event.stop();
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
handleMouse(event) {
|
|
146
|
-
if (this.disabled)
|
|
147
|
-
return;
|
|
148
|
-
if (event.type === "mouse_up") {
|
|
149
|
-
this.on = !this.on;
|
|
150
|
-
this.emitChange();
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
// --- Rendering ---
|
|
154
|
-
render(_options) {
|
|
155
|
-
// Both indicators are exactly 5 cells: "[ON] " and "[OFF]".
|
|
156
|
-
const indicator = this.on ? "[ON] " : "[OFF]";
|
|
157
|
-
const text = `${indicator} ${this.label}`;
|
|
158
|
-
if (this.disabled) {
|
|
159
|
-
return [new Segment(text, new Style({ color: "#666666", bgcolor: "#333333", dim: true }))];
|
|
160
|
-
}
|
|
161
|
-
const keys = VARIANT_KEYS[this.variant];
|
|
162
|
-
const fg = this.resolvePalette(this.on ? keys.onFg : keys.offFg);
|
|
163
|
-
const bg = this.resolvePalette(this.on ? keys.onBg : keys.offBg);
|
|
164
|
-
return [new Segment(text, new Style({ color: fg, bgcolor: bg, underline: this.focused }))];
|
|
165
|
-
}
|
|
166
|
-
measure(_options) {
|
|
167
|
-
// [LAW:one-source-of-truth] cellLen — see button.ts.
|
|
168
|
-
const width = 5 + 1 + cellLen(this.label);
|
|
169
|
-
return { minimum: width, maximum: width };
|
|
170
|
-
}
|
|
171
|
-
// --- Palette resolution ---
|
|
172
|
-
resolvePalette(key) {
|
|
173
|
-
const rgba = this._theme.palette.get(key);
|
|
174
|
-
// [LAW:no-defensive-null-guards] palette must contain all keys; missing is a construction bug.
|
|
175
|
-
return ColorSpec.fromRgba(rgba);
|
|
176
|
-
}
|
|
177
|
-
};
|
|
178
|
-
})();
|
|
179
|
-
export { Toggle };
|
package/dist/widgets/types.d.ts
DELETED
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive widget event types and core interfaces.
|
|
3
|
-
* [LAW:one-source-of-truth] These types are the single authority for the widget contract.
|
|
4
|
-
* Widgets are MobX-observable state machines that implement Renderable,
|
|
5
|
-
* producing Segment[] from current state. They have no knowledge of stdin,
|
|
6
|
-
* terminal escape sequences, or their host environment.
|
|
7
|
-
*/
|
|
8
|
-
import type { Renderable, Measurable, RenderOptions } from "../core/protocol.js";
|
|
9
|
-
import type { Segment } from "../core/segment.js";
|
|
10
|
-
import type { Unsubscribe } from "../core/subscription.js";
|
|
11
|
-
export interface KeyEventInit {
|
|
12
|
-
key: string;
|
|
13
|
-
character: string;
|
|
14
|
-
shift: boolean;
|
|
15
|
-
ctrl: boolean;
|
|
16
|
-
meta: boolean;
|
|
17
|
-
}
|
|
18
|
-
export declare class KeyEvent {
|
|
19
|
-
readonly key: string;
|
|
20
|
-
readonly character: string;
|
|
21
|
-
readonly shift: boolean;
|
|
22
|
-
readonly ctrl: boolean;
|
|
23
|
-
readonly meta: boolean;
|
|
24
|
-
private _stopped;
|
|
25
|
-
constructor(init: KeyEventInit);
|
|
26
|
-
get stopped(): boolean;
|
|
27
|
-
stop(): void;
|
|
28
|
-
}
|
|
29
|
-
export type KeyHandlerPriority = "high" | "normal";
|
|
30
|
-
export interface KeyHandlerOptions {
|
|
31
|
-
priority?: KeyHandlerPriority;
|
|
32
|
-
}
|
|
33
|
-
export interface WidgetMouseEvent {
|
|
34
|
-
type: "mouse_down" | "mouse_up" | "mouse_move" | "scroll_up" | "scroll_down";
|
|
35
|
-
x: number;
|
|
36
|
-
y: number;
|
|
37
|
-
button: number;
|
|
38
|
-
shift: boolean;
|
|
39
|
-
ctrl: boolean;
|
|
40
|
-
}
|
|
41
|
-
export interface WidgetFocusEvent {
|
|
42
|
-
type: "focus" | "blur";
|
|
43
|
-
}
|
|
44
|
-
export interface WidgetBounds {
|
|
45
|
-
x: number;
|
|
46
|
-
y: number;
|
|
47
|
-
width: number;
|
|
48
|
-
height: number;
|
|
49
|
-
}
|
|
50
|
-
export interface InteractiveWidget extends Renderable, Measurable {
|
|
51
|
-
readonly id: string;
|
|
52
|
-
readonly focusable: boolean;
|
|
53
|
-
focused: boolean;
|
|
54
|
-
hovered: boolean;
|
|
55
|
-
active: boolean;
|
|
56
|
-
disabled: boolean;
|
|
57
|
-
visible: boolean;
|
|
58
|
-
bounds: WidgetBounds | null;
|
|
59
|
-
handleKey(event: KeyEvent): void;
|
|
60
|
-
handleMouse(event: WidgetMouseEvent): void;
|
|
61
|
-
handleFocus(event: WidgetFocusEvent): void;
|
|
62
|
-
focus(): void;
|
|
63
|
-
blur(): void;
|
|
64
|
-
setDisabled(value: boolean): void;
|
|
65
|
-
setHovered(value: boolean): void;
|
|
66
|
-
containsPoint(x: number, y: number): boolean;
|
|
67
|
-
onChange(handler: (widget: InteractiveWidget) => void): Unsubscribe;
|
|
68
|
-
onSubmit(handler: (widget: InteractiveWidget) => void): Unsubscribe;
|
|
69
|
-
}
|
|
70
|
-
export type Placement = {
|
|
71
|
-
kind: "flow";
|
|
72
|
-
} | {
|
|
73
|
-
kind: "inline";
|
|
74
|
-
} | {
|
|
75
|
-
kind: "fixed";
|
|
76
|
-
x: number;
|
|
77
|
-
y: number;
|
|
78
|
-
};
|
|
79
|
-
export declare const FLOW: Placement;
|
|
80
|
-
export interface OverlayRenderable {
|
|
81
|
-
renderOverlay(options: RenderOptions): Iterable<Segment> | null;
|
|
82
|
-
}
|
|
83
|
-
export declare function hasOverlay(value: object): value is OverlayRenderable;
|
|
84
|
-
export interface FocusManager {
|
|
85
|
-
readonly current: InteractiveWidget | null;
|
|
86
|
-
readonly widgets: readonly InteractiveWidget[];
|
|
87
|
-
register(widget: InteractiveWidget): void;
|
|
88
|
-
unregister(widget: InteractiveWidget): void;
|
|
89
|
-
next(): void;
|
|
90
|
-
prev(): void;
|
|
91
|
-
focus(widget: InteractiveWidget): void;
|
|
92
|
-
blur(): void;
|
|
93
|
-
handleKey(event: KeyEvent): void;
|
|
94
|
-
onChange(handler: (current: InteractiveWidget | null) => void): Unsubscribe;
|
|
95
|
-
}
|
|
96
|
-
export type MountEntry = InteractiveWidget | {
|
|
97
|
-
widget: InteractiveWidget;
|
|
98
|
-
placement: Placement;
|
|
99
|
-
};
|
|
100
|
-
export interface Screen {
|
|
101
|
-
mount(...entries: MountEntry[]): void;
|
|
102
|
-
unmount(widget: InteractiveWidget): void;
|
|
103
|
-
start(): void;
|
|
104
|
-
stop(): void;
|
|
105
|
-
readonly focusManager: FocusManager;
|
|
106
|
-
readonly running: boolean;
|
|
107
|
-
readonly widgets: readonly InteractiveWidget[];
|
|
108
|
-
}
|
package/dist/widgets/types.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interactive widget event types and core interfaces.
|
|
3
|
-
* [LAW:one-source-of-truth] These types are the single authority for the widget contract.
|
|
4
|
-
* Widgets are MobX-observable state machines that implement Renderable,
|
|
5
|
-
* producing Segment[] from current state. They have no knowledge of stdin,
|
|
6
|
-
* terminal escape sequences, or their host environment.
|
|
7
|
-
*/
|
|
8
|
-
export class KeyEvent {
|
|
9
|
-
key;
|
|
10
|
-
character;
|
|
11
|
-
shift;
|
|
12
|
-
ctrl;
|
|
13
|
-
meta;
|
|
14
|
-
_stopped = false;
|
|
15
|
-
constructor(init) {
|
|
16
|
-
this.key = init.key;
|
|
17
|
-
this.character = init.character;
|
|
18
|
-
this.shift = init.shift;
|
|
19
|
-
this.ctrl = init.ctrl;
|
|
20
|
-
this.meta = init.meta;
|
|
21
|
-
}
|
|
22
|
-
get stopped() { return this._stopped; }
|
|
23
|
-
// Claim this key. Halts further chain dispatch — no high/normal handler
|
|
24
|
-
// and no focused-widget handler downstream of the caller will see it.
|
|
25
|
-
stop() { this._stopped = true; }
|
|
26
|
-
}
|
|
27
|
-
export const FLOW = { kind: "flow" };
|
|
28
|
-
export function hasOverlay(value) {
|
|
29
|
-
return ("renderOverlay" in value &&
|
|
30
|
-
typeof value.renderOverlay === "function");
|
|
31
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WidgetBase — shared MobX observable foundation for interactive widgets.
|
|
3
|
-
* [LAW:one-type-per-behavior] All widgets share the same base; differences
|
|
4
|
-
* are in configuration and state, not in infrastructure.
|
|
5
|
-
*
|
|
6
|
-
* Reactive state is declared with TC39 decorators, which MobX 7 requires on
|
|
7
|
-
* `accessor` members. Each decorator registers its own member, so there is no
|
|
8
|
-
* makeObservable call and subclasses add observables the same way.
|
|
9
|
-
*/
|
|
10
|
-
import type { Segment } from "../core/segment.js";
|
|
11
|
-
import type { RenderOptions } from "../core/protocol.js";
|
|
12
|
-
import type { InteractiveWidget, KeyEvent, WidgetMouseEvent, WidgetFocusEvent, WidgetBounds } from "./types.js";
|
|
13
|
-
import type { Unsubscribe } from "../core/subscription.js";
|
|
14
|
-
export declare abstract class WidgetBase implements InteractiveWidget {
|
|
15
|
-
abstract readonly id: string;
|
|
16
|
-
abstract readonly focusable: boolean;
|
|
17
|
-
accessor focused: boolean;
|
|
18
|
-
accessor hovered: boolean;
|
|
19
|
-
accessor active: boolean;
|
|
20
|
-
accessor disabled: boolean;
|
|
21
|
-
accessor visible: boolean;
|
|
22
|
-
accessor bounds: WidgetBounds | null;
|
|
23
|
-
private readonly changeHandlers;
|
|
24
|
-
private readonly submitHandlers;
|
|
25
|
-
abstract handleKey(event: KeyEvent): void;
|
|
26
|
-
handleMouse(_event: WidgetMouseEvent): void;
|
|
27
|
-
handleFocus(event: WidgetFocusEvent): void;
|
|
28
|
-
focus(): void;
|
|
29
|
-
blur(): void;
|
|
30
|
-
setDisabled(value: boolean): void;
|
|
31
|
-
setHovered(value: boolean): void;
|
|
32
|
-
containsPoint(x: number, y: number): boolean;
|
|
33
|
-
onChange(handler: (widget: InteractiveWidget) => void): Unsubscribe;
|
|
34
|
-
onSubmit(handler: (widget: InteractiveWidget) => void): Unsubscribe;
|
|
35
|
-
protected emitChange(): void;
|
|
36
|
-
protected emitSubmit(): void;
|
|
37
|
-
abstract render(options: RenderOptions): Iterable<Segment>;
|
|
38
|
-
abstract measure(options: RenderOptions): {
|
|
39
|
-
minimum: number;
|
|
40
|
-
maximum: number;
|
|
41
|
-
};
|
|
42
|
-
}
|
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* WidgetBase — shared MobX observable foundation for interactive widgets.
|
|
3
|
-
* [LAW:one-type-per-behavior] All widgets share the same base; differences
|
|
4
|
-
* are in configuration and state, not in infrastructure.
|
|
5
|
-
*
|
|
6
|
-
* Reactive state is declared with TC39 decorators, which MobX 7 requires on
|
|
7
|
-
* `accessor` members. Each decorator registers its own member, so there is no
|
|
8
|
-
* makeObservable call and subclasses add observables the same way.
|
|
9
|
-
*/
|
|
10
|
-
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
11
|
-
var useValue = arguments.length > 2;
|
|
12
|
-
for (var i = 0; i < initializers.length; i++) {
|
|
13
|
-
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
14
|
-
}
|
|
15
|
-
return useValue ? value : void 0;
|
|
16
|
-
};
|
|
17
|
-
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
18
|
-
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
19
|
-
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
20
|
-
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
21
|
-
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
22
|
-
var _, done = false;
|
|
23
|
-
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
24
|
-
var context = {};
|
|
25
|
-
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
26
|
-
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
27
|
-
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
28
|
-
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
29
|
-
if (kind === "accessor") {
|
|
30
|
-
if (result === void 0) continue;
|
|
31
|
-
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
32
|
-
if (_ = accept(result.get)) descriptor.get = _;
|
|
33
|
-
if (_ = accept(result.set)) descriptor.set = _;
|
|
34
|
-
if (_ = accept(result.init)) initializers.unshift(_);
|
|
35
|
-
}
|
|
36
|
-
else if (_ = accept(result)) {
|
|
37
|
-
if (kind === "field") initializers.unshift(_);
|
|
38
|
-
else descriptor[key] = _;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
42
|
-
done = true;
|
|
43
|
-
};
|
|
44
|
-
import { observable, action } from "mobx";
|
|
45
|
-
let WidgetBase = (() => {
|
|
46
|
-
let _instanceExtraInitializers = [];
|
|
47
|
-
let _focused_decorators;
|
|
48
|
-
let _focused_initializers = [];
|
|
49
|
-
let _focused_extraInitializers = [];
|
|
50
|
-
let _hovered_decorators;
|
|
51
|
-
let _hovered_initializers = [];
|
|
52
|
-
let _hovered_extraInitializers = [];
|
|
53
|
-
let _active_decorators;
|
|
54
|
-
let _active_initializers = [];
|
|
55
|
-
let _active_extraInitializers = [];
|
|
56
|
-
let _disabled_decorators;
|
|
57
|
-
let _disabled_initializers = [];
|
|
58
|
-
let _disabled_extraInitializers = [];
|
|
59
|
-
let _visible_decorators;
|
|
60
|
-
let _visible_initializers = [];
|
|
61
|
-
let _visible_extraInitializers = [];
|
|
62
|
-
let _handleFocus_decorators;
|
|
63
|
-
let _focus_decorators;
|
|
64
|
-
let _blur_decorators;
|
|
65
|
-
let _setDisabled_decorators;
|
|
66
|
-
let _setHovered_decorators;
|
|
67
|
-
return class WidgetBase {
|
|
68
|
-
static {
|
|
69
|
-
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
70
|
-
_focused_decorators = [observable];
|
|
71
|
-
_hovered_decorators = [observable];
|
|
72
|
-
_active_decorators = [observable];
|
|
73
|
-
_disabled_decorators = [observable];
|
|
74
|
-
_visible_decorators = [observable];
|
|
75
|
-
_handleFocus_decorators = [action];
|
|
76
|
-
_focus_decorators = [action];
|
|
77
|
-
_blur_decorators = [action];
|
|
78
|
-
_setDisabled_decorators = [action];
|
|
79
|
-
_setHovered_decorators = [action];
|
|
80
|
-
__esDecorate(this, null, _focused_decorators, { kind: "accessor", name: "focused", static: false, private: false, access: { has: obj => "focused" in obj, get: obj => obj.focused, set: (obj, value) => { obj.focused = value; } }, metadata: _metadata }, _focused_initializers, _focused_extraInitializers);
|
|
81
|
-
__esDecorate(this, null, _hovered_decorators, { kind: "accessor", name: "hovered", static: false, private: false, access: { has: obj => "hovered" in obj, get: obj => obj.hovered, set: (obj, value) => { obj.hovered = value; } }, metadata: _metadata }, _hovered_initializers, _hovered_extraInitializers);
|
|
82
|
-
__esDecorate(this, null, _active_decorators, { kind: "accessor", name: "active", static: false, private: false, access: { has: obj => "active" in obj, get: obj => obj.active, set: (obj, value) => { obj.active = value; } }, metadata: _metadata }, _active_initializers, _active_extraInitializers);
|
|
83
|
-
__esDecorate(this, null, _disabled_decorators, { kind: "accessor", name: "disabled", static: false, private: false, access: { has: obj => "disabled" in obj, get: obj => obj.disabled, set: (obj, value) => { obj.disabled = value; } }, metadata: _metadata }, _disabled_initializers, _disabled_extraInitializers);
|
|
84
|
-
__esDecorate(this, null, _visible_decorators, { kind: "accessor", name: "visible", static: false, private: false, access: { has: obj => "visible" in obj, get: obj => obj.visible, set: (obj, value) => { obj.visible = value; } }, metadata: _metadata }, _visible_initializers, _visible_extraInitializers);
|
|
85
|
-
__esDecorate(this, null, _handleFocus_decorators, { kind: "method", name: "handleFocus", static: false, private: false, access: { has: obj => "handleFocus" in obj, get: obj => obj.handleFocus }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
86
|
-
__esDecorate(this, null, _focus_decorators, { kind: "method", name: "focus", static: false, private: false, access: { has: obj => "focus" in obj, get: obj => obj.focus }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
87
|
-
__esDecorate(this, null, _blur_decorators, { kind: "method", name: "blur", static: false, private: false, access: { has: obj => "blur" in obj, get: obj => obj.blur }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
88
|
-
__esDecorate(this, null, _setDisabled_decorators, { kind: "method", name: "setDisabled", static: false, private: false, access: { has: obj => "setDisabled" in obj, get: obj => obj.setDisabled }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
89
|
-
__esDecorate(this, null, _setHovered_decorators, { kind: "method", name: "setHovered", static: false, private: false, access: { has: obj => "setHovered" in obj, get: obj => obj.setHovered }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
90
|
-
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
91
|
-
}
|
|
92
|
-
#focused_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _focused_initializers, false));
|
|
93
|
-
get focused() { return this.#focused_accessor_storage; }
|
|
94
|
-
set focused(value) { this.#focused_accessor_storage = value; }
|
|
95
|
-
#hovered_accessor_storage = (__runInitializers(this, _focused_extraInitializers), __runInitializers(this, _hovered_initializers, false));
|
|
96
|
-
get hovered() { return this.#hovered_accessor_storage; }
|
|
97
|
-
set hovered(value) { this.#hovered_accessor_storage = value; }
|
|
98
|
-
#active_accessor_storage = (__runInitializers(this, _hovered_extraInitializers), __runInitializers(this, _active_initializers, false));
|
|
99
|
-
get active() { return this.#active_accessor_storage; }
|
|
100
|
-
set active(value) { this.#active_accessor_storage = value; }
|
|
101
|
-
#disabled_accessor_storage = (__runInitializers(this, _active_extraInitializers), __runInitializers(this, _disabled_initializers, false));
|
|
102
|
-
get disabled() { return this.#disabled_accessor_storage; }
|
|
103
|
-
set disabled(value) { this.#disabled_accessor_storage = value; }
|
|
104
|
-
#visible_accessor_storage = (__runInitializers(this, _disabled_extraInitializers), __runInitializers(this, _visible_initializers, true));
|
|
105
|
-
get visible() { return this.#visible_accessor_storage; }
|
|
106
|
-
set visible(value) { this.#visible_accessor_storage = value; }
|
|
107
|
-
#bounds_accessor_storage = (__runInitializers(this, _visible_extraInitializers), null);
|
|
108
|
-
// [LAW:types-are-the-program] Layout output, not reactive state. In
|
|
109
|
-
// DefaultScreen usage the sole writer is Screen.draw(); custom hosts
|
|
110
|
-
// (test harnesses, alternative layout loops) also write directly. The
|
|
111
|
-
// only readers are imperative input handlers (containsPoint,
|
|
112
|
-
// handleMouse). Modeling as observable adds reactive surface no
|
|
113
|
-
// consumer uses and creates a strict-mode hazard when draw() runs from
|
|
114
|
-
// a microtask outside its origin autorun.
|
|
115
|
-
get bounds() { return this.#bounds_accessor_storage; }
|
|
116
|
-
set bounds(value) { this.#bounds_accessor_storage = value; }
|
|
117
|
-
changeHandlers = new Set();
|
|
118
|
-
submitHandlers = new Set();
|
|
119
|
-
handleMouse(_event) { }
|
|
120
|
-
handleFocus(event) {
|
|
121
|
-
this.focused = event.type === "focus";
|
|
122
|
-
}
|
|
123
|
-
// --- Programmatic control ---
|
|
124
|
-
// [LAW:single-enforcer] focus()/blur() route through handleFocus so any
|
|
125
|
-
// subclass override (e.g. Dropdown collapsing its overlay on blur)
|
|
126
|
-
// participates in the same transition path the event router uses. There
|
|
127
|
-
// is no second code path that flips `focused` directly from the outside.
|
|
128
|
-
focus() {
|
|
129
|
-
this.handleFocus({ type: "focus" });
|
|
130
|
-
}
|
|
131
|
-
blur() {
|
|
132
|
-
this.handleFocus({ type: "blur" });
|
|
133
|
-
}
|
|
134
|
-
setDisabled(value) {
|
|
135
|
-
this.disabled = value;
|
|
136
|
-
}
|
|
137
|
-
// [LAW:single-enforcer] One canonical setter for hover state lives on
|
|
138
|
-
// the base. EventRouter calls it on every widget whose hit-test result
|
|
139
|
-
// diverges from `hovered`; widgets that need to react to hover transitions
|
|
140
|
-
// override handleMouse and read the synthesized `mouse_move`. The router
|
|
141
|
-
// no longer maintains a "does this widget have setHovered" fallback path.
|
|
142
|
-
setHovered(value) {
|
|
143
|
-
this.hovered = value;
|
|
144
|
-
}
|
|
145
|
-
// --- Hit-testing ---
|
|
146
|
-
containsPoint(x, y) {
|
|
147
|
-
const b = this.bounds;
|
|
148
|
-
if (!b)
|
|
149
|
-
return false;
|
|
150
|
-
return x >= b.x && x < b.x + b.width && y >= b.y && y < b.y + b.height;
|
|
151
|
-
}
|
|
152
|
-
// --- Subscriptions ---
|
|
153
|
-
onChange(handler) {
|
|
154
|
-
this.changeHandlers.add(handler);
|
|
155
|
-
return () => this.changeHandlers.delete(handler);
|
|
156
|
-
}
|
|
157
|
-
onSubmit(handler) {
|
|
158
|
-
this.submitHandlers.add(handler);
|
|
159
|
-
return () => this.submitHandlers.delete(handler);
|
|
160
|
-
}
|
|
161
|
-
emitChange() {
|
|
162
|
-
for (const handler of this.changeHandlers) {
|
|
163
|
-
handler(this);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
emitSubmit() {
|
|
167
|
-
for (const handler of this.submitHandlers) {
|
|
168
|
-
handler(this);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
})();
|
|
173
|
-
export { WidgetBase };
|