1import chroma, { Scale } from "chroma-js";
2import { ColorToken } from "../tokens";
3
4export type Color = string;
5export type ColorRampStep = { value: Color; type: "color"; description: string };
6export type ColorRamp = {
7 [index: number]: ColorRampStep;
8};
9
10export function colorRamp(
11 color: Color | [Color, Color],
12 options?: { steps?: number; increment?: number; }
13): ColorRamp {
14 let scale: Scale;
15 if (Array.isArray(color)) {
16 const [startColor, endColor] = color;
17 scale = chroma.scale([startColor, endColor]);
18 } else {
19 let hue = Math.round(chroma(color).hsl()[0]);
20 let startColor = chroma.hsl(hue, 0.88, 0.96);
21 let endColor = chroma.hsl(hue, 0.68, 0.12);
22 scale = chroma
23 .scale([startColor, color, endColor])
24 .domain([0, 0.5, 1])
25 .mode("hsl")
26 .gamma(1)
27 // .correctLightness(true)
28 .padding([0, 0]);
29 }
30
31 const ramp: ColorRamp = {};
32 const steps = options?.steps || 10;
33 const increment = options?.increment || 100;
34
35 scale.colors(steps, "hex").forEach((color, ix) => {
36 const step = ix * increment;
37 ramp[step] = {
38 value: color,
39 description: `Step: ${step}`,
40 type: "color",
41 };
42 });
43
44 return ramp;
45}
46
47export function withOpacity(color: ColorToken, opacity: number): ColorToken {
48 return {
49 ...color,
50 value: chroma(color.value).alpha(opacity).hex()
51 };
52}