@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.
Files changed (206) hide show
  1. package/README.md +13 -26
  2. package/package.json +7 -3
  3. package/dist/core/box.d.ts +0 -144
  4. package/dist/core/box.js +0 -391
  5. package/dist/core/cells.d.ts +0 -148
  6. package/dist/core/cells.js +0 -266
  7. package/dist/core/color.d.ts +0 -250
  8. package/dist/core/color.js +0 -1029
  9. package/dist/core/console.d.ts +0 -156
  10. package/dist/core/console.js +0 -472
  11. package/dist/core/emoji.d.ts +0 -24
  12. package/dist/core/emoji.js +0 -391
  13. package/dist/core/export-html.d.ts +0 -24
  14. package/dist/core/export-html.js +0 -106
  15. package/dist/core/export-lines.d.ts +0 -121
  16. package/dist/core/export-lines.js +0 -141
  17. package/dist/core/highlighter.d.ts +0 -33
  18. package/dist/core/highlighter.js +0 -124
  19. package/dist/core/json.d.ts +0 -27
  20. package/dist/core/json.js +0 -53
  21. package/dist/core/markup.d.ts +0 -97
  22. package/dist/core/markup.js +0 -619
  23. package/dist/core/measure.d.ts +0 -27
  24. package/dist/core/measure.js +0 -61
  25. package/dist/core/oklch.d.ts +0 -161
  26. package/dist/core/oklch.js +0 -312
  27. package/dist/core/osc8.d.ts +0 -68
  28. package/dist/core/osc8.js +0 -90
  29. package/dist/core/pretty.d.ts +0 -141
  30. package/dist/core/pretty.js +0 -472
  31. package/dist/core/protocol.d.ts +0 -137
  32. package/dist/core/protocol.js +0 -101
  33. package/dist/core/render.d.ts +0 -84
  34. package/dist/core/render.js +0 -145
  35. package/dist/core/segment.d.ts +0 -142
  36. package/dist/core/segment.js +0 -433
  37. package/dist/core/spinnerData.d.ts +0 -10
  38. package/dist/core/spinnerData.js +0 -115
  39. package/dist/core/strip.d.ts +0 -145
  40. package/dist/core/strip.js +0 -308
  41. package/dist/core/style.d.ts +0 -144
  42. package/dist/core/style.js +0 -723
  43. package/dist/core/subscription.d.ts +0 -12
  44. package/dist/core/subscription.js +0 -12
  45. package/dist/core/text.d.ts +0 -255
  46. package/dist/core/text.js +0 -990
  47. package/dist/core/wrap.d.ts +0 -41
  48. package/dist/core/wrap.js +0 -127
  49. package/dist/host/host-stream.d.ts +0 -30
  50. package/dist/host/host-stream.js +0 -35
  51. package/dist/host/index.d.ts +0 -3
  52. package/dist/host/index.js +0 -2
  53. package/dist/host/terminal-host.d.ts +0 -143
  54. package/dist/host/terminal-host.js +0 -132
  55. package/dist/index.d.ts +0 -87
  56. package/dist/index.js +0 -104
  57. package/dist/node/prompt.d.ts +0 -21
  58. package/dist/node/prompt.js +0 -30
  59. package/dist/node/save.d.ts +0 -17
  60. package/dist/node/save.js +0 -21
  61. package/dist/node/terminal-host.d.ts +0 -84
  62. package/dist/node/terminal-host.js +0 -160
  63. package/dist/node/traceback.d.ts +0 -27
  64. package/dist/node/traceback.js +0 -112
  65. package/dist/renderables/align.d.ts +0 -16
  66. package/dist/renderables/align.js +0 -46
  67. package/dist/renderables/columns.d.ts +0 -61
  68. package/dist/renderables/columns.js +0 -168
  69. package/dist/renderables/constrain.d.ts +0 -15
  70. package/dist/renderables/constrain.js +0 -37
  71. package/dist/renderables/flexStrip.d.ts +0 -41
  72. package/dist/renderables/flexStrip.js +0 -200
  73. package/dist/renderables/group.d.ts +0 -11
  74. package/dist/renderables/group.js +0 -15
  75. package/dist/renderables/layout.d.ts +0 -92
  76. package/dist/renderables/layout.js +0 -315
  77. package/dist/renderables/live.d.ts +0 -47
  78. package/dist/renderables/live.js +0 -131
  79. package/dist/renderables/markdown.d.ts +0 -24
  80. package/dist/renderables/markdown.js +0 -182
  81. package/dist/renderables/padding.d.ts +0 -38
  82. package/dist/renderables/padding.js +0 -140
  83. package/dist/renderables/panel.d.ts +0 -116
  84. package/dist/renderables/panel.js +0 -322
  85. package/dist/renderables/progress.d.ts +0 -90
  86. package/dist/renderables/progress.js +0 -241
  87. package/dist/renderables/progressBar.d.ts +0 -31
  88. package/dist/renderables/progressBar.js +0 -52
  89. package/dist/renderables/prompt.d.ts +0 -49
  90. package/dist/renderables/prompt.js +0 -125
  91. package/dist/renderables/rule.d.ts +0 -24
  92. package/dist/renderables/rule.js +0 -90
  93. package/dist/renderables/spinner.d.ts +0 -29
  94. package/dist/renderables/spinner.js +0 -64
  95. package/dist/renderables/status.d.ts +0 -23
  96. package/dist/renderables/status.js +0 -60
  97. package/dist/renderables/syntax.d.ts +0 -35
  98. package/dist/renderables/syntax.js +0 -114
  99. package/dist/renderables/table.d.ts +0 -182
  100. package/dist/renderables/table.js +0 -697
  101. package/dist/renderables/traceback.d.ts +0 -31
  102. package/dist/renderables/traceback.js +0 -109
  103. package/dist/renderables/tree.d.ts +0 -54
  104. package/dist/renderables/tree.js +0 -159
  105. package/dist/template-bindings/color-funcs.d.ts +0 -87
  106. package/dist/template-bindings/color-funcs.js +0 -219
  107. package/dist/template-bindings/helpers.d.ts +0 -24
  108. package/dist/template-bindings/helpers.js +0 -48
  109. package/dist/template-bindings/index.d.ts +0 -107
  110. package/dist/template-bindings/index.js +0 -144
  111. package/dist/template-bindings/palette-funcs.d.ts +0 -94
  112. package/dist/template-bindings/palette-funcs.js +0 -151
  113. package/dist/template-bindings/style-funcs.d.ts +0 -28
  114. package/dist/template-bindings/style-funcs.js +0 -151
  115. package/dist/themes/buildPalette.d.ts +0 -36
  116. package/dist/themes/buildPalette.js +0 -56
  117. package/dist/themes/colorMath.d.ts +0 -82
  118. package/dist/themes/colorMath.js +0 -254
  119. package/dist/themes/colorRef.d.ts +0 -51
  120. package/dist/themes/colorRef.js +0 -96
  121. package/dist/themes/data/atom-one-dark.d.ts +0 -3
  122. package/dist/themes/data/atom-one-dark.js +0 -158
  123. package/dist/themes/data/atom-one-light.d.ts +0 -3
  124. package/dist/themes/data/atom-one-light.js +0 -158
  125. package/dist/themes/data/catppuccin-frappe.d.ts +0 -3
  126. package/dist/themes/data/catppuccin-frappe.js +0 -158
  127. package/dist/themes/data/catppuccin-latte.d.ts +0 -3
  128. package/dist/themes/data/catppuccin-latte.js +0 -158
  129. package/dist/themes/data/catppuccin-macchiato.d.ts +0 -3
  130. package/dist/themes/data/catppuccin-macchiato.js +0 -158
  131. package/dist/themes/data/catppuccin-mocha.d.ts +0 -3
  132. package/dist/themes/data/catppuccin-mocha.js +0 -158
  133. package/dist/themes/data/cyberpunk.d.ts +0 -17
  134. package/dist/themes/data/cyberpunk.js +0 -191
  135. package/dist/themes/data/default.d.ts +0 -3
  136. package/dist/themes/data/default.js +0 -158
  137. package/dist/themes/data/dracula.d.ts +0 -3
  138. package/dist/themes/data/dracula.js +0 -158
  139. package/dist/themes/data/flexoki.d.ts +0 -3
  140. package/dist/themes/data/flexoki.js +0 -158
  141. package/dist/themes/data/gruvbox.d.ts +0 -3
  142. package/dist/themes/data/gruvbox.js +0 -158
  143. package/dist/themes/data/index.d.ts +0 -35
  144. package/dist/themes/data/index.js +0 -64
  145. package/dist/themes/data/monokai.d.ts +0 -3
  146. package/dist/themes/data/monokai.js +0 -158
  147. package/dist/themes/data/nord.d.ts +0 -3
  148. package/dist/themes/data/nord.js +0 -158
  149. package/dist/themes/data/rose-pine-dawn.d.ts +0 -3
  150. package/dist/themes/data/rose-pine-dawn.js +0 -158
  151. package/dist/themes/data/rose-pine-moon.d.ts +0 -3
  152. package/dist/themes/data/rose-pine-moon.js +0 -158
  153. package/dist/themes/data/rose-pine.d.ts +0 -3
  154. package/dist/themes/data/rose-pine.js +0 -158
  155. package/dist/themes/data/solarized-dark.d.ts +0 -3
  156. package/dist/themes/data/solarized-dark.js +0 -158
  157. package/dist/themes/data/solarized-light.d.ts +0 -3
  158. package/dist/themes/data/solarized-light.js +0 -158
  159. package/dist/themes/data/svg-export.d.ts +0 -3
  160. package/dist/themes/data/svg-export.js +0 -158
  161. package/dist/themes/data/textual-ansi.d.ts +0 -3
  162. package/dist/themes/data/textual-ansi.js +0 -158
  163. package/dist/themes/data/textual-dark.d.ts +0 -3
  164. package/dist/themes/data/textual-dark.js +0 -158
  165. package/dist/themes/data/textual-light.d.ts +0 -3
  166. package/dist/themes/data/textual-light.js +0 -158
  167. package/dist/themes/data/tokyo-night.d.ts +0 -3
  168. package/dist/themes/data/tokyo-night.js +0 -158
  169. package/dist/themes/data/types.d.ts +0 -15
  170. package/dist/themes/data/types.js +0 -1
  171. package/dist/themes/palette.d.ts +0 -21
  172. package/dist/themes/palette.js +0 -28
  173. package/dist/themes/ramp.d.ts +0 -83
  174. package/dist/themes/ramp.js +0 -122
  175. package/dist/themes/registry.d.ts +0 -43
  176. package/dist/themes/registry.js +0 -82
  177. package/dist/themes/terminalThemes.d.ts +0 -54
  178. package/dist/themes/terminalThemes.js +0 -68
  179. package/dist/themes/transpose.d.ts +0 -87
  180. package/dist/themes/transpose.js +0 -138
  181. package/dist/widgets/button.d.ts +0 -49
  182. package/dist/widgets/button.js +0 -206
  183. package/dist/widgets/checkbox.d.ts +0 -41
  184. package/dist/widgets/checkbox.js +0 -155
  185. package/dist/widgets/dropdown.d.ts +0 -67
  186. package/dist/widgets/dropdown.js +0 -453
  187. package/dist/widgets/event-router.d.ts +0 -78
  188. package/dist/widgets/event-router.js +0 -622
  189. package/dist/widgets/focus-manager.d.ts +0 -26
  190. package/dist/widgets/focus-manager.js +0 -193
  191. package/dist/widgets/index.d.ts +0 -22
  192. package/dist/widgets/index.js +0 -15
  193. package/dist/widgets/screen.d.ts +0 -98
  194. package/dist/widgets/screen.js +0 -530
  195. package/dist/widgets/slider.d.ts +0 -57
  196. package/dist/widgets/slider.js +0 -270
  197. package/dist/widgets/static-item.d.ts +0 -40
  198. package/dist/widgets/static-item.js +0 -60
  199. package/dist/widgets/text-input.d.ts +0 -274
  200. package/dist/widgets/text-input.js +0 -1162
  201. package/dist/widgets/toggle.d.ts +0 -44
  202. package/dist/widgets/toggle.js +0 -179
  203. package/dist/widgets/types.d.ts +0 -108
  204. package/dist/widgets/types.js +0 -31
  205. package/dist/widgets/widget-base.d.ts +0 -42
  206. package/dist/widgets/widget-base.js +0 -173
