@promptctl/rich-js 0.18.0 → 0.19.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 +9 -7
- package/dist/core/anchor.d.ts +45 -0
- package/dist/core/anchor.js +39 -0
- package/dist/core/ansi.d.ts +65 -0
- package/dist/core/ansi.js +231 -0
- package/dist/core/box.d.ts +145 -0
- package/dist/core/box.js +372 -0
- package/dist/core/cells.d.ts +192 -0
- package/dist/core/cells.js +334 -0
- package/dist/core/clock.d.ts +48 -0
- package/dist/core/clock.js +42 -0
- package/dist/core/color.d.ts +326 -0
- package/dist/core/color.js +1225 -0
- package/dist/core/console.d.ts +196 -0
- package/dist/core/console.js +596 -0
- package/dist/core/easing.d.ts +86 -0
- package/dist/core/easing.js +171 -0
- package/dist/core/emoji.d.ts +24 -0
- package/dist/core/emoji.js +391 -0
- package/dist/core/env.d.ts +16 -0
- package/dist/core/env.js +16 -0
- package/dist/core/export-html.d.ts +59 -0
- package/dist/core/export-html.js +197 -0
- package/dist/core/export-lines.d.ts +130 -0
- package/dist/core/export-lines.js +159 -0
- package/dist/core/export-svg.d.ts +49 -0
- package/dist/core/export-svg.js +213 -0
- package/dist/core/fnv1a.d.ts +10 -0
- package/dist/core/fnv1a.js +17 -0
- package/dist/core/highlighter.d.ts +33 -0
- package/dist/core/highlighter.js +190 -0
- package/dist/core/json.d.ts +27 -0
- package/dist/core/json.js +53 -0
- package/dist/core/markup.d.ts +140 -0
- package/dist/core/markup.js +654 -0
- package/dist/core/measure.d.ts +27 -0
- package/dist/core/measure.js +67 -0
- package/dist/core/memo.d.ts +19 -0
- package/dist/core/memo.js +34 -0
- package/dist/core/oklch.d.ts +161 -0
- package/dist/core/oklch.js +312 -0
- package/dist/core/osc8.d.ts +68 -0
- package/dist/core/osc8.js +78 -0
- package/dist/core/paint.d.ts +107 -0
- package/dist/core/paint.js +150 -0
- package/dist/core/place.d.ts +30 -0
- package/dist/core/place.js +49 -0
- package/dist/core/pretty.d.ts +247 -0
- package/dist/core/pretty.js +906 -0
- package/dist/core/protocol.d.ts +305 -0
- package/dist/core/protocol.js +183 -0
- package/dist/core/render.d.ts +87 -0
- package/dist/core/render.js +105 -0
- package/dist/core/segment.d.ts +162 -0
- package/dist/core/segment.js +488 -0
- package/dist/core/spinnerData.d.ts +12 -0
- package/dist/core/spinnerData.js +117 -0
- package/dist/core/strip.d.ts +152 -0
- package/dist/core/strip.js +326 -0
- package/dist/core/style.d.ts +189 -0
- package/dist/core/style.js +758 -0
- package/dist/core/subscription.d.ts +12 -0
- package/dist/core/subscription.js +12 -0
- package/dist/core/text.d.ts +283 -0
- package/dist/core/text.js +1097 -0
- package/dist/core/wrap.d.ts +46 -0
- package/dist/core/wrap.js +140 -0
- package/dist/host/app.d.ts +133 -0
- package/dist/host/app.js +285 -0
- package/dist/host/host-environment.d.ts +26 -0
- package/dist/host/host-environment.js +44 -0
- package/dist/host/index.d.ts +6 -0
- package/dist/host/index.js +3 -0
- package/dist/host/terminal-host.d.ts +180 -0
- package/dist/host/terminal-host.js +186 -0
- package/dist/index.d.ts +98 -0
- package/dist/index.js +114 -0
- package/dist/node/prompt.d.ts +34 -0
- package/dist/node/prompt.js +51 -0
- package/dist/node/save.d.ts +18 -0
- package/dist/node/save.js +24 -0
- package/dist/node/terminal-host.d.ts +114 -0
- package/dist/node/terminal-host.js +227 -0
- package/dist/node/traceback.d.ts +38 -0
- package/dist/node/traceback.js +98 -0
- package/dist/renderables/align.d.ts +16 -0
- package/dist/renderables/align.js +26 -0
- package/dist/renderables/columns.d.ts +77 -0
- package/dist/renderables/columns.js +191 -0
- package/dist/renderables/constrain.d.ts +15 -0
- package/dist/renderables/constrain.js +31 -0
- package/dist/renderables/effect.d.ts +98 -0
- package/dist/renderables/effect.js +160 -0
- package/dist/renderables/embed.d.ts +107 -0
- package/dist/renderables/embed.js +160 -0
- package/dist/renderables/flexStrip.d.ts +41 -0
- package/dist/renderables/flexStrip.js +200 -0
- package/dist/renderables/group.d.ts +14 -0
- package/dist/renderables/group.js +22 -0
- package/dist/renderables/layout.d.ts +75 -0
- package/dist/renderables/layout.js +223 -0
- package/dist/renderables/live.d.ts +74 -0
- package/dist/renderables/live.js +188 -0
- package/dist/renderables/markdown.d.ts +38 -0
- package/dist/renderables/markdown.js +587 -0
- package/dist/renderables/padding.d.ts +59 -0
- package/dist/renderables/padding.js +147 -0
- package/dist/renderables/panel.d.ts +114 -0
- package/dist/renderables/panel.js +303 -0
- package/dist/renderables/progress.d.ts +178 -0
- package/dist/renderables/progress.js +362 -0
- package/dist/renderables/progressBar.d.ts +31 -0
- package/dist/renderables/progressBar.js +64 -0
- package/dist/renderables/prompt.d.ts +71 -0
- package/dist/renderables/prompt.js +165 -0
- package/dist/renderables/ratio.d.ts +123 -0
- package/dist/renderables/ratio.js +213 -0
- package/dist/renderables/rule.d.ts +26 -0
- package/dist/renderables/rule.js +86 -0
- package/dist/renderables/spinner.d.ts +57 -0
- package/dist/renderables/spinner.js +103 -0
- package/dist/renderables/status.d.ts +29 -0
- package/dist/renderables/status.js +46 -0
- package/dist/renderables/syntax.d.ts +65 -0
- package/dist/renderables/syntax.js +166 -0
- package/dist/renderables/table.d.ts +232 -0
- package/dist/renderables/table.js +973 -0
- package/dist/renderables/traceback.d.ts +32 -0
- package/dist/renderables/traceback.js +279 -0
- package/dist/renderables/tree.d.ts +76 -0
- package/dist/renderables/tree.js +177 -0
- package/dist/renderables/viewport.d.ts +114 -0
- package/dist/renderables/viewport.js +196 -0
- package/dist/template-bindings/color-funcs.d.ts +109 -0
- package/dist/template-bindings/color-funcs.js +243 -0
- package/dist/template-bindings/helpers.d.ts +26 -0
- package/dist/template-bindings/helpers.js +33 -0
- package/dist/template-bindings/index.d.ts +119 -0
- package/dist/template-bindings/index.js +162 -0
- package/dist/template-bindings/palette-funcs.d.ts +96 -0
- package/dist/template-bindings/palette-funcs.js +145 -0
- package/dist/template-bindings/style-funcs.d.ts +28 -0
- package/dist/template-bindings/style-funcs.js +157 -0
- package/dist/themes/buildPalette.d.ts +57 -0
- package/dist/themes/buildPalette.js +100 -0
- package/dist/themes/colorMath.d.ts +94 -0
- package/dist/themes/colorMath.js +280 -0
- package/dist/themes/colorRef.d.ts +36 -0
- package/dist/themes/colorRef.js +78 -0
- package/dist/themes/data/ansi-tables.d.ts +14 -0
- package/dist/themes/data/ansi-tables.js +49 -0
- package/dist/themes/data/atom-one-dark.d.ts +3 -0
- package/dist/themes/data/atom-one-dark.js +177 -0
- package/dist/themes/data/atom-one-light.d.ts +3 -0
- package/dist/themes/data/atom-one-light.js +177 -0
- package/dist/themes/data/catppuccin-frappe.d.ts +3 -0
- package/dist/themes/data/catppuccin-frappe.js +177 -0
- package/dist/themes/data/catppuccin-latte.d.ts +3 -0
- package/dist/themes/data/catppuccin-latte.js +177 -0
- package/dist/themes/data/catppuccin-macchiato.d.ts +3 -0
- package/dist/themes/data/catppuccin-macchiato.js +177 -0
- package/dist/themes/data/catppuccin-mocha.d.ts +3 -0
- package/dist/themes/data/catppuccin-mocha.js +177 -0
- package/dist/themes/data/cyberpunk.d.ts +17 -0
- package/dist/themes/data/cyberpunk.js +193 -0
- package/dist/themes/data/default.d.ts +3 -0
- package/dist/themes/data/default.js +160 -0
- package/dist/themes/data/dracula.d.ts +3 -0
- package/dist/themes/data/dracula.js +177 -0
- package/dist/themes/data/flexoki.d.ts +3 -0
- package/dist/themes/data/flexoki.js +177 -0
- package/dist/themes/data/gruvbox.d.ts +3 -0
- package/dist/themes/data/gruvbox.js +177 -0
- package/dist/themes/data/index.d.ts +35 -0
- package/dist/themes/data/index.js +64 -0
- package/dist/themes/data/monokai.d.ts +3 -0
- package/dist/themes/data/monokai.js +177 -0
- package/dist/themes/data/nord.d.ts +3 -0
- package/dist/themes/data/nord.js +177 -0
- package/dist/themes/data/rose-pine-dawn.d.ts +3 -0
- package/dist/themes/data/rose-pine-dawn.js +177 -0
- package/dist/themes/data/rose-pine-moon.d.ts +3 -0
- package/dist/themes/data/rose-pine-moon.js +177 -0
- package/dist/themes/data/rose-pine.d.ts +3 -0
- package/dist/themes/data/rose-pine.js +177 -0
- package/dist/themes/data/solarized-dark.d.ts +3 -0
- package/dist/themes/data/solarized-dark.js +177 -0
- package/dist/themes/data/solarized-light.d.ts +3 -0
- package/dist/themes/data/solarized-light.js +177 -0
- package/dist/themes/data/svg-export.d.ts +3 -0
- package/dist/themes/data/svg-export.js +177 -0
- package/dist/themes/data/textual-ansi.d.ts +3 -0
- package/dist/themes/data/textual-ansi.js +160 -0
- package/dist/themes/data/textual-dark.d.ts +3 -0
- package/dist/themes/data/textual-dark.js +160 -0
- package/dist/themes/data/textual-light.d.ts +3 -0
- package/dist/themes/data/textual-light.js +160 -0
- package/dist/themes/data/tokyo-night.d.ts +3 -0
- package/dist/themes/data/tokyo-night.js +177 -0
- package/dist/themes/data/types.d.ts +31 -0
- package/dist/themes/data/types.js +10 -0
- package/dist/themes/palette.d.ts +45 -0
- package/dist/themes/palette.js +71 -0
- package/dist/themes/ramp.d.ts +70 -0
- package/dist/themes/ramp.js +103 -0
- package/dist/themes/registry.d.ts +44 -0
- package/dist/themes/registry.js +105 -0
- package/dist/themes/terminalThemes.d.ts +49 -0
- package/dist/themes/terminalThemes.js +63 -0
- package/dist/themes/transpose.d.ts +87 -0
- package/dist/themes/transpose.js +138 -0
- package/dist/widgets/button.d.ts +45 -0
- package/dist/widgets/button.js +177 -0
- package/dist/widgets/checkbox.d.ts +38 -0
- package/dist/widgets/checkbox.js +135 -0
- package/dist/widgets/dropdown.d.ts +64 -0
- package/dist/widgets/dropdown.js +416 -0
- package/dist/widgets/event-router.d.ts +71 -0
- package/dist/widgets/event-router.js +629 -0
- package/dist/widgets/focus-manager.d.ts +45 -0
- package/dist/widgets/focus-manager.js +191 -0
- package/dist/widgets/hit.d.ts +64 -0
- package/dist/widgets/hit.js +113 -0
- package/dist/widgets/index.d.ts +20 -0
- package/dist/widgets/index.js +14 -0
- package/dist/widgets/ink.d.ts +22 -0
- package/dist/widgets/ink.js +31 -0
- package/dist/widgets/slider.d.ts +54 -0
- package/dist/widgets/slider.js +247 -0
- package/dist/widgets/static-item.d.ts +34 -0
- package/dist/widgets/static-item.js +54 -0
- package/dist/widgets/text-input.d.ts +283 -0
- package/dist/widgets/text-input.js +1174 -0
- package/dist/widgets/themed-widget.d.ts +20 -0
- package/dist/widgets/themed-widget.js +89 -0
- package/dist/widgets/toggle.d.ts +41 -0
- package/dist/widgets/toggle.js +157 -0
- package/dist/widgets/types.d.ts +87 -0
- package/dist/widgets/types.js +30 -0
- package/dist/widgets/widget-app.d.ts +65 -0
- package/dist/widgets/widget-app.js +206 -0
- package/dist/widgets/widget-base.d.ts +42 -0
- package/dist/widgets/widget-base.js +172 -0
- package/package.json +16 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThemedWidget — a widget that draws every cell it owns from one theme's
|
|
3
|
+
* palette: the interactive widgets, as against `StaticItem`, which shows
|
|
4
|
+
* content it did not draw.
|
|
5
|
+
*
|
|
6
|
+
* [LAW:one-type-per-behavior] The theme, how it is swapped, what a disabled
|
|
7
|
+
* widget looks like, and the ground a padded row stands on are the same for
|
|
8
|
+
* every such widget, so they live here once.
|
|
9
|
+
*/
|
|
10
|
+
import { Style } from "../core/style.js";
|
|
11
|
+
import type { TerminalTheme } from "../core/color.js";
|
|
12
|
+
import { WidgetBase } from "./widget-base.js";
|
|
13
|
+
import { ink } from "./ink.js";
|
|
14
|
+
export declare abstract class ThemedWidget extends WidgetBase {
|
|
15
|
+
protected accessor theme: TerminalTheme;
|
|
16
|
+
constructor(theme: TerminalTheme | undefined);
|
|
17
|
+
setTheme(theme: TerminalTheme): void;
|
|
18
|
+
protected get ground(): Style;
|
|
19
|
+
protected get disabledInk(): ReturnType<typeof ink>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ThemedWidget — a widget that draws every cell it owns from one theme's
|
|
3
|
+
* palette: the interactive widgets, as against `StaticItem`, which shows
|
|
4
|
+
* content it did not draw.
|
|
5
|
+
*
|
|
6
|
+
* [LAW:one-type-per-behavior] The theme, how it is swapped, what a disabled
|
|
7
|
+
* widget looks like, and the ground a padded row stands on are the same for
|
|
8
|
+
* every such widget, so they live here once.
|
|
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 { observableRef, action } from "mobx";
|
|
45
|
+
import { Style } from "../core/style.js";
|
|
46
|
+
import { DEFAULT_TERMINAL_THEME } from "../themes/terminalThemes.js";
|
|
47
|
+
import { WidgetBase } from "./widget-base.js";
|
|
48
|
+
import { ink } from "./ink.js";
|
|
49
|
+
let ThemedWidget = (() => {
|
|
50
|
+
let _classSuper = WidgetBase;
|
|
51
|
+
let _instanceExtraInitializers = [];
|
|
52
|
+
let _theme_decorators;
|
|
53
|
+
let _theme_initializers = [];
|
|
54
|
+
let _theme_extraInitializers = [];
|
|
55
|
+
let _setTheme_decorators;
|
|
56
|
+
return class ThemedWidget extends _classSuper {
|
|
57
|
+
static {
|
|
58
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
59
|
+
_theme_decorators = [observableRef];
|
|
60
|
+
_setTheme_decorators = [action];
|
|
61
|
+
__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);
|
|
62
|
+
__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);
|
|
63
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
64
|
+
}
|
|
65
|
+
#theme_accessor_storage = (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _theme_initializers, void 0));
|
|
66
|
+
// [LAW:types-are-the-program] @observableRef so setTheme() triggers a
|
|
67
|
+
// re-render: every draw reads its colours through this reference.
|
|
68
|
+
get theme() { return this.#theme_accessor_storage; }
|
|
69
|
+
set theme(value) { this.#theme_accessor_storage = value; }
|
|
70
|
+
constructor(theme) {
|
|
71
|
+
super();
|
|
72
|
+
__runInitializers(this, _theme_extraInitializers);
|
|
73
|
+
this.theme = theme ?? DEFAULT_TERMINAL_THEME;
|
|
74
|
+
}
|
|
75
|
+
setTheme(theme) {
|
|
76
|
+
this.theme = theme;
|
|
77
|
+
}
|
|
78
|
+
get ground() {
|
|
79
|
+
return new Style(ink(this.theme, "foreground", "background"));
|
|
80
|
+
}
|
|
81
|
+
// [LAW:one-source-of-truth] How every widget looks while disabled: the
|
|
82
|
+
// palette's de-emphasized text on its ground. WCAG sets no contrast floor for
|
|
83
|
+
// an inactive control, and this sits under the one for text on purpose.
|
|
84
|
+
get disabledInk() {
|
|
85
|
+
return ink(this.theme, "foreground-muted", "background");
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
})();
|
|
89
|
+
export { ThemedWidget };
|
|
@@ -0,0 +1,41 @@
|
|
|
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 { ThemedWidget } from "./themed-widget.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 ThemedWidget {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly focusable = true;
|
|
30
|
+
accessor label: string;
|
|
31
|
+
accessor on: boolean;
|
|
32
|
+
accessor variant: ToggleVariant;
|
|
33
|
+
constructor(options: ToggleOptions);
|
|
34
|
+
handleKey(event: KeyEvent): void;
|
|
35
|
+
handleMouse(event: WidgetMouseEvent): void;
|
|
36
|
+
protected draw(_options: RenderOptions): Iterable<Segment>;
|
|
37
|
+
measure(_options: RenderOptions): {
|
|
38
|
+
minimum: number;
|
|
39
|
+
maximum: number;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
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 { cellLen } from "../core/cells.js";
|
|
51
|
+
import { ThemedWidget } from "./themed-widget.js";
|
|
52
|
+
import { ink } from "./ink.js";
|
|
53
|
+
// onFg uses on-${accent} (WCAG-correct contrast, picked once at palette
|
|
54
|
+
// build time) so the ON state stays readable on a full accent bg. Earlier
|
|
55
|
+
// versions used text-${accent} here, which is mostly-accent and clashed
|
|
56
|
+
// with the same accent as background. offFg keeps text-${accent} because
|
|
57
|
+
// offBg is mostly-bg-tinted and the contrast holds.
|
|
58
|
+
const VARIANT_KEYS = {
|
|
59
|
+
default: { onBg: "primary", onFg: "on-primary", offBg: "surface", offFg: "foreground" },
|
|
60
|
+
primary: { onBg: "primary", onFg: "on-primary", offBg: "primary-muted", offFg: "text-primary" },
|
|
61
|
+
success: { onBg: "success", onFg: "on-success", offBg: "success-muted", offFg: "text-success" },
|
|
62
|
+
warning: { onBg: "warning", onFg: "on-warning", offBg: "warning-muted", offFg: "text-warning" },
|
|
63
|
+
danger: { onBg: "error", onFg: "on-error", offBg: "error-muted", offFg: "text-error" },
|
|
64
|
+
};
|
|
65
|
+
let Toggle = (() => {
|
|
66
|
+
let _classSuper = ThemedWidget;
|
|
67
|
+
let _instanceExtraInitializers = [];
|
|
68
|
+
let _label_decorators;
|
|
69
|
+
let _label_initializers = [];
|
|
70
|
+
let _label_extraInitializers = [];
|
|
71
|
+
let _on_decorators;
|
|
72
|
+
let _on_initializers = [];
|
|
73
|
+
let _on_extraInitializers = [];
|
|
74
|
+
let _variant_decorators;
|
|
75
|
+
let _variant_initializers = [];
|
|
76
|
+
let _variant_extraInitializers = [];
|
|
77
|
+
let _handleKey_decorators;
|
|
78
|
+
let _handleMouse_decorators;
|
|
79
|
+
return class Toggle extends _classSuper {
|
|
80
|
+
static {
|
|
81
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
82
|
+
_label_decorators = [observable];
|
|
83
|
+
_on_decorators = [observable];
|
|
84
|
+
_variant_decorators = [observableRef];
|
|
85
|
+
_handleKey_decorators = [action];
|
|
86
|
+
_handleMouse_decorators = [action];
|
|
87
|
+
__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);
|
|
88
|
+
__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);
|
|
89
|
+
__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);
|
|
90
|
+
__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);
|
|
91
|
+
__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);
|
|
92
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
93
|
+
}
|
|
94
|
+
id = __runInitializers(this, _instanceExtraInitializers);
|
|
95
|
+
focusable = true;
|
|
96
|
+
#label_accessor_storage = __runInitializers(this, _label_initializers, void 0);
|
|
97
|
+
get label() { return this.#label_accessor_storage; }
|
|
98
|
+
set label(value) { this.#label_accessor_storage = value; }
|
|
99
|
+
#on_accessor_storage = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, _on_initializers, void 0));
|
|
100
|
+
get on() { return this.#on_accessor_storage; }
|
|
101
|
+
set on(value) { this.#on_accessor_storage = value; }
|
|
102
|
+
#variant_accessor_storage = (__runInitializers(this, _on_extraInitializers), __runInitializers(this, _variant_initializers, void 0));
|
|
103
|
+
get variant() { return this.#variant_accessor_storage; }
|
|
104
|
+
set variant(value) { this.#variant_accessor_storage = value; }
|
|
105
|
+
constructor(options) {
|
|
106
|
+
super(options.theme);
|
|
107
|
+
__runInitializers(this, _variant_extraInitializers);
|
|
108
|
+
this.id = options.id ?? `toggle-${options.label.toLowerCase().replace(/\s+/g, "-")}`;
|
|
109
|
+
this.label = options.label;
|
|
110
|
+
this.on = options.on ?? false;
|
|
111
|
+
this.variant = options.variant ?? "default";
|
|
112
|
+
this.disabled = options.disabled ?? false;
|
|
113
|
+
}
|
|
114
|
+
// --- Event handlers ---
|
|
115
|
+
handleKey(event) {
|
|
116
|
+
if (this.disabled)
|
|
117
|
+
return;
|
|
118
|
+
if (event.key === "space") {
|
|
119
|
+
this.on = !this.on;
|
|
120
|
+
this.emitChange();
|
|
121
|
+
event.stop();
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
if (event.key === "enter") {
|
|
125
|
+
this.emitSubmit();
|
|
126
|
+
event.stop();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
handleMouse(event) {
|
|
130
|
+
if (this.disabled)
|
|
131
|
+
return;
|
|
132
|
+
// A release that dragged off the toggle cancels the press.
|
|
133
|
+
if (event.type === "mouse_up" && event.over) {
|
|
134
|
+
this.on = !this.on;
|
|
135
|
+
this.emitChange();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
// --- Rendering ---
|
|
139
|
+
draw(_options) {
|
|
140
|
+
// Both indicators are exactly 5 cells: "[ON] " and "[OFF]".
|
|
141
|
+
const indicator = this.on ? "[ON] " : "[OFF]";
|
|
142
|
+
const text = `${indicator} ${this.label}`;
|
|
143
|
+
if (this.disabled) {
|
|
144
|
+
return [new Segment(text, new Style(this.disabledInk))];
|
|
145
|
+
}
|
|
146
|
+
const keys = VARIANT_KEYS[this.variant];
|
|
147
|
+
const colors = this.on ? ink(this.theme, keys.onFg, keys.onBg) : ink(this.theme, keys.offFg, keys.offBg);
|
|
148
|
+
return [new Segment(text, new Style({ ...colors, underline: this.focused }))];
|
|
149
|
+
}
|
|
150
|
+
measure(_options) {
|
|
151
|
+
// [LAW:one-source-of-truth] cellLen — see button.ts.
|
|
152
|
+
const width = 5 + 1 + cellLen(this.label);
|
|
153
|
+
return { minimum: width, maximum: width };
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
})();
|
|
157
|
+
export { Toggle };
|
|
@@ -0,0 +1,87 @@
|
|
|
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 type ScreenMouseEvent = {
|
|
34
|
+
[T in MouseEventType]: MouseEventOf<T>;
|
|
35
|
+
}[MouseEventType];
|
|
36
|
+
type MouseEventType = "mouse_down" | "mouse_up" | "mouse_move" | "scroll_up" | "scroll_down";
|
|
37
|
+
interface MouseEventOf<Type extends string> {
|
|
38
|
+
type: Type;
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
button: number;
|
|
42
|
+
shift: boolean;
|
|
43
|
+
ctrl: boolean;
|
|
44
|
+
}
|
|
45
|
+
export interface WidgetMouseEvent extends MouseEventOf<"mouse_down" | "mouse_up" | "mouse_move"> {
|
|
46
|
+
over: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface WidgetFocusEvent {
|
|
49
|
+
type: "focus" | "blur";
|
|
50
|
+
}
|
|
51
|
+
export interface InteractiveWidget extends Renderable, Measurable {
|
|
52
|
+
readonly id: string;
|
|
53
|
+
readonly focusable: boolean;
|
|
54
|
+
focused: boolean;
|
|
55
|
+
hovered: boolean;
|
|
56
|
+
active: boolean;
|
|
57
|
+
disabled: boolean;
|
|
58
|
+
handleKey(event: KeyEvent): void;
|
|
59
|
+
handleMouse(event: WidgetMouseEvent): void;
|
|
60
|
+
handleFocus(event: WidgetFocusEvent): void;
|
|
61
|
+
focus(): void;
|
|
62
|
+
blur(): void;
|
|
63
|
+
setDisabled(value: boolean): void;
|
|
64
|
+
setHovered(value: boolean): void;
|
|
65
|
+
onChange(handler: (widget: InteractiveWidget) => void): Unsubscribe;
|
|
66
|
+
onSubmit(handler: (widget: InteractiveWidget) => void): Unsubscribe;
|
|
67
|
+
}
|
|
68
|
+
export interface OverlayRenderable {
|
|
69
|
+
renderOverlay(options: RenderOptions): Iterable<Segment> | null;
|
|
70
|
+
}
|
|
71
|
+
export declare function hasOverlay(value: object): value is OverlayRenderable;
|
|
72
|
+
export interface FocusManager {
|
|
73
|
+
readonly current: InteractiveWidget | null;
|
|
74
|
+
/** The widgets Tab moves between, in the order it moves. */
|
|
75
|
+
readonly widgets: readonly InteractiveWidget[];
|
|
76
|
+
next(): void;
|
|
77
|
+
prev(): void;
|
|
78
|
+
focus(widget: InteractiveWidget): void;
|
|
79
|
+
handleKey(event: KeyEvent): void;
|
|
80
|
+
onChange(handler: (current: InteractiveWidget | null) => void): Unsubscribe;
|
|
81
|
+
}
|
|
82
|
+
export interface FrameSource {
|
|
83
|
+
readonly focusManager: FocusManager;
|
|
84
|
+
readonly frame: readonly (readonly Segment[])[];
|
|
85
|
+
refresh(): void;
|
|
86
|
+
}
|
|
87
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
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 function hasOverlay(value) {
|
|
28
|
+
return ("renderOverlay" in value &&
|
|
29
|
+
typeof value.renderOverlay === "function");
|
|
30
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WidgetApp — an `App` whose view has widgets in it: keys reach the focused
|
|
3
|
+
* widget, the pointer reaches the widget that drew the cell under it, and a
|
|
4
|
+
* change to anything a frame read paints the next one.
|
|
5
|
+
*
|
|
6
|
+
* A widget goes wherever a renderable goes — in a `Panel`, a `Layout` pane, a
|
|
7
|
+
* `Table` cell — and nothing lays it out a second time. Everything added here
|
|
8
|
+
* reads the frame the view drew:
|
|
9
|
+
*
|
|
10
|
+
* - Focus moves in document order: the order widgets start to render in
|
|
11
|
+
* (`RenderOptions.onDraw`), among those with a cell on the frame on screen.
|
|
12
|
+
* Not reading order — in a `Layout` split into columns, reading order
|
|
13
|
+
* zigzags between the columns row by row.
|
|
14
|
+
* - Overlays are painted over the view's frame, in document order, directly
|
|
15
|
+
* below their owner's footprint (`OverlayRenderable`). Paint order is the
|
|
16
|
+
* z-order: a later overlay covers an earlier one.
|
|
17
|
+
* - A pointer event goes to the innermost widget that drew the cell under it
|
|
18
|
+
* (`widgetAt`), in that widget's own coordinates; the wheel goes to the
|
|
19
|
+
* innermost `Viewport` that can move (`scrollTargetAt`).
|
|
20
|
+
*
|
|
21
|
+
* [LAW:locality-or-seam] `App` knows nothing of widgets — `host/` depends on
|
|
22
|
+
* `core/` alone — and this reaches it only through the seams it already has:
|
|
23
|
+
* the view is a renderable, and `onPaint` hears the frame.
|
|
24
|
+
*/
|
|
25
|
+
import { Segment } from "../core/segment.js";
|
|
26
|
+
import type { Unsubscribe } from "../core/subscription.js";
|
|
27
|
+
import { type AppOptions, type AppPhase } from "../host/app.js";
|
|
28
|
+
import type { FocusManager, FrameSource, KeyEvent, KeyHandlerOptions, ScreenMouseEvent } from "./types.js";
|
|
29
|
+
export declare class WidgetApp implements FrameSource {
|
|
30
|
+
readonly focusManager: FocusManager;
|
|
31
|
+
private readonly focus;
|
|
32
|
+
private readonly app;
|
|
33
|
+
private readonly router;
|
|
34
|
+
private readonly reaction;
|
|
35
|
+
private drawn;
|
|
36
|
+
constructor(options: AppOptions);
|
|
37
|
+
get phase(): AppPhase;
|
|
38
|
+
/** The rows on screen now, as painted: what a pointer event lands on. */
|
|
39
|
+
get frame(): readonly (readonly Segment[])[];
|
|
40
|
+
/**
|
|
41
|
+
* Take the terminal, paint the first frame, and route input to its widgets
|
|
42
|
+
* until the app stops — `App.run`, with the input.
|
|
43
|
+
*/
|
|
44
|
+
run(): Promise<void>;
|
|
45
|
+
stop(): void;
|
|
46
|
+
fail(error: unknown): void;
|
|
47
|
+
/**
|
|
48
|
+
* Paint the next frame, as `App.refresh` does. A change to an observable
|
|
49
|
+
* the view read needs none; one no observable carries — a `Viewport`
|
|
50
|
+
* scrolled from a key handler — does.
|
|
51
|
+
*/
|
|
52
|
+
refresh(): void;
|
|
53
|
+
suspend(): Promise<void>;
|
|
54
|
+
/** Paint at the app's rate until the returned function is called, as `App.animate` does. */
|
|
55
|
+
animate(): Unsubscribe;
|
|
56
|
+
/**
|
|
57
|
+
* Hear every key. A `high` handler hears it before the focused widget, a
|
|
58
|
+
* `normal` one after it — and after Tab has moved focus — and a handler
|
|
59
|
+
* that calls `event.stop()` ends the key there.
|
|
60
|
+
*/
|
|
61
|
+
onKey(handler: (event: KeyEvent) => void, options?: KeyHandlerOptions): Unsubscribe;
|
|
62
|
+
/** Hear every pointer event, in terminal cells, before any widget does. */
|
|
63
|
+
onMouse(handler: (event: ScreenMouseEvent) => void): Unsubscribe;
|
|
64
|
+
private compose;
|
|
65
|
+
}
|