@promptctl/rich-js 0.18.1 → 0.20.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 (169) hide show
  1. package/README.md +11 -8
  2. package/dist/core/box.d.ts +3 -1
  3. package/dist/core/box.js +6 -13
  4. package/dist/core/cells.d.ts +61 -28
  5. package/dist/core/cells.js +171 -124
  6. package/dist/core/clock.d.ts +48 -0
  7. package/dist/core/clock.js +42 -0
  8. package/dist/core/color.d.ts +99 -18
  9. package/dist/core/color.js +334 -146
  10. package/dist/core/console.d.ts +38 -7
  11. package/dist/core/console.js +159 -90
  12. package/dist/core/easing.d.ts +86 -0
  13. package/dist/core/easing.js +171 -0
  14. package/dist/core/env.d.ts +16 -0
  15. package/dist/core/env.js +16 -0
  16. package/dist/core/export-html.js +1 -4
  17. package/dist/core/export-lines.d.ts +22 -13
  18. package/dist/core/export-lines.js +37 -19
  19. package/dist/core/export-svg.d.ts +49 -0
  20. package/dist/core/export-svg.js +213 -0
  21. package/dist/core/fnv1a.d.ts +10 -0
  22. package/dist/core/fnv1a.js +17 -0
  23. package/dist/core/highlighter.d.ts +2 -2
  24. package/dist/core/highlighter.js +113 -47
  25. package/dist/core/json.js +1 -1
  26. package/dist/core/markup.d.ts +28 -7
  27. package/dist/core/markup.js +235 -312
  28. package/dist/core/measure.d.ts +3 -3
  29. package/dist/core/measure.js +12 -7
  30. package/dist/core/memo.d.ts +19 -0
  31. package/dist/core/memo.js +34 -0
  32. package/dist/core/noise.d.ts +31 -0
  33. package/dist/core/noise.js +94 -0
  34. package/dist/core/osc8.d.ts +6 -6
  35. package/dist/core/osc8.js +9 -21
  36. package/dist/core/paint.d.ts +107 -0
  37. package/dist/core/paint.js +161 -0
  38. package/dist/core/place.d.ts +1 -1
  39. package/dist/core/place.js +4 -6
  40. package/dist/core/pretty.d.ts +126 -2
  41. package/dist/core/pretty.js +571 -105
  42. package/dist/core/protocol.d.ts +43 -3
  43. package/dist/core/protocol.js +23 -2
  44. package/dist/core/render.d.ts +33 -30
  45. package/dist/core/render.js +43 -83
  46. package/dist/core/segment.d.ts +6 -5
  47. package/dist/core/segment.js +11 -15
  48. package/dist/core/selection.d.ts +12 -0
  49. package/dist/core/selection.js +14 -0
  50. package/dist/core/strip.d.ts +116 -74
  51. package/dist/core/strip.js +266 -217
  52. package/dist/core/style.d.ts +27 -7
  53. package/dist/core/style.js +106 -41
  54. package/dist/core/text.d.ts +43 -16
  55. package/dist/core/text.js +180 -59
  56. package/dist/core/wrap.d.ts +5 -0
  57. package/dist/core/wrap.js +16 -3
  58. package/dist/host/app.d.ts +95 -17
  59. package/dist/host/app.js +201 -61
  60. package/dist/host/index.d.ts +4 -1
  61. package/dist/host/index.js +1 -0
  62. package/dist/host/input.d.ts +84 -0
  63. package/dist/host/input.js +498 -0
  64. package/dist/host/terminal-host.d.ts +15 -2
  65. package/dist/host/terminal-host.js +2 -0
  66. package/dist/index.d.ts +26 -14
  67. package/dist/index.js +17 -7
  68. package/dist/node/prompt.d.ts +13 -0
  69. package/dist/node/prompt.js +30 -9
  70. package/dist/node/save.d.ts +4 -3
  71. package/dist/node/save.js +6 -3
  72. package/dist/node/terminal-host.d.ts +10 -2
  73. package/dist/node/terminal-host.js +7 -0
  74. package/dist/node/traceback.d.ts +2 -1
  75. package/dist/node/traceback.js +3 -39
  76. package/dist/renderables/align.js +2 -9
  77. package/dist/renderables/columns.d.ts +45 -29
  78. package/dist/renderables/columns.js +142 -103
  79. package/dist/renderables/constrain.js +6 -12
  80. package/dist/renderables/effect.d.ts +113 -0
  81. package/dist/renderables/effect.js +182 -0
  82. package/dist/renderables/effects.d.ts +252 -0
  83. package/dist/renderables/effects.js +565 -0
  84. package/dist/renderables/embed.d.ts +94 -31
  85. package/dist/renderables/embed.js +141 -45
  86. package/dist/renderables/group.d.ts +6 -3
  87. package/dist/renderables/group.js +5 -0
  88. package/dist/renderables/layout.d.ts +6 -23
  89. package/dist/renderables/layout.js +24 -113
  90. package/dist/renderables/list-view.d.ts +42 -0
  91. package/dist/renderables/list-view.js +78 -0
  92. package/dist/renderables/live.d.ts +40 -16
  93. package/dist/renderables/live.js +96 -83
  94. package/dist/renderables/markdown.d.ts +16 -2
  95. package/dist/renderables/markdown.js +521 -118
  96. package/dist/renderables/padding.d.ts +22 -1
  97. package/dist/renderables/padding.js +30 -24
  98. package/dist/renderables/panel.d.ts +31 -33
  99. package/dist/renderables/panel.js +137 -141
  100. package/dist/renderables/progress.d.ts +110 -16
  101. package/dist/renderables/progress.js +212 -81
  102. package/dist/renderables/progressBar.d.ts +24 -4
  103. package/dist/renderables/progressBar.js +78 -23
  104. package/dist/renderables/prompt.d.ts +37 -15
  105. package/dist/renderables/prompt.js +125 -85
  106. package/dist/renderables/ratio.d.ts +123 -0
  107. package/dist/renderables/ratio.js +213 -0
  108. package/dist/renderables/rule.d.ts +3 -2
  109. package/dist/renderables/rule.js +50 -52
  110. package/dist/renderables/spinner.d.ts +28 -2
  111. package/dist/renderables/spinner.js +52 -19
  112. package/dist/renderables/status.d.ts +13 -7
  113. package/dist/renderables/status.js +15 -29
  114. package/dist/renderables/syntax.d.ts +37 -7
  115. package/dist/renderables/syntax.js +134 -83
  116. package/dist/renderables/table.d.ts +58 -20
  117. package/dist/renderables/table.js +373 -197
  118. package/dist/renderables/traceback.d.ts +5 -4
  119. package/dist/renderables/traceback.js +239 -68
  120. package/dist/renderables/tree.d.ts +10 -2
  121. package/dist/renderables/tree.js +61 -34
  122. package/dist/renderables/viewport.d.ts +30 -0
  123. package/dist/renderables/viewport.js +61 -7
  124. package/dist/template-bindings/color-funcs.d.ts +31 -9
  125. package/dist/template-bindings/color-funcs.js +40 -14
  126. package/dist/template-bindings/helpers.d.ts +4 -2
  127. package/dist/template-bindings/helpers.js +5 -20
  128. package/dist/template-bindings/index.d.ts +29 -17
  129. package/dist/template-bindings/index.js +36 -20
  130. package/dist/template-bindings/palette-funcs.d.ts +3 -1
  131. package/dist/template-bindings/palette-funcs.js +11 -7
  132. package/dist/template-bindings/style-funcs.js +4 -2
  133. package/dist/themes/buildPalette.d.ts +24 -3
  134. package/dist/themes/buildPalette.js +52 -8
  135. package/dist/themes/colorMath.d.ts +29 -17
  136. package/dist/themes/colorMath.js +74 -48
  137. package/dist/themes/colorRef.d.ts +2 -17
  138. package/dist/themes/colorRef.js +13 -31
  139. package/dist/themes/palette.d.ts +24 -0
  140. package/dist/themes/palette.js +46 -3
  141. package/dist/themes/ramp.d.ts +21 -34
  142. package/dist/themes/ramp.js +23 -42
  143. package/dist/themes/registry.js +39 -28
  144. package/dist/widgets/button.d.ts +2 -6
  145. package/dist/widgets/button.js +9 -40
  146. package/dist/widgets/checkbox.d.ts +2 -5
  147. package/dist/widgets/checkbox.js +9 -31
  148. package/dist/widgets/dropdown.d.ts +2 -5
  149. package/dist/widgets/dropdown.js +17 -51
  150. package/dist/widgets/event-router.d.ts +31 -40
  151. package/dist/widgets/event-router.js +52 -483
  152. package/dist/widgets/index.d.ts +2 -1
  153. package/dist/widgets/ink.d.ts +22 -0
  154. package/dist/widgets/ink.js +31 -0
  155. package/dist/widgets/slider.d.ts +2 -5
  156. package/dist/widgets/slider.js +11 -34
  157. package/dist/widgets/text-input.d.ts +19 -10
  158. package/dist/widgets/text-input.js +156 -147
  159. package/dist/widgets/themed-widget.d.ts +20 -0
  160. package/dist/widgets/themed-widget.js +89 -0
  161. package/dist/widgets/toggle.d.ts +2 -5
  162. package/dist/widgets/toggle.js +8 -31
  163. package/dist/widgets/types.d.ts +8 -25
  164. package/dist/widgets/types.js +8 -0
  165. package/dist/widgets/widget-app.d.ts +24 -7
  166. package/dist/widgets/widget-app.js +35 -18
  167. package/dist/widgets/widget-base.d.ts +2 -0
  168. package/dist/widgets/widget-base.js +9 -2
  169. package/package.json +31 -17
