@promptctl/rich-js 0.24.1 → 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.
Files changed (156) hide show
  1. package/README.md +7 -0
  2. package/dist/core/anchor.d.ts +5 -0
  3. package/dist/core/anchor.js +11 -4
  4. package/dist/core/animation.d.ts +175 -10
  5. package/dist/core/animation.js +283 -15
  6. package/dist/core/ansi.js +2 -2
  7. package/dist/core/box.d.ts +7 -7
  8. package/dist/core/cells.d.ts +23 -13
  9. package/dist/core/cells.js +58 -48
  10. package/dist/core/clock.d.ts +2 -2
  11. package/dist/core/clock.js +6 -4
  12. package/dist/core/color.d.ts +27 -10
  13. package/dist/core/color.js +21 -29
  14. package/dist/core/console.d.ts +28 -17
  15. package/dist/core/console.js +44 -39
  16. package/dist/core/easing.d.ts +30 -0
  17. package/dist/core/easing.js +65 -20
  18. package/dist/core/emoji.d.ts +1 -1
  19. package/dist/core/emoji.js +1 -2
  20. package/dist/core/export-html.js +2 -1
  21. package/dist/core/export-lines.js +3 -3
  22. package/dist/core/highlighter.d.ts +9 -8
  23. package/dist/core/highlighter.js +3 -2
  24. package/dist/core/json.js +2 -2
  25. package/dist/core/markup.js +16 -12
  26. package/dist/core/measure.js +2 -2
  27. package/dist/core/memo.d.ts +11 -2
  28. package/dist/core/memo.js +16 -0
  29. package/dist/core/oklch.js +17 -6
  30. package/dist/core/osc8.d.ts +1 -1
  31. package/dist/core/osc8.js +4 -5
  32. package/dist/core/paint.d.ts +2 -1
  33. package/dist/core/paint.js +4 -3
  34. package/dist/core/pattern.d.ts +21 -0
  35. package/dist/core/pattern.js +21 -0
  36. package/dist/core/pretty.js +9 -10
  37. package/dist/core/protocol.d.ts +100 -39
  38. package/dist/core/protocol.js +167 -21
  39. package/dist/core/render.d.ts +15 -2
  40. package/dist/core/render.js +25 -5
  41. package/dist/core/segment.d.ts +13 -5
  42. package/dist/core/segment.js +23 -9
  43. package/dist/core/spinnerData.d.ts +1 -1
  44. package/dist/core/state.d.ts +53 -0
  45. package/dist/core/state.js +82 -0
  46. package/dist/core/strip.d.ts +13 -16
  47. package/dist/core/strip.js +119 -110
  48. package/dist/core/style.d.ts +47 -14
  49. package/dist/core/style.js +57 -28
  50. package/dist/core/text.d.ts +5 -8
  51. package/dist/core/text.js +116 -124
  52. package/dist/core/timeline.d.ts +30 -5
  53. package/dist/core/timeline.js +43 -7
  54. package/dist/core/tween.d.ts +1 -1
  55. package/dist/core/tween.js +5 -3
  56. package/dist/core/view.d.ts +92 -0
  57. package/dist/core/view.js +83 -0
  58. package/dist/host/app.d.ts +49 -21
  59. package/dist/host/app.js +71 -37
  60. package/dist/host/input.js +3 -4
  61. package/dist/index.d.ts +24 -12
  62. package/dist/index.js +9 -4
  63. package/dist/node/traceback.js +4 -3
  64. package/dist/renderables/align.d.ts +2 -3
  65. package/dist/renderables/align.js +0 -3
  66. package/dist/renderables/change.d.ts +42 -0
  67. package/dist/renderables/change.js +112 -0
  68. package/dist/renderables/columns.d.ts +3 -4
  69. package/dist/renderables/columns.js +2 -7
  70. package/dist/renderables/constrain.d.ts +2 -3
  71. package/dist/renderables/constrain.js +0 -3
  72. package/dist/renderables/effect.d.ts +132 -54
  73. package/dist/renderables/effect.js +188 -115
  74. package/dist/renderables/effects.d.ts +122 -11
  75. package/dist/renderables/effects.js +238 -94
  76. package/dist/renderables/embed.d.ts +1 -1
  77. package/dist/renderables/embed.js +16 -8
  78. package/dist/renderables/flexStrip.d.ts +2 -3
  79. package/dist/renderables/flexStrip.js +0 -4
  80. package/dist/renderables/frames.d.ts +35 -54
  81. package/dist/renderables/frames.js +43 -58
  82. package/dist/renderables/glyph-effect.d.ts +158 -0
  83. package/dist/renderables/glyph-effect.js +237 -0
  84. package/dist/renderables/glyph-effects.d.ts +147 -0
  85. package/dist/renderables/glyph-effects.js +283 -0
  86. package/dist/renderables/group.d.ts +3 -4
  87. package/dist/renderables/group.js +0 -3
  88. package/dist/renderables/layout.d.ts +12 -12
  89. package/dist/renderables/layout.js +40 -46
  90. package/dist/renderables/lifecycle.d.ts +77 -0
  91. package/dist/renderables/lifecycle.js +132 -0
  92. package/dist/renderables/list-view.d.ts +4 -5
  93. package/dist/renderables/list-view.js +9 -13
  94. package/dist/renderables/live.d.ts +36 -21
  95. package/dist/renderables/live.js +88 -41
  96. package/dist/renderables/markdown-parse.d.ts +4 -4
  97. package/dist/renderables/markdown-parse.js +52 -46
  98. package/dist/renderables/markdown-url.js +11 -11
  99. package/dist/renderables/padding.d.ts +4 -5
  100. package/dist/renderables/padding.js +0 -3
  101. package/dist/renderables/panel.d.ts +14 -16
  102. package/dist/renderables/panel.js +6 -14
  103. package/dist/renderables/progress.d.ts +83 -34
  104. package/dist/renderables/progress.js +182 -95
  105. package/dist/renderables/progressBar.d.ts +22 -12
  106. package/dist/renderables/progressBar.js +32 -9
  107. package/dist/renderables/prompt.js +3 -2
  108. package/dist/renderables/python-space.js +2 -1
  109. package/dist/renderables/scroll.d.ts +50 -0
  110. package/dist/renderables/scroll.js +106 -0
  111. package/dist/renderables/spinner.d.ts +35 -14
  112. package/dist/renderables/spinner.js +65 -25
  113. package/dist/renderables/status.js +1 -1
  114. package/dist/renderables/syntax.d.ts +10 -9
  115. package/dist/renderables/syntax.js +3 -2
  116. package/dist/renderables/table.d.ts +34 -40
  117. package/dist/renderables/table.js +41 -63
  118. package/dist/renderables/traceback.d.ts +2 -2
  119. package/dist/renderables/traceback.js +6 -5
  120. package/dist/renderables/tree.d.ts +27 -25
  121. package/dist/renderables/tree.js +104 -58
  122. package/dist/renderables/viewport.d.ts +75 -44
  123. package/dist/renderables/viewport.js +145 -82
  124. package/dist/template-bindings/animation-funcs.d.ts +78 -9
  125. package/dist/template-bindings/animation-funcs.js +132 -14
  126. package/dist/template-bindings/index.d.ts +5 -5
  127. package/dist/template-bindings/index.js +5 -5
  128. package/dist/themes/ramp.d.ts +46 -3
  129. package/dist/themes/ramp.js +61 -4
  130. package/dist/themes/registry.js +5 -7
  131. package/dist/widgets/button.js +3 -2
  132. package/dist/widgets/checkbox.js +4 -3
  133. package/dist/widgets/dropdown.d.ts +3 -1
  134. package/dist/widgets/dropdown.js +20 -15
  135. package/dist/widgets/event-router.js +4 -2
  136. package/dist/widgets/focus-manager.d.ts +2 -0
  137. package/dist/widgets/focus-manager.js +6 -4
  138. package/dist/widgets/hit.d.ts +6 -0
  139. package/dist/widgets/hit.js +8 -1
  140. package/dist/widgets/observable.d.ts +23 -0
  141. package/dist/widgets/observable.js +43 -0
  142. package/dist/widgets/slider.d.ts +1 -1
  143. package/dist/widgets/slider.js +12 -3
  144. package/dist/widgets/static-item.d.ts +2 -3
  145. package/dist/widgets/static-item.js +0 -3
  146. package/dist/widgets/text-input.d.ts +28 -32
  147. package/dist/widgets/text-input.js +360 -346
  148. package/dist/widgets/themed-widget.js +2 -1
  149. package/dist/widgets/toggle.js +4 -3
  150. package/dist/widgets/types.d.ts +10 -4
  151. package/dist/widgets/types.js +8 -2
  152. package/dist/widgets/widget-app.d.ts +14 -4
  153. package/dist/widgets/widget-app.js +36 -7
  154. package/dist/widgets/widget-base.d.ts +2 -2
  155. package/dist/widgets/widget-base.js +29 -18
  156. package/package.json +8 -1
