@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
|
@@ -1,50 +1,113 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The one crossing where content a caller hands a renderable — a table cell, a
|
|
3
|
-
* panel's body, title or subtitle, a
|
|
4
|
-
* a rule's title — becomes something that renderable can
|
|
3
|
+
* panel's body, title or subtitle, a padding's body, a tree label, a column
|
|
4
|
+
* item, a layout pane, a rule's title — becomes something that renderable can
|
|
5
|
+
* lay out.
|
|
5
6
|
* [LAW:single-enforcer]
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* A string is kept as written and read when it is drawn, through `readStr`,
|
|
9
|
+
* under the options it is drawn with. That is where a console's settings
|
|
10
|
+
* arrive: its `markup` decides whether the string is markup, and its
|
|
11
|
+
* highlighter highlights it, exactly as they do for a string handed to `print`.
|
|
12
|
+
* Parsed when the renderable was built, a string was markup under a console
|
|
13
|
+
* that had turned markup off, never met the console's highlighter, and an
|
|
14
|
+
* unmatched closing tag threw from a constructor rather than from the render
|
|
15
|
+
* that would draw it, where Rich's does (rich-markup-3sw).
|
|
11
16
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* default
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `end` is cleared because embedded text is a fragment rather than a printed
|
|
19
|
-
* line; left at the default `"\n"` it draws a trailing blank row. A `RichText`
|
|
20
|
-
* is copied first, since clearing in place would reach back into the caller's
|
|
21
|
-
* object.
|
|
17
|
+
* Text keeps its own `end`, as a body does in Rich: `RichText("foo\n")` draws
|
|
18
|
+
* the blank row its default `"\n"` end makes, and a string reads with that
|
|
19
|
+
* default end as `render_str` gives it. Only a label, set into a line it
|
|
20
|
+
* shares, clears it. A `RichText` is copied when it is handed over, since the
|
|
21
|
+
* caller still holds it, and every text drawn from it is a copy again, since
|
|
22
|
+
* the drawing site may change it.
|
|
22
23
|
*/
|
|
23
24
|
import type { Measurable, Renderable, RenderOptions } from "../core/protocol.js";
|
|
24
25
|
import { Segment } from "../core/segment.js";
|
|
25
|
-
import type { Style } from "../core/style.js";
|
|
26
|
+
import type { Style, TextStyle } from "../core/style.js";
|
|
26
27
|
import { RichText } from "../core/text.js";
|
|
27
28
|
/**
|
|
28
|
-
* Caller content as
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* `[object Object]` is not eaten as a tag.
|
|
29
|
+
* Caller content as text an embedding site lays out. A string is the only kind
|
|
30
|
+
* of content that can contain markup, so it is the only kind whose reading
|
|
31
|
+
* waits for the options; any other value is its `String` form as written, so an
|
|
32
|
+
* object's `[object Object]` is not eaten as a tag.
|
|
32
33
|
*/
|
|
33
|
-
export declare
|
|
34
|
+
export declare class EmbeddedText implements Renderable, Measurable {
|
|
35
|
+
private readonly _source;
|
|
36
|
+
private readonly _readings;
|
|
37
|
+
constructor(content: unknown);
|
|
38
|
+
/**
|
|
39
|
+
* The text this content draws under `options`. A string reads with `base` as
|
|
40
|
+
* its style, as Rich's `render_str(style=)` gives one; text handed over
|
|
41
|
+
* keeps its own, since the caller already said how it looks — so a table's
|
|
42
|
+
* `Text` title draws without the title style, as Rich's does. A highlighted
|
|
43
|
+
* string keeps only its spans: Rich's `render_str` highlights a fresh `Text`
|
|
44
|
+
* of the plain string and copies the spans onto it, so `base` is lost there,
|
|
45
|
+
* and a title Rich reads with highlighting on draws without it.
|
|
46
|
+
*/
|
|
47
|
+
text(options: RenderOptions, base?: TextStyle): RichText;
|
|
48
|
+
render(options: RenderOptions): Iterable<Segment>;
|
|
49
|
+
/**
|
|
50
|
+
* Measured unhighlighted, as Rich's `Measurement.get` reads a string with
|
|
51
|
+
* `highlight=False`: so a container that clears the highlighter for what it
|
|
52
|
+
* draws measures what it draws, whether or not it clears it for what it
|
|
53
|
+
* measures, and no highlighter runs just to be thrown away.
|
|
54
|
+
*/
|
|
55
|
+
measure(options: RenderOptions): {
|
|
56
|
+
minimum: number;
|
|
57
|
+
maximum: number;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
34
60
|
/**
|
|
35
61
|
* Caller content as something an embedding site can render. A non-text
|
|
36
|
-
* `Renderable` (a nested `Panel` or `Table`) passes through: it
|
|
37
|
-
*
|
|
62
|
+
* `Renderable` (a nested `Panel` or `Table`) passes through: it has no markup
|
|
63
|
+
* to parse. Everything else is `EmbeddedText`.
|
|
38
64
|
*/
|
|
39
65
|
export declare function embed(content: unknown): Renderable & Partial<Measurable>;
|
|
40
66
|
/**
|
|
41
67
|
* Caller content set into a line it shares with other drawing — a panel's
|
|
42
|
-
* title or subtitle in its border, a rule's title — as
|
|
43
|
-
*
|
|
44
|
-
*
|
|
68
|
+
* title or subtitle in its border, a rule's title — read as Rich's `_title`
|
|
69
|
+
* reads it: newlines become spaces, so the label stays on its line, and tabs
|
|
70
|
+
* are widened to their stops. Whatever sets it off from the line around it —
|
|
71
|
+
* a panel's space either side, a rule's gaps — is the embedding site's.
|
|
45
72
|
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
48
|
-
|
|
73
|
+
* Held once by the renderable that owns it, so a string's markup is read once
|
|
74
|
+
* and every measure and render after reuses that reading.
|
|
75
|
+
*/
|
|
76
|
+
export declare class InlineLabel {
|
|
77
|
+
private readonly _content;
|
|
78
|
+
constructor(content: string | RichText);
|
|
79
|
+
/**
|
|
80
|
+
* The label drawn under `options`: one line, its own overflow kept for the
|
|
81
|
+
* caller's cut. A string reads with `base` as its style, as `EmbeddedText.text` reads one.
|
|
82
|
+
*/
|
|
83
|
+
text(options: RenderOptions, base?: TextStyle): RichText;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A label cut to `width` cells as Rich's `Text.truncate` cuts one: its plain
|
|
87
|
+
* text set to the width less `marker` — a wide character the cut splits leaves
|
|
88
|
+
* a space in its cell rather than a cell of the line around it — then the
|
|
89
|
+
* marker, with every span that ran past the cut trimmed to the new end, so the
|
|
90
|
+
* pad and the marker take the styling of what they replace. A label that fits
|
|
91
|
+
* is left as it is.
|
|
92
|
+
*/
|
|
93
|
+
export declare function cutLabel(text: RichText, width: number, marker: string): void;
|
|
94
|
+
/**
|
|
95
|
+
* Whether caller content is there at all, decided on the content as given, as
|
|
96
|
+
* Rich's `if self.title` decides it: absent, an empty string and an empty
|
|
97
|
+
* `Text` are not, and markup that styles nothing is — it reads as empty text,
|
|
98
|
+
* but the string that holds it is not empty.
|
|
99
|
+
*/
|
|
100
|
+
export declare function present(content: string | RichText | undefined): content is string | RichText;
|
|
101
|
+
/**
|
|
102
|
+
* A label's text as one line of segments at its natural width, its own styles
|
|
103
|
+
* laid over `base`. The caller has already cut it to its room, so it leaves as
|
|
104
|
+
* it stands: `"ignore"` also leaves it unjustified, its spaces where `pad` put
|
|
105
|
+
* them.
|
|
106
|
+
*/
|
|
107
|
+
export declare function drawLabel(text: RichText, options: RenderOptions, base: Style | undefined): Segment[];
|
|
108
|
+
/**
|
|
109
|
+
* Caller content as a label, or no label at all: content that is not
|
|
110
|
+
* `present` draws the plain rule, and markup that styles nothing is an empty
|
|
111
|
+
* label, which still opens a gap in the rule, as Rich's does.
|
|
49
112
|
*/
|
|
50
|
-
export declare function inlineLabel(content:
|
|
113
|
+
export declare function inlineLabel(content: string | RichText | undefined): InlineLabel | undefined;
|
|
@@ -1,71 +1,167 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The one crossing where content a caller hands a renderable — a table cell, a
|
|
3
|
-
* panel's body, title or subtitle, a
|
|
4
|
-
* a rule's title — becomes something that renderable can
|
|
3
|
+
* panel's body, title or subtitle, a padding's body, a tree label, a column
|
|
4
|
+
* item, a layout pane, a rule's title — becomes something that renderable can
|
|
5
|
+
* lay out.
|
|
5
6
|
* [LAW:single-enforcer]
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* A string is kept as written and read when it is drawn, through `readStr`,
|
|
9
|
+
* under the options it is drawn with. That is where a console's settings
|
|
10
|
+
* arrive: its `markup` decides whether the string is markup, and its
|
|
11
|
+
* highlighter highlights it, exactly as they do for a string handed to `print`.
|
|
12
|
+
* Parsed when the renderable was built, a string was markup under a console
|
|
13
|
+
* that had turned markup off, never met the console's highlighter, and an
|
|
14
|
+
* unmatched closing tag threw from a constructor rather than from the render
|
|
15
|
+
* that would draw it, where Rich's does (rich-markup-3sw).
|
|
11
16
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* default
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* `end` is cleared because embedded text is a fragment rather than a printed
|
|
19
|
-
* line; left at the default `"\n"` it draws a trailing blank row. A `RichText`
|
|
20
|
-
* is copied first, since clearing in place would reach back into the caller's
|
|
21
|
-
* object.
|
|
17
|
+
* Text keeps its own `end`, as a body does in Rich: `RichText("foo\n")` draws
|
|
18
|
+
* the blank row its default `"\n"` end makes, and a string reads with that
|
|
19
|
+
* default end as `render_str` gives it. Only a label, set into a line it
|
|
20
|
+
* shares, clears it. A `RichText` is copied when it is handed over, since the
|
|
21
|
+
* caller still holds it, and every text drawn from it is a copy again, since
|
|
22
|
+
* the drawing site may change it.
|
|
22
23
|
*/
|
|
23
|
-
import {
|
|
24
|
+
import { cellCount, cellLen, setCellSize } from "../core/cells.js";
|
|
25
|
+
import { activeHighlighter, readStr } from "../core/markup.js";
|
|
24
26
|
import { Segment } from "../core/segment.js";
|
|
25
27
|
import { RichText } from "../core/text.js";
|
|
26
28
|
/**
|
|
27
|
-
* Caller content as
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
* `[object Object]` is not eaten as a tag.
|
|
29
|
+
* Caller content as text an embedding site lays out. A string is the only kind
|
|
30
|
+
* of content that can contain markup, so it is the only kind whose reading
|
|
31
|
+
* waits for the options; any other value is its `String` form as written, so an
|
|
32
|
+
* object's `[object Object]` is not eaten as a tag.
|
|
31
33
|
*/
|
|
32
|
-
export
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
34
|
+
export class EmbeddedText {
|
|
35
|
+
// [LAW:types-are-the-program] Two kinds, and the kind is the discriminator: a
|
|
36
|
+
// string still to be read, or text whose reading is already fixed.
|
|
37
|
+
_source;
|
|
38
|
+
// A string's reading under each markup setting, made the first time one is
|
|
39
|
+
// asked for. Parsing is the costly half of drawing a string, and a table
|
|
40
|
+
// measures every cell more than once per print; read on every call, a
|
|
41
|
+
// 500-row table of markup printed 75% slower.
|
|
42
|
+
_readings = new Map();
|
|
43
|
+
constructor(content) {
|
|
44
|
+
if (typeof content === "string") {
|
|
45
|
+
this._source = content;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
this._source = content instanceof RichText ? content.copy() : new RichText(String(content ?? ""));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The text this content draws under `options`. A string reads with `base` as
|
|
53
|
+
* its style, as Rich's `render_str(style=)` gives one; text handed over
|
|
54
|
+
* keeps its own, since the caller already said how it looks — so a table's
|
|
55
|
+
* `Text` title draws without the title style, as Rich's does. A highlighted
|
|
56
|
+
* string keeps only its spans: Rich's `render_str` highlights a fresh `Text`
|
|
57
|
+
* of the plain string and copies the spans onto it, so `base` is lost there,
|
|
58
|
+
* and a title Rich reads with highlighting on draws without it.
|
|
59
|
+
*/
|
|
60
|
+
text(options, base) {
|
|
61
|
+
if (typeof this._source !== "string")
|
|
62
|
+
return this._source.copy();
|
|
63
|
+
const markup = options.markup !== false;
|
|
64
|
+
const reading = this._readings.get(markup) ?? readStr(this._source, markup);
|
|
65
|
+
this._readings.set(markup, reading);
|
|
66
|
+
const text = reading.copy();
|
|
67
|
+
const highlighter = activeHighlighter(options);
|
|
68
|
+
if (base !== undefined && highlighter === undefined)
|
|
69
|
+
text.style = base;
|
|
70
|
+
highlighter?.highlight(text);
|
|
71
|
+
return text;
|
|
72
|
+
}
|
|
73
|
+
render(options) {
|
|
74
|
+
return this.text(options).render(options);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Measured unhighlighted, as Rich's `Measurement.get` reads a string with
|
|
78
|
+
* `highlight=False`: so a container that clears the highlighter for what it
|
|
79
|
+
* draws measures what it draws, whether or not it clears it for what it
|
|
80
|
+
* measures, and no highlighter runs just to be thrown away.
|
|
81
|
+
*/
|
|
82
|
+
measure(options) {
|
|
83
|
+
return this.text({ ...options, highlight: false }).measure(options);
|
|
84
|
+
}
|
|
40
85
|
}
|
|
41
86
|
/**
|
|
42
87
|
* Caller content as something an embedding site can render. A non-text
|
|
43
|
-
* `Renderable` (a nested `Panel` or `Table`) passes through: it
|
|
44
|
-
*
|
|
88
|
+
* `Renderable` (a nested `Panel` or `Table`) passes through: it has no markup
|
|
89
|
+
* to parse. Everything else is `EmbeddedText`.
|
|
45
90
|
*/
|
|
46
91
|
export function embed(content) {
|
|
47
92
|
if (!(content instanceof RichText) && typeof content === "object" && content !== null && "render" in content) {
|
|
48
93
|
return content;
|
|
49
94
|
}
|
|
50
|
-
return
|
|
95
|
+
return new EmbeddedText(content);
|
|
51
96
|
}
|
|
52
97
|
/**
|
|
53
98
|
* Caller content set into a line it shares with other drawing — a panel's
|
|
54
|
-
* title or subtitle in its border, a rule's title — as
|
|
55
|
-
*
|
|
56
|
-
*
|
|
99
|
+
* title or subtitle in its border, a rule's title — read as Rich's `_title`
|
|
100
|
+
* reads it: newlines become spaces, so the label stays on its line, and tabs
|
|
101
|
+
* are widened to their stops. Whatever sets it off from the line around it —
|
|
102
|
+
* a panel's space either side, a rule's gaps — is the embedding site's.
|
|
57
103
|
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
|
|
104
|
+
* Held once by the renderable that owns it, so a string's markup is read once
|
|
105
|
+
* and every measure and render after reuses that reading.
|
|
106
|
+
*/
|
|
107
|
+
export class InlineLabel {
|
|
108
|
+
_content;
|
|
109
|
+
constructor(content) {
|
|
110
|
+
this._content = new EmbeddedText(content);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* The label drawn under `options`: one line, its own overflow kept for the
|
|
114
|
+
* caller's cut. A string reads with `base` as its style, as `EmbeddedText.text` reads one.
|
|
115
|
+
*/
|
|
116
|
+
text(options, base) {
|
|
117
|
+
const text = this._content.text(options, base);
|
|
118
|
+
// A fragment of the line, so its own end is not drawn, as Rich's `_title` clears it.
|
|
119
|
+
text.end = "";
|
|
120
|
+
text.plain = text.plain.replaceAll("\n", " ");
|
|
121
|
+
// Tabs widened before anything measures it, so a cut to the border and
|
|
122
|
+
// the width a title asks for count the cells the label will draw.
|
|
123
|
+
return text.expandTabs();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* A label cut to `width` cells as Rich's `Text.truncate` cuts one: its plain
|
|
128
|
+
* text set to the width less `marker` — a wide character the cut splits leaves
|
|
129
|
+
* a space in its cell rather than a cell of the line around it — then the
|
|
130
|
+
* marker, with every span that ran past the cut trimmed to the new end, so the
|
|
131
|
+
* pad and the marker take the styling of what they replace. A label that fits
|
|
132
|
+
* is left as it is.
|
|
61
133
|
*/
|
|
62
|
-
export function
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
134
|
+
export function cutLabel(text, width, marker) {
|
|
135
|
+
if (text.cellLength <= width)
|
|
136
|
+
return;
|
|
137
|
+
text.plain = setCellSize(text.plain, cellCount(width - cellLen(marker))) + marker;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Whether caller content is there at all, decided on the content as given, as
|
|
141
|
+
* Rich's `if self.title` decides it: absent, an empty string and an empty
|
|
142
|
+
* `Text` are not, and markup that styles nothing is — it reads as empty text,
|
|
143
|
+
* but the string that holds it is not empty.
|
|
144
|
+
*/
|
|
145
|
+
export function present(content) {
|
|
146
|
+
// Asked of what the content is rather than of what it is not, so a `null`
|
|
147
|
+
// from untyped JS is no content, as Rich's `None` is.
|
|
148
|
+
return typeof content === "string" ? content !== "" : content instanceof RichText && content.plain !== "";
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* A label's text as one line of segments at its natural width, its own styles
|
|
152
|
+
* laid over `base`. The caller has already cut it to its room, so it leaves as
|
|
153
|
+
* it stands: `"ignore"` also leaves it unjustified, its spaces where `pad` put
|
|
154
|
+
* them.
|
|
155
|
+
*/
|
|
156
|
+
export function drawLabel(text, options, base) {
|
|
69
157
|
text.overflow = "ignore";
|
|
70
158
|
return [...Segment.applyStyle(text.render(options), base)];
|
|
71
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Caller content as a label, or no label at all: content that is not
|
|
162
|
+
* `present` draws the plain rule, and markup that styles nothing is an empty
|
|
163
|
+
* label, which still opens a gap in the rule, as Rich's does.
|
|
164
|
+
*/
|
|
165
|
+
export function inlineLabel(content) {
|
|
166
|
+
return present(content) ? new InlineLabel(content) : undefined;
|
|
167
|
+
}
|
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
* Group — renders multiple renderables in sequence.
|
|
3
3
|
* No visual chrome — purely a container.
|
|
4
4
|
*/
|
|
5
|
-
import { Segment } from "../core/segment.js";
|
|
6
|
-
import
|
|
7
|
-
|
|
5
|
+
import type { Segment } from "../core/segment.js";
|
|
6
|
+
import { type Measurement } from "../core/measure.js";
|
|
7
|
+
import type { Measurable, Renderable, RenderOptions } from "../core/protocol.js";
|
|
8
|
+
export declare class Group implements Renderable, Measurable {
|
|
8
9
|
readonly renderables: Renderable[];
|
|
9
10
|
constructor(...renderables: Renderable[]);
|
|
10
11
|
render(options: RenderOptions): Iterable<Segment>;
|
|
12
|
+
/** As wide as its widest member: the reference's `measure_renderables`. */
|
|
13
|
+
measure(options: RenderOptions): Measurement;
|
|
11
14
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Group — renders multiple renderables in sequence.
|
|
3
3
|
* No visual chrome — purely a container.
|
|
4
4
|
*/
|
|
5
|
+
import { measureRenderables } from "../core/measure.js";
|
|
5
6
|
import { stackedHeight } from "../core/protocol.js";
|
|
6
7
|
export class Group {
|
|
7
8
|
renderables;
|
|
@@ -14,4 +15,8 @@ export class Group {
|
|
|
14
15
|
yield* renderable.render(memberOptions);
|
|
15
16
|
}
|
|
16
17
|
}
|
|
18
|
+
/** As wide as its widest member: the reference's `measure_renderables`. */
|
|
19
|
+
measure(options) {
|
|
20
|
+
return measureRenderables(options, this.renderables);
|
|
21
|
+
}
|
|
17
22
|
}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { Segment } from "../core/segment.js";
|
|
5
5
|
import type { Renderable, Measurable, RenderOptions } from "../core/protocol.js";
|
|
6
|
+
import type { CellCol } from "../core/cells.js";
|
|
7
|
+
import type { Weight } from "./ratio.js";
|
|
6
8
|
export interface LayoutOptions {
|
|
7
9
|
name?: string;
|
|
8
10
|
ratio?: number;
|
|
@@ -25,7 +27,7 @@ export declare class Layout implements Renderable, Measurable {
|
|
|
25
27
|
* constructor. All three are public and a caller reaches them long after
|
|
26
28
|
* construction — `layout.getByName("pane")!.ratio = -1` walked straight past a
|
|
27
29
|
* constructor-only parse and put a negative weight back into the division that
|
|
28
|
-
* `
|
|
30
|
+
* `ratioResolve` and `ratioBudget` are written to trust.
|
|
29
31
|
*
|
|
30
32
|
* [LAW:parse-dont-validate] The setter is the border, so the guarantee holds
|
|
31
33
|
* for the object's whole lifetime and nothing downstream re-checks. `size` and
|
|
@@ -33,11 +35,11 @@ export declare class Layout implements Renderable, Measurable {
|
|
|
33
35
|
* fractions. Absence is preserved rather than parsed: an undefined `size`
|
|
34
36
|
* selects a flex pane, and `cellCount` would read it as a declared zero.
|
|
35
37
|
*/
|
|
36
|
-
get ratio():
|
|
38
|
+
get ratio(): Weight;
|
|
37
39
|
set ratio(value: number);
|
|
38
|
-
get size():
|
|
40
|
+
get size(): CellCol | undefined;
|
|
39
41
|
set size(value: number | undefined);
|
|
40
|
-
get minimumSize():
|
|
42
|
+
get minimumSize(): CellCol;
|
|
41
43
|
set minimumSize(value: number);
|
|
42
44
|
get children(): Layout[];
|
|
43
45
|
/**
|
|
@@ -57,7 +59,6 @@ export declare class Layout implements Renderable, Measurable {
|
|
|
57
59
|
render(rawOptions: RenderOptions): Iterable<Segment>;
|
|
58
60
|
private _renderColumn;
|
|
59
61
|
private _renderRow;
|
|
60
|
-
private _distributeSpace;
|
|
61
62
|
/**
|
|
62
63
|
* The width this layout would take if nothing constrained it: its content's
|
|
63
64
|
* for a leaf, its children's laid out the way the split lays them out.
|
|
@@ -67,24 +68,6 @@ export declare class Layout implements Renderable, Measurable {
|
|
|
67
68
|
* width there would report a two-line pane as two cells wide.
|
|
68
69
|
*/
|
|
69
70
|
private _naturalWidth;
|
|
70
|
-
/**
|
|
71
|
-
* The budget at which `_distributeSpace` gives every child of a row at least
|
|
72
|
-
* the width it wants — the inverse of the ratio rule above, and the reason
|
|
73
|
-
* this is not the sum of those widths.
|
|
74
|
-
*
|
|
75
|
-
* [LAW:one-source-of-truth] A growing child receives `floor(budget * ratio /
|
|
76
|
-
* totalRatio)`, so to receive `want` cells it needs the budget to reach
|
|
77
|
-
* `want * totalRatio / ratio`, and one budget serves them all: the row needs
|
|
78
|
-
* the largest demand, never their total. Summed instead, a 1:1 split of
|
|
79
|
-
* "left" and "right" reported 9 and then rendered "right" into the 4 cells
|
|
80
|
-
* that `floor(9/2)` actually hands it.
|
|
81
|
-
*
|
|
82
|
-
* The panes that do not grow are paid first here for the same reason they
|
|
83
|
-
* are paid first there — and it is the reason this divides by no zero: a
|
|
84
|
-
* `ratio` of 0 never reaches the division, because a pane that does not grow
|
|
85
|
-
* demands nothing of a budget for growing.
|
|
86
|
-
*/
|
|
87
|
-
private _rowBudgetFor;
|
|
88
71
|
measure(rawOptions: RenderOptions): {
|
|
89
72
|
minimum: number;
|
|
90
73
|
maximum: number;
|