@kljj04/cli-kit 1.0.2 → 1.2.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/index.js CHANGED
@@ -6,6 +6,9 @@ const kit = {
6
6
  },
7
7
  style(...args) {
8
8
  return new KitBuilder().style(...args);
9
+ },
10
+ gradient(from, to) {
11
+ return new KitBuilder().gradient(from, to);
9
12
  }
10
13
  };
11
14
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kljj04/cli-kit",
3
- "version": "1.0.2",
3
+ "version": "1.2.0",
4
4
  "description": "All-in-one terminal styling library. Colors, boxes, tables, spinners, and progress bars.",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/src/color.js CHANGED
@@ -24,6 +24,8 @@ class KitBuilder {
24
24
  this._b = 255;
25
25
  this._styles = [];
26
26
  this._outputType = 'print';
27
+ this._override = false;
28
+ this._gradientColors = null;
27
29
  }
28
30
 
29
31
  color(r, g, b) {
@@ -33,10 +35,17 @@ class KitBuilder {
33
35
  return this;
34
36
  }
35
37
 
38
+ gradient(from, to) {
39
+ this._gradientColors = [from, to];
40
+ return this;
41
+ }
42
+
36
43
  style(...args) {
37
44
  const outputTypes = ['print', 'box', 'spinner', 'progress', 'table'];
38
45
  args.forEach(arg => {
39
- if (outputTypes.includes(arg)) {
46
+ if (arg === 'override') {
47
+ this._override = true;
48
+ } else if (outputTypes.includes(arg)) {
40
49
  this._outputType = arg;
41
50
  } else if (STYLES[arg]) {
42
51
  this._styles.push(arg);
@@ -46,7 +55,7 @@ class KitBuilder {
46
55
  }
47
56
 
48
57
  _buildPrefix() {
49
- const colorCode = rgb(this._r, this._g, this._b);
58
+ const colorCode = this._gradientColors ? '' : rgb(this._r, this._g, this._b);
50
59
  const styleCodes = this._styles.map(s => STYLES[s]).join('');
51
60
  return `${colorCode}${styleCodes}`;
52
61
  }
@@ -63,15 +72,16 @@ class KitBuilder {
63
72
  case 'spinner':
64
73
  return require('./spinner').spinner(prefix, value);
65
74
  case 'progress':
66
- require('./progress').progress(prefix, value);
75
+ require('./progress').progress(prefix, value, this._override, this._gradientColors);
67
76
  break;
68
77
  case 'table':
69
78
  require('./table').table(prefix, value);
70
79
  break;
71
80
  }
72
- // reset for next use
73
81
  this._styles = [];
74
82
  this._outputType = 'print';
83
+ this._override = false;
84
+ this._gradientColors = null;
75
85
  }
76
86
  }
77
87
 
package/src/progress.js CHANGED
@@ -1,13 +1,81 @@
1
1
  const { RESET } = require('./color');
2
2
 
3
- function progress(prefix, value) {
4
- const pct = Math.min(100, Math.max(0, Number(value)));
3
+ function linearize(c) {
4
+ c /= 255;
5
+ return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
6
+ }
7
+
8
+ function delinearize(c) {
9
+ c = c <= 0.0031308 ? 12.92 * c : 1.055 * Math.pow(c, 1 / 2.4) - 0.055;
10
+ return Math.round(Math.min(1, Math.max(0, c)) * 255);
11
+ }
12
+
13
+ function rgbToOklch(r, g, b) {
14
+ const lr = linearize(r), lg = linearize(g), lb = linearize(b);
15
+ const l = 0.4122214708 * lr + 0.5363325363 * lg + 0.0514459929 * lb;
16
+ const m = 0.2119034982 * lr + 0.6806995451 * lg + 0.1073969566 * lb;
17
+ const s = 0.0883024619 * lr + 0.2817188376 * lg + 0.6299787005 * lb;
18
+ const l_ = Math.cbrt(l), m_ = Math.cbrt(m), s_ = Math.cbrt(s);
19
+ const L = 0.2104542553 * l_ + 0.7936177850 * m_ - 0.0040720468 * s_;
20
+ const a = 1.9779984951 * l_ - 2.4285922050 * m_ + 0.4505937099 * s_;
21
+ const bVal = 0.0259040371 * l_ + 0.7827717662 * m_ - 0.8086757660 * s_;
22
+ const C = Math.sqrt(a * a + bVal * bVal);
23
+ const H = Math.atan2(bVal, a) * (180 / Math.PI);
24
+ return [L, C, H < 0 ? H + 360 : H];
25
+ }
26
+
27
+ function oklchToRgb(L, C, H) {
28
+ const hRad = H * (Math.PI / 180);
29
+ const a = C * Math.cos(hRad);
30
+ const b = C * Math.sin(hRad);
31
+ const l_ = L + 0.3963377774 * a + 0.2158037573 * b;
32
+ const m_ = L - 0.1055613458 * a - 0.0638541728 * b;
33
+ const s_ = L - 0.0894841775 * a - 1.2914855480 * b;
34
+ const lc = l_ * l_ * l_, mc = m_ * m_ * m_, sc = s_ * s_ * s_;
35
+ const lr = 4.0767416621 * lc - 3.3077115913 * mc + 0.2309699292 * sc;
36
+ const lg = -1.2684380046 * lc + 2.6097574011 * mc - 0.3413193965 * sc;
37
+ const lb = -0.0041960863 * lc - 0.7034186147 * mc + 1.7076147010 * sc;
38
+ return [delinearize(lr), delinearize(lg), delinearize(lb)];
39
+ }
40
+
41
+ function lerpOklch(from, to, t) {
42
+ const a = rgbToOklch(...from);
43
+ const b = rgbToOklch(...to);
44
+ let dH = b[2] - a[2];
45
+ if (dH > 180) dH -= 360;
46
+ if (dH < -180) dH += 360;
47
+ return oklchToRgb(a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + dH * t);
48
+ }
49
+
50
+ function renderBar(prefix, pct, gradientColors) {
5
51
  const width = 30;
6
52
  const filled = Math.round((pct / 100) * width);
7
53
  const empty = width - filled;
8
54
 
9
- const bar = ''.repeat(filled) + '░'.repeat(empty);
10
- console.log(`${prefix}[${bar}] ${pct}%${RESET}`);
55
+ let bar = '';
56
+ if (gradientColors) {
57
+ for (let i = 0; i < filled; i++) {
58
+ const t = filled > 1 ? i / (filled - 1) : 0;
59
+ const [r, g, b] = lerpOklch(gradientColors[0], gradientColors[1], t);
60
+ bar += `\x1b[38;2;${r};${g};${b}m█`;
61
+ }
62
+ bar += `${RESET}${'░'.repeat(empty)}`;
63
+ } else {
64
+ bar = '█'.repeat(filled) + '░'.repeat(empty);
65
+ }
66
+
67
+ return `${prefix}[${bar}] ${pct}%${RESET}`;
68
+ }
69
+
70
+ function progress(prefix, value, override, gradientColors) {
71
+ const pct = Math.min(100, Math.max(0, Number(value)));
72
+ const bar = renderBar(prefix, pct, gradientColors);
73
+ if (override) {
74
+ process.stdout.write(`\r${bar}`);
75
+ if (pct >= 100) process.stdout.write('\n');
76
+ } else {
77
+ console.log(bar);
78
+ }
11
79
  }
12
80
 
13
81
  module.exports = { progress };