@basiclines/rampa 1.0.1 → 1.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.
Files changed (3) hide show
  1. package/README.md +37 -1
  2. package/dist/index.js +90 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,6 +4,19 @@ Generate mathematically accurate, accessible color palettes from a base color.
4
4
 
5
5
  ## Installation
6
6
 
7
+ ### npm
8
+
9
+ ```bash
10
+ npx @basiclines/rampa -C "#3b82f6"
11
+ ```
12
+
13
+ Or install globally:
14
+
15
+ ```bash
16
+ npm install -g @basiclines/rampa
17
+ rampa -C "#3b82f6"
18
+ ```
19
+
7
20
  ### Homebrew (macOS/Linux)
8
21
 
9
22
  ```bash
@@ -44,6 +57,9 @@ rampa -C "#3b82f6" --size=5 -L 10:90
44
57
  # Add complementary harmony
45
58
  rampa -C "#3b82f6" --add=complementary
46
59
 
60
+ # Add hue-shifted ramp (45 degrees)
61
+ rampa -C "#3b82f6" --add=shift:45
62
+
47
63
  # Output as CSS variables
48
64
  rampa -C "#3b82f6" --output=css
49
65
  ```
@@ -108,7 +124,14 @@ Available blend modes: `normal`, `multiply`, `screen`, `overlay`, `darken`, `lig
108
124
  |------|-------------|
109
125
  | `--add` | Add harmony ramp (repeatable) |
110
126
 
111
- Available harmonies: `complementary`, `triadic`, `analogous`, `split-complementary`, `square`, `compound`
127
+ Available types:
128
+ - `complementary` — Opposite on color wheel (+180°)
129
+ - `triadic` — 3 colors, 120° apart
130
+ - `analogous` — Adjacent colors, 30° apart
131
+ - `split-complementary` — 2 colors near opposite
132
+ - `square` — 4 colors, 90° apart
133
+ - `compound` — Complementary + split
134
+ - `shift:N` — Custom hue rotation by N degrees (e.g., `shift:45`, `shift:-30`)
112
135
 
113
136
  ### Output
114
137
 
@@ -150,6 +173,19 @@ rampa -C "#3b82f6" --tint-color="#FF0000" --tint-opacity=15 --tint-blend=overlay
150
173
  rampa -C "#3b82f6" --add=complementary --add=triadic
151
174
  ```
152
175
 
176
+ ### Custom Hue Shifts
177
+
178
+ ```bash
179
+ # Warm shift (+45°)
180
+ rampa -C "#3b82f6" --add=shift:45
181
+
182
+ # Cool shift (-30°)
183
+ rampa -C "#3b82f6" --add=shift:-30
184
+
185
+ # Multiple shifts
186
+ rampa -C "#3b82f6" --add=shift:30 --add=shift:60 --add=shift:90
187
+ ```
188
+
153
189
  ### JSON Output
154
190
 
155
191
  ```bash
package/dist/index.js CHANGED
@@ -9897,6 +9897,41 @@ function formatCss2(ramps) {
9897
9897
  `);
9898
9898
  }
9899
9899
 
9900
+ // src/utils/terminal-colors.ts
9901
+ function hasLimitedColorSupport() {
9902
+ return process.env.TERM_PROGRAM === "Apple_Terminal";
9903
+ }
9904
+ function rgbTo256(r4, g3, b2) {
9905
+ if (r4 === g3 && g3 === b2) {
9906
+ if (r4 < 8)
9907
+ return 16;
9908
+ if (r4 > 248)
9909
+ return 231;
9910
+ return Math.round((r4 - 8) / 10) + 232;
9911
+ }
9912
+ const rIndex = Math.round(r4 / 255 * 5);
9913
+ const gIndex = Math.round(g3 / 255 * 5);
9914
+ const bIndex = Math.round(b2 / 255 * 5);
9915
+ return 16 + 36 * rIndex + 6 * gIndex + bIndex;
9916
+ }
9917
+ function coloredSquare(r4, g3, b2) {
9918
+ if (hasLimitedColorSupport()) {
9919
+ const colorCode = rgbTo256(r4, g3, b2);
9920
+ return `\x1B[38;5;${colorCode}m■\x1B[0m`;
9921
+ }
9922
+ return `\x1B[38;2;${r4};${g3};${b2}m■\x1B[0m`;
9923
+ }
9924
+ function getColorLimitationNote() {
9925
+ if (hasLimitedColorSupport()) {
9926
+ const dim = "\x1B[2m";
9927
+ const yellow = "\x1B[33m";
9928
+ const reset = "\x1B[0m";
9929
+ return `${yellow}Note:${reset} ${dim}Using 256-color mode. macOS Terminal.app has limited truecolor support.${reset}
9930
+ ${dim}For accurate color previews, use iTerm2, Warp, kitty, or another truecolor terminal.${reset}`;
9931
+ }
9932
+ return null;
9933
+ }
9934
+
9900
9935
  // src/index.ts
