@promptctl/rich-js 0.18.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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 +143 -0
- package/dist/core/box.js +379 -0
- package/dist/core/cells.d.ts +159 -0
- package/dist/core/cells.js +287 -0
- package/dist/core/color.d.ts +246 -0
- package/dist/core/color.js +1038 -0
- package/dist/core/console.d.ts +165 -0
- package/dist/core/console.js +527 -0
- package/dist/core/emoji.d.ts +24 -0
- package/dist/core/emoji.js +391 -0
- package/dist/core/export-html.d.ts +59 -0
- package/dist/core/export-html.js +200 -0
- package/dist/core/export-lines.d.ts +121 -0
- package/dist/core/export-lines.js +141 -0
- package/dist/core/highlighter.d.ts +33 -0
- package/dist/core/highlighter.js +124 -0
- package/dist/core/json.d.ts +27 -0
- package/dist/core/json.js +53 -0
- package/dist/core/markup.d.ts +119 -0
- package/dist/core/markup.js +731 -0
- package/dist/core/measure.d.ts +27 -0
- package/dist/core/measure.js +62 -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 +90 -0
- package/dist/core/place.d.ts +30 -0
- package/dist/core/place.js +51 -0
- package/dist/core/pretty.d.ts +144 -0
- package/dist/core/pretty.js +476 -0
- package/dist/core/protocol.d.ts +267 -0
- package/dist/core/protocol.js +163 -0
- package/dist/core/render.d.ts +84 -0
- package/dist/core/render.js +145 -0
- package/dist/core/segment.d.ts +161 -0
- package/dist/core/segment.js +492 -0
- package/dist/core/spinnerData.d.ts +12 -0
- package/dist/core/spinnerData.js +117 -0
- package/dist/core/strip.d.ts +141 -0
- package/dist/core/strip.js +305 -0
- package/dist/core/style.d.ts +169 -0
- package/dist/core/style.js +695 -0
- package/dist/core/subscription.d.ts +12 -0
- package/dist/core/subscription.js +12 -0
- package/dist/core/text.d.ts +256 -0
- package/dist/core/text.js +976 -0
- package/dist/core/wrap.d.ts +41 -0
- package/dist/core/wrap.js +127 -0
- package/dist/host/app.d.ts +121 -0
- package/dist/host/app.js +255 -0
- package/dist/host/host-environment.d.ts +26 -0
- package/dist/host/host-environment.js +44 -0
- package/dist/host/index.d.ts +5 -0
- package/dist/host/index.js +3 -0
- package/dist/host/terminal-host.d.ts +179 -0
- package/dist/host/terminal-host.js +186 -0
- package/dist/index.d.ts +91 -0
- package/dist/index.js +107 -0
- package/dist/node/prompt.d.ts +21 -0
- package/dist/node/prompt.js +30 -0
- package/dist/node/save.d.ts +17 -0
- package/dist/node/save.js +21 -0
- package/dist/node/terminal-host.d.ts +113 -0
- package/dist/node/terminal-host.js +227 -0
- package/dist/node/traceback.d.ts +37 -0
- package/dist/node/traceback.js +134 -0
- package/dist/renderables/align.d.ts +16 -0
- package/dist/renderables/align.js +33 -0
- package/dist/renderables/columns.d.ts +61 -0
- package/dist/renderables/columns.js +152 -0
- package/dist/renderables/constrain.d.ts +15 -0
- package/dist/renderables/constrain.js +37 -0
- package/dist/renderables/embed.d.ts +50 -0
- package/dist/renderables/embed.js +71 -0
- package/dist/renderables/flexStrip.d.ts +41 -0
- package/dist/renderables/flexStrip.js +200 -0
- package/dist/renderables/group.d.ts +11 -0
- package/dist/renderables/group.js +17 -0
- package/dist/renderables/layout.d.ts +92 -0
- package/dist/renderables/layout.js +312 -0
- package/dist/renderables/live.d.ts +50 -0
- package/dist/renderables/live.js +175 -0
- package/dist/renderables/markdown.d.ts +24 -0
- package/dist/renderables/markdown.js +184 -0
- package/dist/renderables/padding.d.ts +38 -0
- package/dist/renderables/padding.js +141 -0
- package/dist/renderables/panel.d.ts +116 -0
- package/dist/renderables/panel.js +307 -0
- package/dist/renderables/progress.d.ts +90 -0
- package/dist/renderables/progress.js +238 -0
- package/dist/renderables/progressBar.d.ts +31 -0
- package/dist/renderables/progressBar.js +53 -0
- package/dist/renderables/prompt.d.ts +49 -0
- package/dist/renderables/prompt.js +125 -0
- package/dist/renderables/rule.d.ts +25 -0
- package/dist/renderables/rule.js +90 -0
- package/dist/renderables/spinner.d.ts +31 -0
- package/dist/renderables/spinner.js +70 -0
- package/dist/renderables/status.d.ts +23 -0
- package/dist/renderables/status.js +60 -0
- package/dist/renderables/syntax.d.ts +35 -0
- package/dist/renderables/syntax.js +115 -0
- package/dist/renderables/table.d.ts +194 -0
- package/dist/renderables/table.js +795 -0
- package/dist/renderables/traceback.d.ts +31 -0
- package/dist/renderables/traceback.js +108 -0
- package/dist/renderables/tree.d.ts +68 -0
- package/dist/renderables/tree.js +150 -0
- package/dist/renderables/viewport.d.ts +114 -0
- package/dist/renderables/viewport.js +198 -0
- package/dist/template-bindings/color-funcs.d.ts +87 -0
- package/dist/template-bindings/color-funcs.js +217 -0
- package/dist/template-bindings/helpers.d.ts +24 -0
- package/dist/template-bindings/helpers.js +48 -0
- package/dist/template-bindings/index.d.ts +107 -0
- package/dist/template-bindings/index.js +146 -0
- package/dist/template-bindings/palette-funcs.d.ts +94 -0
- package/dist/template-bindings/palette-funcs.js +141 -0
- package/dist/template-bindings/style-funcs.d.ts +28 -0
- package/dist/template-bindings/style-funcs.js +155 -0
- package/dist/themes/buildPalette.d.ts +36 -0
- package/dist/themes/buildPalette.js +56 -0
- package/dist/themes/colorMath.d.ts +82 -0
- package/dist/themes/colorMath.js +254 -0
- package/dist/themes/colorRef.d.ts +51 -0
- package/dist/themes/colorRef.js +96 -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 +21 -0
- package/dist/themes/palette.js +28 -0
- package/dist/themes/ramp.d.ts +83 -0
- package/dist/themes/ramp.js +122 -0
- package/dist/themes/registry.d.ts +44 -0
- package/dist/themes/registry.js +94 -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 +49 -0
- package/dist/widgets/button.js +208 -0
- package/dist/widgets/checkbox.d.ts +41 -0
- package/dist/widgets/checkbox.js +157 -0
- package/dist/widgets/dropdown.d.ts +67 -0
- package/dist/widgets/dropdown.js +450 -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/slider.d.ts +57 -0
- package/dist/widgets/slider.js +270 -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 +274 -0
- package/dist/widgets/text-input.js +1165 -0
- package/dist/widgets/toggle.d.ts +44 -0
- package/dist/widgets/toggle.js +180 -0
- package/dist/widgets/types.d.ts +87 -0
- package/dist/widgets/types.js +30 -0
- package/dist/widgets/widget-app.d.ts +63 -0
- package/dist/widgets/widget-app.js +199 -0
- package/dist/widgets/widget-base.d.ts +40 -0
- package/dist/widgets/widget-base.js +165 -0
- package/package.json +6 -2
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FocusManager — which widget has focus, over the widgets on the frame.
|
|
3
|
+
* [LAW:one-source-of-truth] single authority for which widget has focus.
|
|
4
|
+
* [LAW:dataflow-not-control-flow] focus transitions are observable state;
|
|
5
|
+
* widgets react to focus/blur events, the manager never skips dispatch.
|
|
6
|
+
*/
|
|
7
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
8
|
+
var useValue = arguments.length > 2;
|
|
9
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
10
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
11
|
+
}
|
|
12
|
+
return useValue ? value : void 0;
|
|
13
|
+
};
|
|
14
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
15
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
16
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
17
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
18
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
19
|
+
var _, done = false;
|
|
20
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
21
|
+
var context = {};
|
|
22
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
23
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
24
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
25
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
26
|
+
if (kind === "accessor") {
|
|
27
|
+
if (result === void 0) continue;
|
|
28
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
29
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
30
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
31
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
32
|
+
}
|
|
33
|
+
else if (_ = accept(result)) {
|
|
34
|
+
if (kind === "field") initializers.unshift(_);
|
|
35
|
+
else descriptor[key] = _;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
39
|
+
done = true;
|
|
40
|
+
};
|
|
41
|
+
import { action, observableRef } from "mobx";
|
|
42
|
+
let DefaultFocusManager = (() => {
|
|
43
|
+
let _instanceExtraInitializers = [];
|
|
44
|
+
let _currentWidget_decorators;
|
|
45
|
+
let _currentWidget_initializers = [];
|
|
46
|
+
let _currentWidget_extraInitializers = [];
|
|
47
|
+
let _next_decorators;
|
|
48
|
+
let _prev_decorators;
|
|
49
|
+
let _focus_decorators;
|
|
50
|
+
let _settle_decorators;
|
|
51
|
+
let _clear_decorators;
|
|
52
|
+
let _setFocus_decorators;
|
|
53
|
+
return class DefaultFocusManager {
|
|
54
|
+
static {
|
|
55
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
56
|
+
_currentWidget_decorators = [observableRef];
|
|
57
|
+
_next_decorators = [action];
|
|
58
|
+
_prev_decorators = [action];
|
|
59
|
+
_focus_decorators = [action];
|
|
60
|
+
_settle_decorators = [action];
|
|
61
|
+
_clear_decorators = [action];
|
|
62
|
+
_setFocus_decorators = [action];
|
|
63
|
+
__esDecorate(this, null, _currentWidget_decorators, { kind: "accessor", name: "currentWidget", static: false, private: false, access: { has: obj => "currentWidget" in obj, get: obj => obj.currentWidget, set: (obj, value) => { obj.currentWidget = value; } }, metadata: _metadata }, _currentWidget_initializers, _currentWidget_extraInitializers);
|
|
64
|
+
__esDecorate(this, null, _next_decorators, { kind: "method", name: "next", static: false, private: false, access: { has: obj => "next" in obj, get: obj => obj.next }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
65
|
+
__esDecorate(this, null, _prev_decorators, { kind: "method", name: "prev", static: false, private: false, access: { has: obj => "prev" in obj, get: obj => obj.prev }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
66
|
+
__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);
|
|
67
|
+
__esDecorate(this, null, _settle_decorators, { kind: "method", name: "settle", static: false, private: false, access: { has: obj => "settle" in obj, get: obj => obj.settle }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
68
|
+
__esDecorate(this, null, _clear_decorators, { kind: "method", name: "clear", static: false, private: false, access: { has: obj => "clear" in obj, get: obj => obj.clear }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
69
|
+
__esDecorate(this, null, _setFocus_decorators, { kind: "method", name: "setFocus", static: false, private: false, access: { has: obj => "setFocus" in obj, get: obj => obj.setFocus }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
70
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
71
|
+
}
|
|
72
|
+
onScreen = __runInitializers(this, _instanceExtraInitializers);
|
|
73
|
+
#currentWidget_accessor_storage = __runInitializers(this, _currentWidget_initializers, null);
|
|
74
|
+
get currentWidget() { return this.#currentWidget_accessor_storage; }
|
|
75
|
+
set currentWidget(value) { this.#currentWidget_accessor_storage = value; }
|
|
76
|
+
changeHandlers = (__runInitializers(this, _currentWidget_extraInitializers), new Set());
|
|
77
|
+
/**
|
|
78
|
+
* `onScreen` is the widgets on the frame on screen, in document order.
|
|
79
|
+
*
|
|
80
|
+
* [LAW:one-source-of-truth] It is asked every time rather than kept: a list
|
|
81
|
+
* of the widgets held here would be a second picture of the frame, and
|
|
82
|
+
* wrong from the next paint.
|
|
83
|
+
*/
|
|
84
|
+
constructor(onScreen) {
|
|
85
|
+
this.onScreen = onScreen;
|
|
86
|
+
}
|
|
87
|
+
get current() {
|
|
88
|
+
return this.currentWidget;
|
|
89
|
+
}
|
|
90
|
+
get widgets() {
|
|
91
|
+
return this.onScreen().filter(takesFocus);
|
|
92
|
+
}
|
|
93
|
+
next() {
|
|
94
|
+
const focusable = this.widgets;
|
|
95
|
+
if (focusable.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
const currentIdx = this.currentWidget ? focusable.indexOf(this.currentWidget) : -1;
|
|
98
|
+
const nextIdx = (currentIdx + 1) % focusable.length;
|
|
99
|
+
this.setFocus(focusable[nextIdx]);
|
|
100
|
+
}
|
|
101
|
+
prev() {
|
|
102
|
+
const focusable = this.widgets;
|
|
103
|
+
if (focusable.length === 0)
|
|
104
|
+
return;
|
|
105
|
+
const currentIdx = this.currentWidget ? focusable.indexOf(this.currentWidget) : -1;
|
|
106
|
+
const prevIdx = currentIdx <= 0 ? focusable.length - 1 : currentIdx - 1;
|
|
107
|
+
this.setFocus(focusable[prevIdx]);
|
|
108
|
+
}
|
|
109
|
+
// A widget not on screen yet can take focus: an app that is about to show
|
|
110
|
+
// it focuses it first, and the frame that shows it keeps it (`settle`).
|
|
111
|
+
focus(widget) {
|
|
112
|
+
if (!takesFocus(widget))
|
|
113
|
+
return;
|
|
114
|
+
this.setFocus(widget);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Put focus where the frame just painted lets it rest: it stays on a widget
|
|
118
|
+
* the view drew (`drawn`) that can take it, and otherwise moves to the first
|
|
119
|
+
* one on screen that can, or to none.
|
|
120
|
+
*
|
|
121
|
+
* Drawn, not on screen: a widget cropped for the moment — the terminal
|
|
122
|
+
* shrank, a viewport scrolled, an overlay covers it — is still in the view,
|
|
123
|
+
* and keeps focus and whatever focus holds, like a half-typed filter.
|
|
124
|
+
*
|
|
125
|
+
* [LAW:single-enforcer] The one place focus follows the frame — onto the
|
|
126
|
+
* first widget when the app starts, off a widget that stopped being drawn
|
|
127
|
+
* or was disabled.
|
|
128
|
+
*/
|
|
129
|
+
settle(drawn) {
|
|
130
|
+
const current = this.currentWidget;
|
|
131
|
+
if (current && takesFocus(current) && drawn.includes(current))
|
|
132
|
+
return;
|
|
133
|
+
const first = this.widgets[0];
|
|
134
|
+
if (first)
|
|
135
|
+
this.setFocus(first);
|
|
136
|
+
else
|
|
137
|
+
this.clear();
|
|
138
|
+
}
|
|
139
|
+
onChange(handler) {
|
|
140
|
+
this.changeHandlers.add(handler);
|
|
141
|
+
return () => this.changeHandlers.delete(handler);
|
|
142
|
+
}
|
|
143
|
+
// [LAW:single-enforcer] FocusManager owns Tab/Shift+Tab semantics. The
|
|
144
|
+
// router registers this as a normal-priority handler at construction —
|
|
145
|
+
// it runs after the focused widget, so a widget can `event.stop()`
|
|
146
|
+
// to suppress traversal (e.g. Dropdown when its overlay is open).
|
|
147
|
+
handleKey(event) {
|
|
148
|
+
if (event.key !== "tab")
|
|
149
|
+
return;
|
|
150
|
+
if (event.shift)
|
|
151
|
+
this.prev();
|
|
152
|
+
else
|
|
153
|
+
this.next();
|
|
154
|
+
event.stop();
|
|
155
|
+
}
|
|
156
|
+
// --- Private ---
|
|
157
|
+
// No focus is where `settle` leaves an app with nothing to focus, and only
|
|
158
|
+
// there: anywhere else the next frame would put focus back on the first
|
|
159
|
+
// widget, so there is no public way in.
|
|
160
|
+
clear() {
|
|
161
|
+
if (!this.currentWidget)
|
|
162
|
+
return;
|
|
163
|
+
// [LAW:single-enforcer] WidgetBase.focus()/blur() route through
|
|
164
|
+
// handleFocus; calling it here as well would dispatch twice and run any
|
|
165
|
+
// subclass side effect (e.g. Dropdown clearing its filter) twice.
|
|
166
|
+
this.currentWidget.blur();
|
|
167
|
+
this.currentWidget = null;
|
|
168
|
+
this.emitChange();
|
|
169
|
+
}
|
|
170
|
+
setFocus(widget) {
|
|
171
|
+
if (this.currentWidget === widget)
|
|
172
|
+
return;
|
|
173
|
+
// [LAW:single-enforcer] focus()/blur() already dispatch handleFocus —
|
|
174
|
+
// see clear() for the rationale.
|
|
175
|
+
if (this.currentWidget)
|
|
176
|
+
this.currentWidget.blur();
|
|
177
|
+
this.currentWidget = widget;
|
|
178
|
+
widget.focus();
|
|
179
|
+
this.emitChange();
|
|
180
|
+
}
|
|
181
|
+
emitChange() {
|
|
182
|
+
for (const handler of this.changeHandlers) {
|
|
183
|
+
handler(this.currentWidget);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
})();
|
|
188
|
+
export { DefaultFocusManager };
|
|
189
|
+
function takesFocus(widget) {
|
|
190
|
+
return widget.focusable && !widget.disabled;
|
|
191
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* widgetAt — which widget drew a cell of a painted frame, and where in its
|
|
3
|
+
* own output that cell sits; scrollTargetAt — what the wheel over that cell
|
|
4
|
+
* moves.
|
|
5
|
+
*
|
|
6
|
+
* A widget stamps every cell it draws (`WidgetBase.render`), and a
|
|
7
|
+
* `Scrollable` such as `Viewport` every cell it shows, around its content's
|
|
8
|
+
* stamps. The stamp rides
|
|
9
|
+
* through every container on the cell's `Style`, and the frame a screen paints
|
|
10
|
+
* is therefore its own hit map: nothing lays widgets out a second time to
|
|
11
|
+
* answer "what is under the pointer", so the answer cannot disagree with what
|
|
12
|
+
* the user sees. Z-order is paint order — whoever painted a cell last owns it.
|
|
13
|
+
*/
|
|
14
|
+
import { Segment } from "../core/segment.js";
|
|
15
|
+
import type { Scrollable } from "../core/protocol.js";
|
|
16
|
+
import type { InteractiveWidget } from "./types.js";
|
|
17
|
+
/** A pointer position resolved to the widget that drew it. */
|
|
18
|
+
export interface WidgetHit {
|
|
19
|
+
readonly widget: InteractiveWidget;
|
|
20
|
+
/** Column of the cell in the widget's own output. */
|
|
21
|
+
readonly col: number;
|
|
22
|
+
/** Row of the cell in the widget's own output. */
|
|
23
|
+
readonly row: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The innermost widget that drew the cell at column `x` of row `y` of
|
|
27
|
+
* `frame`, or `undefined` when no widget drew it. A widget nested inside
|
|
28
|
+
* another widget's output wins over the one containing it.
|
|
29
|
+
*/
|
|
30
|
+
export declare function widgetAt(frame: readonly (readonly Segment[])[], x: number, y: number): WidgetHit | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* The innermost `Scrollable` that drew the cell at column `x` of row `y` of
|
|
33
|
+
* `frame` and that `scrollBy(lines)` would move, or `undefined` when none
|
|
34
|
+
* did. A widget drawn inside it does not hide it: the widget's anchor is
|
|
35
|
+
* nested in its. One that cannot move that way — a viewport whose content
|
|
36
|
+
* fits, or that is at that end — passes the wheel to the one around it.
|
|
37
|
+
*/
|
|
38
|
+
export declare function scrollTargetAt(frame: readonly (readonly Segment[])[], x: number, y: number, lines: number): Scrollable | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* Where `widget`'s output starts in `frame` — the cell its own row 0, column
|
|
41
|
+
* 0 falls on — read off the first cell it drew, or `undefined` when it drew
|
|
42
|
+
* none.
|
|
43
|
+
*/
|
|
44
|
+
export declare function originOf(frame: readonly (readonly Segment[])[], widget: InteractiveWidget): {
|
|
45
|
+
x: number;
|
|
46
|
+
y: number;
|
|
47
|
+
} | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Whether `widget` drew the cell at column `x` of row `y` of `frame`, itself
|
|
50
|
+
* or through a widget nested in its output.
|
|
51
|
+
*/
|
|
52
|
+
export declare function drew(frame: readonly (readonly Segment[])[], widget: InteractiveWidget, x: number, y: number): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Where `widget`'s footprint sits in `frame`: the cell its row 0, column 0
|
|
55
|
+
* falls on, and how many of its rows the frame shows down to its lowest — or
|
|
56
|
+
* `undefined` when the frame does not show its row 0.
|
|
57
|
+
*/
|
|
58
|
+
export declare function footprintOf(frame: readonly (readonly Segment[])[], widget: InteractiveWidget): {
|
|
59
|
+
x: number;
|
|
60
|
+
y: number;
|
|
61
|
+
rows: number;
|
|
62
|
+
} | undefined;
|
|
63
|
+
/** Every owner that drew a cell of `frame`, at every depth of nesting. */
|
|
64
|
+
export declare function ownersOn(frame: readonly (readonly Segment[])[]): Set<object>;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* widgetAt — which widget drew a cell of a painted frame, and where in its
|
|
3
|
+
* own output that cell sits; scrollTargetAt — what the wheel over that cell
|
|
4
|
+
* moves.
|
|
5
|
+
*
|
|
6
|
+
* A widget stamps every cell it draws (`WidgetBase.render`), and a
|
|
7
|
+
* `Scrollable` such as `Viewport` every cell it shows, around its content's
|
|
8
|
+
* stamps. The stamp rides
|
|
9
|
+
* through every container on the cell's `Style`, and the frame a screen paints
|
|
10
|
+
* is therefore its own hit map: nothing lays widgets out a second time to
|
|
11
|
+
* answer "what is under the pointer", so the answer cannot disagree with what
|
|
12
|
+
* the user sees. Z-order is paint order — whoever painted a cell last owns it.
|
|
13
|
+
*/
|
|
14
|
+
import { Segment } from "../core/segment.js";
|
|
15
|
+
import { isScrollable } from "../core/protocol.js";
|
|
16
|
+
import { WidgetBase } from "./widget-base.js";
|
|
17
|
+
/**
|
|
18
|
+
* The innermost widget that drew the cell at column `x` of row `y` of
|
|
19
|
+
* `frame`, or `undefined` when no widget drew it. A widget nested inside
|
|
20
|
+
* another widget's output wins over the one containing it.
|
|
21
|
+
*/
|
|
22
|
+
export function widgetAt(frame, x, y) {
|
|
23
|
+
const hit = innermost(frame, x, y, (owner) => (owner instanceof WidgetBase ? owner : undefined));
|
|
24
|
+
return hit && { widget: hit.owner, col: hit.col, row: hit.row };
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The innermost `Scrollable` that drew the cell at column `x` of row `y` of
|
|
28
|
+
* `frame` and that `scrollBy(lines)` would move, or `undefined` when none
|
|
29
|
+
* did. A widget drawn inside it does not hide it: the widget's anchor is
|
|
30
|
+
* nested in its. One that cannot move that way — a viewport whose content
|
|
31
|
+
* fits, or that is at that end — passes the wheel to the one around it.
|
|
32
|
+
*/
|
|
33
|
+
export function scrollTargetAt(frame, x, y, lines) {
|
|
34
|
+
return innermost(frame, x, y, (owner) => isScrollable(owner) && owner.canScrollBy(lines) ? owner : undefined)?.owner;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The innermost owner of the cell at column `x` of row `y` of `frame` that
|
|
38
|
+
* `accept` turns into a `T`, with the cell's place in that owner's output.
|
|
39
|
+
*
|
|
40
|
+
* [LAW:parse-dont-validate] An anchor's owner is any object; `accept` is
|
|
41
|
+
* where it becomes the kind of owner the caller asked for, or nothing.
|
|
42
|
+
*/
|
|
43
|
+
function innermost(frame, x, y, accept) {
|
|
44
|
+
let found;
|
|
45
|
+
for (let a = Segment.anchorAt(frame, x, y); a; a = a.inner) {
|
|
46
|
+
const owner = accept(a.owner);
|
|
47
|
+
if (owner)
|
|
48
|
+
found = { owner, col: a.col, row: a.row };
|
|
49
|
+
}
|
|
50
|
+
return found;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Where `widget`'s output starts in `frame` — the cell its own row 0, column
|
|
54
|
+
* 0 falls on — read off the first cell it drew, or `undefined` when it drew
|
|
55
|
+
* none.
|
|
56
|
+
*/
|
|
57
|
+
export function originOf(frame, widget) {
|
|
58
|
+
for (let y = 0; y < frame.length; y++) {
|
|
59
|
+
let start = 0;
|
|
60
|
+
for (const segment of frame[y]) {
|
|
61
|
+
for (let a = segment.style?.anchor; a; a = a.inner) {
|
|
62
|
+
if (a.owner === widget)
|
|
63
|
+
return { x: start - a.col, y: y - a.row };
|
|
64
|
+
}
|
|
65
|
+
start += segment.cellLength;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Whether `widget` drew the cell at column `x` of row `y` of `frame`, itself
|
|
72
|
+
* or through a widget nested in its output.
|
|
73
|
+
*/
|
|
74
|
+
export function drew(frame, widget, x, y) {
|
|
75
|
+
for (let a = Segment.anchorAt(frame, x, y); a; a = a.inner)
|
|
76
|
+
if (a.owner === widget)
|
|
77
|
+
return true;
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Where `widget`'s footprint sits in `frame`: the cell its row 0, column 0
|
|
82
|
+
* falls on, and how many of its rows the frame shows down to its lowest — or
|
|
83
|
+
* `undefined` when the frame does not show its row 0.
|
|
84
|
+
*/
|
|
85
|
+
export function footprintOf(frame, widget) {
|
|
86
|
+
let origin;
|
|
87
|
+
let rows = 0;
|
|
88
|
+
for (let y = 0; y < frame.length; y++) {
|
|
89
|
+
let start = 0;
|
|
90
|
+
for (const segment of frame[y]) {
|
|
91
|
+
for (let a = segment.style?.anchor; a; a = a.inner) {
|
|
92
|
+
if (a.owner !== widget)
|
|
93
|
+
continue;
|
|
94
|
+
if (a.row === 0 && !origin)
|
|
95
|
+
origin = { x: start - a.col, y };
|
|
96
|
+
rows = Math.max(rows, a.row + 1);
|
|
97
|
+
}
|
|
98
|
+
start += segment.cellLength;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return origin && { ...origin, rows };
|
|
102
|
+
}
|
|
103
|
+
/** Every owner that drew a cell of `frame`, at every depth of nesting. */
|
|
104
|
+
export function ownersOn(frame) {
|
|
105
|
+
const owners = new Set();
|
|
106
|
+
for (const line of frame) {
|
|
107
|
+
for (const segment of line) {
|
|
108
|
+
for (let a = segment.style?.anchor; a; a = a.inner)
|
|
109
|
+
owners.add(a.owner);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return owners;
|
|
113
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export type { KeyEventInit, KeyHandlerPriority, KeyHandlerOptions, ScreenMouseEvent, WidgetMouseEvent, WidgetFocusEvent, InteractiveWidget, OverlayRenderable, FocusManager, } from "./types.js";
|
|
2
|
+
export { hasOverlay, KeyEvent } from "./types.js";
|
|
3
|
+
export { StaticItem } from "./static-item.js";
|
|
4
|
+
export type { StaticItemOptions } from "./static-item.js";
|
|
5
|
+
export { WidgetBase } from "./widget-base.js";
|
|
6
|
+
export { WidgetApp } from "./widget-app.js";
|
|
7
|
+
export { Button } from "./button.js";
|
|
8
|
+
export type { ButtonVariant, ButtonOptions } from "./button.js";
|
|
9
|
+
export { Checkbox } from "./checkbox.js";
|
|
10
|
+
export type { CheckboxOptions } from "./checkbox.js";
|
|
11
|
+
export { Toggle } from "./toggle.js";
|
|
12
|
+
export type { ToggleVariant, ToggleOptions } from "./toggle.js";
|
|
13
|
+
export { TextInput, charGreedyWrap } from "./text-input.js";
|
|
14
|
+
export type { TextInputOptions, WrapStrategy, WrapRow } from "./text-input.js";
|
|
15
|
+
export { Dropdown } from "./dropdown.js";
|
|
16
|
+
export type { DropdownOptions } from "./dropdown.js";
|
|
17
|
+
export { Slider } from "./slider.js";
|
|
18
|
+
export type { SliderOptions } from "./slider.js";
|
|
19
|
+
export { widgetAt } from "./hit.js";
|
|
20
|
+
export type { WidgetHit } from "./hit.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { hasOverlay, KeyEvent } from "./types.js";
|
|
2
|
+
export { StaticItem } from "./static-item.js";
|
|
3
|
+
export { WidgetBase } from "./widget-base.js";
|
|
4
|
+
export { WidgetApp } from "./widget-app.js";
|
|
5
|
+
export { Button } from "./button.js";
|
|
6
|
+
export { Checkbox } from "./checkbox.js";
|
|
7
|
+
export { Toggle } from "./toggle.js";
|
|
8
|
+
export { TextInput, charGreedyWrap } from "./text-input.js";
|
|
9
|
+
export { Dropdown } from "./dropdown.js";
|
|
10
|
+
export { Slider } from "./slider.js";
|
|
11
|
+
export { widgetAt } from "./hit.js";
|
|
12
|
+
// The terminal seam is not re-exported here. It lives on the `host` subpath,
|
|
13
|
+
// and a second path to `TerminalHost` would be the two-clocks problem the
|
|
14
|
+
// subpath split exists to remove.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Slider widget — numeric value within [min, max] with step increments.
|
|
3
|
+
* [LAW:dataflow-not-control-flow] every render emits exactly `width`
|
|
4
|
+
* track cells; the marker cell index is data, not a branch.
|
|
5
|
+
* [LAW:one-type-per-behavior] shared infrastructure inherited from
|
|
6
|
+
* WidgetBase.
|
|
7
|
+
*
|
|
8
|
+
* Visual:
|
|
9
|
+
* track — `width` cells of "─" (ASCII fallback "-")
|
|
10
|
+
* marker — "●" (ASCII fallback "*") at round((value - min) / range * (width - 1))
|
|
11
|
+
* filled — cells left of and including the marker use primary fg
|
|
12
|
+
* on the default terminal bg
|
|
13
|
+
* unfilled — cells right of the marker use surface fg on the default
|
|
14
|
+
* terminal bg (no explicit bgcolor — the unfilled track
|
|
15
|
+
* should sit transparently against whatever the panel /
|
|
16
|
+
* parent paints underneath)
|
|
17
|
+
* focused — underline on the segments
|
|
18
|
+
* disabled — dim
|
|
19
|
+
*/
|
|
20
|
+
import { Segment } from "../core/segment.js";
|
|
21
|
+
import { type RenderOptions } from "../core/protocol.js";
|
|
22
|
+
import type { TerminalTheme } from "../core/color.js";
|
|
23
|
+
import { WidgetBase } from "./widget-base.js";
|
|
24
|
+
import type { KeyEvent, WidgetMouseEvent } from "./types.js";
|
|
25
|
+
export interface SliderOptions {
|
|
26
|
+
value?: number;
|
|
27
|
+
min?: number;
|
|
28
|
+
max?: number;
|
|
29
|
+
step?: number;
|
|
30
|
+
width?: number;
|
|
31
|
+
id?: string;
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
theme?: TerminalTheme;
|
|
34
|
+
}
|
|
35
|
+
export declare class Slider extends WidgetBase {
|
|
36
|
+
readonly id: string;
|
|
37
|
+
readonly focusable = true;
|
|
38
|
+
accessor value: number;
|
|
39
|
+
accessor min: number;
|
|
40
|
+
accessor max: number;
|
|
41
|
+
accessor step: number;
|
|
42
|
+
accessor width: number;
|
|
43
|
+
private accessor _theme;
|
|
44
|
+
private _dragging;
|
|
45
|
+
constructor(options?: SliderOptions);
|
|
46
|
+
setTheme(theme: TerminalTheme): void;
|
|
47
|
+
handleKey(event: KeyEvent): void;
|
|
48
|
+
handleMouse(event: WidgetMouseEvent): void;
|
|
49
|
+
private setValue;
|
|
50
|
+
private setValueFromMouseX;
|
|
51
|
+
protected draw(options: RenderOptions): Iterable<Segment>;
|
|
52
|
+
measure(_options: RenderOptions): {
|
|
53
|
+
minimum: number;
|
|
54
|
+
maximum: number;
|
|
55
|
+
};
|
|
56
|
+
private resolvePalette;
|
|
57
|
+
}
|