@mudah-cli/ui 0.1.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/dist/colors.d.ts +15 -0
- package/dist/colors.js +82 -0
- package/dist/colors.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/markdown.d.ts +12 -0
- package/dist/markdown.js +64 -0
- package/dist/markdown.js.map +1 -0
- package/dist/output.d.ts +63 -0
- package/dist/output.js +111 -0
- package/dist/output.js.map +1 -0
- package/dist/panel.d.ts +20 -0
- package/dist/panel.js +38 -0
- package/dist/panel.js.map +1 -0
- package/dist/table.d.ts +19 -0
- package/dist/table.js +45 -0
- package/dist/table.js.map +1 -0
- package/dist/theme.d.ts +25 -0
- package/dist/theme.js +45 -0
- package/dist/theme.js.map +1 -0
- package/package.json +26 -0
package/dist/colors.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { ColorLevel } from '@mudah-cli/terminal';
|
|
2
|
+
/** Strip ANSI escape sequences (for width measurement). */
|
|
3
|
+
export declare function stripAnsi(text: string): string;
|
|
4
|
+
export declare function visibleLength(text: string): number;
|
|
5
|
+
/**
|
|
6
|
+
* Paint `text` with a hex foreground color, honoring the terminal's color
|
|
7
|
+
* level (0 = no color, 1/8 = nearest 256-color, 24 = truecolor).
|
|
8
|
+
*/
|
|
9
|
+
export declare function paint(hex: string, text: string, level: ColorLevel): string;
|
|
10
|
+
/** Paint `text` with a hex background color. */
|
|
11
|
+
export declare function paintBg(hex: string, text: string, level: ColorLevel): string;
|
|
12
|
+
export declare function dim(text: string, level: ColorLevel): string;
|
|
13
|
+
export declare function bold(text: string, level: ColorLevel): string;
|
|
14
|
+
export declare function italic(text: string, level: ColorLevel): string;
|
|
15
|
+
export declare function underline(text: string, level: ColorLevel): string;
|
package/dist/colors.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/** Strip ANSI escape sequences (for width measurement). */
|
|
2
|
+
export function stripAnsi(text) {
|
|
3
|
+
return text.replace(/\x1b\[[0-9;?]*[A-Za-z]/g, '').replace(/\x1b\][^\x07\x1b]*(\x07|\x1b\\)/g, '');
|
|
4
|
+
}
|
|
5
|
+
export function visibleLength(text) {
|
|
6
|
+
// Conservative: treat CJK/fullwidth as 2 cells.
|
|
7
|
+
let width = 0;
|
|
8
|
+
for (const char of stripAnsi(text)) {
|
|
9
|
+
width += /[\u1100-\u115f\u2e80-\u9fff\uac00-\ud7a3\uf900-\ufaff\uff00-\uff60]/.test(char) ? 2 : 1;
|
|
10
|
+
}
|
|
11
|
+
return width;
|
|
12
|
+
}
|
|
13
|
+
function parseHex(hex) {
|
|
14
|
+
const value = hex.replace('#', '');
|
|
15
|
+
const full = value.length === 3 ? value.split('').map((c) => c + c).join('') : value;
|
|
16
|
+
const n = parseInt(full, 16);
|
|
17
|
+
return [(n >> 16) & 0xff, (n >> 8) & 0xff, n & 0xff];
|
|
18
|
+
}
|
|
19
|
+
const XTERM_256 = (() => {
|
|
20
|
+
const palette = [];
|
|
21
|
+
for (let r = 0; r < 6; r++) {
|
|
22
|
+
for (let g = 0; g < 6; g++) {
|
|
23
|
+
for (let b = 0; b < 6; b++) {
|
|
24
|
+
palette.push([r * 51 - (r > 0 ? 10 : 0), g * 51 - (g > 0 ? 10 : 0), b * 51 - (b > 0 ? 10 : 0)]);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (let i = 0; i < 24; i++) {
|
|
29
|
+
const v = 8 + i * 10;
|
|
30
|
+
palette.push([v, v, v]);
|
|
31
|
+
}
|
|
32
|
+
return palette;
|
|
33
|
+
})();
|
|
34
|
+
function nearestXterm256(rgb) {
|
|
35
|
+
let best = 0;
|
|
36
|
+
let bestDist = Infinity;
|
|
37
|
+
for (let i = 0; i < XTERM_256.length; i++) {
|
|
38
|
+
const [r, g, b] = XTERM_256[i];
|
|
39
|
+
const dist = (rgb[0] - r) ** 2 + (rgb[1] - g) ** 2 + (rgb[2] - b) ** 2;
|
|
40
|
+
if (dist < bestDist) {
|
|
41
|
+
bestDist = dist;
|
|
42
|
+
best = i;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return 16 + best;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Paint `text` with a hex foreground color, honoring the terminal's color
|
|
49
|
+
* level (0 = no color, 1/8 = nearest 256-color, 24 = truecolor).
|
|
50
|
+
*/
|
|
51
|
+
export function paint(hex, text, level) {
|
|
52
|
+
if (level === 0)
|
|
53
|
+
return text;
|
|
54
|
+
const [r, g, b] = parseHex(hex);
|
|
55
|
+
if (level === 24) {
|
|
56
|
+
return `\x1b[38;2;${r};${g};${b}m${text}\x1b[39m`;
|
|
57
|
+
}
|
|
58
|
+
return `\x1b[38;5;${nearestXterm256([r, g, b])}m${text}\x1b[39m`;
|
|
59
|
+
}
|
|
60
|
+
/** Paint `text` with a hex background color. */
|
|
61
|
+
export function paintBg(hex, text, level) {
|
|
62
|
+
if (level === 0)
|
|
63
|
+
return text;
|
|
64
|
+
const [r, g, b] = parseHex(hex);
|
|
65
|
+
if (level === 24) {
|
|
66
|
+
return `\x1b[48;2;${r};${g};${b}m${text}\x1b[49m`;
|
|
67
|
+
}
|
|
68
|
+
return `\x1b[48;5;${nearestXterm256([r, g, b])}m${text}\x1b[49m`;
|
|
69
|
+
}
|
|
70
|
+
export function dim(text, level) {
|
|
71
|
+
return level === 0 ? text : `\x1b[2m${text}\x1b[22m`;
|
|
72
|
+
}
|
|
73
|
+
export function bold(text, level) {
|
|
74
|
+
return level === 0 ? text : `\x1b[1m${text}\x1b[22m`;
|
|
75
|
+
}
|
|
76
|
+
export function italic(text, level) {
|
|
77
|
+
return level === 0 ? text : `\x1b[3m${text}\x1b[23m`;
|
|
78
|
+
}
|
|
79
|
+
export function underline(text, level) {
|
|
80
|
+
return level === 0 ? text : `\x1b[4m${text}\x1b[24m`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=colors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"colors.js","sourceRoot":"","sources":["../src/colors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { bold, dim, italic, paint, paintBg, stripAnsi, underline, visibleLength, } from './colors.js';
|
|
2
|
+
export { Output, type OutputOptions } from './output.js';
|
|
3
|
+
export { renderMarkdown, type RenderMarkdownOptions } from './markdown.js';
|
|
4
|
+
export { renderPanel, type RenderPanelOptions } from './panel.js';
|
|
5
|
+
export { renderTable, type RenderTableOptions, type TableColumn } from './table.js';
|
|
6
|
+
export { resolveTheme, sleekDark, sleekLight, themes, type Theme, type ThemeColors } from './theme.js';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { bold, dim, italic, paint, paintBg, stripAnsi, underline, visibleLength, } from './colors.js';
|
|
2
|
+
export { Output } from './output.js';
|
|
3
|
+
export { renderMarkdown } from './markdown.js';
|
|
4
|
+
export { renderPanel } from './panel.js';
|
|
5
|
+
export { renderTable } from './table.js';
|
|
6
|
+
export { resolveTheme, sleekDark, sleekLight, themes } from './theme.js';
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,GAAG,EACH,MAAM,EACN,KAAK,EACL,OAAO,EACP,SAAS,EACT,SAAS,EACT,aAAa,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,MAAM,EAAsB,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,cAAc,EAA8B,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,WAAW,EAA2B,MAAM,YAAY,CAAC;AAClE,OAAO,EAAE,WAAW,EAA6C,MAAM,YAAY,CAAC;AACpF,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAgC,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ColorLevel } from '@mudah-cli/terminal';
|
|
2
|
+
import type { Theme } from './theme.js';
|
|
3
|
+
export interface RenderMarkdownOptions {
|
|
4
|
+
level: ColorLevel;
|
|
5
|
+
theme?: Theme;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A lightweight markdown renderer for CLI output: headings, bullets,
|
|
9
|
+
* numbered lists, blockquotes, hr, bold/italic/code, links. Not a full
|
|
10
|
+
* CommonMark parser — just enough to read well in a terminal.
|
|
11
|
+
*/
|
|
12
|
+
export declare function renderMarkdown(source: string, options: RenderMarkdownOptions): string;
|
package/dist/markdown.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { bold, dim, italic, paint, underline } from './colors.js';
|
|
2
|
+
import { sleekDark } from './theme.js';
|
|
3
|
+
function inline(text, level, theme) {
|
|
4
|
+
let out = text;
|
|
5
|
+
// Code spans first (protect from other rules by ordering).
|
|
6
|
+
out = out.replace(/`([^`]+)`/g, (_, code) => paint(theme.colors.highlight, code, level));
|
|
7
|
+
// Bold.
|
|
8
|
+
out = out.replace(/\*\*([^*]+)\*\*/g, (_, strong) => bold(strong, level));
|
|
9
|
+
// Italic (single *).
|
|
10
|
+
out = out.replace(/(^|[^*])\*([^*]+)\*(?!\*)/g, (_m, pre, em) => `${pre}${italic(em, level)}`);
|
|
11
|
+
// Links: [text](url) → dim url after text (OSC 8 hyperlinks in v0.2).
|
|
12
|
+
out = out.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_m, label, url) => `${underline(label, level)} ${dim(`<${url}>`, level)}`);
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A lightweight markdown renderer for CLI output: headings, bullets,
|
|
17
|
+
* numbered lists, blockquotes, hr, bold/italic/code, links. Not a full
|
|
18
|
+
* CommonMark parser — just enough to read well in a terminal.
|
|
19
|
+
*/
|
|
20
|
+
export function renderMarkdown(source, options) {
|
|
21
|
+
const theme = options.theme ?? sleekDark;
|
|
22
|
+
const { level } = options;
|
|
23
|
+
const lines = source.split('\n');
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const rawLine of lines) {
|
|
26
|
+
const line = rawLine.replace(/\s+$/, '');
|
|
27
|
+
if (line.trim() === '') {
|
|
28
|
+
out.push('');
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
const heading = /^(#{1,4})\s+(.*)$/.exec(line);
|
|
32
|
+
if (heading) {
|
|
33
|
+
const depth = heading[1].length;
|
|
34
|
+
const text = inline(heading[2], level, theme);
|
|
35
|
+
const styled = depth <= 2 ? underline(bold(paint(theme.colors.accent, text, level), level), level) : bold(text, level);
|
|
36
|
+
out.push(depth === 1 ? `\n${styled}\n` : ` ${' '.repeat((depth - 2) * 2)}${styled}`);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const hr = /^(-{3,}|\*{3,})\s*$/.exec(line.trim());
|
|
40
|
+
if (hr) {
|
|
41
|
+
out.push(dim('─'.repeat(40), level));
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const quote = /^>\s?(.*)$/.exec(line);
|
|
45
|
+
if (quote) {
|
|
46
|
+
out.push(dim(`│ ${inline(quote[1], level, theme)}`, level));
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const bullet = /^[-*]\s+(.*)$/.exec(line);
|
|
50
|
+
if (bullet) {
|
|
51
|
+
out.push(` ${dim('•', level)} ${inline(bullet[1], level, theme)}`);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const numbered = /^\d+[.)]\s+(.*)$/.exec(line);
|
|
55
|
+
if (numbered) {
|
|
56
|
+
const marker = line.slice(0, line.length - numbered[1].length).trim();
|
|
57
|
+
out.push(` ${dim(marker, level)} ${inline(numbered[1], level, theme)}`);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
out.push(inline(line, level, theme));
|
|
61
|
+
}
|
|
62
|
+
return out.join('\n');
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../src/markdown.ts"],"names":[],"mappings":"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"}
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { ColorLevel } from '@mudah-cli/terminal';
|
|
2
|
+
import type { Theme } from './theme.js';
|
|
3
|
+
import { type TableColumn } from './table.js';
|
|
4
|
+
export interface OutputOptions {
|
|
5
|
+
stream?: {
|
|
6
|
+
write(data: string): unknown;
|
|
7
|
+
};
|
|
8
|
+
errorStream?: {
|
|
9
|
+
write(data: string): unknown;
|
|
10
|
+
};
|
|
11
|
+
theme: Theme;
|
|
12
|
+
colorLevel: ColorLevel;
|
|
13
|
+
unicode: boolean;
|
|
14
|
+
/** OSC 9 notifications supported? */
|
|
15
|
+
osc9?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The styled output surface. Every framework message flows through here so
|
|
19
|
+
* theming, color level, unicode, and stream selection stay consistent.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Output {
|
|
22
|
+
private out;
|
|
23
|
+
private err;
|
|
24
|
+
private readonly theme;
|
|
25
|
+
private readonly level;
|
|
26
|
+
private readonly unicode;
|
|
27
|
+
private readonly osc9;
|
|
28
|
+
constructor(options: OutputOptions);
|
|
29
|
+
/** Replace the underlying streams (used by test harnesses). */
|
|
30
|
+
redirect(stream: {
|
|
31
|
+
write(data: string): unknown;
|
|
32
|
+
}, errorStream: {
|
|
33
|
+
write(data: string): unknown;
|
|
34
|
+
}): void;
|
|
35
|
+
get themeName(): string;
|
|
36
|
+
get colorLevel(): ColorLevel;
|
|
37
|
+
raw(message: string): void;
|
|
38
|
+
info(message: string): void;
|
|
39
|
+
success(message: string): void;
|
|
40
|
+
error(message: string): void;
|
|
41
|
+
warn(message: string): void;
|
|
42
|
+
muted(message: string): void;
|
|
43
|
+
/** A muted hint line on the error stream (used alongside error output). */
|
|
44
|
+
hint(message: string): void;
|
|
45
|
+
section(title: string): void;
|
|
46
|
+
bullet(message: string): void;
|
|
47
|
+
keyValue(label: string, value: string): void;
|
|
48
|
+
line(): void;
|
|
49
|
+
table(columns: TableColumn[], rows: string[][]): void;
|
|
50
|
+
panel(title: string | undefined, body: string[], width?: number): void;
|
|
51
|
+
markdown(text: string): void;
|
|
52
|
+
/**
|
|
53
|
+
* Desktop notification via OSC 9 (Ghostty/WezTerm). When unsupported,
|
|
54
|
+
* degrades to a styled status line on stderr.
|
|
55
|
+
*/
|
|
56
|
+
notification(title: string, message: string): void;
|
|
57
|
+
private mark;
|
|
58
|
+
private paint;
|
|
59
|
+
/** Visible width of the current terminal column, for wrapping decisions. */
|
|
60
|
+
padTo(text: string, width: number): string;
|
|
61
|
+
/** Erase the previous `n` lines and reposition (used by live regions). */
|
|
62
|
+
eraseLines(n: number): void;
|
|
63
|
+
}
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { ansi } from '@mudah-cli/terminal';
|
|
2
|
+
import { bold, dim, paint, underline, visibleLength } from './colors.js';
|
|
3
|
+
import { renderPanel } from './panel.js';
|
|
4
|
+
import { renderTable } from './table.js';
|
|
5
|
+
import { renderMarkdown } from './markdown.js';
|
|
6
|
+
/**
|
|
7
|
+
* The styled output surface. Every framework message flows through here so
|
|
8
|
+
* theming, color level, unicode, and stream selection stay consistent.
|
|
9
|
+
*/
|
|
10
|
+
export class Output {
|
|
11
|
+
out;
|
|
12
|
+
err;
|
|
13
|
+
theme;
|
|
14
|
+
level;
|
|
15
|
+
unicode;
|
|
16
|
+
osc9;
|
|
17
|
+
constructor(options) {
|
|
18
|
+
this.out = options.stream ?? process.stdout;
|
|
19
|
+
this.err = options.errorStream ?? process.stderr;
|
|
20
|
+
this.theme = options.theme;
|
|
21
|
+
this.level = options.colorLevel;
|
|
22
|
+
this.unicode = options.unicode;
|
|
23
|
+
this.osc9 = options.osc9 ?? false;
|
|
24
|
+
}
|
|
25
|
+
/** Replace the underlying streams (used by test harnesses). */
|
|
26
|
+
redirect(stream, errorStream) {
|
|
27
|
+
this.out = stream;
|
|
28
|
+
this.err = errorStream;
|
|
29
|
+
}
|
|
30
|
+
get themeName() {
|
|
31
|
+
return this.theme.name;
|
|
32
|
+
}
|
|
33
|
+
get colorLevel() {
|
|
34
|
+
return this.level;
|
|
35
|
+
}
|
|
36
|
+
raw(message) {
|
|
37
|
+
this.out.write(message + '\n');
|
|
38
|
+
}
|
|
39
|
+
info(message) {
|
|
40
|
+
this.out.write(this.paint('info', message) + '\n');
|
|
41
|
+
}
|
|
42
|
+
success(message) {
|
|
43
|
+
this.out.write(this.mark('success') + ' ' + this.paint('success', message) + '\n');
|
|
44
|
+
}
|
|
45
|
+
error(message) {
|
|
46
|
+
this.err.write(this.mark('error') + ' ' + this.paint('error', message) + '\n');
|
|
47
|
+
}
|
|
48
|
+
warn(message) {
|
|
49
|
+
this.err.write(this.mark('warn') + ' ' + this.paint('warn', message) + '\n');
|
|
50
|
+
}
|
|
51
|
+
muted(message) {
|
|
52
|
+
this.out.write(dim(this.paint('muted', message), this.level) + '\n');
|
|
53
|
+
}
|
|
54
|
+
/** A muted hint line on the error stream (used alongside error output). */
|
|
55
|
+
hint(message) {
|
|
56
|
+
this.err.write(dim(this.paint('muted', `Hint: ${message}`), this.level) + '\n');
|
|
57
|
+
}
|
|
58
|
+
section(title) {
|
|
59
|
+
this.out.write('\n' + underline(bold(this.paint('accent', title), this.level), this.level) + '\n');
|
|
60
|
+
}
|
|
61
|
+
bullet(message) {
|
|
62
|
+
this.out.write(` ${this.paint('muted', this.unicode ? '•' : '*')} ${message}\n`);
|
|
63
|
+
}
|
|
64
|
+
keyValue(label, value) {
|
|
65
|
+
const labelPart = bold(this.paint('muted', label), this.level);
|
|
66
|
+
this.out.write(` ${labelPart.padEnd(24)} ${value}\n`);
|
|
67
|
+
}
|
|
68
|
+
line() {
|
|
69
|
+
const ch = this.unicode ? '─' : '-';
|
|
70
|
+
this.out.write(this.paint('border', ch.repeat(60)) + '\n');
|
|
71
|
+
}
|
|
72
|
+
table(columns, rows) {
|
|
73
|
+
this.out.write(renderTable(columns, rows, { level: this.level, unicode: this.unicode }) + '\n');
|
|
74
|
+
}
|
|
75
|
+
panel(title, body, width) {
|
|
76
|
+
this.out.write(renderPanel(title, body, { level: this.level, unicode: this.unicode, width }) + '\n');
|
|
77
|
+
}
|
|
78
|
+
markdown(text) {
|
|
79
|
+
this.out.write(renderMarkdown(text, { level: this.level, theme: this.theme }) + '\n');
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Desktop notification via OSC 9 (Ghostty/WezTerm). When unsupported,
|
|
83
|
+
* degrades to a styled status line on stderr.
|
|
84
|
+
*/
|
|
85
|
+
notification(title, message) {
|
|
86
|
+
if (this.osc9) {
|
|
87
|
+
this.err.write(`\x1b]9;${title}\x1f${message}\x07`);
|
|
88
|
+
this.err.write(`\x1b]777;notify;${title};${message}\x07`);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
this.err.write(this.paint('highlight', '●') + ' ' + bold(title, this.level) + ' ' + dim(message, this.level) + '\n');
|
|
92
|
+
}
|
|
93
|
+
mark(kind) {
|
|
94
|
+
const glyph = kind === 'success' ? (this.unicode ? '✓' : 'v') : kind === 'error' ? (this.unicode ? '✗' : 'x') : this.unicode ? '⚠' : '!';
|
|
95
|
+
return this.paint(kind, glyph);
|
|
96
|
+
}
|
|
97
|
+
paint(key, text) {
|
|
98
|
+
return paint(this.theme.colors[key], text, this.level);
|
|
99
|
+
}
|
|
100
|
+
/** Visible width of the current terminal column, for wrapping decisions. */
|
|
101
|
+
padTo(text, width) {
|
|
102
|
+
const visible = visibleLength(text);
|
|
103
|
+
return text + ' '.repeat(Math.max(0, width - visible));
|
|
104
|
+
}
|
|
105
|
+
/** Erase the previous `n` lines and reposition (used by live regions). */
|
|
106
|
+
eraseLines(n) {
|
|
107
|
+
ansi.moveUp(this.out, n);
|
|
108
|
+
ansi.eraseToEnd(this.out);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"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"}
|
package/dist/panel.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ColorLevel } from '@mudah-cli/terminal';
|
|
2
|
+
import type { Theme } from './theme.js';
|
|
3
|
+
export interface RenderPanelOptions {
|
|
4
|
+
level: ColorLevel;
|
|
5
|
+
unicode: boolean;
|
|
6
|
+
theme?: Theme;
|
|
7
|
+
/** Fixed inner width; defaults to the widest content line (or title). */
|
|
8
|
+
width?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Render a titled box panel:
|
|
12
|
+
*
|
|
13
|
+
* ```
|
|
14
|
+
* ╭─ Mudah ───────────────╮
|
|
15
|
+
* │ line one │
|
|
16
|
+
* │ line two │
|
|
17
|
+
* ╰───────────────────────╯
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare function renderPanel(title: string | undefined, body: string[], options: RenderPanelOptions): string;
|
package/dist/panel.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { bold, paint, visibleLength } from './colors.js';
|
|
2
|
+
import { sleekDark } from './theme.js';
|
|
3
|
+
/**
|
|
4
|
+
* Render a titled box panel:
|
|
5
|
+
*
|
|
6
|
+
* ```
|
|
7
|
+
* ╭─ Mudah ───────────────╮
|
|
8
|
+
* │ line one │
|
|
9
|
+
* │ line two │
|
|
10
|
+
* ╰───────────────────────╯
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export function renderPanel(title, body, options) {
|
|
14
|
+
const theme = options.theme ?? sleekDark;
|
|
15
|
+
const u = options.unicode;
|
|
16
|
+
const border = (ch) => paint(theme.colors.border, ch, options.level);
|
|
17
|
+
const cornerTL = u ? '╭' : '+';
|
|
18
|
+
const cornerTR = u ? '╮' : '+';
|
|
19
|
+
const cornerBL = u ? '╰' : '+';
|
|
20
|
+
const cornerBR = u ? '╯' : '+';
|
|
21
|
+
const vBar = u ? '│' : '|';
|
|
22
|
+
const hBar = u ? '─' : '-';
|
|
23
|
+
const maxContent = Math.max(0, ...body.map((line) => visibleLength(line)));
|
|
24
|
+
const minForTitle = title !== undefined ? visibleLength(title) + 2 : 0;
|
|
25
|
+
const innerWidth = Math.max(options.width ?? 0, maxContent, minForTitle);
|
|
26
|
+
const total = innerWidth + 4;
|
|
27
|
+
const top = title !== undefined
|
|
28
|
+
? `${border(cornerTL)}${border(hBar)} ${paint(theme.colors.accent, bold(title, options.level), options.level)} ${border(hBar.repeat(Math.max(1, innerWidth - visibleLength(title) - 1)))}${border(cornerTR)}`
|
|
29
|
+
: `${border(cornerTL)}${border(hBar.repeat(total - 2))}${border(cornerTR)}`;
|
|
30
|
+
const lines = [top];
|
|
31
|
+
for (const content of body) {
|
|
32
|
+
const padded = content + ' '.repeat(Math.max(0, innerWidth - visibleLength(content)));
|
|
33
|
+
lines.push(`${border(vBar)} ${padded} ${border(vBar)}`);
|
|
34
|
+
}
|
|
35
|
+
lines.push(`${border(cornerBL)}${border(hBar.repeat(total - 2))}${border(cornerBR)}`);
|
|
36
|
+
return lines.join('\n');
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=panel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"panel.js","sourceRoot":"","sources":["../src/panel.ts"],"names":[],"mappings":"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"}
|
package/dist/table.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ColorLevel } from '@mudah-cli/terminal';
|
|
2
|
+
import type { Theme } from './theme.js';
|
|
3
|
+
export interface TableColumn {
|
|
4
|
+
header: string;
|
|
5
|
+
/** Alignment within the column. Default left. */
|
|
6
|
+
align?: 'left' | 'right';
|
|
7
|
+
}
|
|
8
|
+
export interface RenderTableOptions {
|
|
9
|
+
level: ColorLevel;
|
|
10
|
+
unicode: boolean;
|
|
11
|
+
theme?: Theme;
|
|
12
|
+
/** Apply theme colors to the header row. */
|
|
13
|
+
styled?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Render a simple grid table. Pure string output — stream-free, so the UI
|
|
17
|
+
* layer and tests both use it directly.
|
|
18
|
+
*/
|
|
19
|
+
export declare function renderTable(columns: TableColumn[], rows: string[][], options: RenderTableOptions): string;
|
package/dist/table.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { paint, visibleLength } from './colors.js';
|
|
2
|
+
import { sleekDark } from './theme.js';
|
|
3
|
+
function cellWidth(text) {
|
|
4
|
+
return visibleLength(text);
|
|
5
|
+
}
|
|
6
|
+
function pad(text, width, align) {
|
|
7
|
+
const gap = width - cellWidth(text);
|
|
8
|
+
return align === 'right' ? ' '.repeat(Math.max(0, gap)) + text : text + ' '.repeat(Math.max(0, gap));
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Render a simple grid table. Pure string output — stream-free, so the UI
|
|
12
|
+
* layer and tests both use it directly.
|
|
13
|
+
*/
|
|
14
|
+
export function renderTable(columns, rows, options) {
|
|
15
|
+
const theme = options.theme ?? sleekDark;
|
|
16
|
+
const styled = options.styled ?? true;
|
|
17
|
+
const widths = columns.map((col, i) => Math.max(cellWidth(col.header), ...rows.map((row) => cellWidth(row[i] ?? ''))));
|
|
18
|
+
const sepUnicode = options.unicode;
|
|
19
|
+
const hRule = (widths) => (sepUnicode ? '┌' : '+') +
|
|
20
|
+
widths.map((w) => (sepUnicode ? '─' : '-').repeat(w + 2)).join(sepUnicode ? '┬' : '+') +
|
|
21
|
+
(sepUnicode ? '┐' : '+');
|
|
22
|
+
const lines = [hRule(widths)];
|
|
23
|
+
const header = columns.map((col, i) => {
|
|
24
|
+
const text = pad(col.header, widths[i], col.align ?? 'left');
|
|
25
|
+
return styled ? paint(theme.colors.accent, text, options.level) : text;
|
|
26
|
+
});
|
|
27
|
+
lines.push(rowBorder(header));
|
|
28
|
+
if (sepUnicode) {
|
|
29
|
+
lines.push('├' + widths.map((w) => '─'.repeat(w + 2)).join('┼') + '┤');
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
lines.push('+' + widths.map((w) => '-'.repeat(w + 2)).join('+') + '+');
|
|
33
|
+
}
|
|
34
|
+
for (const row of rows) {
|
|
35
|
+
lines.push(rowBorder(row.map((cell, i) => pad(cell, widths[i], columns[i]?.align ?? 'left'))));
|
|
36
|
+
}
|
|
37
|
+
lines.push((sepUnicode ? '└' : '+') +
|
|
38
|
+
widths.map((w) => (sepUnicode ? '─' : '-').repeat(w + 2)).join(sepUnicode ? '┴' : '+') +
|
|
39
|
+
(sepUnicode ? '┘' : '+'));
|
|
40
|
+
return lines.join('\n');
|
|
41
|
+
function rowBorder(cells) {
|
|
42
|
+
return (sepUnicode ? '│' : '|') + cells.map((c) => ` ${c} `).join(sepUnicode ? '│' : '|') + (sepUnicode ? '│' : '|');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=table.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"table.js","sourceRoot":"","sources":["../src/table.ts"],"names":[],"mappings":"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"}
|
package/dist/theme.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface ThemeColors {
|
|
2
|
+
/** Primary brand accent (headings, highlights). */
|
|
3
|
+
accent: string;
|
|
4
|
+
success: string;
|
|
5
|
+
error: string;
|
|
6
|
+
warn: string;
|
|
7
|
+
info: string;
|
|
8
|
+
muted: string;
|
|
9
|
+
border: string;
|
|
10
|
+
highlight: string;
|
|
11
|
+
text: string;
|
|
12
|
+
}
|
|
13
|
+
export interface Theme {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly mode: 'dark' | 'light';
|
|
16
|
+
readonly colors: ThemeColors;
|
|
17
|
+
}
|
|
18
|
+
export declare const sleekDark: Theme;
|
|
19
|
+
export declare const sleekLight: Theme;
|
|
20
|
+
export declare const themes: Record<string, Theme>;
|
|
21
|
+
/**
|
|
22
|
+
* Resolve a theme by name. `'auto'` falls back to dark mode (the safe
|
|
23
|
+
* default for CLI tools); a runtime OSC 10 query can refine this in v0.2.
|
|
24
|
+
*/
|
|
25
|
+
export declare function resolveTheme(name: string | undefined): Theme;
|
package/dist/theme.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export const sleekDark = {
|
|
2
|
+
name: 'sleek-dark',
|
|
3
|
+
mode: 'dark',
|
|
4
|
+
colors: {
|
|
5
|
+
accent: '#7aa2f7',
|
|
6
|
+
success: '#9ece6a',
|
|
7
|
+
error: '#f7768e',
|
|
8
|
+
warn: '#e0af68',
|
|
9
|
+
info: '#7dcfff',
|
|
10
|
+
muted: '#565f89',
|
|
11
|
+
border: '#3b4261',
|
|
12
|
+
highlight: '#bb9af7',
|
|
13
|
+
text: '#a9b1d6',
|
|
14
|
+
},
|
|
15
|
+
};
|
|
16
|
+
export const sleekLight = {
|
|
17
|
+
name: 'sleek-light',
|
|
18
|
+
mode: 'light',
|
|
19
|
+
colors: {
|
|
20
|
+
accent: '#4257b2',
|
|
21
|
+
success: '#2e7d32',
|
|
22
|
+
error: '#c62828',
|
|
23
|
+
warn: '#b26a00',
|
|
24
|
+
info: '#0277bd',
|
|
25
|
+
muted: '#8a94a6',
|
|
26
|
+
border: '#c3cdd9',
|
|
27
|
+
highlight: '#6a3fc0',
|
|
28
|
+
text: '#37474f',
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const themes = {
|
|
32
|
+
sleek: sleekDark,
|
|
33
|
+
'sleek-dark': sleekDark,
|
|
34
|
+
'sleek-light': sleekLight,
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a theme by name. `'auto'` falls back to dark mode (the safe
|
|
38
|
+
* default for CLI tools); a runtime OSC 10 query can refine this in v0.2.
|
|
39
|
+
*/
|
|
40
|
+
export function resolveTheme(name) {
|
|
41
|
+
if (name === undefined || name === 'auto')
|
|
42
|
+
return sleekDark;
|
|
43
|
+
return themes[name] ?? sleekDark;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=theme.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"theme.js","sourceRoot":"","sources":["../src/theme.ts"],"names":[],"mappings":"AAmBA,MAAM,CAAC,MAAM,SAAS,GAAU;IAC9B,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,MAAM;IACZ,MAAM,EAAE;QACN,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,SAAS;KAChB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAU;IAC/B,IAAI,EAAE,aAAa;IACnB,IAAI,EAAE,OAAO;IACb,MAAM,EAAE;QACN,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,SAAS;QAClB,KAAK,EAAE,SAAS;QAChB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,SAAS;QACf,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,SAAS;QACjB,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,SAAS;KAChB;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,MAAM,GAA0B;IAC3C,KAAK,EAAE,SAAS;IAChB,YAAY,EAAE,SAAS;IACvB,aAAa,EAAE,UAAU;CAC1B,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,IAAwB;IACnD,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,SAAS,CAAC;AACnC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mudah-cli/ui",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Terminal design system: tokens, themes, output primitives, tables, panels, and markdown rendering.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=26"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"sideEffects": false,
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@mudah-cli/terminal": "^0.1.0"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
}
|
|
26
|
+
}
|