@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.
- package/README.md +7 -7
- package/dist/core/animation.d.ts +37 -37
- package/dist/core/animation.js +61 -61
- package/dist/core/ansi.d.ts +4 -4
- package/dist/core/ansi.js +9 -9
- package/dist/core/bidi.js +6 -6
- package/dist/core/cells.d.ts +1 -1
- package/dist/core/cells.js +5 -5
- package/dist/core/clock.d.ts +1 -1
- package/dist/core/color.d.ts +50 -50
- package/dist/core/color.js +69 -69
- package/dist/core/console.d.ts +8 -8
- package/dist/core/console.js +5 -5
- package/dist/core/control-codes.d.ts +3 -3
- package/dist/core/control-codes.js +7 -7
- package/dist/core/easing.d.ts +40 -40
- package/dist/core/easing.js +40 -40
- package/dist/core/env.d.ts +1 -1
- package/dist/core/env.js +1 -1
- package/dist/core/export-html.js +1 -1
- package/dist/core/export-lines.d.ts +11 -11
- package/dist/core/export-lines.js +12 -12
- package/dist/core/export-svg.d.ts +3 -3
- package/dist/core/export-svg.js +4 -4
- package/dist/core/markup.js +1 -1
- package/dist/core/memo.d.ts +1 -1
- package/dist/core/memo.js +1 -1
- package/dist/core/oklch.d.ts +14 -14
- package/dist/core/oklch.js +10 -10
- package/dist/core/orient.d.ts +3 -3
- package/dist/core/orient.js +3 -3
- package/dist/core/paint.d.ts +9 -9
- package/dist/core/paint.js +3 -3
- package/dist/core/pretty.d.ts +1 -1
- package/dist/core/pretty.js +3 -3
- package/dist/core/protocol.d.ts +26 -26
- package/dist/core/protocol.js +22 -22
- package/dist/core/render.d.ts +11 -11
- package/dist/core/render.js +12 -12
- package/dist/core/segment.d.ts +3 -3
- package/dist/core/segment.js +5 -5
- package/dist/core/strip.d.ts +83 -83
- package/dist/core/strip.js +70 -70
- package/dist/core/style.d.ts +20 -20
- package/dist/core/style.js +55 -55
- package/dist/core/text.d.ts +2 -2
- package/dist/core/text.js +5 -5
- package/dist/core/timeline.d.ts +5 -5
- package/dist/core/timeline.js +9 -9
- package/dist/core/tween.d.ts +6 -6
- package/dist/core/tween.js +10 -10
- package/dist/core/view.d.ts +4 -4
- package/dist/core/view.js +12 -12
- package/dist/host/app.d.ts +9 -9
- package/dist/host/app.js +12 -12
- package/dist/host/host-environment.d.ts +2 -2
- package/dist/host/host-environment.js +2 -2
- package/dist/host/index.d.ts +2 -2
- package/dist/host/input.d.ts +7 -7
- package/dist/host/input.js +4 -4
- package/dist/host/terminal-colors.d.ts +2 -2
- package/dist/host/terminal-colors.js +4 -4
- package/dist/host/terminal-host.d.ts +2 -2
- package/dist/host/terminal-host.js +1 -1
- package/dist/index.d.ts +14 -14
- package/dist/index.js +10 -10
- package/dist/node/prompt.d.ts +1 -1
- package/dist/node/prompt.js +1 -1
- package/dist/node/terminal-host.d.ts +1 -1
- package/dist/node/traceback.js +2 -2
- package/dist/renderables/change.js +2 -2
- package/dist/renderables/effect.d.ts +39 -39
- package/dist/renderables/effect.js +45 -45
- package/dist/renderables/effects.d.ts +81 -81
- package/dist/renderables/effects.js +157 -157
- package/dist/renderables/embed.d.ts +1 -1
- package/dist/renderables/embed.js +2 -2
- package/dist/renderables/flexStrip.d.ts +7 -7
- package/dist/renderables/flexStrip.js +15 -15
- package/dist/renderables/frames.d.ts +6 -6
- package/dist/renderables/frames.js +11 -11
- package/dist/renderables/glyph-effect.d.ts +15 -15
- package/dist/renderables/glyph-effect.js +17 -17
- package/dist/renderables/glyph-effects.d.ts +7 -7
- package/dist/renderables/glyph-effects.js +16 -16
- package/dist/renderables/html-entities.d.ts +1 -1
- package/dist/renderables/html-entities.js +1 -1
- package/dist/renderables/lifecycle.d.ts +4 -4
- package/dist/renderables/lifecycle.js +12 -12
- package/dist/renderables/live.d.ts +2 -2
- package/dist/renderables/live.js +7 -7
- package/dist/renderables/markdown-parse.js +3 -3
- package/dist/renderables/panel.js +3 -3
- package/dist/renderables/progress.d.ts +1 -1
- package/dist/renderables/progress.js +1 -1
- package/dist/renderables/progressBar.d.ts +1 -1
- package/dist/renderables/progressBar.js +6 -6
- package/dist/renderables/prompt.d.ts +1 -1
- package/dist/renderables/scroll.d.ts +1 -1
- package/dist/renderables/scroll.js +3 -3
- package/dist/renderables/spinner.d.ts +4 -4
- package/dist/renderables/spinner.js +10 -10
- package/dist/renderables/syntax.d.ts +2 -2
- package/dist/renderables/syntax.js +2 -2
- package/dist/renderables/table.js +3 -3
- package/dist/renderables/traceback.d.ts +1 -1
- package/dist/renderables/traceback.js +1 -1
- package/dist/renderables/tree.js +3 -3
- package/dist/template-bindings/animation-funcs.d.ts +14 -14
- package/dist/template-bindings/animation-funcs.js +27 -27
- package/dist/template-bindings/color-funcs.d.ts +14 -14
- package/dist/template-bindings/color-funcs.js +25 -25
- package/dist/template-bindings/index.d.ts +9 -9
- package/dist/template-bindings/index.js +9 -9
- package/dist/template-bindings/palette-funcs.d.ts +1 -1
- package/dist/template-bindings/palette-funcs.js +3 -3
- package/dist/template-bindings/style-funcs.d.ts +5 -5
- package/dist/template-bindings/style-funcs.js +16 -16
- package/dist/themes/{transpose.d.ts → adjust.d.ts} +23 -23
- package/dist/themes/{transpose.js → adjust.js} +28 -28
- package/dist/themes/buildPalette.d.ts +3 -3
- package/dist/themes/buildPalette.js +20 -20
- package/dist/themes/colorMath.d.ts +16 -16
- package/dist/themes/colorMath.js +32 -32
- package/dist/themes/data/ansi-tables.d.ts +2 -2
- package/dist/themes/data/ansi-tables.js +2 -2
- package/dist/themes/data/types.d.ts +4 -4
- package/dist/themes/data/types.js +2 -2
- package/dist/themes/palette.d.ts +12 -12
- package/dist/themes/palette.js +16 -16
- package/dist/themes/ramp.d.ts +17 -17
- package/dist/themes/ramp.js +12 -12
- package/dist/themes/registry.js +4 -4
- package/dist/themes/terminalThemes.d.ts +1 -1
- package/dist/themes/terminalThemes.js +1 -1
- package/dist/widgets/button.d.ts +2 -2
- package/dist/widgets/button.js +4 -4
- package/dist/widgets/checkbox.d.ts +2 -2
- package/dist/widgets/checkbox.js +2 -2
- package/dist/widgets/dropdown.d.ts +2 -2
- package/dist/widgets/dropdown.js +3 -3
- package/dist/widgets/event-router.d.ts +6 -6
- package/dist/widgets/event-router.js +2 -2
- package/dist/widgets/focus-manager.d.ts +3 -3
- package/dist/widgets/focus-manager.js +3 -3
- package/dist/widgets/index.d.ts +2 -2
- package/dist/widgets/index.js +1 -1
- package/dist/widgets/ink.d.ts +3 -3
- package/dist/widgets/ink.js +4 -4
- package/dist/widgets/slider.d.ts +2 -2
- package/dist/widgets/static-item.d.ts +2 -2
- package/dist/widgets/text-input.d.ts +2 -2
- package/dist/widgets/text-input.js +5 -5
- package/dist/widgets/themed-widget.js +1 -1
- package/dist/widgets/toggle.d.ts +3 -3
- package/dist/widgets/toggle.js +3 -3
- package/dist/widgets/types.d.ts +6 -6
- package/dist/widgets/types.js +2 -2
- package/dist/widgets/widget-app.d.ts +10 -10
- package/dist/widgets/widget-app.js +8 -8
- package/dist/widgets/widget-base.d.ts +2 -2
- package/package.json +1 -1
|
@@ -1,48 +1,48 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Adjust a Palette to a new "key" — analogous to adjusting a melody.
|
|
3
3
|
*
|
|
4
4
|
* melody / chord progression :: Palette (relationships between colors)
|
|
5
|
-
* key (signature) ::
|
|
6
|
-
* "in C major" / "in D…" :: the resulting
|
|
5
|
+
* key (signature) :: ColorAdjustment (hue / chroma / lightness deltas)
|
|
6
|
+
* "in C major" / "in D…" :: the resulting adjusted Palette
|
|
7
7
|
*
|
|
8
8
|
* Because OKLCH is perceptually uniform, "+30° hue" looks like a
|
|
9
9
|
* consistent jump everywhere on the color wheel — the way a perfect-fifth
|
|
10
|
-
* interval sounds the same in every musical key.
|
|
11
|
-
* under composition: `
|
|
12
|
-
* colors as a single
|
|
10
|
+
* interval sounds the same in every musical key. Adjustment is closed
|
|
11
|
+
* under composition: `adjust(adjust(p, k1), k2)` produces the same
|
|
12
|
+
* colors as a single adjust with the combined deltas, modulo round-trip
|
|
13
13
|
* quantization.
|
|
14
14
|
*
|
|
15
15
|
* [LAW:dataflow-not-control-flow] A single uniform per-color transform
|
|
16
16
|
* runs for every var in the palette. Anchor protection selects *which*
|
|
17
|
-
* `
|
|
17
|
+
* `ColorAdjustment` to apply (data), not *whether* to apply one (branch).
|
|
18
18
|
*
|
|
19
19
|
* [LAW:one-source-of-truth] Anchor classification lives only in
|
|
20
|
-
* `
|
|
20
|
+
* `HUE_LOCKED_ROOTS` below. Every variant of a semantic root carries the root
|
|
21
21
|
* as its first hyphen segment (`error`, `error-darken-1`, `error-muted`, ...)
|
|
22
22
|
* or after a `text-` or `on-` that draws on it (`text-error`, `on-error`), so
|
|
23
23
|
* one set covers the whole family.
|
|
24
24
|
*
|
|
25
|
-
* [LAW:one-way-deps] Imports flow `core/oklch → themes/
|
|
25
|
+
* [LAW:one-way-deps] Imports flow `core/oklch → themes/adjust`;
|
|
26
26
|
* nothing in core/ depends back on this file.
|
|
27
27
|
*/
|
|
28
|
-
import { type
|
|
28
|
+
import { type ColorAdjustment } from "../core/oklch.js";
|
|
29
29
|
import { Palette } from "./palette.js";
|
|
30
30
|
/**
|
|
31
|
-
* Semantic roots whose hue is locked under
|
|
31
|
+
* Semantic roots whose hue is locked under adjustment. `error` must
|
|
32
32
|
* look red-ish, `success` green-ish, `warning` amber-ish — rotating the
|
|
33
33
|
* hue would make the UI lie about meaning. Lightness and chroma *still*
|
|
34
34
|
* transform for these roles, so they invert correctly during dark↔light
|
|
35
35
|
* flips and respond to chroma scaling alongside everything else.
|
|
36
36
|
*/
|
|
37
|
-
export declare const
|
|
37
|
+
export declare const HUE_LOCKED_ROOTS: ReadonlySet<string>;
|
|
38
38
|
/**
|
|
39
|
-
* Whether a palette var's hue is locked under
|
|
40
|
-
* predicate used by `
|
|
39
|
+
* Whether a palette var's hue is locked under adjustment. The single
|
|
40
|
+
* predicate used by `adjustPalette`. Exported so callers building
|
|
41
41
|
* higher-level theme machinery can stay consistent with the locking rule.
|
|
42
42
|
*/
|
|
43
|
-
export declare function
|
|
43
|
+
export declare function isHueLocked(varName: string): boolean;
|
|
44
44
|
/**
|
|
45
|
-
* Return a new `Palette` whose colors are the
|
|
45
|
+
* Return a new `Palette` whose colors are the adjustment of `palette`'s
|
|
46
46
|
* colors by `key`. Pure. Identity (`IDENTITY`) returns a Palette with byte-exact
|
|
47
47
|
* colors — fast-pathed so identity does not pay the sRGB↔OKLCH round-trip
|
|
48
48
|
* quantization cost.
|
|
@@ -57,12 +57,12 @@ export declare function isAnchored(varName: string): boolean;
|
|
|
57
57
|
* The identity fast-path preserves the source `dark` flag verbatim.
|
|
58
58
|
*
|
|
59
59
|
* @param name Optional override for the resulting palette name. Defaults
|
|
60
|
-
* to the source palette's name. Callers building a family of
|
|
60
|
+
* to the source palette's name. Callers building a family of adjusted
|
|
61
61
|
* palettes (e.g. "gruvbox +60°") supply their own.
|
|
62
62
|
*/
|
|
63
|
-
export declare function
|
|
63
|
+
export declare function adjustPalette(palette: Palette, key: ColorAdjustment, name?: string): Palette;
|
|
64
64
|
/**
|
|
65
|
-
* Build the `
|
|
65
|
+
* Build the `ColorAdjustment` that rotates `palette` so its *tonic* var lands on
|
|
66
66
|
* `targetHueDeg`. The musical operation directly: a key is the set of
|
|
67
67
|
* intervals from the tonic, so "play this theme in the key of <hue>" means
|
|
68
68
|
* "shift every color by exactly the interval that carries the tonic's
|
|
@@ -70,13 +70,13 @@ export declare function transposePalette(palette: Palette, key: ThemeKey, name?:
|
|
|
70
70
|
*
|
|
71
71
|
* Returns a hue-only key (chroma and lightness untouched). Callers that also
|
|
72
72
|
* want to scale chroma or shift lightness spread their own axes over the
|
|
73
|
-
* result — those are independent
|
|
73
|
+
* result — those are independent adjustment dimensions, not part of
|
|
74
74
|
* choosing the key. [LAW:one-type-per-behavior] a degree-shift key and a
|
|
75
75
|
* root-note key are the *same* transform; this is just a second constructor
|
|
76
|
-
* for it, so `
|
|
76
|
+
* for it, so `adjustPalette` stays untouched.
|
|
77
77
|
*
|
|
78
78
|
* Throws if `tonicVar` is absent — the interval has no anchor to measure
|
|
79
79
|
* from, so there is no honest key to return. Failing loudly beats inventing
|
|
80
|
-
* a zero shift that would silently mean "no
|
|
80
|
+
* a zero shift that would silently mean "no adjustment."
|
|
81
81
|
*/
|
|
82
|
-
export declare function
|
|
82
|
+
export declare function adjustmentForRoot(palette: Palette, tonicVar: string, targetHueDeg: number): ColorAdjustment;
|
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Adjust a Palette to a new "key" — analogous to adjusting a melody.
|
|
3
3
|
*
|
|
4
4
|
* melody / chord progression :: Palette (relationships between colors)
|
|
5
|
-
* key (signature) ::
|
|
6
|
-
* "in C major" / "in D…" :: the resulting
|
|
5
|
+
* key (signature) :: ColorAdjustment (hue / chroma / lightness deltas)
|
|
6
|
+
* "in C major" / "in D…" :: the resulting adjusted Palette
|
|
7
7
|
*
|
|
8
8
|
* Because OKLCH is perceptually uniform, "+30° hue" looks like a
|
|
9
9
|
* consistent jump everywhere on the color wheel — the way a perfect-fifth
|
|
10
|
-
* interval sounds the same in every musical key.
|
|
11
|
-
* under composition: `
|
|
12
|
-
* colors as a single
|
|
10
|
+
* interval sounds the same in every musical key. Adjustment is closed
|
|
11
|
+
* under composition: `adjust(adjust(p, k1), k2)` produces the same
|
|
12
|
+
* colors as a single adjust with the combined deltas, modulo round-trip
|
|
13
13
|
* quantization.
|
|
14
14
|
*
|
|
15
15
|
* [LAW:dataflow-not-control-flow] A single uniform per-color transform
|
|
16
16
|
* runs for every var in the palette. Anchor protection selects *which*
|
|
17
|
-
* `
|
|
17
|
+
* `ColorAdjustment` to apply (data), not *whether* to apply one (branch).
|
|
18
18
|
*
|
|
19
19
|
* [LAW:one-source-of-truth] Anchor classification lives only in
|
|
20
|
-
* `
|
|
20
|
+
* `HUE_LOCKED_ROOTS` below. Every variant of a semantic root carries the root
|
|
21
21
|
* as its first hyphen segment (`error`, `error-darken-1`, `error-muted`, ...)
|
|
22
22
|
* or after a `text-` or `on-` that draws on it (`text-error`, `on-error`), so
|
|
23
23
|
* one set covers the whole family.
|
|
24
24
|
*
|
|
25
|
-
* [LAW:one-way-deps] Imports flow `core/oklch → themes/
|
|
25
|
+
* [LAW:one-way-deps] Imports flow `core/oklch → themes/adjust`;
|
|
26
26
|
* nothing in core/ depends back on this file.
|
|
27
27
|
*/
|
|
28
28
|
import { Oklch, isIdentityKey } from "../core/oklch.js";
|
|
29
29
|
import { pattern } from "../core/pattern.js";
|
|
30
30
|
import { Palette } from "./palette.js";
|
|
31
31
|
/**
|
|
32
|
-
* Semantic roots whose hue is locked under
|
|
32
|
+
* Semantic roots whose hue is locked under adjustment. `error` must
|
|
33
33
|
* look red-ish, `success` green-ish, `warning` amber-ish — rotating the
|
|
34
34
|
* hue would make the UI lie about meaning. Lightness and chroma *still*
|
|
35
35
|
* transform for these roles, so they invert correctly during dark↔light
|
|
@@ -39,7 +39,7 @@ import { Palette } from "./palette.js";
|
|
|
39
39
|
// enforcement — typed code cannot call `add`/`delete`. (`Object.freeze` is
|
|
40
40
|
// not used here because it is a no-op on Set membership; relying on it would
|
|
41
41
|
// imply a runtime guarantee it does not provide.)
|
|
42
|
-
export const
|
|
42
|
+
export const HUE_LOCKED_ROOTS = new Set([
|
|
43
43
|
"error",
|
|
44
44
|
"success",
|
|
45
45
|
"warning",
|
|
@@ -51,15 +51,15 @@ function rootOf(varName) {
|
|
|
51
51
|
return dash === -1 ? role : role.slice(0, dash);
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
54
|
-
* Whether a palette var's hue is locked under
|
|
55
|
-
* predicate used by `
|
|
54
|
+
* Whether a palette var's hue is locked under adjustment. The single
|
|
55
|
+
* predicate used by `adjustPalette`. Exported so callers building
|
|
56
56
|
* higher-level theme machinery can stay consistent with the locking rule.
|
|
57
57
|
*/
|
|
58
|
-
export function
|
|
59
|
-
return
|
|
58
|
+
export function isHueLocked(varName) {
|
|
59
|
+
return HUE_LOCKED_ROOTS.has(rootOf(varName));
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
|
-
* Return a new `Palette` whose colors are the
|
|
62
|
+
* Return a new `Palette` whose colors are the adjustment of `palette`'s
|
|
63
63
|
* colors by `key`. Pure. Identity (`IDENTITY`) returns a Palette with byte-exact
|
|
64
64
|
* colors — fast-pathed so identity does not pay the sRGB↔OKLCH round-trip
|
|
65
65
|
* quantization cost.
|
|
@@ -74,23 +74,23 @@ export function isAnchored(varName) {
|
|
|
74
74
|
* The identity fast-path preserves the source `dark` flag verbatim.
|
|
75
75
|
*
|
|
76
76
|
* @param name Optional override for the resulting palette name. Defaults
|
|
77
|
-
* to the source palette's name. Callers building a family of
|
|
77
|
+
* to the source palette's name. Callers building a family of adjusted
|
|
78
78
|
* palettes (e.g. "gruvbox +60°") supply their own.
|
|
79
79
|
*/
|
|
80
|
-
export function
|
|
80
|
+
export function adjustPalette(palette, key, name) {
|
|
81
81
|
if (isIdentityKey(key)) {
|
|
82
|
-
return new Palette(name ?? palette.name, palette.dark, palette.mapRoles((
|
|
82
|
+
return new Palette(name ?? palette.name, palette.dark, palette.mapRoles((color) => color));
|
|
83
83
|
}
|
|
84
84
|
// Anchors share *everything except* hue with the user's key. They still
|
|
85
85
|
// lightness-invert in a dark↔light flip; they still chroma-scale in a
|
|
86
86
|
// saturation sweep — only their hue is held.
|
|
87
87
|
const anchorKey = { ...key, hueShift: 0 };
|
|
88
|
-
const next = palette.mapRoles((
|
|
88
|
+
const next = palette.mapRoles((color, role) => Oklch.fromRgba(color).applyKey(isHueLocked(role) ? anchorKey : key).toRgba());
|
|
89
89
|
const newDark = Oklch.fromRgba(next.background).l < 0.5;
|
|
90
90
|
return new Palette(name ?? palette.name, newDark, next);
|
|
91
91
|
}
|
|
92
92
|
/**
|
|
93
|
-
* Build the `
|
|
93
|
+
* Build the `ColorAdjustment` that rotates `palette` so its *tonic* var lands on
|
|
94
94
|
* `targetHueDeg`. The musical operation directly: a key is the set of
|
|
95
95
|
* intervals from the tonic, so "play this theme in the key of <hue>" means
|
|
96
96
|
* "shift every color by exactly the interval that carries the tonic's
|
|
@@ -98,26 +98,26 @@ export function transposePalette(palette, key, name) {
|
|
|
98
98
|
*
|
|
99
99
|
* Returns a hue-only key (chroma and lightness untouched). Callers that also
|
|
100
100
|
* want to scale chroma or shift lightness spread their own axes over the
|
|
101
|
-
* result — those are independent
|
|
101
|
+
* result — those are independent adjustment dimensions, not part of
|
|
102
102
|
* choosing the key. [LAW:one-type-per-behavior] a degree-shift key and a
|
|
103
103
|
* root-note key are the *same* transform; this is just a second constructor
|
|
104
|
-
* for it, so `
|
|
104
|
+
* for it, so `adjustPalette` stays untouched.
|
|
105
105
|
*
|
|
106
106
|
* Throws if `tonicVar` is absent — the interval has no anchor to measure
|
|
107
107
|
* from, so there is no honest key to return. Failing loudly beats inventing
|
|
108
|
-
* a zero shift that would silently mean "no
|
|
108
|
+
* a zero shift that would silently mean "no adjustment."
|
|
109
109
|
*/
|
|
110
|
-
export function
|
|
110
|
+
export function adjustmentForRoot(palette, tonicVar, targetHueDeg) {
|
|
111
111
|
// Validate the numeric input at the boundary: a non-finite target would
|
|
112
112
|
// propagate as NaN to Oklch's constructor several calls downstream, where
|
|
113
113
|
// the error is far less actionable.
|
|
114
114
|
if (!Number.isFinite(targetHueDeg)) {
|
|
115
|
-
throw new RangeError(`
|
|
115
|
+
throw new RangeError(`adjustmentForRoot: targetHueDeg must be a finite number; got ${targetHueDeg}`);
|
|
116
116
|
}
|
|
117
117
|
const tonic = palette.get(tonicVar);
|
|
118
118
|
if (tonic === undefined) {
|
|
119
|
-
throw new Error(`
|
|
120
|
-
`to use as the tonic; cannot measure the
|
|
119
|
+
throw new Error(`adjustmentForRoot: palette "${palette.name}" has no "${tonicVar}" var ` +
|
|
120
|
+
`to use as the tonic; cannot measure the adjustment interval.`);
|
|
121
121
|
}
|
|
122
122
|
const tonicHue = Oklch.fromRgba(tonic).h;
|
|
123
123
|
let hueShift = (targetHueDeg - tonicHue) % 360;
|
|
@@ -21,13 +21,13 @@ export declare const BASE_KEYS: readonly BaseRole[];
|
|
|
21
21
|
export declare const PALETTE_ROLES: readonly PaletteRole[];
|
|
22
22
|
/**
|
|
23
23
|
* Build a full semantic palette from its base colors and any other role it
|
|
24
|
-
* states: a stated role keeps its
|
|
24
|
+
* states: a stated role keeps its color, and everything derived from it
|
|
25
25
|
* follows it, but for `text-*`, which is held to read on its `*-muted`. An
|
|
26
26
|
* authored theme is this with roles stated; see `RULES` for what a role
|
|
27
27
|
* not stated becomes.
|
|
28
28
|
*
|
|
29
|
-
* A translucent
|
|
30
|
-
* from it, so `on-*` is chosen against the
|
|
29
|
+
* A translucent color is drawn onto `background` before anything is derived
|
|
30
|
+
* from it, so `on-*` is chosen against the color the accent is drawn as.
|
|
31
31
|
* `boost` alone stays a layer: it is what `panel` composites.
|
|
32
32
|
*/
|
|
33
33
|
export declare function buildPalette(name: string, dark: boolean, given: StatedRoles): Palette;
|
|
@@ -24,9 +24,9 @@ const TEXT_ON_MUTED = 4.5;
|
|
|
24
24
|
const ACCENT_KEYS = ["primary", "secondary", "accent", "success", "warning", "error"];
|
|
25
25
|
const TRANSPARENT = new ColorRgba(0, 0, 0, 0);
|
|
26
26
|
const WHITE = new ColorRgba(255, 255, 255);
|
|
27
|
-
const withAlpha = (
|
|
27
|
+
const withAlpha = (color, alpha) => new ColorRgba(color.red, color.green, color.blue, alpha);
|
|
28
28
|
const textOn = (alpha) => (at) => withAlpha(contrastFor(at("background")), alpha);
|
|
29
|
-
// [LAW:one-type-per-behavior] The roles naming another role's
|
|
29
|
+
// [LAW:one-type-per-behavior] The roles naming another role's color outright.
|
|
30
30
|
const same = (role) => (at) => at(role);
|
|
31
31
|
const none = () => TRANSPARENT;
|
|
32
32
|
/** The six rungs around `root`, each `-darken-3`…`-lighten-3` one `LADDER_STEP` apart. */
|
|
@@ -58,7 +58,7 @@ function accentRules(accent) {
|
|
|
58
58
|
* How each role not given to `buildPalette` is derived, following Textual's
|
|
59
59
|
* `ColorSystem`, which generated the bundled themes:
|
|
60
60
|
*
|
|
61
|
-
* - `*-muted` = the
|
|
61
|
+
* - `*-muted` = the color blended 70% toward its opposite base role — every
|
|
62
62
|
* accent AND the two base roles themselves, so a caller
|
|
63
63
|
* de-emphasizing body text reaches for `foreground-muted` the
|
|
64
64
|
* way it reaches for `primary-muted` to de-emphasize an accent.
|
|
@@ -67,7 +67,7 @@ function accentRules(accent) {
|
|
|
67
67
|
* terminal-support-dependent SGR attribute.
|
|
68
68
|
* - `text-*` = contrast text tinted 66% with the accent, the foreground for
|
|
69
69
|
* a `*-muted` ground; `buildPalette` then holds it to that ground
|
|
70
|
-
* - `on-*` = WCAG-correct contrast
|
|
70
|
+
* - `on-*` = WCAG-correct contrast color (black or white) for use as
|
|
71
71
|
* foreground when the FULL accent is the background. Picked by
|
|
72
72
|
* relative luminance — single source of truth so widgets never
|
|
73
73
|
* need to invert fg/bg to get readable text. `contrastFor` is
|
|
@@ -158,13 +158,13 @@ export const PALETTE_ROLES = [...BASE_KEYS, ...Object.keys(RULES)];
|
|
|
158
158
|
const ROLE_NAMES = new Set(PALETTE_ROLES);
|
|
159
159
|
/**
|
|
160
160
|
* Build a full semantic palette from its base colors and any other role it
|
|
161
|
-
* states: a stated role keeps its
|
|
161
|
+
* states: a stated role keeps its color, and everything derived from it
|
|
162
162
|
* follows it, but for `text-*`, which is held to read on its `*-muted`. An
|
|
163
163
|
* authored theme is this with roles stated; see `RULES` for what a role
|
|
164
164
|
* not stated becomes.
|
|
165
165
|
*
|
|
166
|
-
* A translucent
|
|
167
|
-
* from it, so `on-*` is chosen against the
|
|
166
|
+
* A translucent color is drawn onto `background` before anything is derived
|
|
167
|
+
* from it, so `on-*` is chosen against the color the accent is drawn as.
|
|
168
168
|
* `boost` alone stays a layer: it is what `panel` composites.
|
|
169
169
|
*/
|
|
170
170
|
export function buildPalette(name, dark, given) {
|
|
@@ -172,9 +172,9 @@ export function buildPalette(name, dark, given) {
|
|
|
172
172
|
// [LAW:no-ambient-temporal-coupling] A rule asks for the roles it reads, so
|
|
173
173
|
// no order among the rules matters. The eight base roles are always known.
|
|
174
174
|
const at = (role) => {
|
|
175
|
-
const
|
|
176
|
-
known.set(role,
|
|
177
|
-
return
|
|
175
|
+
const color = known.get(role) ?? RULES[role](at, dark);
|
|
176
|
+
known.set(role, color);
|
|
177
|
+
return color;
|
|
178
178
|
};
|
|
179
179
|
// [LAW:single-enforcer] Stated and derived `text-*` alike: the tint is the
|
|
180
180
|
// palette's, whether it reads is decided here. A stated tint stays translucent
|
|
@@ -193,23 +193,23 @@ export function buildPalette(name, dark, given) {
|
|
|
193
193
|
*/
|
|
194
194
|
function statedRoles(name, given) {
|
|
195
195
|
const drawn = drawnOn(name, given.background);
|
|
196
|
-
const stated = Object.entries(given).flatMap(([role,
|
|
196
|
+
const stated = Object.entries(given).flatMap(([role, color]) => {
|
|
197
197
|
if (!ROLE_NAMES.has(role))
|
|
198
198
|
throw new RangeError(`palette ${JSON.stringify(name)}: ${JSON.stringify(role)} is not a role`);
|
|
199
|
-
if (
|
|
199
|
+
if (color === undefined)
|
|
200
200
|
return [];
|
|
201
|
-
return [[role, role === "boost" ?
|
|
201
|
+
return [[role, role === "boost" ? color : drawn(color)]];
|
|
202
202
|
});
|
|
203
203
|
const known = new Map(stated);
|
|
204
|
-
// Every base
|
|
205
|
-
//
|
|
204
|
+
// Every base color is derived from, and a fully transparent one draws no
|
|
205
|
+
// color of its own to derive a muted shade or a contrast from.
|
|
206
206
|
// [LAW:no-silent-failure]
|
|
207
207
|
for (const key of BASE_KEYS) {
|
|
208
|
-
const
|
|
209
|
-
if (
|
|
210
|
-
throw new RangeError(`palette ${JSON.stringify(name)}: ${key} is fully transparent (${
|
|
208
|
+
const color = given[key];
|
|
209
|
+
if (color.alpha === 0) {
|
|
210
|
+
throw new RangeError(`palette ${JSON.stringify(name)}: ${key} is fully transparent (${color.hex}), so there is no color to derive the palette from`);
|
|
211
211
|
}
|
|
212
|
-
known.set(key, drawn(
|
|
212
|
+
known.set(key, drawn(color));
|
|
213
213
|
}
|
|
214
214
|
return known;
|
|
215
215
|
}
|
|
@@ -217,7 +217,7 @@ function statedRoles(name, given) {
|
|
|
217
217
|
* A palette's `text-*`: its tint held to WCAG AA on `*-muted`, moved toward
|
|
218
218
|
* the palette's own text side so it also reads on `background`, where widgets
|
|
219
219
|
* draw it too. The muted floor is the promise: where no lightness on the text
|
|
220
|
-
* side clears it, the
|
|
220
|
+
* side clears it, the color that does is on the other side, and the
|
|
221
221
|
* background pair is the one given up. Every bundled palette clears both
|
|
222
222
|
* (test/themes/text-on-muted.test.ts).
|
|
223
223
|
*
|
|
@@ -10,7 +10,7 @@ export declare function darken(color: ColorRgba, levels: number): ColorRgba;
|
|
|
10
10
|
*/
|
|
11
11
|
export declare function lighten(color: ColorRgba, levels: number): ColorRgba;
|
|
12
12
|
/**
|
|
13
|
-
* Move a
|
|
13
|
+
* Move a color's CIE L* by `amount` (0..1 of the L* scale), keeping its alpha.
|
|
14
14
|
* Textual's `Color.lighten`, which drew every shade ladder in the bundled
|
|
15
15
|
* themes, so a ladder derived here continues the ones authored there.
|
|
16
16
|
*/
|
|
@@ -45,16 +45,16 @@ export { relativeLuminance, contrastRatio };
|
|
|
45
45
|
* in, so the ratio is measured on what the eye actually sees and the returned
|
|
46
46
|
* color is opaque.
|
|
47
47
|
*
|
|
48
|
-
* `drawnAt` is the depth the terminal will draw the pair at. At 256
|
|
48
|
+
* `drawnAt` is the depth the terminal will draw the pair at. At 256 colors
|
|
49
49
|
* the terminal rounds text and background independently, and two roundings
|
|
50
50
|
* can meet in the middle, so the ratio is measured on the drawn pair: a
|
|
51
|
-
*
|
|
51
|
+
* color that loses the floor there is replaced by the nearest cube/grey entry
|
|
52
52
|
* that clears it (whose own rounding is itself). At ANSI the terminal draws
|
|
53
|
-
* each index in its own theme's
|
|
53
|
+
* each index in its own theme's color, so the ratio is measured on
|
|
54
54
|
* `terminal`'s sixteen: a theme whose black is light and white dark (Rosé Pine
|
|
55
|
-
* Dawn) turns the nominal table's sides over. A replacement is the
|
|
55
|
+
* Dawn) turns the nominal table's sides over. A replacement is the color the
|
|
56
56
|
* writer emits as the index nearest `fg` that clears the floor as `terminal`
|
|
57
|
-
* draws it. Truecolor draws the
|
|
57
|
+
* draws it. Truecolor draws the color chosen.
|
|
58
58
|
*
|
|
59
59
|
* [LAW:single-enforcer] The one place "is this text readable, and if not fix
|
|
60
60
|
* it" is decided. Callers route every fg/bg pair through here and the
|
|
@@ -66,35 +66,35 @@ export declare function ensureContrast(fg: ColorRgba, bg: ColorRgba, minRatio?:
|
|
|
66
66
|
drawnAt?: ColorDepth, substrate?: ColorRgba, terminal?: TerminalColors): ColorRgba;
|
|
67
67
|
/**
|
|
68
68
|
* `chosen` (composited opaque over `substrate`), or — when the depth the
|
|
69
|
-
* terminal draws at rounds it to a
|
|
69
|
+
* terminal draws at rounds it to a color `accept` refuses — the color the
|
|
70
70
|
* writer emits as the nearest entry `accept` takes. `accept` sees the
|
|
71
|
-
* candidate as drawn, and `drawn`, the same rounding for any other
|
|
71
|
+
* candidate as drawn, and `drawn`, the same rounding for any other color it
|
|
72
72
|
* measures against, so the caller states a floor once and it holds on the
|
|
73
|
-
*
|
|
73
|
+
* colors the terminal shows — at ANSI, `terminal`'s own sixteen, as
|
|
74
74
|
* `ensureContrast` measures there. Truecolor
|
|
75
|
-
* draws from no table, so a
|
|
75
|
+
* draws from no table, so a color refused there has no replacement;
|
|
76
76
|
* `undefined` means nothing the depth draws is accepted.
|
|
77
77
|
*
|
|
78
78
|
* `ensureContrast` is this with a contrast ratio as the floor; this is for a
|
|
79
79
|
* floor that is not text on its background (an open state standing off every
|
|
80
80
|
* closed cell, two planes standing off each other).
|
|
81
81
|
*/
|
|
82
|
-
export declare function
|
|
82
|
+
export declare function ensureMinimumDelta(chosen: ColorRgba, drawnAt: ColorDepth, accept: (candidate: ColorRgba, drawn: (c: ColorRgba) => ColorRgba) => boolean, substrate?: ColorRgba, terminal?: TerminalColors): ColorRgba | undefined;
|
|
83
83
|
/**
|
|
84
|
-
* The
|
|
84
|
+
* The color a ground is shown as at `drawnAt`: composited over `substrate`
|
|
85
85
|
* (the SGR writer's black by default), rounded to the index the writer emits
|
|
86
86
|
* at that depth, and shown as the terminal shows that index — at ANSI, in
|
|
87
|
-
* `terminal`'s own
|
|
87
|
+
* `terminal`'s own color. The one account `ensureMinimumDelta` and `ensureContrast`
|
|
88
88
|
* measure by, for a caller that measures a floor of its own.
|
|
89
89
|
*/
|
|
90
|
-
export declare function
|
|
90
|
+
export declare function compositedColor(color: ColorRgba, drawnAt: ColorDepth, substrate?: ColorRgba, terminal?: TerminalColors): ColorRgba;
|
|
91
91
|
/**
|
|
92
92
|
* `fg` held to `minRatio` on `bg` in truecolor, moving in lightness toward
|
|
93
93
|
* `toward` (black or white). `ensureContrast` moves toward the pole `bg`
|
|
94
|
-
* itself contrasts with; a
|
|
94
|
+
* itself contrasts with; a color that already has a side (a palette's
|
|
95
95
|
* `text-*` is its text, tinted) passes that side, since on a ground near the
|
|
96
96
|
* 0.179 cutoff both poles clear and only one also reads on everything else
|
|
97
|
-
* the
|
|
97
|
+
* the color is drawn on. Where `toward` cannot clear `minRatio` on `bg`,
|
|
98
98
|
* the floor wins over the side: the answer is `contrastFor(bg)`.
|
|
99
99
|
*/
|
|
100
100
|
export declare function ensureContrastToward(fg: ColorRgba, bg: ColorRgba, minRatio: number, toward: ColorRgba): ColorRgba;
|
package/dist/themes/colorMath.js
CHANGED
|
@@ -72,7 +72,7 @@ export function darken(color, levels) {
|
|
|
72
72
|
export function lighten(color, levels) {
|
|
73
73
|
return darken(color, -levels);
|
|
74
74
|
}
|
|
75
|
-
/** sRGB → CIE L*a*b* (D65, 2°): the space `shiftLightness` moves a
|
|
75
|
+
/** sRGB → CIE L*a*b* (D65, 2°): the space `shiftLightness` moves a color in. */
|
|
76
76
|
function rgbToLab(c) {
|
|
77
77
|
const [r, g, b] = [c.red, c.green, c.blue].map((v) => srgbToLinear(v / 255));
|
|
78
78
|
const [x, y, z] = [
|
|
@@ -96,7 +96,7 @@ function labToRgb(l, a, b, alpha) {
|
|
|
96
96
|
return new ColorRgba(red, green, blue, alpha);
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
|
-
* Move a
|
|
99
|
+
* Move a color's CIE L* by `amount` (0..1 of the L* scale), keeping its alpha.
|
|
100
100
|
* Textual's `Color.lighten`, which drew every shade ladder in the bundled
|
|
101
101
|
* themes, so a ladder derived here continues the ones authored there.
|
|
102
102
|
*/
|
|
@@ -124,8 +124,8 @@ export function contrastFor(bg, substrate = SURFACE_BLACK) {
|
|
|
124
124
|
: new ColorRgba(255, 255, 255);
|
|
125
125
|
}
|
|
126
126
|
// [LAW:one-way-deps] The WCAG measures live in core/color.ts, beside the
|
|
127
|
-
// ColorTable whose `matchReadable` needs them to pick a drawn text
|
|
128
|
-
// below the theme math here. Re-exported so this module stays the
|
|
127
|
+
// ColorTable whose `matchReadable` needs them to pick a drawn text color, and
|
|
128
|
+
// below the theme math here. Re-exported so this module stays the color-math
|
|
129
129
|
// surface.
|
|
130
130
|
export { relativeLuminance, contrastRatio };
|
|
131
131
|
// Iterations for the lightness bisection below. 20 resolves L to ~1e-6 — far
|
|
@@ -148,16 +148,16 @@ const CONTRAST_ITERS = 20;
|
|
|
148
148
|
* in, so the ratio is measured on what the eye actually sees and the returned
|
|
149
149
|
* color is opaque.
|
|
150
150
|
*
|
|
151
|
-
* `drawnAt` is the depth the terminal will draw the pair at. At 256
|
|
151
|
+
* `drawnAt` is the depth the terminal will draw the pair at. At 256 colors
|
|
152
152
|
* the terminal rounds text and background independently, and two roundings
|
|
153
153
|
* can meet in the middle, so the ratio is measured on the drawn pair: a
|
|
154
|
-
*
|
|
154
|
+
* color that loses the floor there is replaced by the nearest cube/grey entry
|
|
155
155
|
* that clears it (whose own rounding is itself). At ANSI the terminal draws
|
|
156
|
-
* each index in its own theme's
|
|
156
|
+
* each index in its own theme's color, so the ratio is measured on
|
|
157
157
|
* `terminal`'s sixteen: a theme whose black is light and white dark (Rosé Pine
|
|
158
|
-
* Dawn) turns the nominal table's sides over. A replacement is the
|
|
158
|
+
* Dawn) turns the nominal table's sides over. A replacement is the color the
|
|
159
159
|
* writer emits as the index nearest `fg` that clears the floor as `terminal`
|
|
160
|
-
* draws it. Truecolor draws the
|
|
160
|
+
* draws it. Truecolor draws the color chosen.
|
|
161
161
|
*
|
|
162
162
|
* [LAW:single-enforcer] The one place "is this text readable, and if not fix
|
|
163
163
|
* it" is decided. Callers route every fg/bg pair through here and the
|
|
@@ -181,23 +181,23 @@ drawnAt = ColorDepth.TRUECOLOR, substrate = SURFACE_BLACK, terminal) {
|
|
|
181
181
|
}
|
|
182
182
|
/**
|
|
183
183
|
* `chosen` (composited opaque over `substrate`), or — when the depth the
|
|
184
|
-
* terminal draws at rounds it to a
|
|
184
|
+
* terminal draws at rounds it to a color `accept` refuses — the color the
|
|
185
185
|
* writer emits as the nearest entry `accept` takes. `accept` sees the
|
|
186
|
-
* candidate as drawn, and `drawn`, the same rounding for any other
|
|
186
|
+
* candidate as drawn, and `drawn`, the same rounding for any other color it
|
|
187
187
|
* measures against, so the caller states a floor once and it holds on the
|
|
188
|
-
*
|
|
188
|
+
* colors the terminal shows — at ANSI, `terminal`'s own sixteen, as
|
|
189
189
|
* `ensureContrast` measures there. Truecolor
|
|
190
|
-
* draws from no table, so a
|
|
190
|
+
* draws from no table, so a color refused there has no replacement;
|
|
191
191
|
* `undefined` means nothing the depth draws is accepted.
|
|
192
192
|
*
|
|
193
193
|
* `ensureContrast` is this with a contrast ratio as the floor; this is for a
|
|
194
194
|
* floor that is not text on its background (an open state standing off every
|
|
195
195
|
* closed cell, two planes standing off each other).
|
|
196
196
|
*/
|
|
197
|
-
export function
|
|
197
|
+
export function ensureMinimumDelta(chosen, drawnAt, accept, substrate = SURFACE_BLACK, terminal) {
|
|
198
198
|
// The floor was measured on `chosen` composited over `substrate`, so that
|
|
199
|
-
// opaque
|
|
200
|
-
// ground would composite into a
|
|
199
|
+
// opaque color is what is returned — never a translucent one a different
|
|
200
|
+
// ground would composite into a color `accept` never saw.
|
|
201
201
|
const opaque = drawnBackground(chosen, substrate);
|
|
202
202
|
const table = drawnTable(drawnAt, terminal);
|
|
203
203
|
const drawn = (c) => shownAs(table, drawnBackground(c, substrate));
|
|
@@ -209,17 +209,17 @@ export function ensureDrawn(chosen, drawnAt, accept, substrate = SURFACE_BLACK,
|
|
|
209
209
|
return index === undefined ? undefined : table.written.get(index);
|
|
210
210
|
}
|
|
211
211
|
/**
|
|
212
|
-
* The
|
|
212
|
+
* The color a ground is shown as at `drawnAt`: composited over `substrate`
|
|
213
213
|
* (the SGR writer's black by default), rounded to the index the writer emits
|
|
214
214
|
* at that depth, and shown as the terminal shows that index — at ANSI, in
|
|
215
|
-
* `terminal`'s own
|
|
215
|
+
* `terminal`'s own color. The one account `ensureMinimumDelta` and `ensureContrast`
|
|
216
216
|
* measure by, for a caller that measures a floor of its own.
|
|
217
217
|
*/
|
|
218
|
-
export function
|
|
219
|
-
return shownAs(drawnTable(drawnAt, terminal), drawnBackground(
|
|
218
|
+
export function compositedColor(color, drawnAt, substrate = SURFACE_BLACK, terminal) {
|
|
219
|
+
return shownAs(drawnTable(drawnAt, terminal), drawnBackground(color, substrate));
|
|
220
220
|
}
|
|
221
221
|
/**
|
|
222
|
-
* An opaque
|
|
222
|
+
* An opaque color as the terminal shows it: downgraded to the index the
|
|
223
223
|
* writer emits and drawn as the terminal draws that index.
|
|
224
224
|
* [LAW:one-source-of-truth] That rounding is `ColorSpec.downgrade`'s, the one
|
|
225
225
|
* `Style.drawnColors` writes; the tables here only list the candidates.
|
|
@@ -232,13 +232,13 @@ function shownAs(table, opaque) {
|
|
|
232
232
|
* surface is a fact about where the pair is drawn, so it arrives as a value:
|
|
233
233
|
* the SGR writer (`Style.toSgrCodes`) and the exports that picture its output
|
|
234
234
|
* composite over `SURFACE_BLACK`, the default here; a caller that composites
|
|
235
|
-
* its
|
|
235
|
+
* its colors onto a different surface itself names that one.
|
|
236
236
|
* [LAW:no-silent-failure] A surface has nothing under it, so a translucent one
|
|
237
|
-
* has no drawn
|
|
237
|
+
* has no drawn color to offer; `compositeOver` would read its raw RGB as if
|
|
238
238
|
* it were opaque, so it is refused here rather than measured wrong.
|
|
239
|
-
* [LAW:one-source-of-truth] Text is chosen against the
|
|
240
|
-
* show — measuring the raw RGBA reads a
|
|
241
|
-
* that "clears" it can land below the floor. Opaque
|
|
239
|
+
* [LAW:one-source-of-truth] Text is chosen against the color the surface will
|
|
240
|
+
* show — measuring the raw RGBA reads a color that is drawn nowhere, and text
|
|
241
|
+
* that "clears" it can land below the floor. Opaque colors composite to
|
|
242
242
|
* themselves.
|
|
243
243
|
*/
|
|
244
244
|
function drawnBackground(bg, substrate) {
|
|
@@ -248,12 +248,12 @@ function drawnBackground(bg, substrate) {
|
|
|
248
248
|
return bg.compositeOver(substrate);
|
|
249
249
|
}
|
|
250
250
|
/**
|
|
251
|
-
* The table the terminal draws from at `drawnAt`. The 256-
|
|
252
|
-
* grey ramp are fixed by xterm, so the
|
|
251
|
+
* The table the terminal draws from at `drawnAt`. The 256-color cube and
|
|
252
|
+
* grey ramp are fixed by xterm, so the color written is the color shown.
|
|
253
253
|
* ANSI 0–15 are the terminal theme's own: the writer still picks the index by
|
|
254
254
|
* the nominal table — the Windows console's at WINDOWS — and the terminal
|
|
255
|
-
* shows `terminal`'s
|
|
256
|
-
* Truecolor draws the chosen
|
|
255
|
+
* shows `terminal`'s color there.
|
|
256
|
+
* Truecolor draws the chosen color itself, as do the depths no table stands
|
|
257
257
|
* behind.
|
|
258
258
|
*/
|
|
259
259
|
function drawnTable(drawnAt, terminal) {
|
|
@@ -272,10 +272,10 @@ function drawnTable(drawnAt, terminal) {
|
|
|
272
272
|
/**
|
|
273
273
|
* `fg` held to `minRatio` on `bg` in truecolor, moving in lightness toward
|
|
274
274
|
* `toward` (black or white). `ensureContrast` moves toward the pole `bg`
|
|
275
|
-
* itself contrasts with; a
|
|
275
|
+
* itself contrasts with; a color that already has a side (a palette's
|
|
276
276
|
* `text-*` is its text, tinted) passes that side, since on a ground near the
|
|
277
277
|
* 0.179 cutoff both poles clear and only one also reads on everything else
|
|
278
|
-
* the
|
|
278
|
+
* the color is drawn on. Where `toward` cannot clear `minRatio` on `bg`,
|
|
279
279
|
* the floor wins over the side: the answer is `contrastFor(bg)`.
|
|
280
280
|
*/
|
|
281
281
|
export function ensureContrastToward(fg, bg, minRatio, toward) {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { type AnsiColorsData } from "./types.js";
|
|
2
2
|
/**
|
|
3
|
-
* The VGA
|
|
3
|
+
* The VGA colors a terminal draws with no theme of its own: Rich's
|
|
4
4
|
* `DEFAULT_TERMINAL_THEME`, and what `textual-ansi` spells its palette in.
|
|
5
5
|
*/
|
|
6
6
|
export declare const VGA_ANSI: AnsiColorsData;
|
|
7
7
|
/**
|
|
8
|
-
* The ANSI tables Textual draws named
|
|
8
|
+
* The ANSI tables Textual draws named colors in for a theme that has no
|
|
9
9
|
* terminal scheme of its own: `MONOKAI` under a dark theme and `ALABASTER`
|
|
10
10
|
* under a light one (`ansi_theme_dark` / `ansi_theme_light` in Textual's
|
|
11
11
|
* `app.py`, values from its `_ansi_theme.py`).
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { STANDARD_TABLE } from "../../core/color.js";
|
|
2
2
|
import { ANSI_SLOTS } from "./types.js";
|
|
3
3
|
/**
|
|
4
|
-
* The VGA
|
|
4
|
+
* The VGA colors a terminal draws with no theme of its own: Rich's
|
|
5
5
|
* `DEFAULT_TERMINAL_THEME`, and what `textual-ansi` spells its palette in.
|
|
6
6
|
*/
|
|
7
7
|
export const VGA_ANSI = Object.fromEntries(ANSI_SLOTS.map((slot, n) => [slot, STANDARD_TABLE.get(n).hex]));
|
|
8
8
|
/**
|
|
9
|
-
* The ANSI tables Textual draws named
|
|
9
|
+
* The ANSI tables Textual draws named colors in for a theme that has no
|
|
10
10
|
* terminal scheme of its own: `MONOKAI` under a dark theme and `ALABASTER`
|
|
11
11
|
* under a light one (`ansi_theme_dark` / `ansi_theme_light` in Textual's
|
|
12
12
|
* `app.py`, values from its `_ansi_theme.py`).
|