9901
9936
  if (process.argv.includes("--help") || process.argv.includes("-h")) {
9902
9937
  showHelp();
@@ -9906,7 +9941,7 @@ function showHelp() {
9906
9941
  const dim = "\x1B[2m";
9907
9942
  const reset = "\x1B[0m";
9908
9943
  const help = `
9909
- rampa v1.0.1
9944
+ rampa v1.1.1
9910
9945
  Generate mathematically accurate color palettes from a base color
9911
9946
 
9912
9947
  USAGE
@@ -9944,7 +9979,7 @@ HARMONIES
9944
9979
  ${cyan}--add <type>${reset} ${dim}Add harmony ramp (can repeat)${reset}
9945
9980
 
9946
9981
  ${dim}Types: complementary, triadic, analogous,${reset}
9947
- ${dim}split-complementary, square, compound${reset}
9982
+ ${dim}split-complementary, square, compound, shift:<degrees>${reset}
9948
9983
 
9949
9984
  OUTPUT
9950
9985
  ${cyan}-O, --output <format>${reset} ${dim}Output format (default: text)${reset}
@@ -9960,6 +9995,7 @@ EXAMPLES
9960
9995
  ${cyan}rampa -C "#3b82f6"${reset}
9961
9996
  ${cyan}rampa -C "#3b82f6" --size=5 -L 10:90${reset}
9962
9997
  ${cyan}rampa -C "#3b82f6" --add=complementary --add=triadic${reset}
9998
+ ${cyan}rampa -C "#3b82f6" --add=shift:45 --add=shift:90${reset}
9963
9999
  ${cyan}rampa -C "#3b82f6" -O css${reset}
9964
10000
  ${cyan}rampa -C "#3b82f6" --tint-color="#FF0000" --tint-opacity=15${reset}
9965
10001
  `;
@@ -10077,16 +10113,19 @@ Examples:
10077
10113
  rampa -C "#3b82f6" --tint-color="#FF0000" --tint-opacity=20 --tint-blend=screen
10078
10114
  `,
10079
10115
  add: `
10080
- --add <harmony> Add harmony ramps (can be used multiple times)
10116
+ --add <type> Add harmony ramps (can be used multiple times)
10081
10117
 
10082
- Available harmonies:
10118
+ Available types:
10083
10119
  ${HARMONY_TYPES.join(", ")}
10120
+ shift:<degrees> - Custom hue rotation (e.g., shift:45, shift:-30)
10084
10121
 
10085
10122
  Examples:
10086
10123
  rampa -C "#3b82f6" --add=complementary
10087
10124
  rampa -C "#3b82f6" --add=triadic
10088
10125
  rampa -C "#3b82f6" --add=complementary --add=analogous
10089
- rampa -C "#3b82f6" --add=split-complementary --add=square
10126
+ rampa -C "#3b82f6" --add=shift:45 # Warm shift
10127
+ rampa -C "#3b82f6" --add=shift:-30 # Cool shift
10128
+ rampa -C "#3b82f6" --add=shift:45 --add=shift:90
10090
10129
  `,
10091
10130
  output: `
10092
10131
  --output, -O <format> Output format
@@ -10140,7 +10179,7 @@ var validFormats = ["hex", "hsl", "rgb", "oklch"];
10140
10179
  var main = defineCommand({
10141
10180
  meta: {
10142
10181
  name: "rampa",
10143
- version: "1.0.1",
10182
+ version: "1.1.1",
10144
10183
  description: "Generate mathematically accurate color palettes from a base color"
10145
10184
  },
10146
10185
  args: {
@@ -10214,7 +10253,7 @@ var main = defineCommand({
10214
10253
  },
10215
10254
  add: {
10216
10255
  type: "string",
10217
- description: "Add harmony ramp (repeatable: complementary, triadic, etc.)"
10256
+ description: "Add harmony ramp (repeatable: complementary, triadic, shift:N, etc.)"
10218
10257
  },
10219
10258
  output: {
10220
10259
  type: "string",
@@ -10334,14 +10373,29 @@ var main = defineCommand({
10334
10373
  }
10335
10374
  const addValues = args.add ? Array.isArray(args.add) ? args.add : [args.add] : [];
10336
10375
  const harmonies = [];
10337
- for (const h2 of addValues) {
10338
- if (!isValidHarmonyType(h2)) {
10339
- console.error(`Error: Invalid harmony type "${h2}"
10376
+ const hueShifts = [];
10377
+ for (const value of addValues) {
10378
+ if (value.startsWith("shift:")) {
10379
+ const shiftStr = value.slice(6);
10380
+ const shift = parseFloat(shiftStr);
10381
+ if (isNaN(shift)) {
10382
+ console.error(`Error: Invalid shift value "${shiftStr}" - must be a number
10340
10383
  `);
10341
- showFlagHelp("add");
10342
- }
10343
- if (!harmonies.includes(h2)) {
10344
- harmonies.push(h2);
10384
+ showFlagHelp("add");
10385
+ }
10386
+ const normalized = (shift % 360 + 360) % 360;
10387
+ if (!hueShifts.includes(normalized)) {
10388
+ hueShifts.push(normalized);
10389
+ }
10390
+ } else {
10391
+ if (!isValidHarmonyType(value)) {
10392
+ console.error(`Error: Invalid harmony type "${value}"
10393
+ `);
10394
+ showFlagHelp("add");
10395
+ }
10396
+ if (!harmonies.includes(value)) {
10397
+ harmonies.push(value);
10398
+ }
10345
10399
  }
10346
10400
  }
10347
10401
  if (!tintColor && tintOpacity > 0) {
@@ -10431,11 +10485,32 @@ var main = defineCommand({
10431
10485
  });
10432
10486
  });
10433
10487
  }
10488
+ for (const shift of hueShifts) {
10489
+ const baseChroma = chroma_js_default(validatedColor);
10490
+ const [h2, s2, l2] = baseChroma.hsl();
10491
+ const shiftedHue = ((h2 || 0) + shift) % 360;
10492
+ const shiftedBaseColor = chroma_js_default.hsl(shiftedHue, s2, l2).hex();
10493
+ const shiftedRampColors = generateColorRamp(buildConfig(shiftedBaseColor));
10494
+ const formattedShiftedColors = shiftedRampColors.map((c4) => formatColor2(c4, outputFormat));
10495
+ ramps.push({
10496
+ name: `shift-${Math.round(shift)}`,
10497
+ baseColor: formatColor2(shiftedBaseColor, outputFormat),
10498
+ config: buildRampConfig(),
10499
+ colors: formattedShiftedColors
10500
+ });
10501
+ }
10434
10502
  if (outputType === "json") {
10435
10503
  console.log(formatJson(ramps));
10436
10504
  } else if (outputType === "css") {
10437
10505
  console.log(formatCss2(ramps));
10438
10506
  } else {
10507
+ if (args.preview) {
10508
+ const limitationNote = getColorLimitationNote();
10509
+ if (limitationNote) {
10510
+ console.log(limitationNote);
10511
+ console.log("");
10512
+ }
10513
+ }
10439
10514
  ramps.forEach((ramp, rampIndex) => {
10440
10515
  if (rampIndex > 0 || ramps.length > 1) {
10441
10516
  if (rampIndex > 0)
@@ -10446,7 +10521,7 @@ var main = defineCommand({
10446
10521
  if (args.preview) {
10447
10522
  const c4 = chroma_js_default(color);
10448
10523
  const [r4, g3, b2] = c4.rgb();
10449
- const square = `\x1B[38;2;${r4};${g3};${b2}m■\x1B[0m`;
10524
+ const square = coloredSquare(r4, g3, b2);
10450
10525
  console.log(`${square} ${color}`);
10451
10526
  } else {
10452
10527
  console.log(color);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basiclines/rampa",
3
- "version": "1.0.1",
3
+ "version": "1.1.1",
4
4
  "description": "Generate mathematically accurate color palettes from a base color",
5
5
  "type": "module",
6
6
  "bin": {