@promptctl/rich-js 0.28.0 → 0.29.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 (162) hide show
  1. package/README.md +7 -7
  2. package/dist/core/animation.d.ts +37 -37
  3. package/dist/core/animation.js +61 -61
  4. package/dist/core/ansi.d.ts +4 -4
  5. package/dist/core/ansi.js +9 -9
  6. package/dist/core/bidi.js +6 -6
  7. package/dist/core/cells.d.ts +1 -1
  8. package/dist/core/cells.js +5 -5
  9. package/dist/core/clock.d.ts +1 -1
  10. package/dist/core/color.d.ts +50 -50
  11. package/dist/core/color.js +69 -69
  12. package/dist/core/console.d.ts +8 -8
  13. package/dist/core/console.js +5 -5
  14. package/dist/core/control-codes.d.ts +3 -3
  15. package/dist/core/control-codes.js +7 -7
  16. package/dist/core/easing.d.ts +40 -40
  17. package/dist/core/easing.js +40 -40
  18. package/dist/core/env.d.ts +1 -1
  19. package/dist/core/env.js +1 -1
  20. package/dist/core/export-html.js +1 -1
  21. package/dist/core/export-lines.d.ts +11 -11
  22. package/dist/core/export-lines.js +12 -12
  23. package/dist/core/export-svg.d.ts +3 -3
  24. package/dist/core/export-svg.js +4 -4
  25. package/dist/core/markup.js +1 -1
  26. package/dist/core/memo.d.ts +1 -1
  27. package/dist/core/memo.js +1 -1
  28. package/dist/core/oklch.d.ts +14 -14
  29. package/dist/core/oklch.js +10 -10
  30. package/dist/core/orient.d.ts +3 -3
  31. package/dist/core/orient.js +3 -3
  32. package/dist/core/paint.d.ts +9 -9
  33. package/dist/core/paint.js +3 -3
  34. package/dist/core/pretty.d.ts +1 -1
  35. package/dist/core/pretty.js +3 -3
  36. package/dist/core/protocol.d.ts +26 -26
  37. package/dist/core/protocol.js +22 -22
  38. package/dist/core/render.d.ts +11 -11
  39. package/dist/core/render.js +12 -12
  40. package/dist/core/segment.d.ts +3 -3
  41. package/dist/core/segment.js +5 -5
  42. package/dist/core/strip.d.ts +83 -83
  43. package/dist/core/strip.js +70 -70
  44. package/dist/core/style.d.ts +20 -20
  45. package/dist/core/style.js +55 -55
  46. package/dist/core/text.d.ts +2 -2
  47. package/dist/core/text.js +5 -5
  48. package/dist/core/timeline.d.ts +5 -5
  49. package/dist/core/timeline.js +9 -9
  50. package/dist/core/tween.d.ts +6 -6
  51. package/dist/core/tween.js +10 -10
  52. package/dist/core/view.d.ts +4 -4
  53. package/dist/core/view.js +12 -12
  54. package/dist/host/app.d.ts +9 -9
  55. package/dist/host/app.js +12 -12
  56. package/dist/host/host-environment.d.ts +2 -2
  57. package/dist/host/host-environment.js +2 -2
  58. package/dist/host/index.d.ts +2 -2
  59. package/dist/host/input.d.ts +7 -7
  60. package/dist/host/input.js +4 -4
  61. package/dist/host/terminal-colors.d.ts +2 -2
  62. package/dist/host/terminal-colors.js +4 -4
  63. package/dist/host/terminal-host.d.ts +2 -2
  64. package/dist/host/terminal-host.js +1 -1
  65. package/dist/index.d.ts +14 -14
  66. package/dist/index.js +10 -10
  67. package/dist/node/prompt.d.ts +1 -1
  68. package/dist/node/prompt.js +1 -1
  69. package/dist/node/terminal-host.d.ts +1 -1
  70. package/dist/node/traceback.js +2 -2
  71. package/dist/renderables/change.js +2 -2
  72. package/dist/renderables/effect.d.ts +39 -39
  73. package/dist/renderables/effect.js +45 -45
  74. package/dist/renderables/effects.d.ts +81 -81
  75. package/dist/renderables/effects.js +157 -157
  76. package/dist/renderables/embed.d.ts +1 -1
  77. package/dist/renderables/embed.js +2 -2
  78. package/dist/renderables/flexStrip.d.ts +7 -7
  79. package/dist/renderables/flexStrip.js +15 -15
  80. package/dist/renderables/frames.d.ts +6 -6
  81. package/dist/renderables/frames.js +11 -11
  82. package/dist/renderables/glyph-effect.d.ts +15 -15
  83. package/dist/renderables/glyph-effect.js +17 -17
  84. package/dist/renderables/glyph-effects.d.ts +7 -7
  85. package/dist/renderables/glyph-effects.js +16 -16
  86. package/dist/renderables/html-entities.d.ts +1 -1
  87. package/dist/renderables/html-entities.js +1 -1
  88. package/dist/renderables/lifecycle.d.ts +4 -4
  89. package/dist/renderables/lifecycle.js +12 -12
  90. package/dist/renderables/live.d.ts +2 -2
  91. package/dist/renderables/live.js +7 -7
  92. package/dist/renderables/markdown-parse.js +3 -3
  93. package/dist/renderables/panel.js +3 -3
  94. package/dist/renderables/progress.d.ts +1 -1
  95. package/dist/renderables/progress.js +1 -1
  96. package/dist/renderables/progressBar.d.ts +1 -1
  97. package/dist/renderables/progressBar.js +6 -6
  98. package/dist/renderables/prompt.d.ts +1 -1
  99. package/dist/renderables/scroll.d.ts +1 -1
  100. package/dist/renderables/scroll.js +3 -3
  101. package/dist/renderables/spinner.d.ts +4 -4
  102. package/dist/renderables/spinner.js +10 -10
  103. package/dist/renderables/syntax.d.ts +2 -2
  104. package/dist/renderables/syntax.js +2 -2
  105. package/dist/renderables/table.js +3 -3
  106. package/dist/renderables/traceback.d.ts +1 -1
  107. package/dist/renderables/traceback.js +1 -1
  108. package/dist/renderables/tree.js +3 -3
  109. package/dist/template-bindings/animation-funcs.d.ts +14 -14
  110. package/dist/template-bindings/animation-funcs.js +27 -27
  111. package/dist/template-bindings/color-funcs.d.ts +14 -14
  112. package/dist/template-bindings/color-funcs.js +25 -25
  113. package/dist/template-bindings/index.d.ts +9 -9
  114. package/dist/template-bindings/index.js +9 -9
  115. package/dist/template-bindings/palette-funcs.d.ts +1 -1
  116. package/dist/template-bindings/palette-funcs.js +3 -3
  117. package/dist/template-bindings/style-funcs.d.ts +5 -5
  118. package/dist/template-bindings/style-funcs.js +16 -16
  119. package/dist/themes/{transpose.d.ts → adjust.d.ts} +23 -23
  120. package/dist/themes/{transpose.js → adjust.js} +28 -28
  121. package/dist/themes/buildPalette.d.ts +3 -3
  122. package/dist/themes/buildPalette.js +20 -20
  123. package/dist/themes/colorMath.d.ts +16 -16
  124. package/dist/themes/colorMath.js +32 -32
  125. package/dist/themes/data/ansi-tables.d.ts +2 -2
  126. package/dist/themes/data/ansi-tables.js +2 -2
  127. package/dist/themes/data/types.d.ts +4 -4
  128. package/dist/themes/data/types.js +2 -2
  129. package/dist/themes/palette.d.ts +12 -12
  130. package/dist/themes/palette.js +16 -16
  131. package/dist/themes/ramp.d.ts +17 -17
  132. package/dist/themes/ramp.js +12 -12
  133. package/dist/themes/registry.js +4 -4
  134. package/dist/themes/terminalThemes.d.ts +1 -1
  135. package/dist/themes/terminalThemes.js +1 -1
  136. package/dist/widgets/button.d.ts +2 -2
  137. package/dist/widgets/button.js +4 -4
  138. package/dist/widgets/checkbox.d.ts +2 -2
  139. package/dist/widgets/checkbox.js +2 -2
  140. package/dist/widgets/dropdown.d.ts +2 -2
  141. package/dist/widgets/dropdown.js +3 -3
  142. package/dist/widgets/event-router.d.ts +6 -6
  143. package/dist/widgets/event-router.js +2 -2
  144. package/dist/widgets/focus-manager.d.ts +3 -3
  145. package/dist/widgets/focus-manager.js +3 -3
  146. package/dist/widgets/index.d.ts +2 -2
  147. package/dist/widgets/index.js +1 -1
  148. package/dist/widgets/ink.d.ts +3 -3
  149. package/dist/widgets/ink.js +4 -4
  150. package/dist/widgets/slider.d.ts +2 -2
  151. package/dist/widgets/static-item.d.ts +2 -2
  152. package/dist/widgets/text-input.d.ts +2 -2
  153. package/dist/widgets/text-input.js +5 -5
  154. package/dist/widgets/themed-widget.js +1 -1
  155. package/dist/widgets/toggle.d.ts +3 -3
  156. package/dist/widgets/toggle.js +3 -3
  157. package/dist/widgets/types.d.ts +6 -6
  158. package/dist/widgets/types.js +2 -2
  159. package/dist/widgets/widget-app.d.ts +10 -10
  160. package/dist/widgets/widget-app.js +8 -8
  161. package/dist/widgets/widget-base.d.ts +2 -2
  162. package/package.json +1 -1
