@promptctl/rich-js 0.17.0 → 0.18.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 +13 -26
- package/package.json +7 -3
- package/dist/core/box.d.ts +0 -144
- package/dist/core/box.js +0 -391
- package/dist/core/cells.d.ts +0 -148
- package/dist/core/cells.js +0 -266
- package/dist/core/color.d.ts +0 -250
- package/dist/core/color.js +0 -1029
- package/dist/core/console.d.ts +0 -156
- package/dist/core/console.js +0 -472
- package/dist/core/emoji.d.ts +0 -24
- package/dist/core/emoji.js +0 -391
- package/dist/core/export-html.d.ts +0 -24
- package/dist/core/export-html.js +0 -106
- package/dist/core/export-lines.d.ts +0 -121
- package/dist/core/export-lines.js +0 -141
- package/dist/core/highlighter.d.ts +0 -33
- package/dist/core/highlighter.js +0 -124
- package/dist/core/json.d.ts +0 -27
- package/dist/core/json.js +0 -53
- package/dist/core/markup.d.ts +0 -97
- package/dist/core/markup.js +0 -619
- package/dist/core/measure.d.ts +0 -27
- package/dist/core/measure.js +0 -61
- package/dist/core/oklch.d.ts +0 -161
- package/dist/core/oklch.js +0 -312
- package/dist/core/osc8.d.ts +0 -68
- package/dist/core/osc8.js +0 -90
- package/dist/core/pretty.d.ts +0 -141
- package/dist/core/pretty.js +0 -472
- package/dist/core/protocol.d.ts +0 -137
- package/dist/core/protocol.js +0 -101
- package/dist/core/render.d.ts +0 -84
- package/dist/core/render.js +0 -145
- package/dist/core/segment.d.ts +0 -142
- package/dist/core/segment.js +0 -433
- package/dist/core/spinnerData.d.ts +0 -10
- package/dist/core/spinnerData.js +0 -115
- package/dist/core/strip.d.ts +0 -145
- package/dist/core/strip.js +0 -308
- package/dist/core/style.d.ts +0 -144
- package/dist/core/style.js +0 -723
- package/dist/core/subscription.d.ts +0 -12
- package/dist/core/subscription.js +0 -12
- package/dist/core/text.d.ts +0 -255
- package/dist/core/text.js +0 -990
- package/dist/core/wrap.d.ts +0 -41
- package/dist/core/wrap.js +0 -127
- package/dist/host/host-stream.d.ts +0 -30
- package/dist/host/host-stream.js +0 -35
- package/dist/host/index.d.ts +0 -3
- package/dist/host/index.js +0 -2
- package/dist/host/terminal-host.d.ts +0 -143
- package/dist/host/terminal-host.js +0 -132
- package/dist/index.d.ts +0 -87
- package/dist/index.js +0 -104
- package/dist/node/prompt.d.ts +0 -21
- package/dist/node/prompt.js +0 -30
- package/dist/node/save.d.ts +0 -17
- package/dist/node/save.js +0 -21
- package/dist/node/terminal-host.d.ts +0 -84
- package/dist/node/terminal-host.js +0 -160
- package/dist/node/traceback.d.ts +0 -27
- package/dist/node/traceback.js +0 -112
- package/dist/renderables/align.d.ts +0 -16
- package/dist/renderables/align.js +0 -46
- package/dist/renderables/columns.d.ts +0 -61
- package/dist/renderables/columns.js +0 -168
- package/dist/renderables/constrain.d.ts +0 -15
- package/dist/renderables/constrain.js +0 -37
- package/dist/renderables/flexStrip.d.ts +0 -41
- package/dist/renderables/flexStrip.js +0 -200
- package/dist/renderables/group.d.ts +0 -11
- package/dist/renderables/group.js +0 -15
- package/dist/renderables/layout.d.ts +0 -92
- package/dist/renderables/layout.js +0 -315
- package/dist/renderables/live.d.ts +0 -47
- package/dist/renderables/live.js +0 -131
- package/dist/renderables/markdown.d.ts +0 -24
- package/dist/renderables/markdown.js +0 -182
- package/dist/renderables/padding.d.ts +0 -38
- package/dist/renderables/padding.js +0 -140
- package/dist/renderables/panel.d.ts +0 -116
- package/dist/renderables/panel.js +0 -322
- package/dist/renderables/progress.d.ts +0 -90
- package/dist/renderables/progress.js +0 -241
- package/dist/renderables/progressBar.d.ts +0 -31
- package/dist/renderables/progressBar.js +0 -52
- package/dist/renderables/prompt.d.ts +0 -49
- package/dist/renderables/prompt.js +0 -125
- package/dist/renderables/rule.d.ts +0 -24
- package/dist/renderables/rule.js +0 -90
- package/dist/renderables/spinner.d.ts +0 -29
- package/dist/renderables/spinner.js +0 -64
- package/dist/renderables/status.d.ts +0 -23
- package/dist/renderables/status.js +0 -60
- package/dist/renderables/syntax.d.ts +0 -35
- package/dist/renderables/syntax.js +0 -114
- package/dist/renderables/table.d.ts +0 -182
- package/dist/renderables/table.js +0 -697
- package/dist/renderables/traceback.d.ts +0 -31
- package/dist/renderables/traceback.js +0 -109
- package/dist/renderables/tree.d.ts +0 -54
- package/dist/renderables/tree.js +0 -159
- package/dist/template-bindings/color-funcs.d.ts +0 -87
- package/dist/template-bindings/color-funcs.js +0 -219
- package/dist/template-bindings/helpers.d.ts +0 -24
- package/dist/template-bindings/helpers.js +0 -48
- package/dist/template-bindings/index.d.ts +0 -107
- package/dist/template-bindings/index.js +0 -144
- package/dist/template-bindings/palette-funcs.d.ts +0 -94
- package/dist/template-bindings/palette-funcs.js +0 -151
- package/dist/template-bindings/style-funcs.d.ts +0 -28
- package/dist/template-bindings/style-funcs.js +0 -151
- package/dist/themes/buildPalette.d.ts +0 -36
- package/dist/themes/buildPalette.js +0 -56
- package/dist/themes/colorMath.d.ts +0 -82
- package/dist/themes/colorMath.js +0 -254
- package/dist/themes/colorRef.d.ts +0 -51
- package/dist/themes/colorRef.js +0 -96
- package/dist/themes/data/atom-one-dark.d.ts +0 -3
- package/dist/themes/data/atom-one-dark.js +0 -158
- package/dist/themes/data/atom-one-light.d.ts +0 -3
- package/dist/themes/data/atom-one-light.js +0 -158
- package/dist/themes/data/catppuccin-frappe.d.ts +0 -3
- package/dist/themes/data/catppuccin-frappe.js +0 -158
- package/dist/themes/data/catppuccin-latte.d.ts +0 -3
- package/dist/themes/data/catppuccin-latte.js +0 -158
- package/dist/themes/data/catppuccin-macchiato.d.ts +0 -3
- package/dist/themes/data/catppuccin-macchiato.js +0 -158
- package/dist/themes/data/catppuccin-mocha.d.ts +0 -3
- package/dist/themes/data/catppuccin-mocha.js +0 -158
- package/dist/themes/data/cyberpunk.d.ts +0 -17
- package/dist/themes/data/cyberpunk.js +0 -191
- package/dist/themes/data/default.d.ts +0 -3
- package/dist/themes/data/default.js +0 -158
- package/dist/themes/data/dracula.d.ts +0 -3
- package/dist/themes/data/dracula.js +0 -158
- package/dist/themes/data/flexoki.d.ts +0 -3
- package/dist/themes/data/flexoki.js +0 -158
- package/dist/themes/data/gruvbox.d.ts +0 -3
- package/dist/themes/data/gruvbox.js +0 -158
- package/dist/themes/data/index.d.ts +0 -35
- package/dist/themes/data/index.js +0 -64
- package/dist/themes/data/monokai.d.ts +0 -3
- package/dist/themes/data/monokai.js +0 -158
- package/dist/themes/data/nord.d.ts +0 -3
- package/dist/themes/data/nord.js +0 -158
- package/dist/themes/data/rose-pine-dawn.d.ts +0 -3
- package/dist/themes/data/rose-pine-dawn.js +0 -158
- package/dist/themes/data/rose-pine-moon.d.ts +0 -3
- package/dist/themes/data/rose-pine-moon.js +0 -158
- package/dist/themes/data/rose-pine.d.ts +0 -3
- package/dist/themes/data/rose-pine.js +0 -158
- package/dist/themes/data/solarized-dark.d.ts +0 -3
- package/dist/themes/data/solarized-dark.js +0 -158
- package/dist/themes/data/solarized-light.d.ts +0 -3
- package/dist/themes/data/solarized-light.js +0 -158
- package/dist/themes/data/svg-export.d.ts +0 -3
- package/dist/themes/data/svg-export.js +0 -158
- package/dist/themes/data/textual-ansi.d.ts +0 -3
- package/dist/themes/data/textual-ansi.js +0 -158
- package/dist/themes/data/textual-dark.d.ts +0 -3
- package/dist/themes/data/textual-dark.js +0 -158
- package/dist/themes/data/textual-light.d.ts +0 -3
- package/dist/themes/data/textual-light.js +0 -158
- package/dist/themes/data/tokyo-night.d.ts +0 -3
- package/dist/themes/data/tokyo-night.js +0 -158
- package/dist/themes/data/types.d.ts +0 -15
- package/dist/themes/data/types.js +0 -1
- package/dist/themes/palette.d.ts +0 -21
- package/dist/themes/palette.js +0 -28
- package/dist/themes/ramp.d.ts +0 -83
- package/dist/themes/ramp.js +0 -122
- package/dist/themes/registry.d.ts +0 -43
- package/dist/themes/registry.js +0 -82
- package/dist/themes/terminalThemes.d.ts +0 -54
- package/dist/themes/terminalThemes.js +0 -68
- package/dist/themes/transpose.d.ts +0 -87
- package/dist/themes/transpose.js +0 -138
- package/dist/widgets/button.d.ts +0 -49
- package/dist/widgets/button.js +0 -206
- package/dist/widgets/checkbox.d.ts +0 -41
- package/dist/widgets/checkbox.js +0 -155
- package/dist/widgets/dropdown.d.ts +0 -67
- package/dist/widgets/dropdown.js +0 -453
- package/dist/widgets/event-router.d.ts +0 -78
- package/dist/widgets/event-router.js +0 -622
- package/dist/widgets/focus-manager.d.ts +0 -26
- package/dist/widgets/focus-manager.js +0 -193
- package/dist/widgets/index.d.ts +0 -22
- package/dist/widgets/index.js +0 -15
- package/dist/widgets/screen.d.ts +0 -98
- package/dist/widgets/screen.js +0 -530
- package/dist/widgets/slider.d.ts +0 -57
- package/dist/widgets/slider.js +0 -270
- package/dist/widgets/static-item.d.ts +0 -40
- package/dist/widgets/static-item.js +0 -60
- package/dist/widgets/text-input.d.ts +0 -274
- package/dist/widgets/text-input.js +0 -1162
- package/dist/widgets/toggle.d.ts +0 -44
- package/dist/widgets/toggle.js +0 -179
- package/dist/widgets/types.d.ts +0 -108
- package/dist/widgets/types.js +0 -31
- package/dist/widgets/widget-base.d.ts +0 -42
- package/dist/widgets/widget-base.js +0 -173
|
@@ -1,322 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Panel — a bordered box that wraps content, with optional title and subtitle.
|
|
3
|
-
*/
|
|
4
|
-
import { cellLen, setCellSize, asCellCol, cellCount } from "../core/cells.js";
|
|
5
|
-
import { Segment } from "../core/segment.js";
|
|
6
|
-
import { NULL_STYLE } from "../core/style.js";
|
|
7
|
-
import { ROUNDED } from "../core/box.js";
|
|
8
|
-
import { Measurement } from "../core/measure.js";
|
|
9
|
-
import { RichText } from "../core/text.js";
|
|
10
|
-
import { normalizePadding } from "./padding.js";
|
|
11
|
-
import { getStyle, isMeasurable, withBoundedWidth, withCellWidth } from "../core/protocol.js";
|
|
12
|
-
function layoutPanel(outerWidth, padding) {
|
|
13
|
-
const [, padRightWanted, , padLeftWanted] = padding;
|
|
14
|
-
// Panel's one division point, and the width reaching it is not always one
|
|
15
|
-
// this file produced: `_getPanelWidth` derives the fit-mode width from
|
|
16
|
-
// `Measurement.get` on an arbitrary `Measurable`, so a renderable reporting a
|
|
17
|
-
// negative maximum arrives here unparsed and reaches `repeat` as a negative
|
|
18
|
-
// count.
|
|
19
|
-
let budget = cellCount(outerWidth);
|
|
20
|
-
const take = (want) => {
|
|
21
|
-
const got = Math.min(want, budget);
|
|
22
|
-
budget -= got;
|
|
23
|
-
return got;
|
|
24
|
-
};
|
|
25
|
-
const left = take(1);
|
|
26
|
-
const right = take(1);
|
|
27
|
-
const firstContentCell = take(1);
|
|
28
|
-
const padLeft = take(padLeftWanted);
|
|
29
|
-
const padRight = take(padRightWanted);
|
|
30
|
-
const contentWidth = firstContentCell + budget;
|
|
31
|
-
return {
|
|
32
|
-
left,
|
|
33
|
-
right,
|
|
34
|
-
padLeft,
|
|
35
|
-
contentWidth,
|
|
36
|
-
padRight,
|
|
37
|
-
spanWidth: padLeft + contentWidth + padRight,
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Every cell of a panel that is not content canvas. Read off the geometry
|
|
42
|
-
* rather than recomputed as `2 + padLeft + padRight`, because the two differ
|
|
43
|
-
* exactly where this panel is squeezed: a width that cannot afford its right
|
|
44
|
-
* frame column or its padding does not spend cells on them, and a measurement
|
|
45
|
-
* that assumed it did would report a minimum larger than its own maximum.
|
|
46
|
-
*/
|
|
47
|
-
function frameOverhead(geometry) {
|
|
48
|
-
return geometry.left + geometry.right + geometry.padLeft + geometry.padRight;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* The style of text set into a border: its own when one was given, the
|
|
52
|
-
* border's otherwise — the one rule for "what colour is the title text in".
|
|
53
|
-
*/
|
|
54
|
-
function borderTextStyle(options, own, border) {
|
|
55
|
-
return own === undefined ? border : getStyle(options, own);
|
|
56
|
-
}
|
|
57
|
-
function toRenderable(content) {
|
|
58
|
-
// [LAW:one-type-per-behavior] Content embedded in a panel is a line, not a
|
|
59
|
-
// printed unit — the same reason columns, table cells, tree labels, and
|
|
60
|
-
// every other embedding site build their RichText with `end: ""`. Now that
|
|
61
|
-
// `RichText.render` honors `end` uniformly (rich-text-5ai), leaving this at
|
|
62
|
-
// the default "\n" would draw a trailing blank row whenever content ends
|
|
63
|
-
// with a literal newline.
|
|
64
|
-
if (typeof content === "string")
|
|
65
|
-
return new RichText(content, { end: "" });
|
|
66
|
-
if (content instanceof RichText) {
|
|
67
|
-
const copy = content.copy();
|
|
68
|
-
copy.end = "";
|
|
69
|
-
return copy;
|
|
70
|
-
}
|
|
71
|
-
return content;
|
|
72
|
-
}
|
|
73
|
-
export class Panel {
|
|
74
|
-
renderable;
|
|
75
|
-
box;
|
|
76
|
-
title;
|
|
77
|
-
subtitle;
|
|
78
|
-
bottomRightAccessory;
|
|
79
|
-
expand;
|
|
80
|
-
style;
|
|
81
|
-
borderStyle;
|
|
82
|
-
titleStyle;
|
|
83
|
-
subtitleStyle;
|
|
84
|
-
width;
|
|
85
|
-
padding;
|
|
86
|
-
constructor(content, options) {
|
|
87
|
-
this.renderable = toRenderable(content);
|
|
88
|
-
this.box = options?.box ?? ROUNDED;
|
|
89
|
-
this.title = options?.title;
|
|
90
|
-
this.subtitle = options?.subtitle;
|
|
91
|
-
this.bottomRightAccessory = options?.bottomRightAccessory;
|
|
92
|
-
this.expand = options?.expand !== false;
|
|
93
|
-
this.style = options?.style ?? NULL_STYLE;
|
|
94
|
-
this.borderStyle = options?.borderStyle ?? NULL_STYLE;
|
|
95
|
-
this.titleStyle = options?.titleStyle;
|
|
96
|
-
this.subtitleStyle = options?.subtitleStyle;
|
|
97
|
-
this.width = options?.width;
|
|
98
|
-
this.padding = normalizePadding(options?.padding ?? [0, 1, 0, 1]);
|
|
99
|
-
}
|
|
100
|
-
*render(rawOptions) {
|
|
101
|
-
const options = withBoundedWidth(rawOptions, this);
|
|
102
|
-
const box = options.asciiOnly ? this.box.substitute({ asciiOnly: true }) : this.box;
|
|
103
|
-
const borderStyle = getStyle(options, this.borderStyle);
|
|
104
|
-
const style = getStyle(options, this.style);
|
|
105
|
-
const border = borderStyle.isNull ? undefined : borderStyle;
|
|
106
|
-
const contentStyle = style.isNull ? undefined : style;
|
|
107
|
-
const geometry = layoutPanel(this._getPanelWidth(options), this.padding);
|
|
108
|
-
const [padTop, , padBottom] = this.padding;
|
|
109
|
-
const contentLines = this._renderContent(options, geometry.contentWidth);
|
|
110
|
-
// Top border (with optional title)
|
|
111
|
-
yield* this._renderTopBorder(options, box, geometry, border);
|
|
112
|
-
// Top padding — a padding row is a content row whose content is nothing.
|
|
113
|
-
for (let i = 0; i < padTop; i++) {
|
|
114
|
-
yield* this._renderRow(box, geometry, [], border, contentStyle);
|
|
115
|
-
}
|
|
116
|
-
for (const line of contentLines) {
|
|
117
|
-
yield* this._renderRow(box, geometry, line, border, contentStyle);
|
|
118
|
-
}
|
|
119
|
-
for (let i = 0; i < padBottom; i++) {
|
|
120
|
-
yield* this._renderRow(box, geometry, [], border, contentStyle);
|
|
121
|
-
}
|
|
122
|
-
// Bottom border (with optional subtitle)
|
|
123
|
-
yield* this._renderBottomBorder(options, box, geometry, border);
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* The wrapped renderable's lines, laid out on a canvas `contentWidth` cells
|
|
127
|
-
* wide. Below width 3 a panel is all frame and the canvas holds no lines —
|
|
128
|
-
* but the render still happens, because a `bottomRightAccessory` thunk
|
|
129
|
-
* fires at every width and reads state this render populates.
|
|
130
|
-
*/
|
|
131
|
-
_renderContent(options, contentWidth) {
|
|
132
|
-
const innerOptions = {
|
|
133
|
-
...options,
|
|
134
|
-
maxWidth: contentWidth,
|
|
135
|
-
};
|
|
136
|
-
const lines = Segment.splitLines([...this.renderable.render(innerOptions)]);
|
|
137
|
-
return contentWidth === 0 ? [] : lines;
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* One row of the panel body: frame column, span, frame column.
|
|
141
|
-
*
|
|
142
|
-
* [LAW:single-enforcer] `adjustLineLength` is the one place a width is
|
|
143
|
-
* decided here, and it runs twice against two different widths. The first
|
|
144
|
-
* pass crops content that rendered wider than the canvas it was handed (a
|
|
145
|
-
* `Table` at its natural width, say) back to the canvas, so an oversized
|
|
146
|
-
* child is trimmed rather than allowed to eat the right-hand padding. The
|
|
147
|
-
* second fills the rest of the span, which is the trailing padding and any
|
|
148
|
-
* shortfall in one stroke.
|
|
149
|
-
*/
|
|
150
|
-
*_renderRow(box, geometry, line, border, contentStyle) {
|
|
151
|
-
const frame = box.getContentChars("row");
|
|
152
|
-
yield new Segment(frame.left.repeat(geometry.left), border);
|
|
153
|
-
const content = Segment.adjustLineLength(line, geometry.contentWidth, contentStyle, false);
|
|
154
|
-
const span = [new Segment(" ".repeat(geometry.padLeft), contentStyle), ...content];
|
|
155
|
-
yield* Segment.adjustLineLength(span, geometry.spanWidth, contentStyle);
|
|
156
|
-
yield new Segment(frame.right.repeat(geometry.right), border);
|
|
157
|
-
yield Segment.line();
|
|
158
|
-
}
|
|
159
|
-
measure(rawOptions) {
|
|
160
|
-
const options = withCellWidth(rawOptions);
|
|
161
|
-
const declared = this._declaredWidth;
|
|
162
|
-
if (declared !== undefined) {
|
|
163
|
-
// A declared width is not a ceiling on the content, it is the answer:
|
|
164
|
-
// `_getPanelWidth` returns it before measuring anything, so the panel
|
|
165
|
-
// draws at this width whatever the content wants. Reported with a
|
|
166
|
-
// content-derived floor instead, `{width: 20}` around "hi" offered 100
|
|
167
|
-
// cells answered 6..20 and then drew 20 every time, and a parent
|
|
168
|
-
// dividing space from the floor under-provisioned it.
|
|
169
|
-
const width = Math.min(options.maxWidth, declared);
|
|
170
|
-
return { minimum: width, maximum: width };
|
|
171
|
-
}
|
|
172
|
-
return this._fitRange(options);
|
|
173
|
-
}
|
|
174
|
-
/**
|
|
175
|
-
* The width this panel wants when nothing declared one for it: its content
|
|
176
|
-
* plus its own frame, both read off the division it will render against.
|
|
177
|
-
*
|
|
178
|
-
* [LAW:one-source-of-truth] `measure` and `_getPanelWidth` ask this same
|
|
179
|
-
* question, and each used to work it out itself — the same `layoutPanel`, the
|
|
180
|
-
* same `frameOverhead`, the same `Math.min(maxWidth, maximum + overhead)`,
|
|
181
|
-
* written twice. That is the pattern `_declaredWidth` below was extracted to
|
|
182
|
-
* stop, left standing for the fit case; changing how overhead is derived in
|
|
183
|
-
* one copy is all it would take to put `measure` and `render` back into the
|
|
184
|
-
* disagreement this epic spent itself closing.
|
|
185
|
-
*/
|
|
186
|
-
_fitRange(options) {
|
|
187
|
-
const geometry = layoutPanel(options.maxWidth, this.padding);
|
|
188
|
-
const overhead = frameOverhead(geometry);
|
|
189
|
-
if (isMeasurable(this.renderable)) {
|
|
190
|
-
const innerOptions = {
|
|
191
|
-
...options,
|
|
192
|
-
maxWidth: geometry.contentWidth,
|
|
193
|
-
};
|
|
194
|
-
const measurement = Measurement.get(innerOptions, this.renderable);
|
|
195
|
-
const maximum = Math.min(options.maxWidth, measurement.maximum + overhead);
|
|
196
|
-
return {
|
|
197
|
-
minimum: Math.min(measurement.minimum + overhead, maximum),
|
|
198
|
-
maximum,
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
// Content that cannot measure itself leaves the panel with nothing to want,
|
|
202
|
-
// so it wants the offer — unbounded included, which `withBoundedWidth`
|
|
203
|
-
// reports rather than turning into a number nobody can defend.
|
|
204
|
-
return { minimum: Math.min(overhead, options.maxWidth), maximum: options.maxWidth };
|
|
205
|
-
}
|
|
206
|
-
/**
|
|
207
|
-
* The width this panel was told to be, as a count of cells.
|
|
208
|
-
*
|
|
209
|
-
* [LAW:one-source-of-truth] `measure` and `_getPanelWidth` answer the same
|
|
210
|
-
* question about the same field, so they read it from here. Answered
|
|
211
|
-
* separately, `measure` reported nine cells of content while `render` drew the
|
|
212
|
-
* declared twelve, and the parent that divided space from the range got a
|
|
213
|
-
* panel three cells wider than the share it granted.
|
|
214
|
-
*/
|
|
215
|
-
get _declaredWidth() {
|
|
216
|
-
return this.width === undefined ? undefined : cellCount(this.width);
|
|
217
|
-
}
|
|
218
|
-
_getPanelWidth(options) {
|
|
219
|
-
const declared = this._declaredWidth;
|
|
220
|
-
if (declared !== undefined)
|
|
221
|
-
return Math.min(declared, options.maxWidth);
|
|
222
|
-
if (this.expand)
|
|
223
|
-
return options.maxWidth;
|
|
224
|
-
return this._fitRange(options).maximum;
|
|
225
|
-
}
|
|
226
|
-
*_renderTopBorder(options, box, geometry, border) {
|
|
227
|
-
const innerBorderWidth = geometry.spanWidth;
|
|
228
|
-
if (!this.title) {
|
|
229
|
-
yield new Segment(box.top.left.repeat(geometry.left), border);
|
|
230
|
-
yield new Segment(box.top.horizontal.repeat(innerBorderWidth), border);
|
|
231
|
-
yield new Segment(box.top.right.repeat(geometry.right), border);
|
|
232
|
-
yield Segment.line();
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
const titleText = typeof this.title === "string" ? this.title : this.title.plain;
|
|
236
|
-
const titleDisplay = ` ${titleText} `;
|
|
237
|
-
const titleWidth = cellLen(titleDisplay);
|
|
238
|
-
const titleSeg = borderTextStyle(options, this.titleStyle, border);
|
|
239
|
-
yield new Segment(box.top.left.repeat(geometry.left), border);
|
|
240
|
-
if (titleWidth >= innerBorderWidth) {
|
|
241
|
-
// Title fills the border. [LAW:one-source-of-truth] cellLen / setCellSize
|
|
242
|
-
// are the cell-width authority — plain .slice would miscount wide chars
|
|
243
|
-
// and break border alignment.
|
|
244
|
-
yield new Segment(setCellSize(titleDisplay, asCellCol(innerBorderWidth)), titleSeg);
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
// Center the title in the top border
|
|
248
|
-
const leftRuleWidth = Math.floor((innerBorderWidth - titleWidth) / 2);
|
|
249
|
-
const rightRuleWidth = innerBorderWidth - titleWidth - leftRuleWidth;
|
|
250
|
-
if (leftRuleWidth > 0)
|
|
251
|
-
yield new Segment(box.top.horizontal.repeat(leftRuleWidth), border);
|
|
252
|
-
yield new Segment(titleDisplay, titleSeg);
|
|
253
|
-
if (rightRuleWidth > 0)
|
|
254
|
-
yield new Segment(box.top.horizontal.repeat(rightRuleWidth), border);
|
|
255
|
-
}
|
|
256
|
-
yield new Segment(box.top.right.repeat(geometry.right), border);
|
|
257
|
-
yield Segment.line();
|
|
258
|
-
}
|
|
259
|
-
*_renderBottomBorder(options, box, geometry, border) {
|
|
260
|
-
const innerBorderWidth = geometry.spanWidth;
|
|
261
|
-
// Resolve the right accessory *now*. Function form evaluates after
|
|
262
|
-
// content has been rendered (Panel.render collects content segments
|
|
263
|
-
// before yielding any borders), so the thunk sees fresh widget state.
|
|
264
|
-
const accessory = this._resolveAccessory(this.bottomRightAccessory);
|
|
265
|
-
const accessoryDisplay = accessory === undefined
|
|
266
|
-
? ""
|
|
267
|
-
: typeof accessory === "string"
|
|
268
|
-
? ` ${accessory} `
|
|
269
|
-
: ` ${accessory.plain} `;
|
|
270
|
-
const accessoryWidth = cellLen(accessoryDisplay);
|
|
271
|
-
const accessoryOwn = accessory instanceof RichText ? accessory.resolvedStyle(options) : NULL_STYLE;
|
|
272
|
-
const accessoryStyle = accessoryOwn.isNull ? border : accessoryOwn;
|
|
273
|
-
yield new Segment(box.bottom.left.repeat(geometry.left), border);
|
|
274
|
-
// Space available for the centered subtitle / rule fill — the accessory
|
|
275
|
-
// (if any) hugs the right edge and the subtitle treats the remainder
|
|
276
|
-
// as its centering canvas.
|
|
277
|
-
const centerWidth = Math.max(0, innerBorderWidth - accessoryWidth);
|
|
278
|
-
if (!this.subtitle) {
|
|
279
|
-
if (centerWidth > 0)
|
|
280
|
-
yield new Segment(box.bottom.horizontal.repeat(centerWidth), border);
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
const subtitleText = typeof this.subtitle === "string" ? this.subtitle : this.subtitle.plain;
|
|
284
|
-
const subtitleDisplay = ` ${subtitleText} `;
|
|
285
|
-
const subtitleWidth = cellLen(subtitleDisplay);
|
|
286
|
-
const subtitleSeg = borderTextStyle(options, this.subtitleStyle, border);
|
|
287
|
-
if (subtitleWidth >= centerWidth) {
|
|
288
|
-
// Cell-aware clip — see _renderTopBorder.
|
|
289
|
-
yield new Segment(setCellSize(subtitleDisplay, asCellCol(centerWidth)), subtitleSeg);
|
|
290
|
-
}
|
|
291
|
-
else {
|
|
292
|
-
const leftRuleWidth = Math.floor((centerWidth - subtitleWidth) / 2);
|
|
293
|
-
const rightRuleWidth = centerWidth - subtitleWidth - leftRuleWidth;
|
|
294
|
-
if (leftRuleWidth > 0)
|
|
295
|
-
yield new Segment(box.bottom.horizontal.repeat(leftRuleWidth), border);
|
|
296
|
-
yield new Segment(subtitleDisplay, subtitleSeg);
|
|
297
|
-
if (rightRuleWidth > 0)
|
|
298
|
-
yield new Segment(box.bottom.horizontal.repeat(rightRuleWidth), border);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
if (accessoryWidth > 0) {
|
|
302
|
-
// Cell-aware clip — see _renderTopBorder.
|
|
303
|
-
const fit = accessoryWidth > innerBorderWidth
|
|
304
|
-
? setCellSize(accessoryDisplay, asCellCol(innerBorderWidth))
|
|
305
|
-
: accessoryDisplay;
|
|
306
|
-
yield new Segment(fit, accessoryStyle);
|
|
307
|
-
}
|
|
308
|
-
yield new Segment(box.bottom.right.repeat(geometry.right), border);
|
|
309
|
-
yield Segment.line();
|
|
310
|
-
}
|
|
311
|
-
_resolveAccessory(a) {
|
|
312
|
-
if (a === undefined)
|
|
313
|
-
return undefined;
|
|
314
|
-
if (typeof a === "function")
|
|
315
|
-
return a();
|
|
316
|
-
return a;
|
|
317
|
-
}
|
|
318
|
-
// --- Static factory ---
|
|
319
|
-
static fit(content, options) {
|
|
320
|
-
return new Panel(content, { ...options, expand: false });
|
|
321
|
-
}
|
|
322
|
-
}
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Progress — displays continuously updated progress bars.
|
|
3
|
-
*/
|
|
4
|
-
import { Segment } from "../core/segment.js";
|
|
5
|
-
import { Console } from "../core/console.js";
|
|
6
|
-
import type { Renderable, RenderOptions } from "../core/protocol.js";
|
|
7
|
-
export interface TaskOptions {
|
|
8
|
-
total?: number;
|
|
9
|
-
start?: boolean;
|
|
10
|
-
visible?: boolean;
|
|
11
|
-
}
|
|
12
|
-
export interface TaskUpdateOptions {
|
|
13
|
-
completed?: number;
|
|
14
|
-
advance?: number;
|
|
15
|
-
description?: string;
|
|
16
|
-
visible?: boolean;
|
|
17
|
-
refresh?: boolean;
|
|
18
|
-
}
|
|
19
|
-
interface Task {
|
|
20
|
-
id: number;
|
|
21
|
-
description: string;
|
|
22
|
-
total: number | undefined;
|
|
23
|
-
completed: number;
|
|
24
|
-
started: boolean;
|
|
25
|
-
visible: boolean;
|
|
26
|
-
startTime: number;
|
|
27
|
-
elapsed: number;
|
|
28
|
-
}
|
|
29
|
-
export interface ProgressColumn extends Renderable {
|
|
30
|
-
render(options: RenderOptions, task?: Task): Iterable<Segment>;
|
|
31
|
-
}
|
|
32
|
-
export declare class TextColumn implements ProgressColumn {
|
|
33
|
-
readonly format: string;
|
|
34
|
-
constructor(format?: string);
|
|
35
|
-
render(options: RenderOptions, task?: Task): Iterable<Segment>;
|
|
36
|
-
}
|
|
37
|
-
export declare class BarColumn implements ProgressColumn {
|
|
38
|
-
readonly barWidth: number;
|
|
39
|
-
constructor(barWidth?: number);
|
|
40
|
-
render(_options: RenderOptions, task?: Task): Iterable<Segment>;
|
|
41
|
-
}
|
|
42
|
-
export declare class TaskProgressColumn implements ProgressColumn {
|
|
43
|
-
render(options: RenderOptions, task?: Task): Iterable<Segment>;
|
|
44
|
-
}
|
|
45
|
-
export declare class TimeRemainingColumn implements ProgressColumn {
|
|
46
|
-
render(options: RenderOptions, task?: Task): Iterable<Segment>;
|
|
47
|
-
}
|
|
48
|
-
export declare class TimeElapsedColumn implements ProgressColumn {
|
|
49
|
-
render(options: RenderOptions, task?: Task): Iterable<Segment>;
|
|
50
|
-
}
|
|
51
|
-
export declare class SpinnerColumn implements ProgressColumn {
|
|
52
|
-
private _spinner;
|
|
53
|
-
constructor(spinnerName?: string);
|
|
54
|
-
render(options: RenderOptions, _task?: Task): Iterable<Segment>;
|
|
55
|
-
}
|
|
56
|
-
export declare class MofNCompleteColumn implements ProgressColumn {
|
|
57
|
-
render(_options: RenderOptions, task?: Task): Iterable<Segment>;
|
|
58
|
-
}
|
|
59
|
-
export interface ProgressOptions {
|
|
60
|
-
refreshPerSecond?: number;
|
|
61
|
-
autoRefresh?: boolean;
|
|
62
|
-
transient?: boolean;
|
|
63
|
-
expand?: boolean;
|
|
64
|
-
console?: Console;
|
|
65
|
-
}
|
|
66
|
-
export declare class Progress implements Renderable {
|
|
67
|
-
private _columns;
|
|
68
|
-
private _tasks;
|
|
69
|
-
private _nextId;
|
|
70
|
-
private _live;
|
|
71
|
-
private _console;
|
|
72
|
-
readonly expand: boolean;
|
|
73
|
-
constructor(...columns: (ProgressColumn | ProgressOptions)[]);
|
|
74
|
-
get console(): Console;
|
|
75
|
-
get finished(): boolean;
|
|
76
|
-
static getDefaultColumns(): ProgressColumn[];
|
|
77
|
-
addTask(description: string, options?: TaskOptions): number;
|
|
78
|
-
updateTask(taskId: number, options: TaskUpdateOptions): void;
|
|
79
|
-
startTask(taskId: number): void;
|
|
80
|
-
start(): void;
|
|
81
|
-
stop(): void;
|
|
82
|
-
refresh(): void;
|
|
83
|
-
render(options: RenderOptions): Iterable<Segment>;
|
|
84
|
-
}
|
|
85
|
-
export declare function track<T>(iterable: Iterable<T>, options?: {
|
|
86
|
-
description?: string;
|
|
87
|
-
total?: number;
|
|
88
|
-
console?: Console;
|
|
89
|
-
}): Iterable<T>;
|
|
90
|
-
export {};
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Progress — displays continuously updated progress bars.
|
|
3
|
-
*/
|
|
4
|
-
import { Segment } from "../core/segment.js";
|
|
5
|
-
import { RichText } from "../core/text.js";
|
|
6
|
-
import { Console } from "../core/console.js";
|
|
7
|
-
import { escape as escapeMarkup, renderMarkup } from "../core/markup.js";
|
|
8
|
-
import { ProgressBar } from "./progressBar.js";
|
|
9
|
-
import { Spinner } from "./spinner.js";
|
|
10
|
-
import { Live } from "./live.js";
|
|
11
|
-
import { Table } from "./table.js";
|
|
12
|
-
import { getStyle } from "../core/protocol.js";
|
|
13
|
-
export class TextColumn {
|
|
14
|
-
format;
|
|
15
|
-
constructor(format) {
|
|
16
|
-
this.format = format ?? "{task.description}";
|
|
17
|
-
}
|
|
18
|
-
*render(options, task) {
|
|
19
|
-
// [LAW:single-enforcer] Format strings flow through the markup parser so
|
|
20
|
-
// tags like `[progress.description]` become Style spans, not literal text.
|
|
21
|
-
// Task descriptions are escaped first to prevent injection of stray tags.
|
|
22
|
-
const description = escapeMarkup(task?.description ?? "");
|
|
23
|
-
// Use a callback so `$&`/`$1`/`$$` in the task description aren't
|
|
24
|
-
// reinterpreted by String.replace as replacement patterns.
|
|
25
|
-
const formatted = this.format.replace(/\{task\.description\}/g, () => description);
|
|
26
|
-
// [LAW:one-type-per-behavior] A column is a row fragment, not a printed
|
|
27
|
-
// line, so it clears `end` the same way `toCellText` does in table.ts —
|
|
28
|
-
// `renderMarkup` returns a fresh `RichText` each call, so it is safe to
|
|
29
|
-
// mutate directly rather than copy.
|
|
30
|
-
const text = renderMarkup(formatted);
|
|
31
|
-
text.end = "";
|
|
32
|
-
yield* text.render(options);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
export class BarColumn {
|
|
36
|
-
barWidth;
|
|
37
|
-
constructor(barWidth) {
|
|
38
|
-
this.barWidth = barWidth ?? 40;
|
|
39
|
-
}
|
|
40
|
-
*render(_options, task) {
|
|
41
|
-
const bar = new ProgressBar({
|
|
42
|
-
total: task?.total ?? 100,
|
|
43
|
-
completed: task?.completed ?? 0,
|
|
44
|
-
width: this.barWidth,
|
|
45
|
-
});
|
|
46
|
-
yield* bar.render(_options);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
export class TaskProgressColumn {
|
|
50
|
-
*render(options, task) {
|
|
51
|
-
const percent = task && task.total
|
|
52
|
-
? Math.min(100, Math.round((task.completed / task.total) * 100))
|
|
53
|
-
: 0;
|
|
54
|
-
yield new Segment(`${percent}%`, getStyle(options, "progress.percentage"));
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
export class TimeRemainingColumn {
|
|
58
|
-
*render(options, task) {
|
|
59
|
-
const style = getStyle(options, "progress.remaining");
|
|
60
|
-
if (!task || !task.total || !task.started || task.completed <= 0) {
|
|
61
|
-
yield new Segment("-:--:--", style);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const elapsed = (Date.now() - task.startTime) / 1000;
|
|
65
|
-
const rate = task.completed / elapsed;
|
|
66
|
-
const remaining = (task.total - task.completed) / rate;
|
|
67
|
-
yield new Segment(formatTime(remaining), style);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
export class TimeElapsedColumn {
|
|
71
|
-
*render(options, task) {
|
|
72
|
-
const style = getStyle(options, "progress.elapsed");
|
|
73
|
-
if (!task || !task.started) {
|
|
74
|
-
yield new Segment("0:00:00", style);
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
const elapsed = (Date.now() - task.startTime) / 1000;
|
|
78
|
-
yield new Segment(formatTime(elapsed), style);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
export class SpinnerColumn {
|
|
82
|
-
_spinner;
|
|
83
|
-
constructor(spinnerName) {
|
|
84
|
-
this._spinner = new Spinner(spinnerName);
|
|
85
|
-
}
|
|
86
|
-
*render(options, _task) {
|
|
87
|
-
yield* this._spinner.render(options);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
export class MofNCompleteColumn {
|
|
91
|
-
*render(_options, task) {
|
|
92
|
-
const completed = task?.completed ?? 0;
|
|
93
|
-
const total = task?.total ?? "?";
|
|
94
|
-
yield new Segment(`${completed}/${total}`);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
function formatTime(seconds) {
|
|
98
|
-
const h = Math.floor(seconds / 3600);
|
|
99
|
-
const m = Math.floor((seconds % 3600) / 60);
|
|
100
|
-
const s = Math.floor(seconds % 60);
|
|
101
|
-
return `${h}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}`;
|
|
102
|
-
}
|
|
103
|
-
export class Progress {
|
|
104
|
-
_columns;
|
|
105
|
-
_tasks;
|
|
106
|
-
_nextId;
|
|
107
|
-
_live;
|
|
108
|
-
_console;
|
|
109
|
-
expand;
|
|
110
|
-
constructor(...columns) {
|
|
111
|
-
// Last arg might be options
|
|
112
|
-
let opts = {};
|
|
113
|
-
const cols = [];
|
|
114
|
-
for (const arg of columns) {
|
|
115
|
-
if ("render" in arg) {
|
|
116
|
-
cols.push(arg);
|
|
117
|
-
}
|
|
118
|
-
else {
|
|
119
|
-
opts = arg;
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
if (cols.length === 0) {
|
|
123
|
-
cols.push(new TextColumn("[progress.description]{task.description}"), new BarColumn(), new TaskProgressColumn(), new TimeRemainingColumn());
|
|
124
|
-
}
|
|
125
|
-
this._columns = cols;
|
|
126
|
-
this._tasks = new Map();
|
|
127
|
-
this._nextId = 1;
|
|
128
|
-
this._console = opts.console ?? new Console({ forceTerminal: true });
|
|
129
|
-
this.expand = opts.expand ?? false;
|
|
130
|
-
this._live = new Live(this, {
|
|
131
|
-
console: this._console,
|
|
132
|
-
refreshPerSecond: opts.refreshPerSecond ?? 10,
|
|
133
|
-
autoRefresh: opts.autoRefresh,
|
|
134
|
-
transient: opts.transient,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
get console() {
|
|
138
|
-
return this._console;
|
|
139
|
-
}
|
|
140
|
-
get finished() {
|
|
141
|
-
for (const task of this._tasks.values()) {
|
|
142
|
-
if (!task.started || (task.total !== undefined && task.completed < task.total)) {
|
|
143
|
-
return false;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return this._tasks.size > 0;
|
|
147
|
-
}
|
|
148
|
-
static getDefaultColumns() {
|
|
149
|
-
return [
|
|
150
|
-
new TextColumn("[progress.description]{task.description}"),
|
|
151
|
-
new BarColumn(),
|
|
152
|
-
new TaskProgressColumn(),
|
|
153
|
-
new TimeRemainingColumn(),
|
|
154
|
-
];
|
|
155
|
-
}
|
|
156
|
-
addTask(description, options) {
|
|
157
|
-
const id = this._nextId++;
|
|
158
|
-
const task = {
|
|
159
|
-
id,
|
|
160
|
-
description,
|
|
161
|
-
total: options?.total,
|
|
162
|
-
completed: 0,
|
|
163
|
-
started: options?.start !== false,
|
|
164
|
-
visible: options?.visible !== false,
|
|
165
|
-
startTime: Date.now(),
|
|
166
|
-
elapsed: 0,
|
|
167
|
-
};
|
|
168
|
-
this._tasks.set(id, task);
|
|
169
|
-
return id;
|
|
170
|
-
}
|
|
171
|
-
updateTask(taskId, options) {
|
|
172
|
-
const task = this._tasks.get(taskId);
|
|
173
|
-
if (!task)
|
|
174
|
-
return;
|
|
175
|
-
if (options.completed !== undefined)
|
|
176
|
-
task.completed = options.completed;
|
|
177
|
-
if (options.advance !== undefined)
|
|
178
|
-
task.completed += options.advance;
|
|
179
|
-
if (options.description !== undefined)
|
|
180
|
-
task.description = options.description;
|
|
181
|
-
if (options.visible !== undefined)
|
|
182
|
-
task.visible = options.visible;
|
|
183
|
-
if (options.refresh) {
|
|
184
|
-
this._live.update(this, { refresh: true });
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
startTask(taskId) {
|
|
188
|
-
const task = this._tasks.get(taskId);
|
|
189
|
-
if (task) {
|
|
190
|
-
task.started = true;
|
|
191
|
-
task.startTime = Date.now();
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
start() {
|
|
195
|
-
this._live.start();
|
|
196
|
-
}
|
|
197
|
-
stop() {
|
|
198
|
-
this._live.stop();
|
|
199
|
-
}
|
|
200
|
-
refresh() {
|
|
201
|
-
this._live.refresh();
|
|
202
|
-
}
|
|
203
|
-
*render(options) {
|
|
204
|
-
const table = Table.grid({ expand: this.expand });
|
|
205
|
-
for (const _col of this._columns) {
|
|
206
|
-
table.addColumn();
|
|
207
|
-
}
|
|
208
|
-
for (const task of this._tasks.values()) {
|
|
209
|
-
if (!task.visible)
|
|
210
|
-
continue;
|
|
211
|
-
const cells = this._columns.map((col) => {
|
|
212
|
-
const segs = [...col.render(options, task)];
|
|
213
|
-
// Build a RichText that preserves segment styles as spans
|
|
214
|
-
const text = new RichText("", { end: "" });
|
|
215
|
-
for (const seg of segs) {
|
|
216
|
-
text.append(seg.text, seg.style);
|
|
217
|
-
}
|
|
218
|
-
return text;
|
|
219
|
-
});
|
|
220
|
-
table.addRow(...cells);
|
|
221
|
-
}
|
|
222
|
-
yield* table.render(options);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
// --- track ---
|
|
226
|
-
export function* track(iterable, options) {
|
|
227
|
-
const items = [...iterable];
|
|
228
|
-
const total = options?.total ?? items.length;
|
|
229
|
-
const progress = new Progress({ console: options?.console });
|
|
230
|
-
const taskId = progress.addTask(options?.description ?? "Working...", { total });
|
|
231
|
-
progress.start();
|
|
232
|
-
try {
|
|
233
|
-
for (let i = 0; i < items.length; i++) {
|
|
234
|
-
yield items[i];
|
|
235
|
-
progress.updateTask(taskId, { completed: i + 1 });
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
finally {
|
|
239
|
-
progress.stop();
|
|
240
|
-
}
|
|
241
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ProgressBar — a visual progress bar rendered with block characters.
|
|
3
|
-
*/
|
|
4
|
-
import { Segment } from "../core/segment.js";
|
|
5
|
-
import { Style } from "../core/style.js";
|
|
6
|
-
import type { Renderable, Measurable, RenderOptions } from "../core/protocol.js";
|
|
7
|
-
export interface ProgressBarOptions {
|
|
8
|
-
total?: number;
|
|
9
|
-
completed?: number;
|
|
10
|
-
width?: number;
|
|
11
|
-
pulse?: boolean;
|
|
12
|
-
style?: string | Style;
|
|
13
|
-
completeStyle?: string | Style;
|
|
14
|
-
finishedStyle?: string | Style;
|
|
15
|
-
}
|
|
16
|
-
export declare class ProgressBar implements Renderable, Measurable {
|
|
17
|
-
total: number;
|
|
18
|
-
completed: number;
|
|
19
|
-
readonly width: number | undefined;
|
|
20
|
-
readonly pulse: boolean;
|
|
21
|
-
readonly style: string | Style;
|
|
22
|
-
readonly completeStyle: string | Style;
|
|
23
|
-
readonly finishedStyle: string | Style;
|
|
24
|
-
constructor(options?: ProgressBarOptions);
|
|
25
|
-
get percentComplete(): number;
|
|
26
|
-
render(options: RenderOptions): Iterable<Segment>;
|
|
27
|
-
measure(_options: RenderOptions): {
|
|
28
|
-
minimum: number;
|
|
29
|
-
maximum: number;
|
|
30
|
-
};
|
|
31
|
-
}
|