@promptctl/rich-js 0.24.0 → 0.25.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 +7 -0
- package/THIRD-PARTY-NOTICES +29 -1
- package/dist/core/anchor.d.ts +5 -0
- package/dist/core/anchor.js +11 -4
- package/dist/core/animation.d.ts +243 -0
- package/dist/core/animation.js +375 -0
- package/dist/core/ansi.js +2 -2
- package/dist/core/box.d.ts +7 -7
- package/dist/core/cell-widths.d.ts +9 -0
- package/dist/core/cell-widths.js +140 -0
- package/dist/core/cells.d.ts +40 -24
- package/dist/core/cells.js +151 -66
- package/dist/core/clock.d.ts +2 -2
- package/dist/core/clock.js +6 -4
- package/dist/core/color.d.ts +27 -10
- package/dist/core/color.js +21 -29
- package/dist/core/console.d.ts +28 -17
- package/dist/core/console.js +48 -43
- package/dist/core/easing.d.ts +140 -10
- package/dist/core/easing.js +328 -50
- package/dist/core/emoji.d.ts +1 -1
- package/dist/core/emoji.js +1 -2
- package/dist/core/export-html.js +2 -1
- package/dist/core/export-lines.js +3 -3
- package/dist/core/highlighter.d.ts +9 -8
- package/dist/core/highlighter.js +3 -2
- package/dist/core/json.js +3 -2
- package/dist/core/markup.js +16 -12
- package/dist/core/measure.js +3 -3
- package/dist/core/memo.d.ts +11 -2
- package/dist/core/memo.js +16 -0
- package/dist/core/oklch.js +17 -6
- package/dist/core/osc8.d.ts +1 -1
- package/dist/core/osc8.js +4 -5
- package/dist/core/paint.d.ts +2 -1
- package/dist/core/paint.js +4 -3
- package/dist/core/pattern.d.ts +21 -0
- package/dist/core/pattern.js +21 -0
- package/dist/core/place.js +2 -1
- package/dist/core/pretty.js +11 -12
- package/dist/core/protocol.d.ts +136 -21
- package/dist/core/protocol.js +203 -16
- package/dist/core/render.d.ts +15 -2
- package/dist/core/render.js +27 -6
- package/dist/core/segment.d.ts +31 -6
- package/dist/core/segment.js +68 -53
- package/dist/core/spinnerData.d.ts +1 -1
- package/dist/core/state.d.ts +53 -0
- package/dist/core/state.js +82 -0
- package/dist/core/strip.d.ts +11 -13
- package/dist/core/strip.js +126 -113
- package/dist/core/style.d.ts +47 -14
- package/dist/core/style.js +74 -34
- package/dist/core/text.d.ts +5 -8
- package/dist/core/text.js +133 -133
- package/dist/core/timeline.d.ts +109 -0
- package/dist/core/timeline.js +180 -0
- package/dist/core/tween.d.ts +49 -0
- package/dist/core/tween.js +71 -0
- package/dist/core/view.d.ts +92 -0
- package/dist/core/view.js +83 -0
- package/dist/host/app.d.ts +49 -21
- package/dist/host/app.js +72 -38
- package/dist/host/input.js +3 -4
- package/dist/index.d.ts +30 -15
- package/dist/index.js +20 -6
- package/dist/node/traceback.js +4 -3
- package/dist/renderables/change.d.ts +42 -0
- package/dist/renderables/change.js +112 -0
- package/dist/renderables/columns.d.ts +1 -1
- package/dist/renderables/columns.js +3 -3
- package/dist/renderables/constrain.js +2 -1
- package/dist/renderables/effect.d.ts +155 -92
- package/dist/renderables/effect.js +203 -136
- package/dist/renderables/effects.d.ts +137 -24
- package/dist/renderables/effects.js +276 -113
- package/dist/renderables/embed.d.ts +1 -1
- package/dist/renderables/embed.js +18 -9
- package/dist/renderables/flexStrip.js +2 -1
- package/dist/renderables/frames.d.ts +45 -43
- package/dist/renderables/frames.js +57 -45
- package/dist/renderables/glyph-effect.d.ts +158 -0
- package/dist/renderables/glyph-effect.js +237 -0
- package/dist/renderables/glyph-effects.d.ts +147 -0
- package/dist/renderables/glyph-effects.js +283 -0
- package/dist/renderables/group.d.ts +1 -1
- package/dist/renderables/group.js +2 -2
- package/dist/renderables/html-entities.d.ts +8 -0
- package/dist/renderables/html-entities.js +386 -0
- package/dist/renderables/layout.d.ts +10 -9
- package/dist/renderables/layout.js +42 -35
- package/dist/renderables/lifecycle.d.ts +77 -0
- package/dist/renderables/lifecycle.js +132 -0
- package/dist/renderables/list-view.d.ts +2 -2
- package/dist/renderables/list-view.js +11 -8
- package/dist/renderables/live.d.ts +36 -21
- package/dist/renderables/live.js +89 -42
- package/dist/renderables/markdown-parse.d.ts +109 -0
- package/dist/renderables/markdown-parse.js +1427 -0
- package/dist/renderables/markdown-url.d.ts +19 -0
- package/dist/renderables/markdown-url.js +314 -0
- package/dist/renderables/markdown.d.ts +5 -7
- package/dist/renderables/markdown.js +356 -683
- package/dist/renderables/padding.d.ts +7 -20
- package/dist/renderables/padding.js +29 -50
- package/dist/renderables/panel.d.ts +30 -32
- package/dist/renderables/panel.js +65 -109
- package/dist/renderables/progress.d.ts +83 -32
- package/dist/renderables/progress.js +186 -90
- package/dist/renderables/progressBar.d.ts +22 -12
- package/dist/renderables/progressBar.js +33 -10
- package/dist/renderables/prompt.js +3 -2
- package/dist/renderables/python-space.d.ts +13 -0
- package/dist/renderables/python-space.js +25 -0
- package/dist/renderables/scroll.d.ts +50 -0
- package/dist/renderables/scroll.js +106 -0
- package/dist/renderables/spinner.d.ts +57 -24
- package/dist/renderables/spinner.js +101 -49
- package/dist/renderables/status.js +1 -1
- package/dist/renderables/syntax.d.ts +10 -9
- package/dist/renderables/syntax.js +5 -3
- package/dist/renderables/table.d.ts +48 -46
- package/dist/renderables/table.js +170 -208
- package/dist/renderables/traceback.d.ts +3 -3
- package/dist/renderables/traceback.js +12 -10
- package/dist/renderables/tree.d.ts +28 -25
- package/dist/renderables/tree.js +108 -58
- package/dist/renderables/viewport.d.ts +77 -38
- package/dist/renderables/viewport.js +156 -72
- package/dist/template-bindings/animation-funcs.d.ts +78 -9
- package/dist/template-bindings/animation-funcs.js +132 -14
- package/dist/template-bindings/index.d.ts +5 -5
- package/dist/template-bindings/index.js +7 -6
- package/dist/themes/ramp.d.ts +62 -4
- package/dist/themes/ramp.js +82 -4
- package/dist/themes/registry.js +5 -7
- package/dist/widgets/button.js +3 -2
- package/dist/widgets/checkbox.js +4 -3
- package/dist/widgets/dropdown.d.ts +3 -1
- package/dist/widgets/dropdown.js +20 -15
- package/dist/widgets/event-router.js +4 -2
- package/dist/widgets/focus-manager.d.ts +23 -14
- package/dist/widgets/focus-manager.js +34 -33
- package/dist/widgets/hit.d.ts +6 -0
- package/dist/widgets/hit.js +8 -1
- package/dist/widgets/index.d.ts +1 -1
- package/dist/widgets/observable.d.ts +23 -0
- package/dist/widgets/observable.js +43 -0
- package/dist/widgets/slider.d.ts +1 -1
- package/dist/widgets/slider.js +12 -3
- package/dist/widgets/static-item.d.ts +1 -1
- package/dist/widgets/static-item.js +6 -7
- package/dist/widgets/text-input.d.ts +53 -47
- package/dist/widgets/text-input.js +456 -399
- package/dist/widgets/themed-widget.js +2 -1
- package/dist/widgets/toggle.js +4 -3
- package/dist/widgets/types.d.ts +10 -4
- package/dist/widgets/types.js +8 -2
- package/dist/widgets/widget-app.d.ts +32 -6
- package/dist/widgets/widget-app.js +74 -27
- package/dist/widgets/widget-base.d.ts +2 -2
- package/dist/widgets/widget-base.js +29 -21
- package/package.json +9 -5
package/dist/widgets/hit.d.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
* answer "what is under the pointer", so the answer cannot disagree with what
|
|
12
12
|
* the user sees. Z-order is paint order — whoever painted a cell last owns it.
|
|
13
13
|
*/
|
|
14
|
+
import type { Anchor } from "../core/anchor.js";
|
|
14
15
|
import { Segment } from "../core/segment.js";
|
|
15
16
|
import type { Scrollable } from "../core/protocol.js";
|
|
16
17
|
import type { InteractiveWidget } from "./types.js";
|
|
@@ -50,6 +51,11 @@ export declare function originOf(frame: readonly (readonly Segment[])[], widget:
|
|
|
50
51
|
* or through a widget nested in its output.
|
|
51
52
|
*/
|
|
52
53
|
export declare function drew(frame: readonly (readonly Segment[])[], widget: InteractiveWidget, x: number, y: number): boolean;
|
|
54
|
+
/**
|
|
55
|
+
* What `widget`'s own draw stamped on the cell at column `x` of row `y` of
|
|
56
|
+
* `frame`, inside its stamp, or `undefined` when it drew none of it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function cellOf(frame: readonly (readonly Segment[])[], widget: InteractiveWidget, x: number, y: number): Anchor | undefined;
|
|
53
59
|
/**
|
|
54
60
|
* Where `widget`'s footprint sits in `frame`: the cell its row 0, column 0
|
|
55
61
|
* falls on, and how many of its rows the frame shows down to its lowest — or
|
package/dist/widgets/hit.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* answer "what is under the pointer", so the answer cannot disagree with what
|
|
12
12
|
* the user sees. Z-order is paint order — whoever painted a cell last owns it.
|
|
13
13
|
*/
|
|
14
|
-
import { drawnBy } from "../core/anchor.js";
|
|
14
|
+
import { drawnBy, levelOf } from "../core/anchor.js";
|
|
15
15
|
import { Segment } from "../core/segment.js";
|
|
16
16
|
import { isScrollable } from "../core/protocol.js";
|
|
17
17
|
import { WidgetBase } from "./widget-base.js";
|
|
@@ -75,6 +75,13 @@ export function originOf(frame, widget) {
|
|
|
75
75
|
export function drew(frame, widget, x, y) {
|
|
76
76
|
return drawnBy(Segment.anchorAt(frame, x, y), widget);
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* What `widget`'s own draw stamped on the cell at column `x` of row `y` of
|
|
80
|
+
* `frame`, inside its stamp, or `undefined` when it drew none of it.
|
|
81
|
+
*/
|
|
82
|
+
export function cellOf(frame, widget, x, y) {
|
|
83
|
+
return levelOf(Segment.anchorAt(frame, x, y), widget)?.inner;
|
|
84
|
+
}
|
|
78
85
|
/**
|
|
79
86
|
* Where `widget`'s footprint sits in `frame`: the cell its row 0, column 0
|
|
80
87
|
* falls on, and how many of its rows the frame shows down to its lowest — or
|
package/dist/widgets/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export { StaticItem } from "./static-item.js";
|
|
|
4
4
|
export type { StaticItemOptions } from "./static-item.js";
|
|
5
5
|
export { WidgetBase } from "./widget-base.js";
|
|
6
6
|
export { WidgetApp } from "./widget-app.js";
|
|
7
|
-
export type { WidgetAppOptions } from "./widget-app.js";
|
|
7
|
+
export type { WidgetAppOptions, WidgetPresence } from "./widget-app.js";
|
|
8
8
|
export { Button } from "./button.js";
|
|
9
9
|
export type { ButtonVariant, ButtonOptions } from "./button.js";
|
|
10
10
|
export { Checkbox } from "./checkbox.js";
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* observable — the widgets' state carrier: mobx's `observableRef` accessor
|
|
3
|
+
* decorator, refusing a write during a render or measure the widget was not
|
|
4
|
+
* made in.
|
|
5
|
+
*
|
|
6
|
+
* A render changes nothing (`src/core/state.ts`). `State` refuses a write in
|
|
7
|
+
* its setter; a widget's state is a mobx observable, whose setter is mobx's, so
|
|
8
|
+
* the refusal is an interceptor every instance registers on each of its
|
|
9
|
+
* observables as it is made, holding the pass it was made in. `core/` cannot do
|
|
10
|
+
* this itself: mobx is an optional peer, reachable only through `./widgets`.
|
|
11
|
+
*
|
|
12
|
+
* There is no deep `observable`. It turns an array or object into a mobx one
|
|
13
|
+
* whose contents are written without the interceptor, so a refusal on the
|
|
14
|
+
* accessor alone would be a refusal of half the writes. A held value is
|
|
15
|
+
* replaced whole, and the render-purity gate reports one whose type can be
|
|
16
|
+
* written in place.
|
|
17
|
+
*
|
|
18
|
+
* Every observable accessor in `src/widgets/` is declared with this, never
|
|
19
|
+
* with mobx's own: `test/seam/render-purity.ts` sanctions an accessor
|
|
20
|
+
* decorated from this module and reports any other as a writable property.
|
|
21
|
+
*/
|
|
22
|
+
/** mobx's `observableRef` (the reference, not its contents), refusing a write during a render or measure. */
|
|
23
|
+
export declare function observableRef<This extends object, Value>(target: ClassAccessorDecoratorTarget<This, Value>, context: ClassAccessorDecoratorContext<This, Value>): ClassAccessorDecoratorResult<This, Value>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* observable — the widgets' state carrier: mobx's `observableRef` accessor
|
|
3
|
+
* decorator, refusing a write during a render or measure the widget was not
|
|
4
|
+
* made in.
|
|
5
|
+
*
|
|
6
|
+
* A render changes nothing (`src/core/state.ts`). `State` refuses a write in
|
|
7
|
+
* its setter; a widget's state is a mobx observable, whose setter is mobx's, so
|
|
8
|
+
* the refusal is an interceptor every instance registers on each of its
|
|
9
|
+
* observables as it is made, holding the pass it was made in. `core/` cannot do
|
|
10
|
+
* this itself: mobx is an optional peer, reachable only through `./widgets`.
|
|
11
|
+
*
|
|
12
|
+
* There is no deep `observable`. It turns an array or object into a mobx one
|
|
13
|
+
* whose contents are written without the interceptor, so a refusal on the
|
|
14
|
+
* accessor alone would be a refusal of half the writes. A held value is
|
|
15
|
+
* replaced whole, and the render-purity gate reports one whose type can be
|
|
16
|
+
* written in place.
|
|
17
|
+
*
|
|
18
|
+
* Every observable accessor in `src/widgets/` is declared with this, never
|
|
19
|
+
* with mobx's own: `test/seam/render-purity.ts` sanctions an accessor
|
|
20
|
+
* decorated from this module and reports any other as a writable property.
|
|
21
|
+
*/
|
|
22
|
+
import { observableRef as mobxObservableRef, intercept } from "mobx";
|
|
23
|
+
import { activePass } from "../core/protocol.js";
|
|
24
|
+
import { refuseRenderWrite } from "../core/state.js";
|
|
25
|
+
/** mobx's accessor decorator, typed as what it returns for an accessor: a `get`, a `set` and an `init`, always all three. */
|
|
26
|
+
const mobxRef = mobxObservableRef;
|
|
27
|
+
/** mobx's `observableRef` (the reference, not its contents), refusing a write during a render or measure. */
|
|
28
|
+
export function observableRef(target, context) {
|
|
29
|
+
const inner = mobxRef(target, context);
|
|
30
|
+
return {
|
|
31
|
+
...inner,
|
|
32
|
+
init(value) {
|
|
33
|
+
const initial = inner.init.call(this, value);
|
|
34
|
+
const owner = activePass();
|
|
35
|
+
// [LAW:single-enforcer] The rule is `State`'s, applied by its one enforcer.
|
|
36
|
+
intercept(this, context.name, (change) => {
|
|
37
|
+
refuseRenderWrite(owner);
|
|
38
|
+
return change;
|
|
39
|
+
});
|
|
40
|
+
return initial;
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
package/dist/widgets/slider.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export declare class Slider extends ThemedWidget {
|
|
|
40
40
|
accessor max: number;
|
|
41
41
|
accessor step: number;
|
|
42
42
|
accessor width: number;
|
|
43
|
-
private _dragging;
|
|
43
|
+
private accessor _dragging;
|
|
44
44
|
constructor(options?: SliderOptions);
|
|
45
45
|
handleKey(event: KeyEvent): void;
|
|
46
46
|
handleMouse(event: WidgetMouseEvent): void;
|
package/dist/widgets/slider.js
CHANGED
|
@@ -51,7 +51,8 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
51
51
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
52
52
|
done = true;
|
|
53
53
|
};
|
|
54
|
-
import {
|
|
54
|
+
import { action } from "mobx";
|
|
55
|
+
import { observableRef } from "./observable.js";
|
|
55
56
|
import { Segment } from "../core/segment.js";
|
|
56
57
|
import { Style } from "../core/style.js";
|
|
57
58
|
import { drawable } from "../core/protocol.js";
|
|
@@ -76,17 +77,21 @@ let Slider = (() => {
|
|
|
76
77
|
let _width_decorators;
|
|
77
78
|
let _width_initializers = [];
|
|
78
79
|
let _width_extraInitializers = [];
|
|
80
|
+
let __dragging_decorators;
|
|
81
|
+
let __dragging_initializers = [];
|
|
82
|
+
let __dragging_extraInitializers = [];
|
|
79
83
|
let _handleKey_decorators;
|
|
80
84
|
let _handleMouse_decorators;
|
|
81
85
|
let _setValue_decorators;
|
|
82
86
|
return class Slider extends _classSuper {
|
|
83
87
|
static {
|
|
84
88
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
85
|
-
_value_decorators = [
|
|
89
|
+
_value_decorators = [observableRef];
|
|
86
90
|
_min_decorators = [observableRef];
|
|
87
91
|
_max_decorators = [observableRef];
|
|
88
92
|
_step_decorators = [observableRef];
|
|
89
93
|
_width_decorators = [observableRef];
|
|
94
|
+
__dragging_decorators = [observableRef];
|
|
90
95
|
_handleKey_decorators = [action];
|
|
91
96
|
_handleMouse_decorators = [action];
|
|
92
97
|
_setValue_decorators = [action];
|
|
@@ -95,6 +100,7 @@ let Slider = (() => {
|
|
|
95
100
|
__esDecorate(this, null, _max_decorators, { kind: "accessor", name: "max", static: false, private: false, access: { has: obj => "max" in obj, get: obj => obj.max, set: (obj, value) => { obj.max = value; } }, metadata: _metadata }, _max_initializers, _max_extraInitializers);
|
|
96
101
|
__esDecorate(this, null, _step_decorators, { kind: "accessor", name: "step", static: false, private: false, access: { has: obj => "step" in obj, get: obj => obj.step, set: (obj, value) => { obj.step = value; } }, metadata: _metadata }, _step_initializers, _step_extraInitializers);
|
|
97
102
|
__esDecorate(this, null, _width_decorators, { kind: "accessor", name: "width", static: false, private: false, access: { has: obj => "width" in obj, get: obj => obj.width, set: (obj, value) => { obj.width = value; } }, metadata: _metadata }, _width_initializers, _width_extraInitializers);
|
|
103
|
+
__esDecorate(this, null, __dragging_decorators, { kind: "accessor", name: "_dragging", static: false, private: false, access: { has: obj => "_dragging" in obj, get: obj => obj._dragging, set: (obj, value) => { obj._dragging = value; } }, metadata: _metadata }, __dragging_initializers, __dragging_extraInitializers);
|
|
98
104
|
__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);
|
|
99
105
|
__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);
|
|
100
106
|
__esDecorate(this, null, _setValue_decorators, { kind: "method", name: "setValue", static: false, private: false, access: { has: obj => "setValue" in obj, get: obj => obj.setValue }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -117,9 +123,12 @@ let Slider = (() => {
|
|
|
117
123
|
#width_accessor_storage = (__runInitializers(this, _step_extraInitializers), __runInitializers(this, _width_initializers, void 0));
|
|
118
124
|
get width() { return this.#width_accessor_storage; }
|
|
119
125
|
set width(value) { this.#width_accessor_storage = value; }
|
|
120
|
-
|
|
126
|
+
#_dragging_accessor_storage = (__runInitializers(this, _width_extraInitializers), __runInitializers(this, __dragging_initializers, false));
|
|
127
|
+
get _dragging() { return this.#_dragging_accessor_storage; }
|
|
128
|
+
set _dragging(value) { this.#_dragging_accessor_storage = value; }
|
|
121
129
|
constructor(options = {}) {
|
|
122
130
|
super(options.theme);
|
|
131
|
+
__runInitializers(this, __dragging_extraInitializers);
|
|
123
132
|
this.id = options.id ?? `slider-${Math.random().toString(36).slice(2, 8)}`;
|
|
124
133
|
this.min = options.min ?? 0;
|
|
125
134
|
this.max = options.max ?? 100;
|
|
@@ -22,7 +22,7 @@ export interface StaticItemOptions {
|
|
|
22
22
|
export declare class StaticItem extends WidgetBase {
|
|
23
23
|
readonly id: string;
|
|
24
24
|
readonly focusable = false;
|
|
25
|
-
private readonly
|
|
25
|
+
private readonly body;
|
|
26
26
|
private readonly measureFn;
|
|
27
27
|
constructor(options: StaticItemOptions);
|
|
28
28
|
handleKey(_event: KeyEvent): void;
|
|
@@ -11,27 +11,26 @@
|
|
|
11
11
|
* renderable.
|
|
12
12
|
*/
|
|
13
13
|
import { Segment } from "../core/segment.js";
|
|
14
|
+
import { render } from "../core/protocol.js";
|
|
14
15
|
import { WidgetBase } from "./widget-base.js";
|
|
15
16
|
export class StaticItem extends WidgetBase {
|
|
16
17
|
id;
|
|
17
18
|
focusable = false;
|
|
18
|
-
|
|
19
|
+
// The body as a renderable either way: a function is one that holds nothing.
|
|
20
|
+
body;
|
|
19
21
|
measureFn;
|
|
20
22
|
constructor(options) {
|
|
21
23
|
super();
|
|
22
24
|
this.id = options.id;
|
|
23
25
|
const r = options.render;
|
|
24
|
-
this.
|
|
25
|
-
typeof r === "function"
|
|
26
|
-
? (opts) => r(opts)
|
|
27
|
-
: (opts) => r.render(opts);
|
|
26
|
+
this.body = typeof r === "function" ? { render: r } : r;
|
|
28
27
|
this.measureFn = options.measure;
|
|
29
28
|
}
|
|
30
29
|
// Static items don't respond to keys. WidgetBase.handleMouse / handleFocus
|
|
31
30
|
// are already no-ops, so we only need to satisfy the abstract handleKey.
|
|
32
31
|
handleKey(_event) { }
|
|
33
32
|
draw(options) {
|
|
34
|
-
return this.
|
|
33
|
+
return render(this.body, options);
|
|
35
34
|
}
|
|
36
35
|
measure(options) {
|
|
37
36
|
if (this.measureFn)
|
|
@@ -41,7 +40,7 @@ export class StaticItem extends WidgetBase {
|
|
|
41
40
|
// values too, not just the "\n" sentinel segment. Walking segments and
|
|
42
41
|
// testing `seg.text === "\n"` miscounts widths for any renderable
|
|
43
42
|
// that emits "a\nb" as a single segment.
|
|
44
|
-
const segments = Array.from(this.
|
|
43
|
+
const segments = Array.from(render(this.body, options));
|
|
45
44
|
const lines = Segment.splitLines(segments);
|
|
46
45
|
let max = 0;
|
|
47
46
|
for (const line of lines) {
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Two modes:
|
|
5
5
|
* - single-line (default): Enter submits; newlines in value are rendered
|
|
6
|
-
* as a literal `↵` glyph if they ever appear
|
|
6
|
+
* as a literal `↵` glyph if they ever appear, and
|
|
7
|
+
* any other glyph of zero cells as `◌`.
|
|
7
8
|
* - multi-line (`multiline: true`): Enter inserts a `\n`; `value` may
|
|
8
9
|
* contain logical line breaks; Up/Down navigate
|
|
9
10
|
* between logical lines preserving column intent.
|
|
11
|
+
* A glyph of zero cells is drawn as `◌` here too.
|
|
10
12
|
*
|
|
11
13
|
* [LAW:dataflow-not-control-flow] cursor and value are observable data; the
|
|
12
14
|
* keymap dispatches to small `@action` mutators that all flow through the
|
|
@@ -66,23 +68,25 @@ import { type CellCol, type CodePoint, type CodeUnit } from "../core/cells.js";
|
|
|
66
68
|
import { type RenderOptions } from "../core/protocol.js";
|
|
67
69
|
import type { TerminalTheme } from "../core/color.js";
|
|
68
70
|
import { ThemedWidget } from "./themed-widget.js";
|
|
69
|
-
import type { KeyEvent, WidgetMouseEvent } from "./types.js";
|
|
71
|
+
import type { KeyEvent, WidgetFocusEvent, WidgetMouseEvent } from "./types.js";
|
|
70
72
|
/**
|
|
71
73
|
* A soft-wrap strategy. Given one logical line of text and cell-width budgets,
|
|
72
|
-
* return the visual sub-rows that line wraps into. The
|
|
73
|
-
*
|
|
74
|
-
*
|
|
74
|
+
* return the visual sub-rows that line wraps into. The line arrives as the
|
|
75
|
+
* widget shows it — each glyph of zero cells already its one-cell `◌`, each
|
|
76
|
+
* glyph of a password its mask — so the budget counts the cells drawn. The
|
|
77
|
+
* first sub-row uses `firstWidth` as its capacity; every subsequent
|
|
78
|
+
* (continuation) sub-row uses `continuationWidth` (typically
|
|
79
|
+
* `firstWidth - cellLen(continuationMarker)`).
|
|
75
80
|
*
|
|
76
|
-
* Each returned row
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* - `start` — code-unit offset into the *logical line* where `content`
|
|
80
|
-
* begins, so the widget can map visual positions back to absolute `value`
|
|
81
|
-
* offsets for cursor projection.
|
|
81
|
+
* Each returned row is the stretch `[start, end)` of the line as given that
|
|
82
|
+
* the row draws; the widget draws the matching stretch of `value` and
|
|
83
|
+
* prepends the continuation marker itself.
|
|
82
84
|
*
|
|
83
|
-
* [LAW:types-are-the-program]
|
|
84
|
-
*
|
|
85
|
-
*
|
|
85
|
+
* [LAW:types-are-the-program] A row names where it falls in the line rather
|
|
86
|
+
* than carrying text of its own, so it cannot draw anything the line does not
|
|
87
|
+
* hold. Budget params are `CellCol`; offsets are `CodePoint` (a `CodeUnit` on
|
|
88
|
+
* a code-point boundary) — the type system prevents mixing these integer
|
|
89
|
+
* spaces inside a custom strategy.
|
|
86
90
|
*
|
|
87
91
|
* Built-in: `charGreedyWrap` (break at any character at the width limit).
|
|
88
92
|
* Custom: any function matching this signature. Template-aware wrapping
|
|
@@ -94,9 +98,10 @@ export type WrapStrategy = (logicalLine: string, budget: {
|
|
|
94
98
|
continuationWidth: CellCol;
|
|
95
99
|
}) => readonly WrapRow[];
|
|
96
100
|
export interface WrapRow {
|
|
97
|
-
|
|
98
|
-
/** Code-point offset into the logical line where `content` begins. */
|
|
101
|
+
/** Offset into the line as given where the row begins. */
|
|
99
102
|
readonly start: CodePoint;
|
|
103
|
+
/** Offset into the line as given where the row ends, exclusive. */
|
|
104
|
+
readonly end: CodePoint;
|
|
100
105
|
}
|
|
101
106
|
/**
|
|
102
107
|
* Character-greedy soft wrap. Breaks at any character once `firstWidth`
|
|
@@ -106,7 +111,7 @@ export interface WrapRow {
|
|
|
106
111
|
*
|
|
107
112
|
* Wide characters (CJK, emoji) are treated as atomic: a char that would
|
|
108
113
|
* straddle the budget is moved to the next row rather than split, and one too
|
|
109
|
-
* wide for the whole budget is force-taken — see `
|
|
114
|
+
* wide for the whole budget is force-taken — see `cellRows`.
|
|
110
115
|
*/
|
|
111
116
|
export declare const charGreedyWrap: WrapStrategy;
|
|
112
117
|
export interface TextInputOptions {
|
|
@@ -163,10 +168,11 @@ export interface TextInputOptions {
|
|
|
163
168
|
* area on the first/last visible row when scroll is possible in that
|
|
164
169
|
* direction. Fully self-contained — host needs no wiring.
|
|
165
170
|
* - `"indices"`: the widget suppresses in-content arrows and instead
|
|
166
|
-
*
|
|
167
|
-
*
|
|
168
|
-
* border. Useful when the surrounding
|
|
169
|
-
* indicator so widget content area stays
|
|
171
|
+
* answers `scrollIndicatorText(frame)` (e.g. `"[14/102]"`) for a frame
|
|
172
|
+
* it is drawn in, which a `Panel`'s `bottomRightAccessory` function
|
|
173
|
+
* hands it, to display in the border. Useful when the surrounding
|
|
174
|
+
* chrome should carry the indicator so widget content area stays
|
|
175
|
+
* untouched.
|
|
170
176
|
* - `"none"`: no indicator at all.
|
|
171
177
|
*/
|
|
172
178
|
scrollIndicator?: "arrows" | "indices" | "none";
|
|
@@ -192,6 +198,7 @@ export declare class TextInput extends ThemedWidget {
|
|
|
192
198
|
readonly focusable = true;
|
|
193
199
|
private accessor _value;
|
|
194
200
|
private accessor _cursor;
|
|
201
|
+
private accessor _blinkFrom;
|
|
195
202
|
get value(): string;
|
|
196
203
|
set value(v: string);
|
|
197
204
|
get cursorPosition(): CodePoint;
|
|
@@ -209,35 +216,23 @@ export declare class TextInput extends ThemedWidget {
|
|
|
209
216
|
accessor indicatorStyleOverride: Style | undefined;
|
|
210
217
|
accessor cursorStyleOverride: Style | undefined;
|
|
211
218
|
accessor contentStyleOverride: Style | undefined;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
* back to logical-line motion in that case.
|
|
217
|
-
*
|
|
218
|
-
* [LAW:dataflow-not-control-flow] One source of truth for "what does Up
|
|
219
|
-
* mean right now": the row table the renderer just produced. No parallel
|
|
220
|
-
* "where would the cursor go" math; both the renderer and the keymap
|
|
221
|
-
* read from the same array.
|
|
222
|
-
*/
|
|
223
|
-
private _visualRows;
|
|
224
|
-
private _preferredColumn;
|
|
225
|
-
private _killBuffer;
|
|
226
|
-
private _scrollStart;
|
|
227
|
-
private _singleLineViewportStart;
|
|
228
|
-
private _singleLineAsciiOnly;
|
|
219
|
+
private readonly _preferredColumn;
|
|
220
|
+
private readonly _killBuffer;
|
|
221
|
+
private readonly _drawn;
|
|
222
|
+
private readonly _viewport;
|
|
229
223
|
readonly multiline: boolean;
|
|
230
224
|
constructor(options?: TextInputOptions);
|
|
231
225
|
handleKey(event: KeyEvent): void;
|
|
226
|
+
handleFocus(event: WidgetFocusEvent): void;
|
|
227
|
+
private _edit;
|
|
232
228
|
handleMouse(event: WidgetMouseEvent): void;
|
|
233
229
|
setHovered(value: boolean): void;
|
|
234
230
|
moveCharLeft(): void;
|
|
235
231
|
moveCharRight(): void;
|
|
236
232
|
moveLineUp(): void;
|
|
237
233
|
moveLineDown(): void;
|
|
234
|
+
private _moveLine;
|
|
238
235
|
private _clampColForRow;
|
|
239
|
-
private _cursorVisualRow;
|
|
240
|
-
private _cursorVisualCol;
|
|
241
236
|
moveLineStart(): void;
|
|
242
237
|
moveLineEnd(): void;
|
|
243
238
|
moveDocStart(): void;
|
|
@@ -257,27 +252,38 @@ export declare class TextInput extends ThemedWidget {
|
|
|
257
252
|
private _insertText;
|
|
258
253
|
protected get ground(): Style;
|
|
259
254
|
protected draw(options: RenderOptions): Iterable<Segment>;
|
|
255
|
+
private _shownAs;
|
|
260
256
|
private _shown;
|
|
257
|
+
private _shownCells;
|
|
258
|
+
private _offsetAtShownCell;
|
|
259
|
+
private _singleLine;
|
|
260
|
+
private _showsPlaceholder;
|
|
261
261
|
private _renderSingleLine;
|
|
262
262
|
private _renderMultiline;
|
|
263
|
+
private _caret;
|
|
264
|
+
private _drawsArrows;
|
|
263
265
|
private _emitRowContent;
|
|
264
|
-
private
|
|
265
|
-
measure(
|
|
266
|
+
private _rows;
|
|
267
|
+
measure(options: RenderOptions): {
|
|
266
268
|
minimum: number;
|
|
267
269
|
maximum: number;
|
|
268
270
|
};
|
|
269
271
|
/**
|
|
270
272
|
* `[X/Y]` scroll-position string when there's actually something to
|
|
271
273
|
* scroll, else `undefined`. X is the cursor's 1-indexed visual row; Y is
|
|
272
|
-
* the total visual row count.
|
|
273
|
-
*
|
|
274
|
-
*
|
|
274
|
+
* the total visual row count. Hand it a frame this field is drawn in — a
|
|
275
|
+
* `Panel`'s `bottomRightAccessory` function is handed its body's:
|
|
276
|
+
*
|
|
277
|
+
* bottomRightAccessory: (body) => input.scrollIndicatorText(body)
|
|
278
|
+
*
|
|
279
|
+
* It counts the rows that frame laid out, read off the field's own cells, so
|
|
280
|
+
* it is right on the frame it labels however deep the field sits in it.
|
|
275
281
|
*
|
|
276
282
|
* Returns `undefined` when:
|
|
277
283
|
* - `scrollIndicator` is not `"indices"`, or
|
|
278
284
|
* - `maxRows` is unset, or total visual rows ≤ maxRows (nothing to
|
|
279
285
|
* scroll), or
|
|
280
|
-
* -
|
|
286
|
+
* - `frame` shows none of the field's rows (a width too narrow to draw it).
|
|
281
287
|
*/
|
|
282
|
-
|
|
288
|
+
scrollIndicatorText(frame: readonly (readonly Segment[])[]): string | undefined;
|
|
283
289
|
}
|