@@ -29,36 +29,36 @@
29
29
  * arguments on every evaluation, so the sequence is prepared on every one:
30
30
  * a template has nowhere to keep it, and keeping it here would be the memo
31
31
  * keyed on the arguments that `FrameSequence` is instead of. `stepped <seconds>
32
- * <color> <seconds> <color> …` is the colour in progress at the moment, a
33
- * colour value like every colour function's (`./color-funcs.ts`), so it
34
- * nests where a colour goes — `fg (stepped …)`, `readableOn (stepped …) $bg
32
+ * <color> <seconds> <color> …` is the color in progress at the moment, a
33
+ * color value like every color function's (`./color-funcs.ts`), so it
34
+ * nests where a color goes — `fg (stepped …)`, `ensureContrast (stepped …) $bg
35
35
  * 4.5` — and the ground it must read on is the template's to name, as it
36
- * is for any colour. Either argument list is one float/value cycle end to
36
+ * is for any color. Either argument list is one float/value cycle end to
37
37
  * end, so the engine's `alternating` gate types every slot and lifts each
38
38
  * string frame to a fragment; the pairing — a trailing hold with no frame or
39
- * colour — is parsed in `pairs`, once. [LAW:types-are-the-program]
39
+ * color — is parsed in `pairs`, once. [LAW:types-are-the-program]
40
40
  *
41
41
  * The rest start at a moment the template names, on the timeline's clock —
42
42
  * a field of the host's state, the moment a value changed — and each is the
43
43
  * animation `Timeline.play(start)` runs, so a start is a timeline like any
44
44
  * other and nothing here offsets a time by hand. `tween <seconds> <ease>
45
45
  * <start> <from> <to>` is a number eased from one value to another and held
46
- * (`core/tween.ts`), its ease spelled by name (`parseEase`); `loop <seconds>
46
+ * (`core/tween.ts`), its ease spelled by name (`parseEasing`); `loop <seconds>
47
47
  * <start>` is the way through a period, 0 to 1 and round again — two
48
48
  * cells started a step apart are a stagger. Each is a number, so it goes
49
- * wherever a number goes: a colour tween is `ramp (tween …) "linear" 0 $from
49
+ * wherever a number goes: a color tween is `ramp (tween …) "linear" 0 $from
50
50
  * 1 $to` and a ramp scrolling is `ramp (loop …) …`, because `ColorRamp` is
51
- * the one place two colours are blended and a colour tween is a two-stop
51
+ * the one place two colors are blended and a color tween is a two-stop
52
52
  * ramp read over time (`ColorRamp.over`). [LAW:one-source-of-truth] A
53
53
  * second blender here would be a second answer to what lies between two