@@ -56,16 +56,16 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
56
56
  if (target) Object.defineProperty(target, contextIn.name, descriptor);
57
57
  done = true;
58
58
  };
59
- import { observable, action, observableRef, observableShallow } from "mobx";
59
+ import { observable, action, observableShallow } from "mobx";
60
60
  import { Segment } from "../core/segment.js";
61
61
  import { Style } from "../core/style.js";
62
- import { ColorSpec } from "../core/color.js";
63
62
  import { cellLen, setCellSize, splitText, asCellCol } from "../core/cells.js";
64
- import { DEFAULT_TERMINAL_THEME } from "../themes/terminalThemes.js";
65
63
  import { drawable } from "../core/protocol.js";
66
- import { WidgetBase } from "./widget-base.js";
64
+ import { moveSelection } from "../core/selection.js";
65
+ import { ThemedWidget } from "./themed-widget.js";
66
+ import { ink } from "./ink.js";
67
67
  let Dropdown = (() => {
68
- let _classSuper = WidgetBase;
68
+ let _classSuper = ThemedWidget;
69
69
  let _instanceExtraInitializers = [];
70
70
  let _options_decorators;
71
71
  let _options_initializers = [];
@@ -82,10 +82,6 @@ let Dropdown = (() => {
82
82
  let _filter_decorators;
83
83
  let _filter_initializers = [];
84
84
  let _filter_extraInitializers = [];
85
- let __theme_decorators;
86
- let __theme_initializers = [];
87
- let __theme_extraInitializers = [];
88
- let _setTheme_decorators;
89
85
  let _handleKey_decorators;
90
86
  let _handleMouse_decorators;
91
87
  let _handleFocus_decorators;
@@ -97,8 +93,6 @@ let Dropdown = (() => {
97
93
  _expanded_decorators = [observable];
98
94
  _highlightedIndex_decorators = [observable];
99
95
  _filter_decorators = [observable];
100
- __theme_decorators = [observableRef];
101
- _setTheme_decorators = [action];
102
96
  _handleKey_decorators = [action];
103
97
  _handleMouse_decorators = [action];
104
98
  _handleFocus_decorators = [action];
@@ -107,8 +101,6 @@ let Dropdown = (() => {
107
101
  __esDecorate(this, null, _expanded_decorators, { kind: "accessor", name: "expanded", static: false, private: false, access: { has: obj => "expanded" in obj, get: obj => obj.expanded, set: (obj, value) => { obj.expanded = value; } }, metadata: _metadata }, _expanded_initializers, _expanded_extraInitializers);
108
102
  __esDecorate(this, null, _highlightedIndex_decorators, { kind: "accessor", name: "highlightedIndex", static: false, private: false, access: { has: obj => "highlightedIndex" in obj, get: obj => obj.highlightedIndex, set: (obj, value) => { obj.highlightedIndex = value; } }, metadata: _metadata }, _highlightedIndex_initializers, _highlightedIndex_extraInitializers);
109
103
  __esDecorate(this, null, _filter_decorators, { kind: "accessor", name: "filter", static: false, private: false, access: { has: obj => "filter" in obj, get: obj => obj.filter, set: (obj, value) => { obj.filter = value; } }, metadata: _metadata }, _filter_initializers, _filter_extraInitializers);
110
- __esDecorate(this, null, __theme_decorators, { kind: "accessor", name: "_theme", static: false, private: false, access: { has: obj => "_theme" in obj, get: obj => obj._theme, set: (obj, value) => { obj._theme = value; } }, metadata: _metadata }, __theme_initializers, __theme_extraInitializers);
111
- __esDecorate(this, null, _setTheme_decorators, { kind: "method", name: "setTheme", static: false, private: false, access: { has: obj => "setTheme" in obj, get: obj => obj.setTheme }, metadata: _metadata }, null, _instanceExtraInitializers);
112
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);
113
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);
114
106
  __esDecorate(this, null, _handleFocus_decorators, { kind: "method", name: "handleFocus", static: false, private: false, access: { has: obj => "handleFocus" in obj, get: obj => obj.handleFocus }, metadata: _metadata }, null, _instanceExtraInitializers);
@@ -144,15 +136,9 @@ let Dropdown = (() => {
144
136
  }
145
137
  return result;
146
138
  }
147
- #_theme_accessor_storage = (__runInitializers(this, _filter_extraInitializers), __runInitializers(this, __theme_initializers, void 0));
148
- // [LAW:types-are-the-program] @observableRef so setTheme() triggers a
149
- // re-render — render() and resolvePalette() read _theme.palette, so the
150
- // theme reference must participate in MobX reactivity.
151
- get _theme() { return this.#_theme_accessor_storage; }
152
- set _theme(value) { this.#_theme_accessor_storage = value; }
153
139
  constructor(options) {
154
- super();
155
- __runInitializers(this, __theme_extraInitializers);
140
+ super(options.theme);
141
+ __runInitializers(this, _filter_extraInitializers);
156
142
  this.id = options.id ?? `dropdown-${Math.random().toString(36).slice(2, 8)}`;
157
143
  this.options = [...options.options];
158
144
  // [LAW:types-are-the-program] selectedIndex must point to a valid
@@ -163,7 +149,6 @@ let Dropdown = (() => {
163
149
  this.selectedIndex = this.clampIndex(options.selectedIndex ?? 0);
164
150
  this.highlightedIndex = this.selectedIndex;
165
151
  this.disabled = options.disabled ?? false;
166
- this._theme = options.theme ?? DEFAULT_TERMINAL_THEME;
167
152
  }
168
153
  // [LAW:single-enforcer] One place owns "is this index valid for the
169
154
  // current options". selectedIndex and options are public observables —
@@ -176,7 +161,6 @@ let Dropdown = (() => {
176
161
  return 0;
177
162
  return Math.max(0, Math.min(n, this.options.length - 1));
178
163
  }
179
- setTheme(theme) { this._theme = theme; }
180
164
  // --- Event handlers ---
181
165
  handleKey(event) {
182
166
  if (this.disabled)
@@ -206,12 +190,11 @@ let Dropdown = (() => {
206
190
  // expanded
207
191
  switch (event.key) {
208
192
  case "up":
209
- this.highlightedIndex = Math.max(0, this.highlightedIndex - 1);
193
+ this.highlightedIndex = moveSelection(this.highlightedIndex, -1, this.filteredOptions.length);
210
194
  event.stop();
211
195
  return;
212
196
  case "down": {
213
- const max = Math.max(0, this.filteredOptions.length - 1);
214
- this.highlightedIndex = Math.min(max, this.highlightedIndex + 1);
197
+ this.highlightedIndex = moveSelection(this.highlightedIndex, 1, this.filteredOptions.length);
215
198
  event.stop();
216
199
  return;
217
200
  }
@@ -322,10 +305,9 @@ let Dropdown = (() => {
322
305
  const caret = this.focused ? drawable(options, "│", "|") : "";
323
306
  const maxLabelLen = this.maxLabelLen();
324
307
  const baseStyle = this.disabled
325
- ? new Style({ color: "#666666", bgcolor: "#333333", dim: true })
308
+ ? new Style(this.disabledInk)
326
309
  : new Style({
327
- color: this.resolvePalette("foreground"),
328
- bgcolor: this.resolvePalette("surface"),
310
+ ...ink(this.theme, "foreground", "surface"),
329
311
  underline: this.focused,
330
312
  });
331
313
  const headerLabel = this.headerText(maxLabelLen, caret);
@@ -381,10 +363,9 @@ let Dropdown = (() => {
381
363
  const text = setCellSize("(no matches)", asCellCol(maxLabelLen));
382
364
  const inner = ` ${text} `;
383
365
  const style = this.disabled
384
- ? new Style({ color: "#666666", bgcolor: "#333333", dim: true })
366
+ ? new Style(this.disabledInk)
385
367
  : new Style({
386
- color: this.resolvePalette("foreground"),
387
- bgcolor: this.resolvePalette("surface"),
368
+ ...ink(this.theme, "foreground", "surface"),
388
369
  dim: true,
389
370
  });
390
371
  return [
@@ -405,21 +386,12 @@ let Dropdown = (() => {
405
386
  // Highlighted: muted bg → text-primary (mostly-accent fg) is readable.
406
387
  // Selected: full primary bg → on-primary (WCAG contrast) for fg.
407
388
  const rowStyle = this.disabled
408
- ? new Style({ color: "#666666", bgcolor: "#333333", dim: true })
389
+ ? new Style(this.disabledInk)
409
390
  : isHighlighted
410
- ? new Style({
411
- color: this.resolvePalette("text-primary"),
412
- bgcolor: this.resolvePalette("primary-muted"),
413
- })
391
+ ? new Style(ink(this.theme, "text-primary", "primary-muted"))
414
392
  : isSelected
415
- ? new Style({
416
- color: this.resolvePalette("on-primary"),
417
- bgcolor: this.resolvePalette("primary"),
418
- })
419
- : new Style({
420
- color: this.resolvePalette("foreground"),
421
- bgcolor: this.resolvePalette("surface"),
422
- });
393
+ ? new Style(ink(this.theme, "on-primary", "primary"))
394
+ : new Style(ink(this.theme, "foreground", "surface"));
423
395
  return [
424
396
  new Segment(" ", rowStyle),
425
397
  new Segment(inner, rowStyle),
@@ -439,12 +411,6 @@ let Dropdown = (() => {
439
411
  const width = this.maxLabelLen() + 4;
440
412
  return { minimum: width, maximum: width };
441
413
  }
442
- // --- Palette resolution ---
443
- resolvePalette(key) {
444
- const rgba = this._theme.palette.get(key);
445
- // [LAW:no-defensive-null-guards] palette must contain all keys.
446
- return ColorSpec.fromRgba(rgba);
447
- }
448
414
  };
449
415
  })();
450
416
  export { Dropdown };
@@ -1,49 +1,38 @@
1
1
  /**
2
- * EventRouter — parses raw stdin into KeyEvent / ScreenMouseEvent values
3
- * and dispatches them to widgets via a FocusManager and the frame on screen.
2
+ * EventRouter — dispatches the keys and pointer events an `App` hears to
3
+ * widgets, via a FocusManager and the frame on screen.
4
4
  *
5
- * It reads the terminal and never sets it up: raw mode and mouse tracking are
6
- * the runtime's (`App`), which undoes them on every path out.
7
- *
8
- * [LAW:single-enforcer] ANSI escape parsing lives only here — widgets never
9
- * see raw bytes. One parser, one dispatch surface.
10
- *
11
- * [LAW:dataflow-not-control-flow] The same parse pipeline runs for every
12
- * input chunk: append → consume one event at a time until the buffer can't
13
- * yield more. The byte's value, not a side-mode, decides which event is
14
- * emitted. There is no "are we mid-sequence" mode flag — the buffer head
15
- * carries all the state we need.
16
- *
17
- * Lone-ESC handling: a bare `\x1b` is ambiguous (escape key vs. start of a
18
- * CSI sequence). When the buffer is drained but ends with a lone ESC, the
19
- * router defers emission via setTimeout(0). The next chunk cancels the timer
20
- * if it extends the sequence. Tests can call `flush()` to drain synchronously.
5
+ * It parses nothing and reads no terminal: `App` owns the one parser over its
6
+ * host's input (`host/input`), and `WidgetApp` hands this what the app hears.
21
7
  */
22
8
  import { KeyEvent } from "./types.js";
23
- import type { FrameSource, ScreenMouseEvent, KeyHandlerOptions } from "./types.js";
9
+ import type { FrameSource, KeyHandlerOptions } from "./types.js";
24
10
  import type { Unsubscribe } from "../core/subscription.js";
25
- import type { TerminalHost } from "../host/terminal-host.js";
11
+ import type { KeyPress } from "../host/input.js";
12
+ import type { AppMouseEvent } from "../host/app.js";
13
+ import type { Wheel } from "../host/app.js";
26
14
  type KeyHandler = (event: KeyEvent) => void;
27
15
  export interface EventRouterOptions {
28
16
  source: FrameSource;
29
- /** The I/O capability the router reads input from. */
30
- host: TerminalHost;
17
+ /** Whether a left-button press focuses the widget under it before it hears the press. */
18
+ focusOnClick: boolean;
31
19
  }
32
20
  export declare class EventRouter {
33
21
  private readonly source;
34
- private readonly host;
35
- private buffer;
36
- private running;
37
- private dataUnsubscribe;
38
- private escTimer;
22
+ private readonly focusOnClick;
39
23
  private captured;
40
24
  private pointer;
41
25
  private hoveredWidget;
42
26
  private readonly keyChain;
43
27
  private readonly mouseHandlers;
44
28
  constructor(options: EventRouterOptions);
45
- start(): void;
46
- stop(): void;
29
+ /**
30
+ * Drop what a run left behind — a captured drag, the pointer, hover — so the
31
+ * router is in the shape a fresh construction would be.
32
+ *
33
+ * [LAW:one-source-of-truth] Per-session state belongs to one session.
34
+ */
35
+ reset(): void;
47
36
  /**
48
37
  * Read hover again off the frame just painted: under a pointer that has not
49
38
  * moved, a widget may have gone, moved, or arrived.
@@ -53,17 +42,19 @@ export declare class EventRouter {
53
42
  */
54
43
  framePainted(): void;
55
44
  onKey(handler: KeyHandler, options?: KeyHandlerOptions): Unsubscribe;
56
- onMouse(handler: (event: ScreenMouseEvent) => void): Unsubscribe;
57
- /** Feed a chunk of bytes (or a string of bytes) into the parser. */
58
- feed(chunk: Uint8Array | string): void;
59
- /** Force any pending lone ESC out of the buffer. */
60
- flush(): void;
61
- private drain;
62
- private consumeOne;
63
- private consumePrintable;
64
- private consumeEscape;
65
- private consumeSS3;
66
- private consumeCSI;
45
+ onMouse(handler: (event: AppMouseEvent) => void): Unsubscribe;
46
+ /** Route a key the app heard. */
47
+ key(press: KeyPress): void;
48
+ /** Route a pointer event the app heard. */
49
+ mouse(event: AppMouseEvent): void;
50
+ /**
51
+ * Scroll the innermost viewport under the pointer that can move, a line a
52
+ * notch, past any widget it shows there and whatever a drag captured.
53
+ * Whether one moved is the answer: with none, the app passes the wheel
54
+ * outward.
55
+ */
56
+ wheel({ x, y, lines }: Wheel): boolean;
57
+ private point;
67
58
  private dispatchKey;
68
59
  private dispatchMouse;
69
60
  private hover;