@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.
- package/README.md +11 -8
- package/dist/core/box.d.ts +3 -1
- package/dist/core/box.js +6 -13
- package/dist/core/cells.d.ts +61 -28
- package/dist/core/cells.js +171 -124
- package/dist/core/clock.d.ts +48 -0
- package/dist/core/clock.js +42 -0
- package/dist/core/color.d.ts +99 -18
- package/dist/core/color.js +334 -146
- package/dist/core/console.d.ts +38 -7
- package/dist/core/console.js +159 -90
- package/dist/core/easing.d.ts +86 -0
- package/dist/core/easing.js +171 -0
- package/dist/core/env.d.ts +16 -0
- package/dist/core/env.js +16 -0
- package/dist/core/export-html.js +1 -4
- package/dist/core/export-lines.d.ts +22 -13
- package/dist/core/export-lines.js +37 -19
- package/dist/core/export-svg.d.ts +49 -0
- package/dist/core/export-svg.js +213 -0
- package/dist/core/fnv1a.d.ts +10 -0
- package/dist/core/fnv1a.js +17 -0
- package/dist/core/highlighter.d.ts +2 -2
- package/dist/core/highlighter.js +113 -47
- package/dist/core/json.js +1 -1
- package/dist/core/markup.d.ts +28 -7
- package/dist/core/markup.js +235 -312
- package/dist/core/measure.d.ts +3 -3
- package/dist/core/measure.js +12 -7
- package/dist/core/memo.d.ts +19 -0
- package/dist/core/memo.js +34 -0
- package/dist/core/noise.d.ts +31 -0
- package/dist/core/noise.js +94 -0
- package/dist/core/osc8.d.ts +6 -6
- package/dist/core/osc8.js +9 -21
- package/dist/core/paint.d.ts +107 -0
- package/dist/core/paint.js +161 -0
- package/dist/core/place.d.ts +1 -1
- package/dist/core/place.js +4 -6
- package/dist/core/pretty.d.ts +126 -2
- package/dist/core/pretty.js +571 -105
- package/dist/core/protocol.d.ts +43 -3
- package/dist/core/protocol.js +23 -2
- package/dist/core/render.d.ts +33 -30
- package/dist/core/render.js +43 -83
- package/dist/core/segment.d.ts +6 -5
- package/dist/core/segment.js +11 -15
- package/dist/core/selection.d.ts +12 -0
- package/dist/core/selection.js +14 -0
- package/dist/core/strip.d.ts +116 -74
- package/dist/core/strip.js +266 -217
- package/dist/core/style.d.ts +27 -7
- package/dist/core/style.js +106 -41
- package/dist/core/text.d.ts +43 -16
- package/dist/core/text.js +180 -59
- package/dist/core/wrap.d.ts +5 -0
- package/dist/core/wrap.js +16 -3
- package/dist/host/app.d.ts +95 -17
- package/dist/host/app.js +201 -61
- package/dist/host/index.d.ts +4 -1
- package/dist/host/index.js +1 -0
- package/dist/host/input.d.ts +84 -0
- package/dist/host/input.js +498 -0
- package/dist/host/terminal-host.d.ts +15 -2
- package/dist/host/terminal-host.js +2 -0
- package/dist/index.d.ts +26 -14
- package/dist/index.js +17 -7
- package/dist/node/prompt.d.ts +13 -0
- package/dist/node/prompt.js +30 -9
- package/dist/node/save.d.ts +4 -3
- package/dist/node/save.js +6 -3
- package/dist/node/terminal-host.d.ts +10 -2
- package/dist/node/terminal-host.js +7 -0
- package/dist/node/traceback.d.ts +2 -1
- package/dist/node/traceback.js +3 -39
- package/dist/renderables/align.js +2 -9
- package/dist/renderables/columns.d.ts +45 -29
- package/dist/renderables/columns.js +142 -103
- package/dist/renderables/constrain.js +6 -12
- package/dist/renderables/effect.d.ts +113 -0
- package/dist/renderables/effect.js +182 -0
- package/dist/renderables/effects.d.ts +252 -0
- package/dist/renderables/effects.js +565 -0
- package/dist/renderables/embed.d.ts +94 -31
- package/dist/renderables/embed.js +141 -45
- package/dist/renderables/group.d.ts +6 -3
- package/dist/renderables/group.js +5 -0
- package/dist/renderables/layout.d.ts +6 -23
- package/dist/renderables/layout.js +24 -113
- package/dist/renderables/list-view.d.ts +42 -0
- package/dist/renderables/list-view.js +78 -0
- package/dist/renderables/live.d.ts +40 -16
- package/dist/renderables/live.js +96 -83
- package/dist/renderables/markdown.d.ts +16 -2
- package/dist/renderables/markdown.js +521 -118
- package/dist/renderables/padding.d.ts +22 -1
- package/dist/renderables/padding.js +30 -24
- package/dist/renderables/panel.d.ts +31 -33
- package/dist/renderables/panel.js +137 -141
- package/dist/renderables/progress.d.ts +110 -16
- package/dist/renderables/progress.js +212 -81
- package/dist/renderables/progressBar.d.ts +24 -4
- package/dist/renderables/progressBar.js +78 -23
- package/dist/renderables/prompt.d.ts +37 -15
- package/dist/renderables/prompt.js +125 -85
- package/dist/renderables/ratio.d.ts +123 -0
- package/dist/renderables/ratio.js +213 -0
- package/dist/renderables/rule.d.ts +3 -2
- package/dist/renderables/rule.js +50 -52
- package/dist/renderables/spinner.d.ts +28 -2
- package/dist/renderables/spinner.js +52 -19
- package/dist/renderables/status.d.ts +13 -7
- package/dist/renderables/status.js +15 -29
- package/dist/renderables/syntax.d.ts +37 -7
- package/dist/renderables/syntax.js +134 -83
- package/dist/renderables/table.d.ts +58 -20
- package/dist/renderables/table.js +373 -197
- package/dist/renderables/traceback.d.ts +5 -4
- package/dist/renderables/traceback.js +239 -68
- package/dist/renderables/tree.d.ts +10 -2
- package/dist/renderables/tree.js +61 -34
- package/dist/renderables/viewport.d.ts +30 -0
- package/dist/renderables/viewport.js +61 -7
- package/dist/template-bindings/color-funcs.d.ts +31 -9
- package/dist/template-bindings/color-funcs.js +40 -14
- package/dist/template-bindings/helpers.d.ts +4 -2
- package/dist/template-bindings/helpers.js +5 -20
- package/dist/template-bindings/index.d.ts +29 -17
- package/dist/template-bindings/index.js +36 -20
- package/dist/template-bindings/palette-funcs.d.ts +3 -1
- package/dist/template-bindings/palette-funcs.js +11 -7
- package/dist/template-bindings/style-funcs.js +4 -2
- package/dist/themes/buildPalette.d.ts +24 -3
- package/dist/themes/buildPalette.js +52 -8
- package/dist/themes/colorMath.d.ts +29 -17
- package/dist/themes/colorMath.js +74 -48
- package/dist/themes/colorRef.d.ts +2 -17
- package/dist/themes/colorRef.js +13 -31
- package/dist/themes/palette.d.ts +24 -0
- package/dist/themes/palette.js +46 -3
- package/dist/themes/ramp.d.ts +21 -34
- package/dist/themes/ramp.js +23 -42
- package/dist/themes/registry.js +39 -28
- package/dist/widgets/button.d.ts +2 -6
- package/dist/widgets/button.js +9 -40
- package/dist/widgets/checkbox.d.ts +2 -5
- package/dist/widgets/checkbox.js +9 -31
- package/dist/widgets/dropdown.d.ts +2 -5
- package/dist/widgets/dropdown.js +17 -51
- package/dist/widgets/event-router.d.ts +31 -40
- package/dist/widgets/event-router.js +52 -483
- package/dist/widgets/index.d.ts +2 -1
- package/dist/widgets/ink.d.ts +22 -0
- package/dist/widgets/ink.js +31 -0
- package/dist/widgets/slider.d.ts +2 -5
- package/dist/widgets/slider.js +11 -34
- package/dist/widgets/text-input.d.ts +19 -10
- package/dist/widgets/text-input.js +156 -147
- package/dist/widgets/themed-widget.d.ts +20 -0
- package/dist/widgets/themed-widget.js +89 -0
- package/dist/widgets/toggle.d.ts +2 -5
- package/dist/widgets/toggle.js +8 -31
- package/dist/widgets/types.d.ts +8 -25
- package/dist/widgets/types.js +8 -0
- package/dist/widgets/widget-app.d.ts +24 -7
- package/dist/widgets/widget-app.js +35 -18
- package/dist/widgets/widget-base.d.ts +2 -0
- package/dist/widgets/widget-base.js +9 -2
- package/package.json +31 -17
package/dist/themes/ramp.js
CHANGED
|
@@ -9,46 +9,22 @@
|
|
|
9
9
|
* can no longer transpose with the palette it was meant to belong to. A ramp
|
|
10
10
|
* is the one function whose input is a number, so the decision stays inside.
|
|
11
11
|
*
|
|
12
|
-
* A threshold cascade is a ramp too: the same stops with
|
|
12
|
+
* A threshold cascade is a ramp too: the same stops with the `step` ease hold
|
|
13
13
|
* each color until the next position, which is exactly `≥ threshold → hotter`
|
|
14
14
|
* written as data. [LAW:one-type-per-behavior] One primitive; the easing is a
|
|
15
|
-
* value
|
|
16
|
-
* was
|
|
15
|
+
* value — any `Ease` from `core/easing`, the vocabulary every effect shares —
|
|
16
|
+
* so a gradient and a cascade differ by one word, not by which function was
|
|
17
|
+
* called. [LAW:dataflow-not-control-flow] `at` applies it unconditionally.
|
|
17
18
|
*
|
|
18
19
|
* Interpolation is in OKLCH (`Oklch.mix`), so a `linear` ramp between two
|
|
19
20
|
* theme colors passes through perceptually even steps rather than the muddy
|
|
20
21
|
* midpoints of an sRGB blend.
|
|
21
22
|
*
|
|
22
|
-
* [LAW:one-way-deps] Imports `core/color` and `core/oklch`
|
|
23
|
-
* knows what a palette is. Resolving stop *names* is the template binding's
|
|
23
|
+
* [LAW:one-way-deps] Imports `core/color`, `core/easing` and `core/oklch`
|
|
24
|
+
* only; nothing here knows what a palette is. Resolving stop *names* is the template binding's
|
|
24
25
|
* job (`paletteFuncs`), which hands this module resolved colors.
|
|
25
26
|
*/
|
|
26
27
|
import { Oklch } from "../core/oklch.js";
|
|
27
|
-
/**
|
|
28
|
-
* How a value between two stops maps to progress along them. Each easing is
|
|
29
|
-
* a function on segment progress `t ∈ [0, 1)` — `linear` keeps it, `step`
|
|
30
|
-
* holds the left stop for the whole segment.
|
|
31
|
-
*
|
|
32
|
-
* [LAW:dataflow-not-control-flow] The easing is looked up by name and applied
|
|
33
|
-
* unconditionally; `at` runs the same code for a gradient and a cascade.
|
|
34
|
-
*/
|
|
35
|
-
export const RAMP_EASINGS = {
|
|
36
|
-
linear: (t) => t,
|
|
37
|
-
step: () => 0,
|
|
38
|
-
};
|
|
39
|
-
export const RAMP_EASING_NAMES = Object.keys(RAMP_EASINGS);
|
|
40
|
-
/**
|
|
41
|
-
* The gate a spelled easing crosses. [LAW:parse-dont-validate] — returns the
|
|
42
|
-
* narrowed name, so `ColorRamp` never re-checks. Unknown names throw naming
|
|
43
|
-
* every legal one. [LAW:no-silent-failure]
|
|
44
|
-
*/
|
|
45
|
-
export function parseRampEasing(name) {
|
|
46
|
-
if (!Object.hasOwn(RAMP_EASINGS, name)) {
|
|
47
|
-
throw new RangeError(`unknown ramp easing ${JSON.stringify(name)}; expected one of ` +
|
|
48
|
-
RAMP_EASING_NAMES.map((n) => JSON.stringify(n)).join(", "));
|
|
49
|
-
}
|
|
50
|
-
return name;
|
|
51
|
-
}
|
|
52
28
|
/**
|
|
53
29
|
* An immutable ramp over stops sorted by position.
|
|
54
30
|
*
|
|
@@ -65,10 +41,10 @@ export function parseRampEasing(name) {
|
|
|
65
41
|
* same way).
|
|
66
42
|
*/
|
|
67
43
|
export class ColorRamp {
|
|
68
|
-
|
|
44
|
+
ease;
|
|
69
45
|
stops;
|
|
70
|
-
constructor(
|
|
71
|
-
this.
|
|
46
|
+
constructor(ease, stops) {
|
|
47
|
+
this.ease = ease;
|
|
72
48
|
this.stops = stops;
|
|
73
49
|
if (stops.length === 0) {
|
|
74
50
|
throw new RangeError("a ColorRamp needs at least one stop");
|
|
@@ -86,14 +62,19 @@ export class ColorRamp {
|
|
|
86
62
|
}
|
|
87
63
|
/**
|
|
88
64
|
* The color at `value`. Below the first stop it is the first color; at or
|
|
89
|
-
* above the last stop it is the last; between two stops
|
|
90
|
-
*
|
|
91
|
-
*
|
|
65
|
+
* above the last stop it is the last; between two stops the raw progress
|
|
66
|
+
* from the lower to the upper goes through `ease`, and the eased progress
|
|
67
|
+
* says how far to mix.
|
|
92
68
|
*
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
*
|
|
96
|
-
* paint a color the author
|
|
69
|
+
* Eased progress 0 is the lower stop's color and 1 the upper's, byte for
|
|
70
|
+
* byte — the exactness contract, not a shortcut: the sRGB → OKLCH → sRGB
|
|
71
|
+
* round-trip can land a channel one unit off, and a ramp that did not hit
|
|
72
|
+
* its own stops exactly would make a `step` ramp paint a color the author
|
|
73
|
+
* never wrote. So a value on a stop is that stop's color whenever the ease
|
|
74
|
+
* starts at 0, as every built-in does but `step-start` and the
|
|
75
|
+
* `jump-start`/`jump-both` steps, which jump at the start of the interval as
|
|
76
|
+
* CSS defines them. An ease that overshoots [0, 1] holds the end colors
|
|
77
|
+
* where it does: a ramp never paints outside its stops.
|
|
97
78
|
*/
|
|
98
79
|
at(value) {
|
|
99
80
|
if (!Number.isFinite(value)) {
|
|
@@ -110,9 +91,9 @@ export class ColorRamp {
|
|
|
110
91
|
if (lower === stops.length - 1)
|
|
111
92
|
return from.color;
|
|
112
93
|
// `to.at > value >= from.at` by construction of `lower`, so the segment
|
|
113
|
-
// has positive width and
|
|
94
|
+
// has positive width and raw progress is in [0, 1).
|
|
114
95
|
const to = stops[lower + 1];
|
|
115
|
-
const t =
|
|
96
|
+
const t = this.ease((value - from.at) / (to.at - from.at));
|
|
116
97
|
if (t <= 0)
|
|
117
98
|
return from.color;
|
|
118
99
|
if (t >= 1)
|
package/dist/themes/registry.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Palette } from "./palette.js";
|
|
1
|
+
import { ColorParseError, ColorTable, parseHexColor } from "../core/color.js";
|
|
2
|
+
import { Palette, drawnOn } from "./palette.js";
|
|
3
|
+
import { ACCENT_KEYS, accentText } from "./buildPalette.js";
|
|
3
4
|
import { THEMES } from "./data/index.js";
|
|
4
5
|
import { ANSI_SLOTS } from "./data/types.js";
|
|
5
6
|
const THEME_NAMES = Object.freeze(Object.keys(THEMES).sort());
|
|
@@ -31,17 +32,22 @@ function isThemeName(name) {
|
|
|
31
32
|
*/
|
|
32
33
|
export function getThemeBaseColors(name) {
|
|
33
34
|
const data = THEMES[name];
|
|
35
|
+
const bg = requireBaseVar(data, "background");
|
|
36
|
+
// The colours `getThemePalette(name)` hands out for the same names: drawn on
|
|
37
|
+
// the theme's own background, as a Palette draws every colour it holds.
|
|
38
|
+
const draw = drawnOn(data.name, bg);
|
|
39
|
+
const base = (key) => draw(requireBaseVar(data, key));
|
|
34
40
|
return {
|
|
35
41
|
name: data.name,
|
|
36
42
|
dark: data.dark,
|
|
37
|
-
bg
|
|
38
|
-
fg:
|
|
39
|
-
primary:
|
|
40
|
-
secondary:
|
|
41
|
-
accent:
|
|
42
|
-
success:
|
|
43
|
-
warning:
|
|
44
|
-
error:
|
|
43
|
+
bg,
|
|
44
|
+
fg: base("foreground"),
|
|
45
|
+
primary: base("primary"),
|
|
46
|
+
secondary: base("secondary"),
|
|
47
|
+
accent: base("accent"),
|
|
48
|
+
success: base("success"),
|
|
49
|
+
warning: base("warning"),
|
|
50
|
+
error: base("error"),
|
|
45
51
|
ansi: new ColorTable(ANSI_SLOTS.map((slot) => parseOpaqueHex(data.ansi[slot], data.name, `ansi.${slot}`))),
|
|
46
52
|
};
|
|
47
53
|
}
|
|
@@ -64,31 +70,36 @@ function requireBaseVar(data, key) {
|
|
|
64
70
|
function hydrate(data) {
|
|
65
71
|
const map = new Map();
|
|
66
72
|
for (const [k, v] of Object.entries(data.vars)) {
|
|
67
|
-
map.set(k, parseHex(v, data.name, k));
|
|
73
|
+
map.set(k, parseHex(v, data.name, `var ${k}`));
|
|
74
|
+
}
|
|
75
|
+
// The data is Textual's as authored; its `text-*` is held to the pair this
|
|
76
|
+
// library promises by the same rule `buildPalette` derives it with.
|
|
77
|
+
for (const key of ACCENT_KEYS) {
|
|
78
|
+
const text = requireBaseVar(data, `text-${key}`);
|
|
79
|
+
map.set(`text-${key}`, accentText(text, requireBaseVar(data, `${key}-muted`), requireBaseVar(data, "background")));
|
|
68
80
|
}
|
|
69
81
|
return new Palette(data.name, data.dark, map);
|
|
70
82
|
}
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
83
|
+
// Theme data is authored, so a malformed colour names the theme and the key it
|
|
84
|
+
// sits under; the grammar itself is `parseHexColor`'s.
|
|
85
|
+
function parseHex(value, theme, key) {
|
|
86
|
+
try {
|
|
87
|
+
return parseHexColor(value);
|
|
88
|
+
}
|
|
89
|
+
catch (cause) {
|
|
90
|
+
if (!(cause instanceof ColorParseError))
|
|
91
|
+
throw cause;
|
|
92
|
+
throw new Error(`Theme ${theme}: ${key}: ${cause.message}`, { cause });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
77
95
|
/**
|
|
78
96
|
* An ANSI slot is a colour a terminal paints, never a blend, so it takes no
|
|
79
97
|
* alpha: `flattenAlpha` leaves a STANDARD spec alone and would pass one through.
|
|
80
98
|
*/
|
|
81
99
|
function parseOpaqueHex(value, theme, key) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
return parseRgbHex(value.slice(1));
|
|
86
|
-
}
|
|
87
|
-
function parseHex(value, theme, key) {
|
|
88
|
-
const hex = value.startsWith("#") ? value.slice(1) : value;
|
|
89
|
-
if ((hex.length !== 6 && hex.length !== 8) || !HEX_RE.test(hex)) {
|
|
90
|
-
throw new Error(`Theme ${theme}: var ${key} has invalid hex ${JSON.stringify(value)} ` +
|
|
91
|
-
`(expected #RRGGBB or #RRGGBBAA)`);
|
|
100
|
+
const color = parseHex(value, theme, key);
|
|
101
|
+
if (color.alpha !== 1) {
|
|
102
|
+
throw new Error(`Theme ${theme}: ${key} has alpha in ${JSON.stringify(value)} (expected #RRGGBB)`);
|
|
92
103
|
}
|
|
93
|
-
return
|
|
104
|
+
return color;
|
|
94
105
|
}
|
package/dist/widgets/button.d.ts
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { Segment } from "../core/segment.js";
|
|
19
19
|
import type { RenderOptions } from "../core/protocol.js";
|
|
20
20
|
import type { TerminalTheme } from "../core/color.js";
|
|
21
|
-
import {
|
|
21
|
+
import { ThemedWidget } from "./themed-widget.js";
|
|
22
22
|
import type { KeyEvent, WidgetMouseEvent } from "./types.js";
|
|
23
23
|
export type ButtonVariant = "default" | "primary" | "success" | "warning" | "danger";
|
|
24
24
|
export interface ButtonOptions {
|
|
@@ -28,14 +28,12 @@ export interface ButtonOptions {
|
|
|
28
28
|
disabled?: boolean;
|
|
29
29
|
theme?: TerminalTheme;
|
|
30
30
|
}
|
|
31
|
-
export declare class Button extends
|
|
31
|
+
export declare class Button extends ThemedWidget {
|
|
32
32
|
readonly id: string;
|
|
33
33
|
readonly focusable = true;
|
|
34
34
|
accessor label: string;
|
|
35
35
|
accessor variant: ButtonVariant;
|
|
36
|
-
private accessor _theme;
|
|
37
36
|
constructor(options: ButtonOptions);
|
|
38
|
-
setTheme(theme: TerminalTheme): void;
|
|
39
37
|
handleKey(event: KeyEvent): void;
|
|
40
38
|
handleMouse(event: WidgetMouseEvent): void;
|
|
41
39
|
setActive(value: boolean): void;
|
|
@@ -44,6 +42,4 @@ export declare class Button extends WidgetBase {
|
|
|
44
42
|
minimum: number;
|
|
45
43
|
maximum: number;
|
|
46
44
|
};
|
|
47
|
-
private resolveColors;
|
|
48
|
-
private resolvePalette;
|
|
49
45
|
}
|
package/dist/widgets/button.js
CHANGED
|
@@ -52,10 +52,9 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
52
52
|
import { observable, action, observableRef } from "mobx";
|
|
53
53
|
import { Segment } from "../core/segment.js";
|
|
54
54
|
import { Style } from "../core/style.js";
|
|
55
|
-
import { ColorSpec } from "../core/color.js";
|
|
56
55
|
import { cellLen } from "../core/cells.js";
|
|
57
|
-
import {
|
|
58
|
-
import {
|
|
56
|
+
import { ThemedWidget } from "./themed-widget.js";
|
|
57
|
+
import { ink } from "./ink.js";
|
|
59
58
|
// Variant → palette key mapping. Per variant:
|
|
60
59
|
// bg / fg — normal state. Muted accent bg + mostly-accent fg → readable.
|
|
61
60
|
// hover — full accent bg; pair with hoverFg, NOT with `fg`. The
|
|
@@ -70,7 +69,7 @@ const VARIANT_KEYS = {
|
|
|
70
69
|
danger: { bg: "error-muted", fg: "text-error", hover: "error", hoverFg: "on-error" },
|
|
71
70
|
};
|
|
72
71
|
let Button = (() => {
|
|
73
|
-
let _classSuper =
|
|
72
|
+
let _classSuper = ThemedWidget;
|
|
74
73
|
let _instanceExtraInitializers = [];
|
|
75
74
|
let _label_decorators;
|
|
76
75
|
let _label_initializers = [];
|
|
@@ -78,10 +77,6 @@ let Button = (() => {
|
|
|
78
77
|
let _variant_decorators;
|
|
79
78
|
let _variant_initializers = [];
|
|
80
79
|
let _variant_extraInitializers = [];
|
|
81
|
-
let __theme_decorators;
|
|
82
|
-
let __theme_initializers = [];
|
|
83
|
-
let __theme_extraInitializers = [];
|
|
84
|
-
let _setTheme_decorators;
|
|
85
80
|
let _handleKey_decorators;
|
|
86
81
|
let _handleMouse_decorators;
|
|
87
82
|
let _setActive_decorators;
|
|
@@ -90,15 +85,11 @@ let Button = (() => {
|
|
|
90
85
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
91
86
|
_label_decorators = [observable];
|
|
92
87
|
_variant_decorators = [observableRef];
|
|
93
|
-
__theme_decorators = [observableRef];
|
|
94
|
-
_setTheme_decorators = [action];
|
|
95
88
|
_handleKey_decorators = [action];
|
|
96
89
|
_handleMouse_decorators = [action];
|
|
97
90
|
_setActive_decorators = [action];
|
|
98
91
|
__esDecorate(this, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
|
|
99
92
|
__esDecorate(this, null, _variant_decorators, { kind: "accessor", name: "variant", static: false, private: false, access: { has: obj => "variant" in obj, get: obj => obj.variant, set: (obj, value) => { obj.variant = value; } }, metadata: _metadata }, _variant_initializers, _variant_extraInitializers);
|
|
100
|
-
__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);
|
|
101
|
-
__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);
|
|
102
93
|
__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);
|
|
103
94
|
__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);
|
|
104
95
|
__esDecorate(this, null, _setActive_decorators, { kind: "method", name: "setActive", static: false, private: false, access: { has: obj => "setActive" in obj, get: obj => obj.setActive }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
@@ -112,21 +103,14 @@ let Button = (() => {
|
|
|
112
103
|
#variant_accessor_storage = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, _variant_initializers, void 0));
|
|
113
104
|
get variant() { return this.#variant_accessor_storage; }
|
|
114
105
|
set variant(value) { this.#variant_accessor_storage = value; }
|
|
115
|
-
#_theme_accessor_storage = (__runInitializers(this, _variant_extraInitializers), __runInitializers(this, __theme_initializers, void 0));
|
|
116
|
-
// [LAW:types-are-the-program] @observableRef so setTheme() triggers a
|
|
117
|
-
// re-render — see slider.ts.
|
|
118
|
-
get _theme() { return this.#_theme_accessor_storage; }
|
|
119
|
-
set _theme(value) { this.#_theme_accessor_storage = value; }
|
|
120
106
|
constructor(options) {
|
|
121
|
-
super();
|
|
122
|
-
__runInitializers(this,
|
|
107
|
+
super(options.theme);
|
|
108
|
+
__runInitializers(this, _variant_extraInitializers);
|
|
123
109
|
this.id = options.id ?? `button-${options.label.toLowerCase().replace(/\s+/g, "-")}`;
|
|
124
110
|
this.label = options.label;
|
|
125
111
|
this.variant = options.variant ?? "default";
|
|
126
112
|
this.disabled = options.disabled ?? false;
|
|
127
|
-
this._theme = options.theme ?? DEFAULT_TERMINAL_THEME;
|
|
128
113
|
}
|
|
129
|
-
setTheme(theme) { this._theme = theme; }
|
|
130
114
|
// --- Event handlers ---
|
|
131
115
|
handleKey(event) {
|
|
132
116
|
if (this.disabled)
|
|
@@ -170,19 +154,17 @@ let Button = (() => {
|
|
|
170
154
|
const right = focused ? "]" : " ";
|
|
171
155
|
const text = `${left} ${this.label} ${right}`;
|
|
172
156
|
if (this.disabled) {
|
|
173
|
-
return [new Segment(text, new Style(
|
|
157
|
+
return [new Segment(text, new Style(this.disabledInk))];
|
|
174
158
|
}
|
|
175
159
|
// Active and hover share the same colour pair (full accent bg + on-accent fg).
|
|
176
160
|
// Active is differentiated by bold, not by inverting fg/bg — inversion gives
|
|
177
161
|
// mostly-accent text on mostly-bg-tinted background, which is unreadable for
|
|
178
162
|
// accents whose contrast partner depends on luminance.
|
|
163
|
+
const keys = VARIANT_KEYS[this.variant];
|
|
179
164
|
if (this.active || this.hovered) {
|
|
180
|
-
|
|
181
|
-
const bg = this.resolvePalette(VARIANT_KEYS[this.variant].hover);
|
|
182
|
-
return [new Segment(text, new Style({ color: fg, bgcolor: bg, bold: this.active }))];
|
|
165
|
+
return [new Segment(text, new Style({ ...ink(this.theme, keys.hoverFg, keys.hover), bold: this.active }))];
|
|
183
166
|
}
|
|
184
|
-
|
|
185
|
-
return [new Segment(text, new Style({ color: fg, bgcolor: bg }))];
|
|
167
|
+
return [new Segment(text, new Style(ink(this.theme, keys.fg, keys.bg)))];
|
|
186
168
|
}
|
|
187
169
|
measure(_options) {
|
|
188
170
|
// [LAW:one-source-of-truth] cellLen is the cell-width authority; .length
|
|
@@ -190,19 +172,6 @@ let Button = (() => {
|
|
|
190
172
|
const width = cellLen(this.label) + 4;
|
|
191
173
|
return { minimum: width, maximum: width };
|
|
192
174
|
}
|
|
193
|
-
// --- Palette resolution ---
|
|
194
|
-
resolveColors(bgKey) {
|
|
195
|
-
const keys = VARIANT_KEYS[this.variant];
|
|
196
|
-
return {
|
|
197
|
-
fg: this.resolvePalette(keys.fg),
|
|
198
|
-
bg: this.resolvePalette(bgKey === "hover" ? keys.hover : keys.bg),
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
resolvePalette(key) {
|
|
202
|
-
const rgba = this._theme.palette.get(key);
|
|
203
|
-
// [LAW:no-defensive-null-guards] palette is required and must contain all keys.
|
|
204
|
-
return ColorSpec.fromRgba(rgba);
|
|
205
|
-
}
|
|
206
175
|
};
|
|
207
176
|
})();
|
|
208
177
|
export { Button };
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { Segment } from "../core/segment.js";
|
|
14
14
|
import { type RenderOptions } from "../core/protocol.js";
|
|
15
15
|
import type { TerminalTheme } from "../core/color.js";
|
|
16
|
-
import {
|
|
16
|
+
import { ThemedWidget } from "./themed-widget.js";
|
|
17
17
|
import type { KeyEvent, WidgetMouseEvent } from "./types.js";
|
|
18
18
|
export interface CheckboxOptions {
|
|
19
19
|
label: string;
|
|
@@ -22,14 +22,12 @@ export interface CheckboxOptions {
|
|
|
22
22
|
disabled?: boolean;
|
|
23
23
|
theme?: TerminalTheme;
|
|
24
24
|
}
|
|
25
|
-
export declare class Checkbox extends
|
|
25
|
+
export declare class Checkbox extends ThemedWidget {
|
|
26
26
|
readonly id: string;
|
|
27
27
|
readonly focusable = true;
|
|
28
28
|
accessor label: string;
|
|
29
29
|
accessor checked: boolean;
|
|
30
|
-
private accessor _theme;
|
|
31
30
|
constructor(options: CheckboxOptions);
|
|
32
|
-
setTheme(theme: TerminalTheme): void;
|
|
33
31
|
handleKey(event: KeyEvent): void;
|
|
34
32
|
handleMouse(event: WidgetMouseEvent): void;
|
|
35
33
|
protected draw(options: RenderOptions): Iterable<Segment>;
|
|
@@ -37,5 +35,4 @@ export declare class Checkbox extends WidgetBase {
|
|
|
37
35
|
minimum: number;
|
|
38
36
|
maximum: number;
|
|
39
37
|
};
|
|
40
|
-
private resolvePalette;
|
|
41
38
|
}
|
package/dist/widgets/checkbox.js
CHANGED
|
@@ -44,16 +44,15 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
44
44
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
45
45
|
done = true;
|
|
46
46
|
};
|
|
47
|
-
import { observable, action
|
|
47
|
+
import { observable, action } from "mobx";
|
|
48
48
|
import { Segment } from "../core/segment.js";
|
|
49
49
|
import { Style } from "../core/style.js";
|
|
50
|
-
import { ColorSpec } from "../core/color.js";
|
|
51
50
|
import { cellLen } from "../core/cells.js";
|
|
52
|
-
import { DEFAULT_TERMINAL_THEME } from "../themes/terminalThemes.js";
|
|
53
51
|
import { drawable } from "../core/protocol.js";
|
|
54
|
-
import {
|
|
52
|
+
import { ThemedWidget } from "./themed-widget.js";
|
|
53
|
+
import { ink } from "./ink.js";
|
|
55
54
|
let Checkbox = (() => {
|
|
56
|
-
let _classSuper =
|
|
55
|
+
let _classSuper = ThemedWidget;
|
|
57
56
|
let _instanceExtraInitializers = [];
|
|
58
57
|
let _label_decorators;
|
|
59
58
|
let _label_initializers = [];
|
|
@@ -61,10 +60,6 @@ let Checkbox = (() => {
|
|
|
61
60
|
let _checked_decorators;
|
|
62
61
|
let _checked_initializers = [];
|
|
63
62
|
let _checked_extraInitializers = [];
|
|
64
|
-
let __theme_decorators;
|
|
65
|
-
let __theme_initializers = [];
|
|
66
|
-
let __theme_extraInitializers = [];
|
|
67
|
-
let _setTheme_decorators;
|
|
68
63
|
let _handleKey_decorators;
|
|
69
64
|
let _handleMouse_decorators;
|
|
70
65
|
return class Checkbox extends _classSuper {
|
|
@@ -72,14 +67,10 @@ let Checkbox = (() => {
|
|
|
72
67
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
73
68
|
_label_decorators = [observable];
|
|
74
69
|
_checked_decorators = [observable];
|
|
75
|
-
__theme_decorators = [observableRef];
|
|
76
|
-
_setTheme_decorators = [action];
|
|
77
70
|
_handleKey_decorators = [action];
|
|
78
71
|
_handleMouse_decorators = [action];
|
|
79
72
|
__esDecorate(this, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
|
|
80
73
|
__esDecorate(this, null, _checked_decorators, { kind: "accessor", name: "checked", static: false, private: false, access: { has: obj => "checked" in obj, get: obj => obj.checked, set: (obj, value) => { obj.checked = value; } }, metadata: _metadata }, _checked_initializers, _checked_extraInitializers);
|
|
81
|
-
__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);
|
|
82
|
-
__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);
|
|
83
74
|
__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);
|
|
84
75
|
__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);
|
|
85
76
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
@@ -92,21 +83,14 @@ let Checkbox = (() => {
|
|
|
92
83
|
#checked_accessor_storage = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, _checked_initializers, void 0));
|
|
93
84
|
get checked() { return this.#checked_accessor_storage; }
|
|
94
85
|
set checked(value) { this.#checked_accessor_storage = value; }
|
|
95
|
-
#_theme_accessor_storage = (__runInitializers(this, _checked_extraInitializers), __runInitializers(this, __theme_initializers, void 0));
|
|
96
|
-
// [LAW:types-are-the-program] @observableRef so setTheme() triggers a
|
|
97
|
-
// re-render — see slider.ts.
|
|
98
|
-
get _theme() { return this.#_theme_accessor_storage; }
|
|
99
|
-
set _theme(value) { this.#_theme_accessor_storage = value; }
|
|
100
86
|
constructor(options) {
|
|
101
|
-
super();
|
|
102
|
-
__runInitializers(this,
|
|
87
|
+
super(options.theme);
|
|
88
|
+
__runInitializers(this, _checked_extraInitializers);
|
|
103
89
|
this.id = options.id ?? `checkbox-${options.label.toLowerCase().replace(/\s+/g, "-")}`;
|
|
104
90
|
this.label = options.label;
|
|
105
91
|
this.checked = options.checked ?? false;
|
|
106
92
|
this.disabled = options.disabled ?? false;
|
|
107
|
-
this._theme = options.theme ?? DEFAULT_TERMINAL_THEME;
|
|
108
93
|
}
|
|
109
|
-
setTheme(theme) { this._theme = theme; }
|
|
110
94
|
// --- Event handlers ---
|
|
111
95
|
handleKey(event) {
|
|
112
96
|
if (this.disabled)
|
|
@@ -136,22 +120,16 @@ let Checkbox = (() => {
|
|
|
136
120
|
const indicator = this.checked ? drawable(options, "✓", "x") : " ";
|
|
137
121
|
const text = `[${indicator}] ${this.label}`;
|
|
138
122
|
if (this.disabled) {
|
|
139
|
-
return [new Segment(text, new Style(
|
|
123
|
+
return [new Segment(text, new Style(this.disabledInk))];
|
|
140
124
|
}
|
|
141
|
-
const
|
|
142
|
-
return [new Segment(text, new Style({
|
|
125
|
+
const colors = ink(this.theme, this.checked ? "text-primary" : "foreground", "background");
|
|
126
|
+
return [new Segment(text, new Style({ ...colors, underline: this.focused }))];
|
|
143
127
|
}
|
|
144
128
|
measure(_options) {
|
|
145
129
|
// [LAW:one-source-of-truth] cellLen — see button.ts.
|
|
146
130
|
const width = cellLen(this.label) + 4;
|
|
147
131
|
return { minimum: width, maximum: width };
|
|
148
132
|
}
|
|
149
|
-
// --- Palette resolution ---
|
|
150
|
-
resolvePalette(key) {
|
|
151
|
-
const rgba = this._theme.palette.get(key);
|
|
152
|
-
// [LAW:no-defensive-null-guards] palette must contain all keys; missing is a construction bug.
|
|
153
|
-
return ColorSpec.fromRgba(rgba);
|
|
154
|
-
}
|
|
155
133
|
};
|
|
156
134
|
})();
|
|
157
135
|
export { Checkbox };
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
import { Segment } from "../core/segment.js";
|
|
26
26
|
import { type RenderOptions } from "../core/protocol.js";
|
|
27
27
|
import type { TerminalTheme } from "../core/color.js";
|
|
28
|
-
import {
|
|
28
|
+
import { ThemedWidget } from "./themed-widget.js";
|
|
29
29
|
import type { KeyEvent, WidgetMouseEvent, WidgetFocusEvent, OverlayRenderable } from "./types.js";
|
|
30
30
|
export interface DropdownOptions {
|
|
31
31
|
options: string[];
|
|
@@ -34,7 +34,7 @@ export interface DropdownOptions {
|
|
|
34
34
|
disabled?: boolean;
|
|
35
35
|
theme?: TerminalTheme;
|
|
36
36
|
}
|
|
37
|
-
export declare class Dropdown extends
|
|
37
|
+
export declare class Dropdown extends ThemedWidget implements OverlayRenderable {
|
|
38
38
|
readonly id: string;
|
|
39
39
|
readonly focusable = true;
|
|
40
40
|
accessor options: string[];
|
|
@@ -46,10 +46,8 @@ export declare class Dropdown extends WidgetBase implements OverlayRenderable {
|
|
|
46
46
|
label: string;
|
|
47
47
|
idx: number;
|
|
48
48
|
}[];
|
|
49
|
-
private accessor _theme;
|
|
50
49
|
constructor(options: DropdownOptions);
|
|
51
50
|
private clampIndex;
|
|
52
|
-
setTheme(theme: TerminalTheme): void;
|
|
53
51
|
handleKey(event: KeyEvent): void;
|
|
54
52
|
handleMouse(event: WidgetMouseEvent): void;
|
|
55
53
|
handleFocus(event: WidgetFocusEvent): void;
|
|
@@ -63,5 +61,4 @@ export declare class Dropdown extends WidgetBase implements OverlayRenderable {
|
|
|
63
61
|
minimum: number;
|
|
64
62
|
maximum: number;
|
|
65
63
|
};
|
|
66
|
-
private resolvePalette;
|
|
67
64
|
}
|