54
- * colours. `glyphs <name> <start> <fragment>` is the fragment through a
54
+ * colors. `glyphs <name> <start> <fragment>` is the fragment through a
55
55
  * glyph effect from the catalogue (`GLYPH_EFFECT_CATALOGUE`), at its
56
56
  * defaults, before any render (`reglyphText`). Every argument list is an
57
57
  * exact arity of typed slots, so a slot of the wrong kind fails at the gate.
58
58
  *
59
59
  * Every function says when what it drew changes, so a host paints a
60
60
  * template while it moves and not after — and says it only for what the
61
- * output depends on. A number or a colour has no cells to carry a hold, and
61
+ * output depends on. A number or a color has no cells to carry a hold, and
62
62
  * a fragment's cells lose theirs the moment it is flattened (`printf "%s"`),
63
63
  * so no function stamps cells or tells the frame itself. Each marks its
64
64
  * return with the hold its value is in (`marked`, the engine's evaluation
@@ -67,7 +67,7 @@
67
67
  * the output depends on it. `emitted` is where a template's cells take a
68
68
  * hold: every fragment the template emits, stamped with the holds of the
69
69
  * marked values its action read. `decided` is the route for a hold no cell
70
- * can carry, told to the frame (`TemplateFrame.onHold`): a mark an
70
+ * can carry, told to the frame (`TemplateFrame.onValidity`): a mark an
71
71
  * `if`/`with`/`range` consumed, whichever arm it took, because the frame may
72
72
  * show cells for it later and must say when without a cell to say it on, as
73
73
  * a placed animation of no cells does (`placed`) — and, by the same rule, a
@@ -83,8 +83,8 @@
83
83
  * draw and never say they move. [LAW:no-silent-failure]
84
84
  */
85
85
  import { marked } from "@promptctl/go-template-js";
86
- import { Animation, frameTimeOf, holdOf, shownAt, stamp } from "../core/animation.js";
87
- import { Phase, beat, finiteTime, parseEase } from "../core/easing.js";
86
+ import { Animation, frameTimeOf, validityOf, shownAt, stampValidity } from "../core/animation.js";
87
+ import { WrapMode, stepSequence, finiteTime, parseEasing } from "../core/easing.js";
88
88
  import { layerStyle } from "../core/style.js";
89
89
  import { Timeline } from "../core/timeline.js";
90
90
  import { tween } from "../core/tween.js";
@@ -96,20 +96,20 @@ import { asColor } from "./color-funcs.js";
96
96
  import { asFragment } from "./helpers.js";
97
97
  /** The frame a renderable is drawn in, as the frame a template it evaluates there is drawn for. */
98
98
  export function templateFrame(options) {
99
- return { time: frameTimeOf(options), onHold: options.onHold, reducedMotion: options.reducedMotion, asciiOnly: options.asciiOnly };
99
+ return { time: frameTimeOf(options), onValidity: options.onValidity, reducedMotion: options.reducedMotion, asciiOnly: options.asciiOnly };
100
100
  }
101
101
  /**
102
102
  * The mark a function puts on its return: the hold its value is in, and the
103
103
  * frame it was drawn for, which is the one `decided` tells. Only the two
104
104
  * hooks here read one; a consumer's own marks pass through them untouched,
105
- * and a foreign token shaped like a `Hold` is not one.
105
+ * and a foreign token shaped like a `ValidityInterval` is not one.
106
106
  * [LAW:types-are-the-program]
107
107
  */
108
- class HoldMark {
109
- hold;
108
+ class ValidityMark {
109
+ validity;
110
110
  frame;
111
- constructor(hold, frame) {
112
- this.hold = hold;
111
+ constructor(validity, frame) {
112
+ this.validity = validity;
113
113
  this.frame = frame;
114
114
  }
115
115
  }
@@ -190,7 +190,7 @@ export function withAnimation(config, frame, options = {}) {
190
190
  const drawn = (what, animation, at) => {
191
191
  const t = finiteTime(what, at.time);
192
192
  const shown = shownAt(Timeline.run(timeline(), animation), t, at);
193
- return marked(shown.value, new HoldMark(holdOf(shown, t), at));
193
+ return marked(shown.value, new ValidityMark(validityOf(shown, t), at));
194
194
  };
195
195
  const startedAt = (start, animation) => Timeline.run(Timeline.play(start), animation);
196
196
  const framesFunc = {
@@ -205,20 +205,20 @@ export function withAnimation(config, frame, options = {}) {
205
205
  const steppedFunc = {
206
206
  fn: ((...tail) => {
207
207
  const steps = pairs("color", tail, (v) => asColor(v, "stepped"));
208
- return drawn("stepped", Animation.map(beat(steps.map((s) => s.seconds)), (step) => steps[step].value.hex), frame());
208
+ return drawn("stepped", Animation.map(stepSequence(steps.map((s) => s.seconds)), (step) => steps[step].value.hex), frame());
209
209
  }),
210
210
  argTypes: ["float", "string"],
211
211
  arity: { kind: "alternating", minimum: 2 },
212
212
  returnType: "string",
213
213
  };
214
214
  const tweenFunc = {
215
- fn: ((seconds, ease, start, from, to) => drawn("tween", startedAt(start, tween(from, to, { seconds, ease: parseEase(ease) })), frame())),
215
+ fn: ((seconds, ease, start, from, to) => drawn("tween", startedAt(start, tween(from, to, { seconds, ease: parseEasing(ease) })), frame())),
216
216
  argTypes: ["float", "string", "float", "float", "float"],
217
217
  arity: { kind: "exact" },
218
218
  returnType: "float",
219
219
  };
220
220
  const loopFunc = {
221
- fn: ((seconds, start) => drawn("loop", startedAt(start, Animation.continuous(Phase.loop(seconds))), frame())),
221
+ fn: ((seconds, start) => drawn("loop", startedAt(start, Animation.continuous(WrapMode.loop(seconds))), frame())),
222
222
  argTypes: ["float", "float"],
223
223
  arity: { kind: "exact" },
224
224
  returnType: "float",
@@ -242,10 +242,10 @@ export function withAnimation(config, frame, options = {}) {
242
242
  if (taken.length > 0) {
243
243
  throw new RangeError(`withAnimation registers ${taken.join(", ")}, already in config.funcs`);
244
244
  }
245
- const holdMarks = (marks) => [...marks].filter((mark) => mark instanceof HoldMark);
245
+ const holdMarks = (marks) => [...marks].filter((mark) => mark instanceof ValidityMark);
246
246
  // The holds among `marks` layered onto the fragment's base style, which an
247
247
  // empty text still draws as its one piece of no width: `Style.add` keeps
248
- // the later `lastChange` and the sooner `nextChange`, so cells that read
248
+ // the later `validFrom` and the sooner `validUntil`, so cells that read
249
249
  // two animated values are in the intersection of their holds, as two
250
250
  // styles laid together are anywhere. A fragment no hold reaches is handed
251
251
  // back as it came — the engine calls this for every emission — and one a
@@ -256,12 +256,12 @@ export function withAnimation(config, frame, options = {}) {
256
256
  if (holds.length === 0)
257
257
  return fragment;
258
258
  const result = fragment.copy();
259
- result.style = holds.reduce((style, mark) => layerStyle(style, stamp(mark.hold)), fragment.style);
259
+ result.style = holds.reduce((style, mark) => layerStyle(style, stampValidity(mark.validity)), fragment.style);
260
260
  return result;
261
261
  };
262
262
  const told = (marks) => {
263
263
  for (const mark of holdMarks(marks))
264
- mark.frame.onHold?.(mark.hold);
264
+ mark.frame.onValidity?.(mark.validity);
265
265
  };
266
266
  // The hooks `config` brought run first and hear everything they did; a
267
267
  // consumer that stamps or listens on its own loses nothing to this binding.
@@ -44,9 +44,9 @@
44
44
  * No precision is given up: `darken`, `blendRgb`, and `contrastFor` already
45
45
  * take and return 8-bit `ColorRgba`. The one caveat is OKLCH: each of the
46
46
  * axis functions below round-trips sRGB→OKLCH→sRGB, so chaining three or more
47
- * of them quantizes visibly. Compose two, or reach for `transposePalette` when
47
+ * of them quantizes visibly. Compose two, or reach for `adjustPalette` when
48
48
  * a whole palette needs adapting — the same caveat that already applies to
49
- * chained transpositions.
49
+ * chained adjustments.
50
50
  *
51
51
  * ### Palette-free on purpose
52
52
  *
@@ -66,23 +66,23 @@ import { ColorDepth, type ColorRgba, type TerminalTheme } from "../core/color.js
66
66
  * same one — a palette name passed where a color belongs (`darken "primary" 2`)
67
67
  * — and an author who reads "wrap it: darken (color "primary")" is corrected in
68
68
  * one step, where "expected #RRGGBB" leaves them guessing. What it parses
69
- * must then be a colour these functions can compute with (`computable`).
69
+ * must then be a color these functions can compute with (`computable`).
70
70
  * [LAW:no-silent-failure]
71
71
  */
72
72
  export declare function asColor(value: string, func: string): ColorRgba;
73
73
  /**
74
- * A colour the colour functions can compute with. A fully transparent one — a
75
- * theme's "no background", `#00000000` — has no colour of its own: what shows
74
+ * A color the color functions can compute with. A fully transparent one — a
75
+ * theme's "no background", `#00000000` — has no color of its own: what shows
76
76
  * through it is whatever surface it lands on, which a template cannot know.
77
77
  * Darkening, mixing or contrasting it would answer for a surface nobody named,
78
- * so it is refused here, for every colour function and every `ramp` stop.
78
+ * so it is refused here, for every color function and every `ramp` stop.
79
79
  * [LAW:single-enforcer]
80
80
  */
81
- export declare function computable(colour: ColorRgba, func: string, written: string): ColorRgba;
81
+ export declare function computable(color: ColorRgba, func: string, written: string): ColorRgba;
82
82
  /**
83
- * Where `readableOn`'s text will be drawn: the depth the output is encoded at,
84
- * and the terminal that draws it when that is known. At sixteen colours a
85
- * terminal paints each slot in its own theme's colour, so the floor is measured
83
+ * Where `ensureContrast`'s text will be drawn: the depth the output is encoded at,
84
+ * and the terminal that draws it when that is known. At sixteen colors a
85
+ * terminal paints each slot in its own theme's color, so the floor is measured
86
86
  * in `terminal`'s sixteen; without one, in the VGA defaults (the Windows
87
87
  * console's at `WINDOWS`). Both are facts about the one place the text lands,
88
88
  * so they arrive together.
@@ -92,11 +92,11 @@ export interface DrawnAt {
92
92
  readonly terminal?: TerminalTheme;
93
93
  }
94
94
  /**
95
- * The `readableOn` binding, measuring where `drawnAt` says the text lands when
95
+ * The `ensureContrast` binding, measuring where `drawnAt` says the text lands when
96
96
  * it is evaluated — a consumer that renders to a per-call destination
97
97
  * registers its own.
98
98
  */
99
- export declare const readableOnFunc: (drawnAt: () => DrawnAt) => TemplateFunc;
99
+ export declare const ensureContrastFunc: (drawnAt: () => DrawnAt) => TemplateFunc;
100
100
  /**
101
101
  * The palette-free color vocabulary: every function takes colors and returns a
102
102
  * color, so they compose by nesting.
@@ -106,7 +106,7 @@ export declare const readableOnFunc: (drawnAt: () => DrawnAt) => TemplateFunc;
106
106
  * | `darken c n` / `lighten c n` | slide HSL lightness by N 10% levels |
107
107
  * | `mix a b pct` | blend `a` toward `b` by `pct`% (0 → `a`, 100 → `b`) |
108
108
  * | `contrastOn bg` | black or white, whichever is readable on `bg` |
109
- * | `readableOn fg bg ratio` | `fg` nudged in OKLCH lightness until it clears `ratio` on `bg`, hue preserved |
109
+ * | `ensureContrast fg bg ratio` | `fg` nudged in OKLCH lightness until it clears `ratio` on `bg`, hue preserved |
110
110
  * | `shiftHue c deg` | rotate hue in OKLCH |
111
111
  * | `scaleChroma c f` | multiply chroma (0 → gray, 1 → identity) |
112
112
  * | `scaleLightness c f` | multiply lightness (1 → identity, -1 → invert) |
@@ -116,7 +116,7 @@ export declare const readableOnFunc: (drawnAt: () => DrawnAt) => TemplateFunc;
116
116
  * `richTextStyleFuncs()`'s `fg`/`bg` to paint them onto text.
117
117
  *
118
118
  * @param drawnAt where the text will be drawn — the depth, and the terminal
119
- * when known — read on every `readableOn` evaluation so a host that learns
119
+ * when known — read on every `ensureContrast` evaluation so a host that learns
120
120
  * its destination per render passes one getter; defaults to truecolor.
121
121
  */
122
122
  export declare function colorFuncs(drawnAt?: () => DrawnAt): FuncMap;
@@ -44,9 +44,9 @@
44
44
  * No precision is given up: `darken`, `blendRgb`, and `contrastFor` already
45
45
  * take and return 8-bit `ColorRgba`. The one caveat is OKLCH: each of the
46
46
  * axis functions below round-trips sRGB→OKLCH→sRGB, so chaining three or more
47
- * of them quantizes visibly. Compose two, or reach for `transposePalette` when
47
+ * of them quantizes visibly. Compose two, or reach for `adjustPalette` when
48
48
  * a whole palette needs adapting — the same caveat that already applies to
49
- * chained transpositions.
49
+ * chained adjustments.
50
50
  *
51
51
  * ### Palette-free on purpose
52
52
  *
@@ -67,13 +67,13 @@ import { darken, contrastFor, ensureContrast } from "../themes/colorMath.js";
67
67
  * same one — a palette name passed where a color belongs (`darken "primary" 2`)
68
68
  * — and an author who reads "wrap it: darken (color "primary")" is corrected in
69
69
  * one step, where "expected #RRGGBB" leaves them guessing. What it parses
70
- * must then be a colour these functions can compute with (`computable`).
70
+ * must then be a color these functions can compute with (`computable`).
71
71
  * [LAW:no-silent-failure]
72
72
  */
73
73
  export function asColor(value, func) {
74
- let colour;
74
+ let color;
75
75
  try {
76
- colour = parseHexColor(value.trim());
76
+ color = parseHexColor(value.trim());
77
77
  }
78
78
  catch (cause) {
79
79
  if (!(cause instanceof ColorParseError))
@@ -81,24 +81,24 @@ export function asColor(value, func) {
81
81
  throw new TypeError(`${func} expected a color (#RRGGBB or #RRGGBBAA), got ${JSON.stringify(value)}` +
82
82
  ` — to use a palette name here, wrap it: ${func} (color ${JSON.stringify(value)}) …`, { cause });
83
83
  }
84
- return computable(colour, func, JSON.stringify(value));
84
+ return computable(color, func, JSON.stringify(value));
85
85
  }
86
86
  /**
87
- * A colour the colour functions can compute with. A fully transparent one — a
88
- * theme's "no background", `#00000000` — has no colour of its own: what shows
87
+ * A color the color functions can compute with. A fully transparent one — a
88
+ * theme's "no background", `#00000000` — has no color of its own: what shows
89
89
  * through it is whatever surface it lands on, which a template cannot know.
90
90
  * Darkening, mixing or contrasting it would answer for a surface nobody named,
91
- * so it is refused here, for every colour function and every `ramp` stop.
91
+ * so it is refused here, for every color function and every `ramp` stop.
92
92
  * [LAW:single-enforcer]
93
93
  */
94
- export function computable(colour, func, written) {
95
- if (colour.alpha === 0) {
96
- throw new RangeError(`${func} got ${written}, which is fully transparent: it draws no colour of its own, ` +
97
- `so there is nothing to compute with — use the colour of the surface it sits on, e.g. (color "background")`);
94
+ export function computable(color, func, written) {
95
+ if (color.alpha === 0) {
96
+ throw new RangeError(`${func} got ${written}, which is fully transparent: it draws no color of its own, ` +
97
+ `so there is nothing to compute with — use the color of the surface it sits on, e.g. (color "background")`);
98
98
  }
99
- return colour;
99
+ return color;
100
100
  }
101
- // [LAW:single-enforcer] Every colour function is fixed-arity, so the engine's
101
+ // [LAW:single-enforcer] Every color function is fixed-arity, so the engine's
102
102
  // arity gate refuses a missing or surplus argument before the body runs.
103
103
  function colorFunc(argTypes, fn) {
104
104
  return { fn, argTypes, arity: { kind: "exact" }, returnType: "string" };
@@ -147,7 +147,7 @@ const mixFunc = colorFunc(["string", "string", "float"], ((fromHex, towardHex, p
147
147
  //
148
148
  // Two different questions, so two functions rather than one with a flag:
149
149
  // `contrastOn` asks "what is maximally readable here" (black or white, WCAG
150
- // relative-luminance cutoff); `readableOn` asks "keep this color recognizably
150
+ // relative-luminance cutoff); `ensureContrast` asks "keep this color recognizably
151
151
  // itself, but guarantee it clears `ratio`" — it slides OKLCH lightness and
152
152
  // preserves hue, so a blue on dark blue becomes a lighter blue rather than
153
153
  // white.
@@ -168,19 +168,19 @@ const RATIO_RANGE = {
168
168
  const contrastOnFunc = colorFunc(["string"], ((bgHex) => contrastFor(asColor(bgHex, "contrastOn")).hex));
169
169
  const TRUECOLOR = { depth: ColorDepth.TRUECOLOR };
170
170
  /**
171
- * The `readableOn` binding, measuring where `drawnAt` says the text lands when
171
+ * The `ensureContrast` binding, measuring where `drawnAt` says the text lands when
172
172
  * it is evaluated — a consumer that renders to a per-call destination
173
173
  * registers its own.
174
174
  */
175
- export const readableOnFunc = (drawnAt) => colorFunc(["string", "string", "float"], ((fgHex, bgHex, ratio) => {
175
+ export const ensureContrastFunc = (drawnAt) => colorFunc(["string", "string", "float"], ((fgHex, bgHex, ratio) => {
176
176
  const { depth, terminal } = drawnAt();
177
- return ensureContrast(asColor(fgHex, "readableOn"), asColor(bgHex, "readableOn"), asAmount(ratio, "readableOn", "ratio", RATIO_RANGE), depth, undefined, terminal).hex;
177
+ return ensureContrast(asColor(fgHex, "ensureContrast"), asColor(bgHex, "ensureContrast"), asAmount(ratio, "ensureContrast", "ratio", RATIO_RANGE), depth, undefined, terminal).hex;
178
178
  }));
179
179
  // --- OKLCH axes ---
180
180
  //
181
- // [LAW:one-source-of-truth] One function per `ThemeKey` axis, and the table is
182
- // keyed BY the axis so the compiler proves it total: add a field to `ThemeKey`
183
- // and this object stops satisfying `Record<keyof ThemeKey, string>` until a
181
+ // [LAW:one-source-of-truth] One function per `ColorAdjustment` axis, and the table is
182
+ // keyed BY the axis so the compiler proves it total: add a field to `ColorAdjustment`
183
+ // and this object stops satisfying `Record<keyof ColorAdjustment, string>` until a
184
184
  // binding name is chosen for it. The same derive-registrations-from-the-real-
185
185
  // inventory trick `attributeFuncs()` uses over `ATTRIBUTE_NAMES`.
186
186
  //
@@ -218,7 +218,7 @@ function oklchAxisFuncs() {
218
218
  * | `darken c n` / `lighten c n` | slide HSL lightness by N 10% levels |
219
219
  * | `mix a b pct` | blend `a` toward `b` by `pct`% (0 → `a`, 100 → `b`) |
220
220
  * | `contrastOn bg` | black or white, whichever is readable on `bg` |
221
- * | `readableOn fg bg ratio` | `fg` nudged in OKLCH lightness until it clears `ratio` on `bg`, hue preserved |
221
+ * | `ensureContrast fg bg ratio` | `fg` nudged in OKLCH lightness until it clears `ratio` on `bg`, hue preserved |
222
222
  * | `shiftHue c deg` | rotate hue in OKLCH |
223
223
  * | `scaleChroma c f` | multiply chroma (0 → gray, 1 → identity) |
224
224
  * | `scaleLightness c f` | multiply lightness (1 → identity, -1 → invert) |
@@ -228,7 +228,7 @@ function oklchAxisFuncs() {
228
228
  * `richTextStyleFuncs()`'s `fg`/`bg` to paint them onto text.
229
229
  *
230
230
  * @param drawnAt where the text will be drawn — the depth, and the terminal
231
- * when known — read on every `readableOn` evaluation so a host that learns
231
+ * when known — read on every `ensureContrast` evaluation so a host that learns
232
232
  * its destination per render passes one getter; defaults to truecolor.
233
233
  */
234
234
  export function colorFuncs(drawnAt = () => TRUECOLOR) {
@@ -237,7 +237,7 @@ export function colorFuncs(drawnAt = () => TRUECOLOR) {
237
237
  lighten: lightenFunc,
238
238
  mix: mixFunc,
239
239
  contrastOn: contrastOnFunc,
240
- readableOn: readableOnFunc(drawnAt),
240
+ ensureContrast: ensureContrastFunc(drawnAt),
241
241
  ...oklchAxisFuncs(),
242
242
  };
243
243
  }
@@ -6,10 +6,10 @@
6
6
  * functions. The split between the two exported registrations is exactly the
7
7
  * split between what needs a theme and what does not:
8
8
  *
9
- * - `richTextFuncs()` — the colour sinks (`fg`/`bg`), the palette-free colour
9
+ * - `richTextFuncs()` — the color sinks (`fg`/`bg`), the palette-free color
10
10
  * math (`darken`, `mix`, `contrastOn`, the OKLCH axes …), text attributes,
11
11
  * and `link`. Needs no configuration; safe to register unconditionally. A
12
- * consumer with no theme system still gets the complete colour vocabulary by
12
+ * consumer with no theme system still gets the complete color vocabulary by
13
13
  * feeding it hex literals.
14
14
  * - `paletteFuncs(getPalette)` — `color` and `ramp`, the two functions that
15
15
  * resolve a palette name. This is the *only* registration that knows a
@@ -22,12 +22,12 @@
22
22
  * host's to hand in (`./animation-funcs.ts`).
23
23
  *
24
24
  * `createRichTextEngine()` wires up `richTextFuncs()` only — it cannot supply a
25
- * palette. Consumers that name theme colours call `paletteFuncs(getPalette)`
25
+ * palette. Consumers that name theme colors call `paletteFuncs(getPalette)`
26
26
  * and merge it into their own engine config.
27
27
  *
28
- * Colours compose by nesting, like every other function:
28
+ * Colors compose by nesting, like every other function:
29
29
  * `{{ fg (darken (color "primary") 2) (bold "x") }}`. There is no second
30
- * markup grammar and no colour-spec mini-language — the template *is* the
30
+ * markup grammar and no color-spec mini-language — the template *is* the
31
31
  * composition mechanism.
32
32
  *
33
33
  * Fragment type: `RichText`. Chosen because it is the library's primary
@@ -44,14 +44,14 @@ import { Segment } from "../core/segment.js";
44
44
  import type { RenderOptions } from "../core/protocol.js";
45
45
  import { type DrawnAt } from "./color-funcs.js";
46
46
  export { paletteFuncs } from "./palette-funcs.js";
47
- export { colorFuncs, readableOnFunc, type DrawnAt } from "./color-funcs.js";
47
+ export { colorFuncs, ensureContrastFunc, type DrawnAt } from "./color-funcs.js";
48
48
  export { withAnimation, templateFrame, type AnimationOptions, type TemplateFrame } from "./animation-funcs.js";
49
49
  /**
50
- * Funcs registered by the rich-js binding — the colour sinks, the palette-free
51
- * colour math, text attributes, and the `link` cell-splitter. Nothing here
50
+ * Funcs registered by the rich-js binding — the color sinks, the palette-free
51
+ * color math, text attributes, and the `link` cell-splitter. Nothing here
52
52
  * needs a theme; the two that do (`color`, `ramp`) ship separately via
53
53
  * `paletteFuncs(getPalette)`, merged consumer-side. `drawnAt` is forwarded to
54
- * `colorFuncs` — the depth `readableOn` measures at, truecolor when omitted.
54
+ * `colorFuncs` — the depth `ensureContrast` measures at, truecolor when omitted.
55
55
  *
56
56
  * `FuncMap` is not parameterised over `T` in `@promptctl/go-template-js` — the engine's
57
57
  * `T` lives on the `Engine`/`EngineConfig`, and per-function input/output
@@ -6,10 +6,10 @@
6
6
  * functions. The split between the two exported registrations is exactly the
7
7
  * split between what needs a theme and what does not:
8
8
  *
9
- * - `richTextFuncs()` — the colour sinks (`fg`/`bg`), the palette-free colour
9
+ * - `richTextFuncs()` — the color sinks (`fg`/`bg`), the palette-free color
10
10
  * math (`darken`, `mix`, `contrastOn`, the OKLCH axes …), text attributes,
11
11
  * and `link`. Needs no configuration; safe to register unconditionally. A
12
- * consumer with no theme system still gets the complete colour vocabulary by
12
+ * consumer with no theme system still gets the complete color vocabulary by
13
13
  * feeding it hex literals.
14
14
  * - `paletteFuncs(getPalette)` — `color` and `ramp`, the two functions that
15
15
  * resolve a palette name. This is the *only* registration that knows a
@@ -22,12 +22,12 @@
22
22
  * host's to hand in (`./animation-funcs.ts`).
23
23
  *
24
24
  * `createRichTextEngine()` wires up `richTextFuncs()` only — it cannot supply a
25
- * palette. Consumers that name theme colours call `paletteFuncs(getPalette)`
25
+ * palette. Consumers that name theme colors call `paletteFuncs(getPalette)`
26
26
  * and merge it into their own engine config.
27
27
  *
28
- * Colours compose by nesting, like every other function:
28
+ * Colors compose by nesting, like every other function:
29
29
  * `{{ fg (darken (color "primary") 2) (bold "x") }}`. There is no second
30
- * markup grammar and no colour-spec mini-language — the template *is* the
30
+ * markup grammar and no color-spec mini-language — the template *is* the
31
31
  * composition mechanism.
32
32
  *
33
33
  * Fragment type: `RichText`. Chosen because it is the library's primary
@@ -46,14 +46,14 @@ import { render } from "../core/protocol.js";
46
46
  import { richTextStyleFuncs } from "./style-funcs.js";
47
47
  import { colorFuncs } from "./color-funcs.js";
48
48
  export { paletteFuncs } from "./palette-funcs.js";
49
- export { colorFuncs, readableOnFunc } from "./color-funcs.js";
49
+ export { colorFuncs, ensureContrastFunc } from "./color-funcs.js";
50
50
  export { withAnimation, templateFrame } from "./animation-funcs.js";
51
51
  /**
52
- * Funcs registered by the rich-js binding — the colour sinks, the palette-free
53
- * colour math, text attributes, and the `link` cell-splitter. Nothing here
52
+ * Funcs registered by the rich-js binding — the color sinks, the palette-free
53
+ * color math, text attributes, and the `link` cell-splitter. Nothing here
54
54
  * needs a theme; the two that do (`color`, `ramp`) ship separately via
55
55
  * `paletteFuncs(getPalette)`, merged consumer-side. `drawnAt` is forwarded to
56
- * `colorFuncs` — the depth `readableOn` measures at, truecolor when omitted.
56
+ * `colorFuncs` — the depth `ensureContrast` measures at, truecolor when omitted.
57
57
  *
58
58
  * `FuncMap` is not parameterised over `T` in `@promptctl/go-template-js` — the engine's
59
59
  * `T` lives on the `Engine`/`EngineConfig`, and per-function input/output
@@ -69,7 +69,7 @@ import type { Palette } from "../themes/palette.js";
69
69
  *
70
70
  * `color` resolves a palette variable name to its hex string — `#RRGGBB`, or
71
71
  * `#00000000` for a theme's "no background", which `bg` paints as no
72
- * background and the colour functions refuse — and passes
72
+ * background and the color functions refuse — and passes
73
73
  * an already-literal color through unchanged. That second half is not a
74
74
  * convenience — it makes `color` **idempotent**, which is what lets consumers
75
75
  * apply it unconditionally to any author-written color string without first
@@ -63,7 +63,7 @@
63
63
  * they are gone.
64
64
  */
65
65
  import { resolveColorRef } from "../themes/colorRef.js";
66
- import { parseEase } from "../core/easing.js";
66
+ import { parseEasing } from "../core/easing.js";
67
67
  import { ColorRamp } from "../themes/ramp.js";
68
68
  import { computable } from "./color-funcs.js";
69
69
  /**
@@ -97,7 +97,7 @@ function colorStops(tail, palette) {
97
97
  *
98
98
  * `color` resolves a palette variable name to its hex string — `#RRGGBB`, or
99
99
  * `#00000000` for a theme's "no background", which `bg` paints as no
100
- * background and the colour functions refuse — and passes
100
+ * background and the color functions refuse — and passes
101
101
  * an already-literal color through unchanged. That second half is not a
102
102
  * convenience — it makes `color` **idempotent**, which is what lets consumers
103
103
  * apply it unconditionally to any author-written color string without first
@@ -135,7 +135,7 @@ export function paletteFuncs(getPalette) {
135
135
  // value, the ease, and one stop, so the gate refuses a stopless call.
136
136
  // [LAW:types-are-the-program]
137
137
  const rampFunc = {
138
- fn: ((value, ease, ...tail) => new ColorRamp(parseEase(ease), colorStops(tail, getPalette())).at(value)
138
+ fn: ((value, ease, ...tail) => new ColorRamp(parseEasing(ease), colorStops(tail, getPalette())).at(value)
139
139
  .hex),
140
140
  argTypes: ["float", "string"],
141
141
  arity: { kind: "alternating", minimum: 4 },
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * [LAW:one-source-of-truth] The function inventory below mirrors the
5
5
  * string-syntax style vocabulary documented in `docs/style.md` — the two
6
- * colour slots (`fg`/`bg`), text attributes (positive + negated), short
6
+ * color slots (`fg`/`bg`), text attributes (positive + negated), short
7
7
  * aliases, and the hyperlink. Each registration is a templating-time analogue
8
8
  * of a piece of `Style.parse`, so a template fragment composed by these
9
9
  * functions round-trips through `Style` without semantic drift.
@@ -12,17 +12,17 @@
12
12
  * shape: child `RichText` in, `RichText` out. The styling difference
13
13
  * lives in a captured `Style` value (or constructor closure), not in
14
14
  * branches inside a single dispatch. That is why this file is mostly
15
- * factories — the data (the colour, the attribute name) is the
15
+ * factories — the data (the color, the attribute name) is the
16
16
  * variability; the operation is fixed.
17
17
  */
18
18
  import type { FuncMap } from "@promptctl/go-template-js";
19
19
  /**
20
- * Text-styling registrations: the two colour sinks (`fg`, `bg`), text
20
+ * Text-styling registrations: the two color sinks (`fg`, `bg`), text
21
21
  * attributes (canonical names, short aliases, and `not_*` negations), the
22
22
  * hyperlink cell-splitter (`link`), and the multi-attribute `style` spec.
23
23
  *
24
- * Colours themselves come from elsewhere: `colorFuncs()` for the palette-free
25
- * math, `paletteFuncs()` for naming a theme colour. This module only paints.
24
+ * Colors themselves come from elsewhere: `colorFuncs()` for the palette-free
25
+ * math, `paletteFuncs()` for naming a theme color. This module only paints.
26
26
  * [LAW:one-way-deps] — nothing here imports a palette.
27
27
  */
28
28
  export declare function richTextStyleFuncs(): FuncMap;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * [LAW:one-source-of-truth] The function inventory below mirrors the
5
5
  * string-syntax style vocabulary documented in `docs/style.md` — the two
6
- * colour slots (`fg`/`bg`), text attributes (positive + negated), short
6
+ * color slots (`fg`/`bg`), text attributes (positive + negated), short
7
7
  * aliases, and the hyperlink. Each registration is a templating-time analogue
8
8
  * of a piece of `Style.parse`, so a template fragment composed by these
9
9
  * functions round-trips through `Style` without semantic drift.
@@ -12,7 +12,7 @@
12
12
  * shape: child `RichText` in, `RichText` out. The styling difference
13
13
  * lives in a captured `Style` value (or constructor closure), not in
14
14
  * branches inside a single dispatch. That is why this file is mostly
15
- * factories — the data (the colour, the attribute name) is the
15
+ * factories — the data (the color, the attribute name) is the
16
16
  * variability; the operation is fixed.
17
17
  */
18
18
  import { Style, ATTRIBUTE_NAMES, ATTRIBUTE_SHORT_ALIASES, } from "../core/style.js";
@@ -26,26 +26,26 @@ function attrFunc(style) {
26
26
  returnType: "T",
27
27
  };
28
28
  }
29
- // --- Colour sinks ---
29
+ // --- Color sinks ---
30
30
  //
31
- // `fg` and `bg` are the only two colour-applying functions, and they are the
32
- // terminal step of the colour pipeline: `color` names a colour, the functions
31
+ // `fg` and `bg` are the only two color-applying functions, and they are the
32
+ // terminal step of the color pipeline: `color` names a color, the functions
33
33
  // in `color-funcs.ts` transform it, these paint it onto text.
34
34
  //
35
35
  // [LAW:composability] They replace five separate families — one function per
36
- // ANSI colour name (`red`, `bright_blue`, …), `hex`, `rgb`, `color` (256-index),
37
- // and `on` (background). Every one of those encoded *which colour* in the
36
+ // ANSI color name (`red`, `bright_blue`, …), `hex`, `rgb`, `color` (256-index),
37
+ // and `on` (background). Every one of those encoded *which color* in the
38
38
  // function's identity, so the vocabulary could only grow by adding names, and
39
- // a colour computed at render time could not be applied at all. Here the colour
40
- // is an argument, so the sink admits every colour that exists and every colour
39
+ // a color computed at render time could not be applied at all. Here the color
40
+ // is an argument, so the sink admits every color that exists and every color
41
41
  // that will ever exist. Two functions, unbounded reach.
42
42
  //
43
43
  // [LAW:types-are-the-program] The slot accepts the full `ColorSpec.parse`
44
- // vocabulary, which is wider than the hex the colour math produces — and that
45
- // width is deliberate, not laxity. `#7aa2f7` is a *concrete* colour; `"red"`
44
+ // vocabulary, which is wider than the hex the color math produces — and that
45
+ // width is deliberate, not laxity. `#7aa2f7` is a *concrete* color; `"red"`
46
46
  // and `"color(42)"` are *symbolic* ones the terminal resolves against its own
47
- // theme. Only concrete colours can be darkened or blended, which is why the
48
- // colour-math functions take hex alone; but both kinds can be painted, so the
47
+ // theme. Only concrete colors can be darkened or blended, which is why the
48
+ // color-math functions take hex alone; but both kinds can be painted, so the
49
49
  // sink takes the union. The type of each slot is exactly the set of values that
50
50
  // slot can mean something for.
51
51
  function colorSinkFunc(slot) {
@@ -138,12 +138,12 @@ const linkFunc = {
138
138
  };
139
139
  // --- Public assembly ---
140
140
  /**
141
- * Text-styling registrations: the two colour sinks (`fg`, `bg`), text
141
+ * Text-styling registrations: the two color sinks (`fg`, `bg`), text
142
142
  * attributes (canonical names, short aliases, and `not_*` negations), the
143
143
  * hyperlink cell-splitter (`link`), and the multi-attribute `style` spec.
144
144
  *
145
- * Colours themselves come from elsewhere: `colorFuncs()` for the palette-free
146
- * math, `paletteFuncs()` for naming a theme colour. This module only paints.
145
+ * Colors themselves come from elsewhere: `colorFuncs()` for the palette-free
146
+ * math, `paletteFuncs()` for naming a theme color. This module only paints.
147
147
  * [LAW:one-way-deps] — nothing here imports a palette.
148
148
  */
149
149
  export function richTextStyleFuncs() {