@hypercli/ui 0.1.1
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/LICENSE +21 -0
- package/README.md +11 -0
- package/dist/capabilities/index.d.ts +62 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +182 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/colors.d.ts +32 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +40 -0
- package/dist/colors.js.map +1 -0
- package/dist/components/columns.d.ts +28 -0
- package/dist/components/columns.d.ts.map +1 -0
- package/dist/components/columns.js +70 -0
- package/dist/components/columns.js.map +1 -0
- package/dist/components/confirmPrompt.d.ts +38 -0
- package/dist/components/confirmPrompt.d.ts.map +1 -0
- package/dist/components/confirmPrompt.js +109 -0
- package/dist/components/confirmPrompt.js.map +1 -0
- package/dist/components/diff.d.ts +37 -0
- package/dist/components/diff.d.ts.map +1 -0
- package/dist/components/diff.js +36 -0
- package/dist/components/diff.js.map +1 -0
- package/dist/components/helpLayout.d.ts +59 -0
- package/dist/components/helpLayout.d.ts.map +1 -0
- package/dist/components/helpLayout.js +103 -0
- package/dist/components/helpLayout.js.map +1 -0
- package/dist/components/index.d.ts +38 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +23 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/keyValue.d.ts +31 -0
- package/dist/components/keyValue.d.ts.map +1 -0
- package/dist/components/keyValue.js +36 -0
- package/dist/components/keyValue.js.map +1 -0
- package/dist/components/list.d.ts +30 -0
- package/dist/components/list.d.ts.map +1 -0
- package/dist/components/list.js +80 -0
- package/dist/components/list.js.map +1 -0
- package/dist/components/message.d.ts +33 -0
- package/dist/components/message.d.ts.map +1 -0
- package/dist/components/message.js +86 -0
- package/dist/components/message.js.map +1 -0
- package/dist/components/panel.d.ts +28 -0
- package/dist/components/panel.d.ts.map +1 -0
- package/dist/components/panel.js +30 -0
- package/dist/components/panel.js.map +1 -0
- package/dist/components/progressBar.d.ts +44 -0
- package/dist/components/progressBar.d.ts.map +1 -0
- package/dist/components/progressBar.js +154 -0
- package/dist/components/progressBar.js.map +1 -0
- package/dist/components/section.d.ts +22 -0
- package/dist/components/section.d.ts.map +1 -0
- package/dist/components/section.js +48 -0
- package/dist/components/section.js.map +1 -0
- package/dist/components/selectPrompt.d.ts +58 -0
- package/dist/components/selectPrompt.d.ts.map +1 -0
- package/dist/components/selectPrompt.js +206 -0
- package/dist/components/selectPrompt.js.map +1 -0
- package/dist/components/spinner.d.ts +38 -0
- package/dist/components/spinner.d.ts.map +1 -0
- package/dist/components/spinner.js +125 -0
- package/dist/components/spinner.js.map +1 -0
- package/dist/components/statusList.d.ts +22 -0
- package/dist/components/statusList.d.ts.map +1 -0
- package/dist/components/statusList.js +43 -0
- package/dist/components/statusList.js.map +1 -0
- package/dist/components/table.d.ts +39 -0
- package/dist/components/table.d.ts.map +1 -0
- package/dist/components/table.js +132 -0
- package/dist/components/table.js.map +1 -0
- package/dist/components/textPrompt.d.ts +43 -0
- package/dist/components/textPrompt.d.ts.map +1 -0
- package/dist/components/textPrompt.js +123 -0
- package/dist/components/textPrompt.js.map +1 -0
- package/dist/components/tree.d.ts +30 -0
- package/dist/components/tree.d.ts.map +1 -0
- package/dist/components/tree.js +49 -0
- package/dist/components/tree.js.map +1 -0
- package/dist/ds-index.d.ts +113 -0
- package/dist/ds-index.d.ts.map +1 -0
- package/dist/ds-index.js +112 -0
- package/dist/ds-index.js.map +1 -0
- package/dist/help.d.ts +32 -0
- package/dist/help.d.ts.map +1 -0
- package/dist/help.js +34 -0
- package/dist/help.js.map +1 -0
- package/dist/hyper-theme.d.ts +8 -0
- package/dist/hyper-theme.d.ts.map +1 -0
- package/dist/hyper-theme.js +30 -0
- package/dist/hyper-theme.js.map +1 -0
- package/dist/index.d.ts +50 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/md.d.ts +12 -0
- package/dist/md.d.ts.map +1 -0
- package/dist/md.js +19 -0
- package/dist/md.js.map +1 -0
- package/dist/messages.d.ts +20 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +65 -0
- package/dist/messages.js.map +1 -0
- package/dist/palette.d.ts +20 -0
- package/dist/palette.d.ts.map +1 -0
- package/dist/palette.js +22 -0
- package/dist/palette.js.map +1 -0
- package/dist/primitives/align.d.ts +23 -0
- package/dist/primitives/align.d.ts.map +1 -0
- package/dist/primitives/align.js +40 -0
- package/dist/primitives/align.js.map +1 -0
- package/dist/primitives/badge.d.ts +24 -0
- package/dist/primitives/badge.d.ts.map +1 -0
- package/dist/primitives/badge.js +40 -0
- package/dist/primitives/badge.js.map +1 -0
- package/dist/primitives/border.d.ts +29 -0
- package/dist/primitives/border.d.ts.map +1 -0
- package/dist/primitives/border.js +100 -0
- package/dist/primitives/border.js.map +1 -0
- package/dist/primitives/context.d.ts +48 -0
- package/dist/primitives/context.d.ts.map +1 -0
- package/dist/primitives/context.js +64 -0
- package/dist/primitives/context.js.map +1 -0
- package/dist/primitives/divider.d.ts +25 -0
- package/dist/primitives/divider.d.ts.map +1 -0
- package/dist/primitives/divider.js +56 -0
- package/dist/primitives/divider.js.map +1 -0
- package/dist/primitives/indent.d.ts +16 -0
- package/dist/primitives/indent.d.ts.map +1 -0
- package/dist/primitives/indent.js +25 -0
- package/dist/primitives/indent.js.map +1 -0
- package/dist/primitives/index.d.ts +32 -0
- package/dist/primitives/index.d.ts.map +1 -0
- package/dist/primitives/index.js +22 -0
- package/dist/primitives/index.js.map +1 -0
- package/dist/primitives/line.d.ts +21 -0
- package/dist/primitives/line.d.ts.map +1 -0
- package/dist/primitives/line.js +29 -0
- package/dist/primitives/line.js.map +1 -0
- package/dist/primitives/markdown.d.ts +91 -0
- package/dist/primitives/markdown.d.ts.map +1 -0
- package/dist/primitives/markdown.js +62 -0
- package/dist/primitives/markdown.js.map +1 -0
- package/dist/primitives/pad.d.ts +24 -0
- package/dist/primitives/pad.d.ts.map +1 -0
- package/dist/primitives/pad.js +20 -0
- package/dist/primitives/pad.js.map +1 -0
- package/dist/primitives/stack.d.ts +22 -0
- package/dist/primitives/stack.d.ts.map +1 -0
- package/dist/primitives/stack.js +21 -0
- package/dist/primitives/stack.js.map +1 -0
- package/dist/primitives/styledText.d.ts +36 -0
- package/dist/primitives/styledText.d.ts.map +1 -0
- package/dist/primitives/styledText.js +42 -0
- package/dist/primitives/styledText.js.map +1 -0
- package/dist/primitives/symbol.d.ts +15 -0
- package/dist/primitives/symbol.d.ts.map +1 -0
- package/dist/primitives/symbol.js +18 -0
- package/dist/primitives/symbol.js.map +1 -0
- package/dist/primitives/truncate.d.ts +23 -0
- package/dist/primitives/truncate.d.ts.map +1 -0
- package/dist/primitives/truncate.js +99 -0
- package/dist/primitives/truncate.js.map +1 -0
- package/dist/primitives/wrap.d.ts +23 -0
- package/dist/primitives/wrap.d.ts.map +1 -0
- package/dist/primitives/wrap.js +30 -0
- package/dist/primitives/wrap.js.map +1 -0
- package/dist/render/ansi-utils.d.ts +49 -0
- package/dist/render/ansi-utils.d.ts.map +1 -0
- package/dist/render/ansi-utils.js +405 -0
- package/dist/render/ansi-utils.js.map +1 -0
- package/dist/render/index.d.ts +11 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +11 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/sgr.d.ts +60 -0
- package/dist/render/sgr.d.ts.map +1 -0
- package/dist/render/sgr.js +191 -0
- package/dist/render/sgr.js.map +1 -0
- package/dist/render/strip.d.ts +24 -0
- package/dist/render/strip.d.ts.map +1 -0
- package/dist/render/strip.js +81 -0
- package/dist/render/strip.js.map +1 -0
- package/dist/render/width.d.ts +30 -0
- package/dist/render/width.d.ts.map +1 -0
- package/dist/render/width.js +149 -0
- package/dist/render/width.js.map +1 -0
- package/dist/shortcuts.d.ts +76 -0
- package/dist/shortcuts.d.ts.map +1 -0
- package/dist/shortcuts.js +117 -0
- package/dist/shortcuts.js.map +1 -0
- package/dist/styles.d.ts +43 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +44 -0
- package/dist/styles.js.map +1 -0
- package/dist/symbols.d.ts +19 -0
- package/dist/symbols.d.ts.map +1 -0
- package/dist/symbols.js +21 -0
- package/dist/symbols.js.map +1 -0
- package/dist/test/compare.d.ts +28 -0
- package/dist/test/compare.d.ts.map +1 -0
- package/dist/test/compare.js +37 -0
- package/dist/test/compare.js.map +1 -0
- package/dist/test/index.d.ts +16 -0
- package/dist/test/index.d.ts.map +1 -0
- package/dist/test/index.js +14 -0
- package/dist/test/index.js.map +1 -0
- package/dist/test/mock.d.ts +50 -0
- package/dist/test/mock.d.ts.map +1 -0
- package/dist/test/mock.js +135 -0
- package/dist/test/mock.js.map +1 -0
- package/dist/test/render.d.ts +29 -0
- package/dist/test/render.d.ts.map +1 -0
- package/dist/test/render.js +87 -0
- package/dist/test/render.js.map +1 -0
- package/dist/test/snapshot.d.ts +16 -0
- package/dist/test/snapshot.d.ts.map +1 -0
- package/dist/test/snapshot.js +216 -0
- package/dist/test/snapshot.js.map +1 -0
- package/dist/theme/builtins.d.ts +10 -0
- package/dist/theme/builtins.d.ts.map +1 -0
- package/dist/theme/builtins.js +102 -0
- package/dist/theme/builtins.js.map +1 -0
- package/dist/theme/engine.d.ts +51 -0
- package/dist/theme/engine.d.ts.map +1 -0
- package/dist/theme/engine.js +123 -0
- package/dist/theme/engine.js.map +1 -0
- package/dist/theme/index.d.ts +10 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +12 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/theme/merge.d.ts +24 -0
- package/dist/theme/merge.d.ts.map +1 -0
- package/dist/theme/merge.js +66 -0
- package/dist/theme/merge.js.map +1 -0
- package/dist/theme/types.d.ts +44 -0
- package/dist/theme/types.d.ts.map +1 -0
- package/dist/theme/types.js +8 -0
- package/dist/theme/types.js.map +1 -0
- package/dist/theme.d.ts +9 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +53 -0
- package/dist/theme.js.map +1 -0
- package/dist/tokens/defaults.d.ts +13 -0
- package/dist/tokens/defaults.d.ts.map +1 -0
- package/dist/tokens/defaults.js +248 -0
- package/dist/tokens/defaults.js.map +1 -0
- package/dist/tokens/index.d.ts +10 -0
- package/dist/tokens/index.d.ts.map +1 -0
- package/dist/tokens/index.js +10 -0
- package/dist/tokens/index.js.map +1 -0
- package/dist/tokens/resolver.d.ts +100 -0
- package/dist/tokens/resolver.d.ts.map +1 -0
- package/dist/tokens/resolver.js +138 -0
- package/dist/tokens/resolver.js.map +1 -0
- package/dist/tokens/types.d.ts +265 -0
- package/dist/tokens/types.d.ts.map +1 -0
- package/dist/tokens/types.js +10 -0
- package/dist/tokens/types.js.map +1 -0
- package/dist/tokens.d.ts +26 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +30 -0
- package/dist/tokens.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SelectPrompt Component
|
|
3
|
+
*
|
|
4
|
+
* Prompts the user to select a single option from a list.
|
|
5
|
+
* Uses raw mode to capture keystrokes for arrow navigation.
|
|
6
|
+
* Falls back to numbered list input in non-TTY environments.
|
|
7
|
+
*/
|
|
8
|
+
import * as readline from "node:readline";
|
|
9
|
+
import { getContext, styledText, symbol } from "../primitives/index.js";
|
|
10
|
+
/**
|
|
11
|
+
* Formats the select question line.
|
|
12
|
+
* Returns: `? message` with `?` in accent color.
|
|
13
|
+
*/
|
|
14
|
+
export function formatSelectQuestion(message) {
|
|
15
|
+
const q = styledText("?", { color: "accent", bold: true });
|
|
16
|
+
return `${q} ${message}`;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Formats the submitted answer line.
|
|
20
|
+
* Returns: `checkmark message selected-label`.
|
|
21
|
+
*/
|
|
22
|
+
export function formatSelectAnswer(message, selectedLabel) {
|
|
23
|
+
const icon = styledText(symbol("success"), { color: "success" });
|
|
24
|
+
const label = styledText(selectedLabel, { dim: true });
|
|
25
|
+
return `${icon} ${message} ${label}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Renders the option list for display.
|
|
29
|
+
* Returns an array of formatted option lines.
|
|
30
|
+
*/
|
|
31
|
+
export function renderOptions(options, activeIndex, scrollOffset, maxVisible) {
|
|
32
|
+
const ctx = getContext();
|
|
33
|
+
const lines = [];
|
|
34
|
+
const visible = options.slice(scrollOffset, scrollOffset + maxVisible);
|
|
35
|
+
for (let i = 0; i < visible.length; i++) {
|
|
36
|
+
const option = visible[i];
|
|
37
|
+
const realIndex = scrollOffset + i;
|
|
38
|
+
const isActive = realIndex === activeIndex;
|
|
39
|
+
if (option.disabled) {
|
|
40
|
+
const pointer = " ";
|
|
41
|
+
const label = styledText(option.label, { dim: true });
|
|
42
|
+
const disabled = styledText("(disabled)", { dim: true });
|
|
43
|
+
lines.push(`${pointer}${label} ${disabled}`);
|
|
44
|
+
}
|
|
45
|
+
else if (isActive) {
|
|
46
|
+
const pointer = styledText(symbol("pointer"), { color: "accent" });
|
|
47
|
+
const label = styledText(option.label, { color: "accent" });
|
|
48
|
+
const hint = option.hint ? ` ${styledText(option.hint, { dim: true })}` : "";
|
|
49
|
+
lines.push(`${pointer} ${label}${hint}`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const pointer = " ";
|
|
53
|
+
lines.push(`${pointer}${option.label}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Scroll indicators
|
|
57
|
+
if (scrollOffset > 0) {
|
|
58
|
+
const arrow = styledText(symbol("arrowUp"), { dim: true });
|
|
59
|
+
lines[0] = `${lines[0]} ${arrow}`;
|
|
60
|
+
}
|
|
61
|
+
if (scrollOffset + maxVisible < options.length) {
|
|
62
|
+
const arrow = styledText(symbol("arrowDown"), { dim: true });
|
|
63
|
+
lines[lines.length - 1] = `${lines[lines.length - 1]} ${arrow}`;
|
|
64
|
+
}
|
|
65
|
+
return lines;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Find the next non-disabled index in a direction.
|
|
69
|
+
*/
|
|
70
|
+
function findNextEnabled(options, from, direction) {
|
|
71
|
+
let index = from;
|
|
72
|
+
const len = options.length;
|
|
73
|
+
for (let attempts = 0; attempts < len; attempts++) {
|
|
74
|
+
index = (index + direction + len) % len;
|
|
75
|
+
if (!options[index].disabled)
|
|
76
|
+
return index;
|
|
77
|
+
}
|
|
78
|
+
return from; // All disabled, stay put
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Prompts the user to select a single option from a list using arrow-key navigation.
|
|
82
|
+
* Falls back to numbered list input in non-TTY environments.
|
|
83
|
+
*
|
|
84
|
+
* @typeParam T - The value type of the selectable options.
|
|
85
|
+
* @param options - Select prompt configuration.
|
|
86
|
+
* @returns The value of the selected option.
|
|
87
|
+
*/
|
|
88
|
+
export function selectPrompt(options) {
|
|
89
|
+
const ctx = getContext();
|
|
90
|
+
const stream = process.stderr;
|
|
91
|
+
const maxVisible = options.maxVisible ?? 10;
|
|
92
|
+
const isTTY = !!process.stdin.isTTY;
|
|
93
|
+
// Find first non-disabled option
|
|
94
|
+
let activeIndex = options.options.findIndex((o) => !o.disabled);
|
|
95
|
+
if (activeIndex === -1) {
|
|
96
|
+
return Promise.reject(new Error("All options are disabled"));
|
|
97
|
+
}
|
|
98
|
+
let scrollOffset = 0;
|
|
99
|
+
function adjustScroll() {
|
|
100
|
+
if (activeIndex < scrollOffset) {
|
|
101
|
+
scrollOffset = activeIndex;
|
|
102
|
+
}
|
|
103
|
+
else if (activeIndex >= scrollOffset + maxVisible) {
|
|
104
|
+
scrollOffset = activeIndex - maxVisible + 1;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
if (!isTTY) {
|
|
109
|
+
// Non-TTY: numbered list fallback
|
|
110
|
+
stream.write(`${options.message}\n`);
|
|
111
|
+
options.options.forEach((opt, i) => {
|
|
112
|
+
const disabled = opt.disabled ? " (disabled)" : "";
|
|
113
|
+
stream.write(` ${i + 1}. ${opt.label}${disabled}\n`);
|
|
114
|
+
});
|
|
115
|
+
stream.write("Enter number: ");
|
|
116
|
+
const rl = readline.createInterface({
|
|
117
|
+
input: process.stdin,
|
|
118
|
+
terminal: false,
|
|
119
|
+
});
|
|
120
|
+
rl.once("line", (line) => {
|
|
121
|
+
rl.close();
|
|
122
|
+
const num = Number.parseInt(line.trim(), 10);
|
|
123
|
+
if (Number.isNaN(num) || num < 1 || num > options.options.length) {
|
|
124
|
+
reject(new Error(`Invalid selection: "${line.trim()}"`));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const selected = options.options[num - 1];
|
|
128
|
+
if (selected.disabled) {
|
|
129
|
+
reject(new Error(`Option "${selected.label}" is disabled`));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
resolve(selected.value);
|
|
133
|
+
});
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// Interactive TTY mode with raw keypress handling
|
|
137
|
+
const question = formatSelectQuestion(options.message);
|
|
138
|
+
let renderedLines = 0;
|
|
139
|
+
function render() {
|
|
140
|
+
// Clear previously rendered lines
|
|
141
|
+
if (renderedLines > 0) {
|
|
142
|
+
for (let i = 0; i < renderedLines; i++) {
|
|
143
|
+
stream.write("\x1b[A"); // move up
|
|
144
|
+
}
|
|
145
|
+
stream.write("\r\x1b[J"); // clear from cursor to end
|
|
146
|
+
}
|
|
147
|
+
adjustScroll();
|
|
148
|
+
const lines = renderOptions(options.options, activeIndex, scrollOffset, maxVisible);
|
|
149
|
+
stream.write(`${question}\n`);
|
|
150
|
+
for (const line of lines) {
|
|
151
|
+
stream.write(`${line}\n`);
|
|
152
|
+
}
|
|
153
|
+
renderedLines = lines.length + 1; // +1 for the question line
|
|
154
|
+
}
|
|
155
|
+
// Hide cursor
|
|
156
|
+
stream.write("\x1b[?25l");
|
|
157
|
+
render();
|
|
158
|
+
// Enable raw mode for keypress capture
|
|
159
|
+
process.stdin.setRawMode(true);
|
|
160
|
+
process.stdin.resume();
|
|
161
|
+
const onData = (data) => {
|
|
162
|
+
const key = data.toString();
|
|
163
|
+
// Ctrl+C
|
|
164
|
+
if (key === "\x03") {
|
|
165
|
+
cleanup();
|
|
166
|
+
stream.write("\x1b[?25h");
|
|
167
|
+
reject(new Error("Prompt cancelled"));
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Enter
|
|
171
|
+
if (key === "\r" || key === "\n") {
|
|
172
|
+
cleanup();
|
|
173
|
+
// Clear the rendered options
|
|
174
|
+
if (renderedLines > 0) {
|
|
175
|
+
for (let i = 0; i < renderedLines; i++) {
|
|
176
|
+
stream.write("\x1b[A");
|
|
177
|
+
}
|
|
178
|
+
stream.write("\r\x1b[J");
|
|
179
|
+
}
|
|
180
|
+
const selected = options.options[activeIndex];
|
|
181
|
+
stream.write(`${formatSelectAnswer(options.message, selected.label)}\n`);
|
|
182
|
+
stream.write("\x1b[?25h");
|
|
183
|
+
resolve(selected.value);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Arrow keys (escape sequences)
|
|
187
|
+
if (key === "\x1b[A" || key === "k") {
|
|
188
|
+
// Up
|
|
189
|
+
activeIndex = findNextEnabled(options.options, activeIndex, -1);
|
|
190
|
+
render();
|
|
191
|
+
}
|
|
192
|
+
else if (key === "\x1b[B" || key === "j") {
|
|
193
|
+
// Down
|
|
194
|
+
activeIndex = findNextEnabled(options.options, activeIndex, 1);
|
|
195
|
+
render();
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
function cleanup() {
|
|
199
|
+
process.stdin.removeListener("data", onData);
|
|
200
|
+
process.stdin.setRawMode(false);
|
|
201
|
+
process.stdin.pause();
|
|
202
|
+
}
|
|
203
|
+
process.stdin.on("data", onData);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=selectPrompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectPrompt.js","sourceRoot":"","sources":["../../src/components/selectPrompt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spinner Component
|
|
3
|
+
*
|
|
4
|
+
* An animated spinner indicator for indeterminate operations.
|
|
5
|
+
* Manages terminal output directly via process.stderr.write and cursor control.
|
|
6
|
+
* Gracefully degrades in non-TTY/CI environments to static line output.
|
|
7
|
+
*/
|
|
8
|
+
/** Options for creating a spinner. */
|
|
9
|
+
export type SpinnerOptions = {
|
|
10
|
+
/** Initial spinner label text. */
|
|
11
|
+
text?: string;
|
|
12
|
+
/** Spinner animation style. Defaults to `'dots'`. */
|
|
13
|
+
style?: "dots" | "line" | "arc";
|
|
14
|
+
/** Output stream for spinner rendering. Defaults to `process.stderr`. */
|
|
15
|
+
stream?: NodeJS.WriteStream;
|
|
16
|
+
};
|
|
17
|
+
/** Handle for controlling a running spinner. */
|
|
18
|
+
export type SpinnerHandle = {
|
|
19
|
+
/** Start the spinner animation, optionally setting the label text. */
|
|
20
|
+
start(text?: string): void;
|
|
21
|
+
/** Update the spinner label text. */
|
|
22
|
+
update(text: string): void;
|
|
23
|
+
/** Stop the spinner, optionally showing a final message. */
|
|
24
|
+
stop(finalText?: string): void;
|
|
25
|
+
/** Stop with a success icon and optional message. */
|
|
26
|
+
succeed(text?: string): void;
|
|
27
|
+
/** Stop with a failure icon and optional message. */
|
|
28
|
+
fail(text?: string): void;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Creates an animated spinner for indeterminate operations.
|
|
32
|
+
* Gracefully degrades to static output in non-TTY/CI environments.
|
|
33
|
+
*
|
|
34
|
+
* @param options - Spinner configuration.
|
|
35
|
+
* @returns A handle to control the spinner lifecycle.
|
|
36
|
+
*/
|
|
37
|
+
export declare function spinner(options?: SpinnerOptions): SpinnerHandle;
|
|
38
|
+
//# sourceMappingURL=spinner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/components/spinner.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,sCAAsC;AACtC,MAAM,MAAM,cAAc,GAAG;IAC5B,kCAAkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IAChC,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC,WAAW,CAAC;CAC5B,CAAC;AAEF,gDAAgD;AAChD,MAAM,MAAM,aAAa,GAAG;IAC3B,sEAAsE;IACtE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,qCAAqC;IACrC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,4DAA4D;IAC5D,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,qDAAqD;IACrD,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,qDAAqD;IACrD,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAgI/D"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Spinner Component
|
|
3
|
+
*
|
|
4
|
+
* An animated spinner indicator for indeterminate operations.
|
|
5
|
+
* Manages terminal output directly via process.stderr.write and cursor control.
|
|
6
|
+
* Gracefully degrades in non-TTY/CI environments to static line output.
|
|
7
|
+
*/
|
|
8
|
+
import { getContext, styledText, symbol } from "../primitives/index.js";
|
|
9
|
+
import { stripAnsi } from "../render/index.js";
|
|
10
|
+
/**
|
|
11
|
+
* Creates an animated spinner for indeterminate operations.
|
|
12
|
+
* Gracefully degrades to static output in non-TTY/CI environments.
|
|
13
|
+
*
|
|
14
|
+
* @param options - Spinner configuration.
|
|
15
|
+
* @returns A handle to control the spinner lifecycle.
|
|
16
|
+
*/
|
|
17
|
+
export function spinner(options) {
|
|
18
|
+
const ctx = getContext();
|
|
19
|
+
const stream = options?.stream ?? process.stderr;
|
|
20
|
+
const style = options?.style ?? "dots";
|
|
21
|
+
let currentText = options?.text ?? "";
|
|
22
|
+
let frameIndex = 0;
|
|
23
|
+
let timer = null;
|
|
24
|
+
let startTime = null;
|
|
25
|
+
let running = false;
|
|
26
|
+
const spinnerKey = `spinner${style.charAt(0).toUpperCase()}${style.slice(1)}`;
|
|
27
|
+
const frames = ctx.tokens.motion[spinnerKey];
|
|
28
|
+
const interval = ctx.tokens.motion.spinnerInterval;
|
|
29
|
+
const isTTY = !!stream.isTTY;
|
|
30
|
+
const isInteractive = isTTY && !ctx.capabilities.isCI;
|
|
31
|
+
function clearLine() {
|
|
32
|
+
// Clear current line: move to column 0, clear to end of line
|
|
33
|
+
stream.write("\r\x1b[K");
|
|
34
|
+
}
|
|
35
|
+
function renderFrame() {
|
|
36
|
+
const frame = frames[frameIndex % frames.length];
|
|
37
|
+
frameIndex++;
|
|
38
|
+
clearLine();
|
|
39
|
+
const frameStyled = styledText(frame, { color: "accent" });
|
|
40
|
+
stream.write(`${frameStyled} ${currentText}`);
|
|
41
|
+
}
|
|
42
|
+
function formatDuration(ms) {
|
|
43
|
+
if (ms < 1000)
|
|
44
|
+
return `${ms}ms`;
|
|
45
|
+
const s = (ms / 1000).toFixed(1);
|
|
46
|
+
return `${s}s`;
|
|
47
|
+
}
|
|
48
|
+
const handle = {
|
|
49
|
+
start(text) {
|
|
50
|
+
if (running)
|
|
51
|
+
return;
|
|
52
|
+
running = true;
|
|
53
|
+
if (text !== undefined)
|
|
54
|
+
currentText = text;
|
|
55
|
+
startTime = Date.now();
|
|
56
|
+
if (!isInteractive) {
|
|
57
|
+
// Non-TTY/CI: static output
|
|
58
|
+
const prefix = ctx.capabilities.unicode ? symbol("running") : "[..]";
|
|
59
|
+
stream.write(`${prefix} ${currentText}\n`);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Hide cursor
|
|
63
|
+
stream.write("\x1b[?25l");
|
|
64
|
+
frameIndex = 0;
|
|
65
|
+
renderFrame();
|
|
66
|
+
timer = setInterval(renderFrame, interval);
|
|
67
|
+
},
|
|
68
|
+
update(text) {
|
|
69
|
+
currentText = text;
|
|
70
|
+
if (!isInteractive) {
|
|
71
|
+
const prefix = ctx.capabilities.unicode ? symbol("running") : "[..]";
|
|
72
|
+
stream.write(`${prefix} ${text}\n`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
// Next renderFrame tick will pick up the new text
|
|
76
|
+
},
|
|
77
|
+
stop(finalText) {
|
|
78
|
+
if (!running)
|
|
79
|
+
return;
|
|
80
|
+
running = false;
|
|
81
|
+
if (timer) {
|
|
82
|
+
clearInterval(timer);
|
|
83
|
+
timer = null;
|
|
84
|
+
}
|
|
85
|
+
if (!isInteractive) {
|
|
86
|
+
if (finalText) {
|
|
87
|
+
stream.write(`${finalText}\n`);
|
|
88
|
+
}
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
clearLine();
|
|
92
|
+
if (finalText) {
|
|
93
|
+
stream.write(`${finalText}\n`);
|
|
94
|
+
}
|
|
95
|
+
// Show cursor
|
|
96
|
+
stream.write("\x1b[?25h");
|
|
97
|
+
},
|
|
98
|
+
succeed(text) {
|
|
99
|
+
const finalText = text ?? currentText;
|
|
100
|
+
const elapsed = startTime !== null ? Date.now() - startTime : 0;
|
|
101
|
+
const icon = styledText(symbol("success"), { color: "success" });
|
|
102
|
+
const duration = styledText(` ${formatDuration(elapsed)}`, { dim: true });
|
|
103
|
+
if (!isInteractive) {
|
|
104
|
+
const prefix = ctx.capabilities.unicode ? symbol("success") : "[OK]";
|
|
105
|
+
stream.write(`${prefix} ${finalText}${duration}\n`);
|
|
106
|
+
running = false;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
handle.stop(`${icon} ${finalText}${duration}`);
|
|
110
|
+
},
|
|
111
|
+
fail(text) {
|
|
112
|
+
const finalText = text ?? currentText;
|
|
113
|
+
const icon = styledText(symbol("error"), { color: "error" });
|
|
114
|
+
if (!isInteractive) {
|
|
115
|
+
const prefix = ctx.capabilities.unicode ? symbol("error") : "[FAIL]";
|
|
116
|
+
stream.write(`${prefix} ${finalText}\n`);
|
|
117
|
+
running = false;
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
handle.stop(`${icon} ${finalText}`);
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
return handle;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/components/spinner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* statusList Component (Static)
|
|
3
|
+
*
|
|
4
|
+
* Renders a list of items with status icons and optional detail text.
|
|
5
|
+
*/
|
|
6
|
+
/** A single item in a status list. */
|
|
7
|
+
export type StatusListItem = {
|
|
8
|
+
/** Display text for this item. */
|
|
9
|
+
text: string;
|
|
10
|
+
/** Current status, determining the icon and color. */
|
|
11
|
+
status: "pending" | "running" | "success" | "error" | "warning" | "skipped";
|
|
12
|
+
/** Optional detail text shown inline (if short) or on the next line (if long). */
|
|
13
|
+
detail?: string;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Renders a list of items with status-mapped icons and colors.
|
|
17
|
+
*
|
|
18
|
+
* @param items - The status list items to render.
|
|
19
|
+
* @returns The formatted status list as a multi-line string.
|
|
20
|
+
*/
|
|
21
|
+
export declare function statusList(items: StatusListItem[]): string;
|
|
22
|
+
//# sourceMappingURL=statusList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statusList.d.ts","sourceRoot":"","sources":["../../src/components/statusList.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,sCAAsC;AACtC,MAAM,MAAM,cAAc,GAAG;IAC5B,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IAC5E,kFAAkF;IAClF,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAWF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,MAAM,CAyB1D"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* statusList Component (Static)
|
|
3
|
+
*
|
|
4
|
+
* Renders a list of items with status icons and optional detail text.
|
|
5
|
+
*/
|
|
6
|
+
import { getContext, indent, stack, styledText, symbol } from "../primitives/index.js";
|
|
7
|
+
const STATUS_COLOR_MAP = {
|
|
8
|
+
success: "success",
|
|
9
|
+
error: "error",
|
|
10
|
+
warning: "warning",
|
|
11
|
+
running: "info",
|
|
12
|
+
pending: "fgMuted",
|
|
13
|
+
skipped: "fgMuted",
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Renders a list of items with status-mapped icons and colors.
|
|
17
|
+
*
|
|
18
|
+
* @param items - The status list items to render.
|
|
19
|
+
* @returns The formatted status list as a multi-line string.
|
|
20
|
+
*/
|
|
21
|
+
export function statusList(items) {
|
|
22
|
+
const ctx = getContext();
|
|
23
|
+
const iconGap = " ".repeat(ctx.tokens.space.iconGap);
|
|
24
|
+
const lines = [];
|
|
25
|
+
for (const item of items) {
|
|
26
|
+
const icon = symbol(item.status);
|
|
27
|
+
const color = STATUS_COLOR_MAP[item.status];
|
|
28
|
+
const text = styledText(item.text, { color });
|
|
29
|
+
let line = icon + iconGap + text;
|
|
30
|
+
if (item.detail) {
|
|
31
|
+
// If detail is short (< 40 chars), show inline; otherwise on next line indented
|
|
32
|
+
if (item.detail.length < 40) {
|
|
33
|
+
line += ` ${styledText(`(${item.detail})`, { dim: true })}`;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
line += `\n${indent(styledText(item.detail, { dim: true }), 1)}`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
lines.push(line);
|
|
40
|
+
}
|
|
41
|
+
return stack(lines);
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=statusList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"statusList.js","sourceRoot":"","sources":["../../src/components/statusList.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAavF,MAAM,gBAAgB,GAAwD;IAC7E,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;IACd,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;CAClB,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,KAAuB;IACjD,MAAM,GAAG,GAAG,UAAU,EAAE,CAAC;IACzB,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACrD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACjC,MAAM,KAAK,GAAG,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAE9C,IAAI,IAAI,GAAG,IAAI,GAAG,OAAO,GAAG,IAAI,CAAC;QAEjC,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACjB,gFAAgF;YAChF,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;gBAC7B,IAAI,IAAI,IAAI,UAAU,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;YAC7D,CAAC;iBAAM,CAAC;gBACP,IAAI,IAAI,KAAK,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAClE,CAAC;QACF,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* table Component
|
|
3
|
+
*
|
|
4
|
+
* Renders tabular data in multiple variants: minimal, borderless, grid, outer.
|
|
5
|
+
*/
|
|
6
|
+
/** Definition of a single table column. */
|
|
7
|
+
export type TableColumn = {
|
|
8
|
+
/** Property key used to look up values in each data row. */
|
|
9
|
+
key: string;
|
|
10
|
+
/** Display header text. Defaults to the `key`. */
|
|
11
|
+
header?: string;
|
|
12
|
+
/** Cell text alignment. Defaults to `'left'`. */
|
|
13
|
+
align?: "left" | "right" | "center";
|
|
14
|
+
/** Fixed column width in characters, or `'auto'` to fit content. */
|
|
15
|
+
width?: number | "auto";
|
|
16
|
+
/** Maximum column width. Only effective when `truncate` is enabled. */
|
|
17
|
+
maxWidth?: number;
|
|
18
|
+
/** Whether to truncate cell text that exceeds `maxWidth`. */
|
|
19
|
+
truncate?: boolean;
|
|
20
|
+
};
|
|
21
|
+
/** Options for rendering a table. */
|
|
22
|
+
export type TableOptions = {
|
|
23
|
+
/** Column definitions describing the table structure. */
|
|
24
|
+
columns: TableColumn[];
|
|
25
|
+
/** Row data as an array of records keyed by column `key`. */
|
|
26
|
+
data: Array<Record<string, unknown>>;
|
|
27
|
+
/** Table rendering variant. Defaults to `'minimal'`. */
|
|
28
|
+
variant?: "minimal" | "grid" | "borderless" | "outer";
|
|
29
|
+
/** Text to display when `data` is empty. Defaults to `''`. */
|
|
30
|
+
emptyText?: string;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Renders tabular data in aligned columns with multiple visual variants.
|
|
34
|
+
*
|
|
35
|
+
* @param options - Table configuration.
|
|
36
|
+
* @returns The formatted table as a multi-line string.
|
|
37
|
+
*/
|
|
38
|
+
export declare function table(options: TableOptions): string;
|
|
39
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/components/table.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,2CAA2C;AAC3C,MAAM,MAAM,WAAW,GAAG;IACzB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,kDAAkD;IAClD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iDAAiD;IACjD,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;IACpC,oEAAoE;IACpE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,qCAAqC;AACrC,MAAM,MAAM,YAAY,GAAG;IAC1B,yDAAyD;IACzD,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,6DAA6D;IAC7D,IAAI,EAAE,KAAK,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrC,wDAAwD;IACxD,OAAO,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,CAAC;IACtD,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAmJnD"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* table Component
|
|
3
|
+
*
|
|
4
|
+
* Renders tabular data in multiple variants: minimal, borderless, grid, outer.
|
|
5
|
+
*/
|
|
6
|
+
import { getContext, styledText } from "../primitives/index.js";
|
|
7
|
+
import { ansiPad, ansiTruncate, stringWidth } from "../render/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Renders tabular data in aligned columns with multiple visual variants.
|
|
10
|
+
*
|
|
11
|
+
* @param options - Table configuration.
|
|
12
|
+
* @returns The formatted table as a multi-line string.
|
|
13
|
+
*/
|
|
14
|
+
export function table(options) {
|
|
15
|
+
const ctx = getContext();
|
|
16
|
+
const variant = options.variant ?? "minimal";
|
|
17
|
+
const gutter = ctx.tokens.space.gutter;
|
|
18
|
+
const chars = ctx.tokens.border.chars;
|
|
19
|
+
const columns = options.columns;
|
|
20
|
+
const data = options.data;
|
|
21
|
+
// Handle empty data
|
|
22
|
+
if (data.length === 0) {
|
|
23
|
+
return options.emptyText ?? "";
|
|
24
|
+
}
|
|
25
|
+
// Convert data to cell strings
|
|
26
|
+
const cellData = data.map((row) => columns.map((col) => {
|
|
27
|
+
const val = row[col.key];
|
|
28
|
+
return val === null || val === undefined ? "" : String(val);
|
|
29
|
+
}));
|
|
30
|
+
// Calculate column widths
|
|
31
|
+
const colWidths = columns.map((col, i) => {
|
|
32
|
+
if (typeof col.width === "number")
|
|
33
|
+
return col.width;
|
|
34
|
+
// Auto: max of header width and all data widths
|
|
35
|
+
let max = stringWidth(col.header ?? col.key);
|
|
36
|
+
for (const row of cellData) {
|
|
37
|
+
const w = stringWidth(row[i]);
|
|
38
|
+
if (w > max)
|
|
39
|
+
max = w;
|
|
40
|
+
}
|
|
41
|
+
if (col.maxWidth && max > col.maxWidth) {
|
|
42
|
+
max = col.maxWidth;
|
|
43
|
+
}
|
|
44
|
+
return max;
|
|
45
|
+
});
|
|
46
|
+
// Format cell content (truncate + align)
|
|
47
|
+
function formatCell(text, colIndex) {
|
|
48
|
+
const col = columns[colIndex];
|
|
49
|
+
const width = colWidths[colIndex];
|
|
50
|
+
let result = text;
|
|
51
|
+
if (col.truncate && col.maxWidth) {
|
|
52
|
+
const currentW = stringWidth(result);
|
|
53
|
+
if (currentW > width) {
|
|
54
|
+
result = ansiTruncate(result, width, ctx.tokens.symbol.ellipsis);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return ansiPad(result, width, col.align ?? "left");
|
|
58
|
+
}
|
|
59
|
+
// Build header cells
|
|
60
|
+
const headerCells = columns.map((col, i) => {
|
|
61
|
+
const headerText = col.header ?? col.key;
|
|
62
|
+
const formatted = ansiPad(headerText, colWidths[i], col.align ?? "left");
|
|
63
|
+
return styledText(formatted, { bold: true });
|
|
64
|
+
});
|
|
65
|
+
// Build data rows
|
|
66
|
+
const dataRows = cellData.map((row) => row.map((cell, i) => formatCell(cell, i)));
|
|
67
|
+
const lines = [];
|
|
68
|
+
const gutterStr = " ".repeat(gutter);
|
|
69
|
+
if (variant === "minimal") {
|
|
70
|
+
lines.push(headerCells.join(gutterStr));
|
|
71
|
+
// Divider under headers
|
|
72
|
+
const dividerParts = colWidths.map((w) => chars.horizontal.repeat(w));
|
|
73
|
+
lines.push(dividerParts.join(gutterStr));
|
|
74
|
+
for (const row of dataRows) {
|
|
75
|
+
lines.push(row.join(gutterStr));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else if (variant === "borderless") {
|
|
79
|
+
lines.push(headerCells.join(gutterStr));
|
|
80
|
+
for (const row of dataRows) {
|
|
81
|
+
lines.push(row.join(gutterStr));
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
else if (variant === "grid") {
|
|
85
|
+
const sep = chars.vertical;
|
|
86
|
+
const innerWidth = colWidths.reduce((s, w) => s + w, 0) + (columns.length - 1) * 3; // " | " between columns
|
|
87
|
+
// Top border
|
|
88
|
+
const topParts = colWidths.map((w) => chars.horizontal.repeat(w));
|
|
89
|
+
lines.push(chars.topLeft +
|
|
90
|
+
topParts.join(chars.horizontal + chars.teeDown + chars.horizontal) +
|
|
91
|
+
chars.topRight);
|
|
92
|
+
// Header row
|
|
93
|
+
lines.push(`${sep} ${headerCells.join(` ${sep} `)} ${sep}`);
|
|
94
|
+
// Header divider
|
|
95
|
+
const hDivParts = colWidths.map((w) => chars.horizontal.repeat(w));
|
|
96
|
+
lines.push(chars.teeRight +
|
|
97
|
+
hDivParts.join(chars.horizontal + chars.cross + chars.horizontal) +
|
|
98
|
+
chars.teeLeft);
|
|
99
|
+
// Data rows with dividers between them
|
|
100
|
+
for (let i = 0; i < dataRows.length; i++) {
|
|
101
|
+
lines.push(`${sep} ${dataRows[i].join(` ${sep} `)} ${sep}`);
|
|
102
|
+
if (i < dataRows.length - 1) {
|
|
103
|
+
lines.push(chars.teeRight +
|
|
104
|
+
hDivParts.join(chars.horizontal + chars.cross + chars.horizontal) +
|
|
105
|
+
chars.teeLeft);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// Bottom border
|
|
109
|
+
lines.push(chars.bottomLeft +
|
|
110
|
+
topParts.join(chars.horizontal + chars.teeUp + chars.horizontal) +
|
|
111
|
+
chars.bottomRight);
|
|
112
|
+
}
|
|
113
|
+
else if (variant === "outer") {
|
|
114
|
+
const sep = chars.vertical;
|
|
115
|
+
// Top border
|
|
116
|
+
const topParts = colWidths.map((w) => chars.horizontal.repeat(w));
|
|
117
|
+
const innerHWidth = colWidths.reduce((s, w) => s + w, 0) + (columns.length - 1) * gutter;
|
|
118
|
+
lines.push(chars.topLeft + chars.horizontal.repeat(innerHWidth + 2) + chars.topRight);
|
|
119
|
+
// Header row
|
|
120
|
+
lines.push(`${sep} ${headerCells.join(gutterStr)} ${sep}`);
|
|
121
|
+
// Header divider
|
|
122
|
+
lines.push(`${sep} ${colWidths.map((w) => chars.horizontal.repeat(w)).join(gutterStr)} ${sep}`);
|
|
123
|
+
// Data rows
|
|
124
|
+
for (const row of dataRows) {
|
|
125
|
+
lines.push(`${sep} ${row.join(gutterStr)} ${sep}`);
|
|
126
|
+
}
|
|
127
|
+
// Bottom border
|
|
128
|
+
lines.push(chars.bottomLeft + chars.horizontal.repeat(innerHWidth + 2) + chars.bottomRight);
|
|
129
|
+
}
|
|
130
|
+
return lines.join("\n");
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=table.js.map
|