@@ -38,7 +38,8 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
38
38
  if (target) Object.defineProperty(target, contextIn.name, descriptor);
39
39
  done = true;
40
40
  };
41
- import { action, observableRef } from "mobx";
41
+ import { action } from "mobx";
42
+ import { observableRef } from "./observable.js";
42
43
  let DefaultFocusManager = (() => {
43
44
  let _instanceExtraInitializers = [];
44
45
  let _currentWidget_decorators;
@@ -162,7 +163,7 @@ let DefaultFocusManager = (() => {
162
163
  // [LAW:single-enforcer] WidgetBase.focus()/blur() route through
163
164
  // handleFocus; calling it here as well would dispatch twice and run any
164
165
  // subclass side effect (e.g. Dropdown clearing its filter) twice.
165
- this.currentWidget.blur();
166
+ this.currentWidget.blur(this.view.frameTime());
166
167
  this.currentWidget = null;
167
168
  this.emitChange();
168
169
  }
@@ -171,10 +172,11 @@ let DefaultFocusManager = (() => {
171
172
  return;
172
173
  // [LAW:single-enforcer] focus()/blur() already dispatch handleFocus —
173
174
  // see clear() for the rationale.
175
+ const time = this.view.frameTime();
174
176
  if (this.currentWidget)
175
- this.currentWidget.blur();
177
+ this.currentWidget.blur(time);
176
178
  this.currentWidget = widget;
177
- widget.focus();
179
+ widget.focus(time);
178
180
  this.emitChange();
179
181
  }
180
182
  emitChange() {
@@ -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
@@ -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
@@ -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
+ }
@@ -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;
@@ -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 { observable, action, observableRef } from "mobx";
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 = [observable];
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
- _dragging = (__runInitializers(this, _width_extraInitializers), false);
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;
@@ -11,7 +11,7 @@
11
11
  * renderable.
12
12
  */
13
13
  import { Segment } from "../core/segment.js";
14
- import type { Composite, Measurable, Renderable, RenderOptions } from "../core/protocol.js";
14
+ import type { Measurable, Renderable, RenderOptions } from "../core/protocol.js";
15
15
  import { WidgetBase } from "./widget-base.js";
16
16
  import type { KeyEvent } from "./types.js";
17
17
  export interface StaticItemOptions {
@@ -19,13 +19,12 @@ export interface StaticItemOptions {
19
19
  render: Renderable | ((options: RenderOptions) => Iterable<Segment>);
20
20
  measure?: Measurable["measure"];
21
21
  }
22
- export declare class StaticItem extends WidgetBase implements Composite {
22
+ export declare class StaticItem extends WidgetBase {
23
23
  readonly id: string;
24
24
  readonly focusable = false;
25
25
  private readonly body;
26
26
  private readonly measureFn;
27
27
  constructor(options: StaticItemOptions);
28
- contents(): Iterable<Renderable>;
29
28
  handleKey(_event: KeyEvent): void;
30
29
  protected draw(options: RenderOptions): Iterable<Segment>;
31
30
  measure(options: RenderOptions): {
@@ -26,9 +26,6 @@ export class StaticItem extends WidgetBase {
26
26
  this.body = typeof r === "function" ? { render: r } : r;
27
27
  this.measureFn = options.measure;
28
28
  }
29
- *contents() {
30
- yield this.body;
31
- }
32
29
  // Static items don't respond to keys. WidgetBase.handleMouse / handleFocus
33
30
  // are already no-ops, so we only need to satisfy the abstract handleKey.
34
31
  handleKey(_event) { }
@@ -68,7 +68,7 @@ import { type CellCol, type CodePoint, type CodeUnit } from "../core/cells.js";
68
68
  import { type RenderOptions } from "../core/protocol.js";
69
69
  import type { TerminalTheme } from "../core/color.js";
70
70
  import { ThemedWidget } from "./themed-widget.js";
71
- import type { KeyEvent, WidgetMouseEvent } from "./types.js";
71
+ import type { KeyEvent, WidgetFocusEvent, WidgetMouseEvent } from "./types.js";
72
72
  /**
73
73
  * A soft-wrap strategy. Given one logical line of text and cell-width budgets,
74
74
  * return the visual sub-rows that line wraps into. The line arrives as the
@@ -111,7 +111,7 @@ export interface WrapRow {
111
111
  *
112
112
  * Wide characters (CJK, emoji) are treated as atomic: a char that would
113
113
  * straddle the budget is moved to the next row rather than split, and one too
114
- * wide for the whole budget is force-taken — see `cellStepFrom`.
114
+ * wide for the whole budget is force-taken — see `cellRows`.
115
115
  */
116
116
  export declare const charGreedyWrap: WrapStrategy;
117
117
  export interface TextInputOptions {
@@ -168,10 +168,11 @@ export interface TextInputOptions {
168
168
  * area on the first/last visible row when scroll is possible in that
169
169
  * direction. Fully self-contained — host needs no wiring.
170
170
  * - `"indices"`: the widget suppresses in-content arrows and instead
171
- * publishes `scrollIndicatorText` (e.g. `"[14/102]"`) for the host
172
- * (typically a `Panel`'s `bottomRightAccessory`) to display in the
173
- * border. Useful when the surrounding chrome should carry the
174
- * indicator so widget content area stays untouched.
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.
175
176
  * - `"none"`: no indicator at all.
176
177
  */
177
178
  scrollIndicator?: "arrows" | "indices" | "none";
@@ -197,6 +198,7 @@ export declare class TextInput extends ThemedWidget {
197
198
  readonly focusable = true;
198
199
  private accessor _value;
199
200
  private accessor _cursor;
201
+ private accessor _blinkFrom;
200
202
  get value(): string;
201
203
  set value(v: string);
202
204
  get cursorPosition(): CodePoint;
@@ -214,35 +216,23 @@ export declare class TextInput extends ThemedWidget {
214
216
  accessor indicatorStyleOverride: Style | undefined;
215
217
  accessor cursorStyleOverride: Style | undefined;
216
218
  accessor contentStyleOverride: Style | undefined;
217
- /**
218
- * Last computed visual-row decomposition. Cached at the end of `render()`
219
- * so vertical motion (Up/Down) can step row-by-row without re-running the
220
- * wrap strategy. Null before the first render — vertical motion falls
221
- * back to logical-line motion in that case.
222
- *
223
- * [LAW:dataflow-not-control-flow] One source of truth for "what does Up
224
- * mean right now": the row table the renderer just produced. No parallel
225
- * "where would the cursor go" math; both the renderer and the keymap
226
- * read from the same array.
227
- */
228
- private _visualRows;
229
- private _preferredColumn;
230
- private _killBuffer;
231
- private _scrollStart;
232
- private _singleLineViewportStart;
233
- private _drawn;
219
+ private readonly _preferredColumn;
220
+ private readonly _killBuffer;
221
+ private readonly _drawn;
222
+ private readonly _viewport;
234
223
  readonly multiline: boolean;
235
224
  constructor(options?: TextInputOptions);
236
225
  handleKey(event: KeyEvent): void;
226
+ handleFocus(event: WidgetFocusEvent): void;
227
+ private _edit;
237
228
  handleMouse(event: WidgetMouseEvent): void;
238
229
  setHovered(value: boolean): void;
239
230
  moveCharLeft(): void;
240
231
  moveCharRight(): void;
241
232
  moveLineUp(): void;
242
233
  moveLineDown(): void;
234
+ private _moveLine;
243
235
  private _clampColForRow;
244
- private _cursorVisualRow;
245
- private _cursorVisualCol;
246
236
  moveLineStart(): void;
247
237
  moveLineEnd(): void;
248
238
  moveDocStart(): void;
@@ -266,11 +256,14 @@ export declare class TextInput extends ThemedWidget {
266
256
  private _shown;
267
257
  private _shownCells;
268
258
  private _offsetAtShownCell;
259
+ private _singleLine;
260
+ private _showsPlaceholder;
269
261
  private _renderSingleLine;
270
262
  private _renderMultiline;
263
+ private _caret;
271
264
  private _drawsArrows;
272
265
  private _emitRowContent;
273
- private _computeVisualRows;
266
+ private _rows;
274
267
  measure(options: RenderOptions): {
275
268
  minimum: number;
276
269
  maximum: number;
@@ -278,16 +271,19 @@ export declare class TextInput extends ThemedWidget {
278
271
  /**
279
272
  * `[X/Y]` scroll-position string when there's actually something to
280
273
  * scroll, else `undefined`. X is the cursor's 1-indexed visual row; Y is
281
- * the total visual row count. Reads cached state populated by the most
282
- * recent `render()` — call from a `Panel.bottomRightAccessory` thunk so
283
- * it evaluates after content has been rendered for the current frame;
284
- * `BorderAccessory` names the widths where it has not.
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.
285
281
  *
286
282
  * Returns `undefined` when:
287
283
  * - `scrollIndicator` is not `"indices"`, or
288
284
  * - `maxRows` is unset, or total visual rows ≤ maxRows (nothing to
289
285
  * scroll), or
290
- * - no render has happened yet (cache is empty).
286
+ * - `frame` shows none of the field's rows (a width too narrow to draw it).
291
287
  */
292
- get scrollIndicatorText(): string | undefined;
288
+ scrollIndicatorText(frame: readonly (readonly Segment[])[]): string | undefined;
293
289
  }