@@ -1,433 +0,0 @@
1
- /**
2
- * Segment — the atomic rendering unit. Every piece of styled terminal output
3
- * is represented as a Segment: (text, style?, control?).
4
- */
5
- import { cellLen, splitText, asCellCol } from "./cells.js";
6
- // --- ControlType ---
7
- export var ControlType;
8
- (function (ControlType) {
9
- ControlType["BELL"] = "bell";
10
- ControlType["CARRIAGE_RETURN"] = "carriage_return";
11
- ControlType["HOME"] = "home";
12
- ControlType["CLEAR"] = "clear";
13
- ControlType["SHOW_CURSOR"] = "show_cursor";
14
- ControlType["HIDE_CURSOR"] = "hide_cursor";
15
- ControlType["ENABLE_ALT_SCREEN"] = "enable_alt_screen";
16
- ControlType["DISABLE_ALT_SCREEN"] = "disable_alt_screen";
17
- ControlType["CURSOR_UP"] = "cursor_up";
18
- ControlType["CURSOR_DOWN"] = "cursor_down";
19
- ControlType["CURSOR_FORWARD"] = "cursor_forward";
20
- ControlType["CURSOR_BACKWARD"] = "cursor_backward";
21
- ControlType["CURSOR_MOVE_TO_COLUMN"] = "cursor_move_to_column";
22
- ControlType["CURSOR_MOVE_TO"] = "cursor_move_to";
23
- ControlType["ERASE_IN_LINE"] = "erase_in_line";
24
- ControlType["SET_WINDOW_TITLE"] = "set_window_title";
25
- })(ControlType || (ControlType = {}));
26
- // --- Segment ---
27
- export class Segment {
28
- text;
29
- style;
30
- control;
31
- constructor(text, style, control) {
32
- this.text = text;
33
- this.style = style;
34
- this.control = control;
35
- }
36
- get cellLength() {
37
- return this.control ? 0 : cellLen(this.text);
38
- }
39
- get hasText() {
40
- return this.text.length > 0;
41
- }
42
- get isControl() {
43
- return this.control !== undefined;
44
- }
45
- /**
46
- * Splits at a cell position. Returns [left, right].
47
- */
48
- splitCells(position) {
49
- const len = this.cellLength;
50
- if (position >= len)
51
- return [this, new Segment("")];
52
- if (position <= 0)
53
- return [new Segment(""), this];
54
- const [leftText, rightText] = splitText(this.text, position);
55
- return [
56
- new Segment(leftText, this.style),
57
- new Segment(rightText, this.style),
58
- ];
59
- }
60
- // --- Static factories ---
61
- static _line;
62
- static line() {
63
- return (Segment._line ??= new Segment("\n"));
64
- }
65
- // --- Static transformations ---
66
- /**
67
- * Yields segments with combined styles.
68
- */
69
- static *applyStyle(segments, style, postStyle) {
70
- for (const segment of segments) {
71
- if (segment.isControl) {
72
- yield segment;
73
- continue;
74
- }
75
- let s = segment.style;
76
- if (style)
77
- s = style.add(s);
78
- if (postStyle)
79
- s = s ? s.add(postStyle) : postStyle;
80
- yield new Segment(segment.text, s, segment.control);
81
- }
82
- }
83
- /**
84
- * Filters segments by control status.
85
- */
86
- static *filterControl(segments, isControl) {
87
- for (const segment of segments) {
88
- if (segment.isControl === isControl)
89
- yield segment;
90
- }
91
- }
92
- /**
93
- * Splits segments at newlines. Yields arrays of segments per line.
94
- */
95
- static splitLines(segments) {
96
- const lines = [];
97
- let currentLine = [];
98
- for (const segment of segments) {
99
- if (segment.isControl) {
100
- currentLine.push(segment);
101
- continue;
102
- }
103
- const text = segment.text;
104
- if (!text.includes("\n")) {
105
- currentLine.push(segment);
106
- continue;
107
- }
108
- const parts = text.split("\n");
109
- for (let i = 0; i < parts.length; i++) {
110
- if (i > 0) {
111
- lines.push(currentLine);
112
- currentLine = [];
113
- }
114
- const part = parts[i];
115
- if (part.length > 0) {
116
- currentLine.push(new Segment(part, segment.style));
117
- }
118
- }
119
- }
120
- if (currentLine.length > 0) {
121
- lines.push(currentLine);
122
- }
123
- return lines;
124
- }
125
- /**
126
- * Adjusts a line of segments to exactly `width` cells.
127
- */
128
- static adjustLineLength(line, width, style, pad = true) {
129
- const currentWidth = Segment.getLineLength(line);
130
- if (currentWidth === width)
131
- return line;
132
- if (currentWidth < width) {
133
- if (!pad)
134
- return line;
135
- return [...line, new Segment(" ".repeat(width - currentWidth), style)];
136
- }
137
- // Crop to width
138
- const result = [];
139
- let remaining = width;
140
- for (const segment of line) {
141
- if (segment.isControl) {
142
- result.push(segment);
143
- continue;
144
- }
145
- const segWidth = segment.cellLength;
146
- if (segWidth <= remaining) {
147
- result.push(segment);
148
- remaining -= segWidth;
149
- }
150
- else {
151
- const [left] = segment.splitCells(asCellCol(remaining));
152
- result.push(left);
153
- remaining = 0;
154
- break;
155
- }
156
- }
157
- return result;
158
- }
159
- /**
160
- * Crops a renderable's output so no line exceeds `width`, leaving short lines
161
- * alone and the line structure exactly as it arrived.
162
- *
163
- * [LAW:single-enforcer] `adjustLineLength` is where a width is enforced, but
164
- * it takes one line and a container holding arbitrary content has a stream of
165
- * them. Without this step the container has to trust content to honour the
166
- * offer, and content that ignores it overflows the region — which is how a
167
- * `Layout` leaf and a `Tree` label came to emit forty cells into a one-cell
168
- * offer while `Panel` and `Padding`, which split and adjust, did not.
169
- *
170
- * One segment in, one segment out, shortening text and nothing else — so the
171
- * line structure that arrives is the line structure that leaves. Two earlier
172
- * shapes of this both decided how many lines there were and both were wrong:
173
- * built on `splitLines`, which cannot tell `"abc"` from `"abc\n"`, it invented
174
- * a trailing newline and dropped the row of an empty `Tree` label entirely,
175
- * running its guides into the next row; rebuilt to accumulate lines, it
176
- * dropped the zero-width-but-present line `RichText` emits at an offer of 0,
177
- * and a row split rendered nothing at all. A crop shortens; it does not count.
178
- *
179
- * A wide glyph the edge cuts through leaves a space in the cell it would have
180
- * half-filled, so a cropped line still reaches the edge — the reference's
181
- * `set_cell_size`, which `splitText` already is. An unbounded `width` crops
182
- * nothing, and a segment the crop did not change leaves as itself.
183
- */
184
- static *cropLines(segments, width) {
185
- const cap = Math.max(0, width);
186
- let used = 0;
187
- for (const segment of segments) {
188
- if (segment.isControl) {
189
- yield segment;
190
- continue;
191
- }
192
- const parts = segment.text.split("\n");
193
- for (let i = 0; i < parts.length; i++) {
194
- if (i > 0)
195
- used = 0;
196
- const [piece] = splitText(parts[i], asCellCol(cap - used));
197
- used += cellLen(piece);
198
- parts[i] = piece;
199
- }
200
- const cropped = parts.join("\n");
201
- yield cropped === segment.text ? segment : new Segment(cropped, segment.style);
202
- }
203
- }
204
- /**
205
- * Returns total cell width of a line. Ignores control segments.
206
- */
207
- static getLineLength(line) {
208
- let width = 0;
209
- for (const segment of line) {
210
- if (!segment.isControl) {
211
- width += segment.cellLength;
212
- }
213
- }
214
- return width;
215
- }
216
- /**
217
- * Returns [width, height] of a set of lines.
218
- */
219
- static getShape(lines) {
220
- if (lines.length === 0)
221
- return [0, 0];
222
- let maxWidth = 0;
223
- for (const line of lines) {
224
- const w = Segment.getLineLength(line);
225
- if (w > maxWidth)
226
- maxWidth = w;
227
- }
228
- return [maxWidth, lines.length];
229
- }
230
- /**
231
- * Composes cells side by side into full lines. Each cell contributes its
232
- * own lines cropped/padded to its declared width; a cell shorter than the
233
- * tallest is filled with blank space so the grid stays aligned. Adjacent
234
- * cells are separated by a gutter of spaces, and each merged row ends with a
235
- * line break. This is the single side-by-side merge used by every horizontal
236
- * layout (Columns grid rows, Layout row splits).
237
- */
238
- static *mergeHorizontal(cells, gutter = 0) {
239
- let height = 0;
240
- for (const cell of cells) {
241
- if (cell.lines.length > height)
242
- height = cell.lines.length;
243
- }
244
- const gap = gutter > 0 ? [new Segment(" ".repeat(gutter))] : [];
245
- for (let row = 0; row < height; row++) {
246
- for (let col = 0; col < cells.length; col++) {
247
- if (col > 0)
248
- yield* gap;
249
- const cell = cells[col];
250
- yield* Segment.adjustLineLength(cell.lines[row] ?? [], cell.width);
251
- }
252
- yield Segment.line();
253
- }
254
- }
255
- /**
256
- * Merges contiguous segments with the same style.
257
- */
258
- static *simplify(segments) {
259
- let pending;
260
- for (const segment of segments) {
261
- if (!pending) {
262
- pending = segment;
263
- continue;
264
- }
265
- if (stylesEqual(pending.style, segment.style) && !segment.isControl && !pending.isControl) {
266
- pending = new Segment(pending.text + segment.text, pending.style);
267
- }
268
- else {
269
- yield pending;
270
- pending = segment;
271
- }
272
- }
273
- if (pending)
274
- yield pending;
275
- }
276
- /**
277
- * Yields segments with links removed.
278
- */
279
- static *stripLinks(segments) {
280
- for (const segment of segments) {
281
- if (segment.style?.link) {
282
- yield new Segment(segment.text, segment.style.clearMetaAndLinks(), segment.control);
283
- }
284
- else {
285
- yield segment;
286
- }
287
- }
288
- }
289
- /**
290
- * Yields segments with all styles removed.
291
- */
292
- static *stripStyles(segments) {
293
- for (const segment of segments) {
294
- yield new Segment(segment.text, undefined, segment.control);
295
- }
296
- }
297
- /**
298
- * Yields segments with colors removed but attributes preserved.
299
- */
300
- static *removeColor(segments) {
301
- for (const segment of segments) {
302
- if (segment.style) {
303
- yield new Segment(segment.text, segment.style.withoutColor, segment.control);
304
- }
305
- else {
306
- yield segment;
307
- }
308
- }
309
- }
310
- /**
311
- * Divides segments at cell positions. Yields arrays of segments for each section.
312
- */
313
- static divide(segments, cuts) {
314
- if (cuts.length === 0)
315
- return [segments];
316
- const result = [];
317
- let segmentIndex = 0;
318
- let cellOffset = 0;
319
- let currentSegment = segments[segmentIndex];
320
- for (const cut of cuts) {
321
- const section = [];
322
- while (currentSegment && cellOffset + currentSegment.cellLength <= cut) {
323
- if (currentSegment.isControl) {
324
- section.push(currentSegment);
325
- }
326
- else {
327
- section.push(currentSegment);
328
- cellOffset += currentSegment.cellLength;
329
- }
330
- segmentIndex++;
331
- currentSegment = segments[segmentIndex];
332
- }
333
- if (currentSegment && !currentSegment.isControl && cellOffset < cut) {
334
- const splitAt = asCellCol(cut - cellOffset);
335
- const [left, right] = currentSegment.splitCells(splitAt);
336
- if (left.hasText)
337
- section.push(left);
338
- cellOffset += left.cellLength;
339
- currentSegment = right;
340
- }
341
- result.push(section);
342
- }
343
- // Remaining segments
344
- const tail = [];
345
- if (currentSegment?.hasText)
346
- tail.push(currentSegment);
347
- segmentIndex++;
348
- while (segmentIndex < segments.length) {
349
- tail.push(segments[segmentIndex]);
350
- segmentIndex++;
351
- }
352
- if (tail.length > 0)
353
- result.push(tail);
354
- return result;
355
- }
356
- // --- Layout helpers ---
357
- /**
358
- * Pads below to fill height.
359
- */
360
- static alignTop(lines, width, height, style) {
361
- const result = lines.map((line) => Segment.adjustLineLength(line, width, style));
362
- const blankLine = [new Segment(" ".repeat(width), style)];
363
- while (result.length < height) {
364
- result.push([...blankLine]);
365
- }
366
- return result.slice(0, height);
367
- }
368
- /**
369
- * Pads above to fill height. Content at bottom.
370
- */
371
- static alignBottom(lines, width, height, style) {
372
- const adjusted = lines.map((line) => Segment.adjustLineLength(line, width, style));
373
- const blankLine = [new Segment(" ".repeat(width), style)];
374
- const padCount = Math.max(0, height - adjusted.length);
375
- const result = [];
376
- for (let i = 0; i < padCount; i++) {
377
- result.push([...blankLine]);
378
- }
379
- result.push(...adjusted);
380
- return result.slice(0, height);
381
- }
382
- /**
383
- * Pads above and below. Content in middle.
384
- */
385
- static alignMiddle(lines, width, height, style) {
386
- const adjusted = lines.map((line) => Segment.adjustLineLength(line, width, style));
387
- const blankLine = [new Segment(" ".repeat(width), style)];
388
- const padAbove = Math.max(0, Math.floor((height - adjusted.length) / 2));
389
- const result = [];
390
- for (let i = 0; i < padAbove; i++) {
391
- result.push([...blankLine]);
392
- }
393
- result.push(...adjusted);
394
- while (result.length < height) {
395
- result.push([...blankLine]);
396
- }
397
- return result.slice(0, height);
398
- }
399
- /**
400
- * Forces lines to exactly width x height.
401
- */
402
- static setShape(lines, width, height, style) {
403
- const result = lines.map((line) => Segment.adjustLineLength(line, width, style));
404
- const blankLine = [new Segment(" ".repeat(width), style)];
405
- while (result.length < height) {
406
- result.push([...blankLine]);
407
- }
408
- return result.slice(0, height);
409
- }
410
- /**
411
- * Splits segments into lines and adjusts each to exactly `width` cells.
412
- */
413
- static splitAndCropLines(segments, width, pad = true, includeNewLines = false, style) {
414
- const rawLines = Segment.splitLines(segments);
415
- const result = [];
416
- for (const line of rawLines) {
417
- const adjusted = Segment.adjustLineLength(line, width, style, pad);
418
- result.push(adjusted);
419
- if (includeNewLines) {
420
- result[result.length - 1].push(Segment.line());
421
- }
422
- }
423
- return result;
424
- }
425
- }
426
- // --- Internal helpers ---
427
- function stylesEqual(a, b) {
428
- if (a === b)
429
- return true;
430
- if (!a || !b)
431
- return false;
432
- return a.equals(b);
433
- }
@@ -1,10 +0,0 @@
1
- /**
2
- * Built-in spinner frame data.
3
- * [LAW:one-type-per-behavior] All spinners are instances of SpinnerData — differ only by frame data.
4
- */
5
- export interface SpinnerData {
6
- readonly frames: readonly string[];
7
- readonly interval: number;
8
- }
9
- export declare const SPINNERS: Record<string, SpinnerData>;
10
- export declare const DEFAULT_SPINNER = "dots";
@@ -1,115 +0,0 @@
1
- /**
2
- * Built-in spinner frame data.
3
- * [LAW:one-type-per-behavior] All spinners are instances of SpinnerData — differ only by frame data.
4
- */
5
- // [LAW:one-source-of-truth] Single authoritative collection of spinner definitions
6
- export const SPINNERS = {
7
- dots: { frames: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"], interval: 80 },
8
- dots2: { frames: ["⣾", "⣽", "⣻", "⢿", "⡿", "⣟", "⣯", "⣷"], interval: 80 },
9
- dots3: { frames: ["⠋", "⠙", "⠚", "⠞", "⠖", "⠦", "⠴", "⠲", "⠳", "⠓"], interval: 80 },
10
- line: { frames: ["-", "\\", "|", "/"], interval: 130 },
11
- line2: { frames: ["⠂", "-", "–", "—", "–", "-"], interval: 100 },
12
- pipe: { frames: ["┤", "┘", "┴", "└", "├", "┌", "┬", "┐"], interval: 100 },
13
- simpleDots: { frames: [". ", ".. ", "...", " "], interval: 400 },
14
- simpleDotsScrolling: { frames: [". ", ".. ", "...", " ..", " .", " "], interval: 200 },
15
- star: { frames: ["✶", "✸", "✹", "✺", "✹", "✷"], interval: 70 },
16
- star2: { frames: ["+", "x", "*"], interval: 80 },
17
- flip: { frames: ["_", "_", "_", "-", "`", "`", "'", "´", "-", "_", "_", "_"], interval: 70 },
18
- hamburger: { frames: ["☱", "☲", "☴"], interval: 100 },
19
- growVertical: { frames: ["▁", "▃", "▄", "▅", "▆", "▇", "▆", "▅", "▄", "▃"], interval: 120 },
20
- growHorizontal: { frames: ["▏", "▎", "▍", "▌", "▋", "▊", "▉", "▊", "▋", "▌", "▍", "▎"], interval: 120 },
21
- balloon: { frames: [" ", ".", "o", "O", "@", "*", " "], interval: 140 },
22
- balloon2: { frames: [".", "o", "O", "°", "O", "o", "."], interval: 120 },
23
- noise: { frames: ["▓", "▒", "░"], interval: 100 },
24
- bounce: { frames: ["⠁", "⠂", "⠄", "⠂"], interval: 120 },
25
- boxBounce: { frames: ["▖", "▘", "▝", "▗"], interval: 120 },
26
- boxBounce2: { frames: ["▌", "▀", "▐", "▄"], interval: 100 },
27
- triangle: { frames: ["◢", "◣", "◤", "◥"], interval: 50 },
28
- arc: { frames: ["◜", "◠", "◝", "◞", "◡", "◟"], interval: 100 },
29
- circle: { frames: ["◡", "⊙", "◠"], interval: 120 },
30
- squareCorners: { frames: ["◰", "◳", "◲", "◱"], interval: 180 },
31
- circleQuarters: { frames: ["◴", "◷", "◶", "◵"], interval: 120 },
32
- circleHalves: { frames: ["◐", "◓", "◑", "◒"], interval: 50 },
33
- squish: { frames: ["╫", "╪"], interval: 100 },
34
- toggle: { frames: ["⊶", "⊷"], interval: 250 },
35
- toggle2: { frames: ["▫", "▪"], interval: 80 },
36
- toggle3: { frames: ["□", "■"], interval: 120 },
37
- toggle4: { frames: ["■", "□", "▪", "▫"], interval: 100 },
38
- toggle5: { frames: ["▮", "▯"], interval: 100 },
39
- toggle6: { frames: ["ဝ", "၀"], interval: 300 },
40
- toggle7: { frames: ["⦾", "⦿"], interval: 80 },
41
- toggle8: { frames: ["◍", "◌"], interval: 100 },
42
- toggle9: { frames: ["◉", "◎"], interval: 100 },
43
- toggle10: { frames: ["㊂", "㊀", "㊁"], interval: 100 },
44
- toggle11: { frames: ["⧇", "⧆"], interval: 50 },
45
- toggle12: { frames: ["☗", "☖"], interval: 120 },
46
- toggle13: { frames: ["=", "*", "-"], interval: 80 },
47
- arrow: { frames: ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"], interval: 100 },
48
- arrow2: { frames: ["⬆️ ", "↗️ ", "➡️ ", "↘️ ", "⬇️ ", "↙️ ", "⬅️ ", "↖️ "], interval: 80 },
49
- arrow3: { frames: ["▹▹▹▹▹", "▸▹▹▹▹", "▹▸▹▹▹", "▹▹▸▹▹", "▹▹▹▸▹", "▹▹▹▹▸"], interval: 120 },
50
- bouncingBar: { frames: [
51
- "[ ]", "[= ]", "[== ]", "[=== ]", "[ ===]", "[ ==]", "[ =]", "[ ]",
52
- "[ =]", "[ ==]", "[ ===]", "[====]", "[=== ]", "[== ]", "[= ]",
53
- ], interval: 80 },
54
- bouncingBall: { frames: [
55
- "( ● )", "( ● )", "( ● )", "( ● )", "( ●)", "( ● )",
56
- "( ● )", "( ● )", "( ● )", "(● )",
57
- ], interval: 80 },
58
- smiley: { frames: ["😄 ", "😝 "], interval: 200 },
59
- monkey: { frames: ["🙈 ", "🙈 ", "🙉 ", "🙊 "], interval: 300 },
60
- hearts: { frames: ["💛 ", "💙 ", "💜 ", "💚 ", "❤️ "], interval: 100 },
61
- clock: { frames: ["🕛 ", "🕐 ", "🕑 ", "🕒 ", "🕓 ", "🕔 ", "🕕 ", "🕖 ", "🕗 ", "🕘 ", "🕙 ", "🕚 "], interval: 100 },
62
- earth: { frames: ["🌍 ", "🌎 ", "🌏 "], interval: 180 },
63
- moon: { frames: ["🌑 ", "🌒 ", "🌓 ", "🌔 ", "🌕 ", "🌖 ", "🌗 ", "🌘 "], interval: 80 },
64
- runner: { frames: ["🚶 ", "🏃 "], interval: 140 },
65
- pong: { frames: [
66
- "▐⠂ ▌", "▐⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌",
67
- "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌",
68
- "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌", "▐ ⠂▌",
69
- "▐ ⠠▌", "▐ ⡀▌", "▐ ⠠ ▌", "▐ ⠂ ▌", "▐ ⠈ ▌",
70
- "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐ ⠠ ▌", "▐ ⠂ ▌",
71
- "▐ ⠈ ▌", "▐ ⠂ ▌", "▐ ⠠ ▌", "▐ ⡀ ▌", "▐⠠ ▌",
72
- ], interval: 80 },
73
- material: { frames: [
74
- "█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
75
- "███▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "████▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
76
- "██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁", "██████▁▁▁▁▁▁▁▁▁▁▁▁▁▁",
77
- "███████▁▁▁▁▁▁▁▁▁▁▁▁▁", "████████▁▁▁▁▁▁▁▁▁▁▁▁",
78
- "█████████▁▁▁▁▁▁▁▁▁▁▁", "█████████▁▁▁▁▁▁▁▁▁▁▁",
79
- "██████████▁▁▁▁▁▁▁▁▁▁", "███████████▁▁▁▁▁▁▁▁▁",
80
- "█████████████▁▁▁▁▁▁▁", "██████████████▁▁▁▁▁▁",
81
- "██████████████▁▁▁▁▁▁", "▁██████████████▁▁▁▁▁",
82
- "▁██████████████▁▁▁▁▁", "▁██████████████▁▁▁▁▁",
83
- "▁▁██████████████▁▁▁▁", "▁▁▁██████████████▁▁▁",
84
- "▁▁▁▁█████████████▁▁▁", "▁▁▁▁██████████████▁▁",
85
- "▁▁▁▁██████████████▁▁", "▁▁▁▁▁██████████████▁",
86
- "▁▁▁▁▁██████████████▁", "▁▁▁▁▁██████████████▁",
87
- "▁▁▁▁▁▁██████████████", "▁▁▁▁▁▁██████████████",
88
- "▁▁▁▁▁▁▁█████████████", "▁▁▁▁▁▁▁█████████████",
89
- "▁▁▁▁▁▁▁▁████████████", "▁▁▁▁▁▁▁▁████████████",
90
- "▁▁▁▁▁▁▁▁▁███████████", "▁▁▁▁▁▁▁▁▁███████████",
91
- "▁▁▁▁▁▁▁▁▁▁██████████", "▁▁▁▁▁▁▁▁▁▁██████████",
92
- "▁▁▁▁▁▁▁▁▁▁▁▁████████", "▁▁▁▁▁▁▁▁▁▁▁▁▁███████",
93
- "▁▁▁▁▁▁▁▁▁▁▁▁▁▁██████", "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████",
94
- "▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁█████", "█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁████",
95
- "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███", "██▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁███",
96
- "███▁▁▁▁▁▁▁▁▁▁▁▁▁▁███", "████▁▁▁▁▁▁▁▁▁▁▁▁▁▁██",
97
- "█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█", "█████▁▁▁▁▁▁▁▁▁▁▁▁▁▁█",
98
- "██████▁▁▁▁▁▁▁▁▁▁▁▁▁█", "████████▁▁▁▁▁▁▁▁▁▁▁▁",
99
- "█████████▁▁▁▁▁▁▁▁▁▁▁", "█████████▁▁▁▁▁▁▁▁▁▁▁",
100
- "█████████▁▁▁▁▁▁▁▁▁▁▁", "█████████▁▁▁▁▁▁▁▁▁▁▁",
101
- "███████████▁▁▁▁▁▁▁▁▁", "████████████▁▁▁▁▁▁▁▁",
102
- "████████████▁▁▁▁▁▁▁▁", "██████████████▁▁▁▁▁▁",
103
- "██████████████▁▁▁▁▁▁", "▁██████████████▁▁▁▁▁",
104
- "▁██████████████▁▁▁▁▁", "▁▁▁██████████████▁▁▁",
105
- "▁▁▁▁▁████████████▁▁▁", "▁▁▁▁▁████████████▁▁▁",
106
- "▁▁▁▁▁▁███████████▁▁▁", "▁▁▁▁▁▁▁▁█████████▁▁▁",
107
- "▁▁▁▁▁▁▁▁█████████▁▁▁", "▁▁▁▁▁▁▁▁▁█████████▁▁",
108
- "▁▁▁▁▁▁▁▁▁█████████▁▁", "▁▁▁▁▁▁▁▁▁▁█████████▁",
109
- ], interval: 17 },
110
- aesthetic: { frames: [
111
- "▰▱▱▱▱▱▱", "▰▰▱▱▱▱▱", "▰▰▰▱▱▱▱", "▰▰▰▰▱▱▱",
112
- "▰▰▰▰▰▱▱", "▰▰▰▰▰▰▱", "▰▰▰▰▰▰▰", "▰▱▱▱▱▱▱",
113
- ], interval: 80 },
114
- };
115
- export const DEFAULT_SPINNER = "dots";