Files
ssh-portfolio/src/terminal.js
T

28 lines
2.1 KiB
JavaScript

export const ESC = '\x1b[';
export const colors = { cyan: 36, yellow: 33, green: 32, magenta: 35, blue: 34, white: 37, red: 31, brightBlack: 90 };
export const color = (name, text) => `\x1b[${colors[name] || colors.cyan}m${text}\x1b[0m`;
export const clear = '\x1b[0m\x1b[2J\x1b[3J\x1b[H';
export const crlf = text => String(text).replace(/\r?\n/g, '\r\n');
export const visibleLength = text => String(text).replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, '').length;
export const truncate = (text, width) => Array.from(String(text)).slice(0, Math.max(0, width)).join('');
export function header(left, right, width, leftColor = 'cyan', rightColor = 'brightBlack') {
const safeWidth = Math.max(30, width || 80);
const safeRight = truncate(right, Math.max(0, safeWidth - 2));
const safeLeft = truncate(left, Math.max(1, safeWidth - safeRight.length - 2));
return `${color(leftColor, safeLeft)}${' '.repeat(Math.max(1, safeWidth - safeLeft.length - safeRight.length))}${color(rightColor, safeRight)}`;
}
export function box(title, lines, width, theme = {}) {
const outer = Math.max(30, width || 80); const inner = outer - 4;
const primary = theme.primary || 'cyan'; const muted = theme.muted || 'brightBlack';
const titleText = ` ${truncate(title, inner - 2)} `; const topFill = Math.max(0, outer - titleText.length - 2);
let output = `${color(muted, '╭─')}${color(primary, titleText)}${color(muted, `${'─'.repeat(topFill)}`)}\r\n`;
for (const source of lines) {
const wrapped = wrap(source, inner);
for (const line of wrapped) output += `${color(muted, '│')} ${line}${' '.repeat(Math.max(0, inner - visibleLength(line)))} ${color(muted, '│')}\r\n`;
}
return output + color(muted, `${'─'.repeat(outer - 2)}`);
}
export function wrap(text, width = 78) {
const out = []; for (const paragraph of String(text).split('\n')) { if (!paragraph) { out.push(''); continue; } let line = ''; for (const word of paragraph.split(/\s+/)) { if (line && visibleLength(line) + visibleLength(word) + 1 > width) { out.push(line); line = word; } else line += (line ? ' ' : '') + word; } out.push(line); } return out;
}