@trap_stevo/terminal-plus
Version:
Transform your CLI into a visually striking, feature-rich command layer. Blend animated gradients, stylish badges, dynamic progress bars, sleek tables, and precise formatting utilities — all turning terminal output into a powerful visual experience.
136 lines (135 loc) • 6.7 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
function _classPrivateMethodInitSpec(e, a) { _checkPrivateRedeclaration(e, a), a.add(e); }
function _checkPrivateRedeclaration(e, t) { if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object"); }
function _assertClassBrand(e, t, n) { if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n; throw new TypeError("Private element is not present on this object"); }
const GraphemeSplitter = require("grapheme-splitter");
const readline = require("readline");
var _TerminalSpinner_brand = /*#__PURE__*/new WeakSet();
class TerminalSpinner {
constructor(label, options = {}, colorEngine) {
_classPrivateMethodInitSpec(this, _TerminalSpinner_brand);
this.label = label;
this.colorEngine = colorEngine;
this.chalk = colorEngine.chalk;
this.interval = options.interval || 80;
this.textColor = options.textColor || "#ffffff";
this.backgroundColor = options.backgroundColor || null;
this.gradientShift = options.gradientShift || false;
this.textGradientSpeed = options.textGradientSpeed || 1;
this.bgGradientSpeed = options.bgGradientSpeed || 1;
this.textGradientReverse = options.textGradientReverse || false;
this.bgGradientReverse = options.bgGradientReverse || false;
this.textGradientTick = 0;
this.bgGradientTick = 0;
this.gradient = options.gradient || null;
this.icon = options.icon || null;
this.prefix = options.prefix || "";
this.suffix = options.suffix || "";
this.padding = options.padding || 1;
this.inline = options.inline !== false;
this.index = 0;
this.timer = null;
const preset = options.preset;
const customFrames = options.frames;
if (preset && TerminalSpinner.framePresets[preset]) {
this.frames = TerminalSpinner.framePresets[preset];
} else {
this.frames = customFrames || TerminalSpinner.framePresets.dots;
}
}
start() {
if (this.timer) {
return;
}
this.timer = setInterval(() => {
if (this.gradientShift) {
if (Array.isArray(this.textColor) && this.textColor.length > 1) {
if (++this.textGradientTick >= this.textGradientSpeed) {
this.textGradientTick = 0;
if (this.textGradientReverse) {
this.textColor.unshift(this.textColor.pop());
} else {
this.textColor.push(this.textColor.shift());
}
}
}
if (Array.isArray(this.backgroundColor) && this.backgroundColor.length > 1) {
if (++this.bgGradientTick >= this.bgGradientSpeed) {
this.bgGradientTick = 0;
if (this.bgGradientReverse) {
this.backgroundColor.unshift(this.backgroundColor.pop());
} else {
this.backgroundColor.push(this.backgroundColor.shift());
}
}
}
}
const frame = this.frames[this.index = (this.index + 1) % this.frames.length];
const output = _assertClassBrand(_TerminalSpinner_brand, this, _formatText).call(this, frame);
readline.cursorTo(process.stdout, 0);
process.stdout.write(this.inline ? `${this.prefix}${output}${this.suffix}` : `\n${this.prefix}${output}${this.suffix}\n`);
}, this.interval);
}
stop(finalText = null) {
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
readline.clearLine(process.stdout, 0);
readline.cursorTo(process.stdout, 0);
if (finalText !== null) {
const styled = this.chalk.hex(this.textColor)(String(finalText));
process.stdout.write(this.inline ? styled : `\n${styled}\n`);
}
}
}
}
function _formatText(frame) {
const splitter = new GraphemeSplitter();
let content = " ".repeat(this.padding) + frame + " ";
if (this.icon) {
content += this.icon + " ";
}
content += this.label + " ".repeat(this.padding);
const graphemes = splitter.splitGraphemes(content);
const useTextGradient = Array.isArray(this.textColor) && this.textColor.length >= 2;
const useBgGradient = Array.isArray(this.backgroundColor) && this.backgroundColor.length >= 2;
const textColors = useTextGradient ? this.colorEngine.generateGradientColors(this.textColor, graphemes.length) : null;
const bgColors = useBgGradient ? this.colorEngine.generateGradientColors(this.backgroundColor, graphemes.length) : null;
return graphemes.map((g, i) => {
const chalk = this.chalk;
let styled = g;
if (useTextGradient) {
const [r, gVal, b] = textColors[i];
styled = chalk.rgb(r, gVal, b)(styled);
} else {
styled = chalk.hex(this.textColor)(styled);
}
if (useBgGradient) {
const [r, gVal, b] = bgColors[i];
styled = chalk.bgRgb(r, gVal, b)(styled);
} else if (this.backgroundColor) {
styled = chalk.bgHex(this.backgroundColor)(styled);
}
return styled;
}).join("");
}
(0, _defineProperty2.default)(TerminalSpinner, "framePresets", {
dots: ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"],
line: ["-", "\\", "|", "/"],
arrows: ["←", "↖", "↑", "↗", "→", "↘", "↓", "↙"],
circle: ["◐", "◓", "◑", "◒"],
bounce: [".", "o", "O", "o", "."],
bar: ["[ ]", "[= ]", "[== ]", "[=== ]", "[ ===]", "[ ==]", "[ =]", "[ ]"],
grow: ["▁", "▃", "▄", "▅", "▆", "▇", "█", "▇", "▆", "▅", "▄", "▃"],
clock: ["🕛", "🕐", "🕑", "🕒", "🕓", "🕔", "🕕", "🕖", "🕗", "🕘", "🕙", "🕚"],
simple: [".", "..", "...", "....", "....."],
supercape: ["🦸♂️ 🏃", " 🦸♂️ 🏃", " 🦸♂️ 🏃", " 🦸♂️ 🏃", " 🦸♂️ 🏃", " 🦸♂️🏃", " 🦸♂️ 🏃", " 🦸♂️ 🏃", " 🦸♂️ 🏃", " 🦸♂️ 🏃"],
fireball: ["🔥 ", " 🔥 ", " 🔥 ", " 🔥 ", " 🔥 ", " 🔥", " 🔥 ", " 🔥 ", " 🔥 ", " 🔥 "],
magic: ["✨ ", " ✨ ", " ✨ ", " ✨ ", " ✨ ", " ✨", " ✨ ", " ✨ ", " ✨ ", " ✨ "],
rocket: ["🚀 ", " 🚀 ", " 🚀 ", " 🚀 ", " 🚀 ", " 🚀 ", " 🚀", " 🚀 ", " 🚀 ", " 🚀 ", " 🚀 ", " 🚀 "],
retro: ["👾 🛸", " 👾 🛸", " 👾 🛸", " 👾 🛸", " 👾 🛸", " 👾🛸", " 👾 🛸", " 👾 🛸", " 👾 🛸", " 👾 🛸"]
});
;
module.exports = TerminalSpinner;