@poupe/theme-builder
Version:
Design token management and theme generation system for Poupe UI framework
441 lines (440 loc) • 14.4 kB
JavaScript
import { formatCSSRules, formatCSSRulesArray, generateCSSRules, generateCSSRulesArray, unsafeKeys } from "@poupe/css";
import { Blend, DynamicScheme, Hct, TonalPalette, Variant } from "@poupe/material-color-utilities";
import { Colord, colord as colord$1, extend } from "colord";
import mixPlugin from "colord/plugins/mix";
const uint32 = (n) => n >>> 0;
const uint8 = (n) => n >>> 0 & 255;
const alphaFromArgb = (argb) => uint8(uint32(argb) >> 24);
const redFromArgb = (argb) => uint8(uint32(argb) >> 16);
const greenFromArgb = (argb) => uint8(uint32(argb) >> 8);
const blueFromArgb = (argb) => uint8(uint32(argb));
const defaultColors = {
indianred: "#cd5c5c",
lightcoral: "#f08080",
salmon: "#fa8072",
darksalmon: "#e9967a",
crimson: "#dc143c",
red: "#ff0000",
firebrick: "#b22222",
darkred: "#8b0000",
pink: "#ffc0cb",
lightpink: "#ffb6c1",
hotpink: "#ff69b4",
deeppink: "#ff1493",
mediumvioletred: "#c71585",
palevioletred: "#db7093",
lightsalmon: "#ffa07a",
coral: "#ff7f50",
tomato: "#ff6347",
orangered: "#ff4500",
darkorange: "#ff8c00",
orange: "#ffa500",
gold: "#ffd700",
yellow: "#ffff00",
lightyellow: "#ffffe0",
lemonchiffon: "#fffacd",
lightgoldenrodyellow: "#fafad2",
papayawhip: "#ffefd5",
moccasin: "#ffe4b5",
peachpuff: "#ffdab9",
palegoldenrod: "#eee8aa",
khaki: "#f0e68c",
darkkhaki: "#bdb76b",
lavender: "#e6e6fa",
thistle: "#d8bfd8",
plum: "#dda0dd",
violet: "#ee82ee",
orchid: "#da70d6",
fuchsia: "#ff00ff",
magenta: "#ff00ff",
mediumorchid: "#ba55d3",
mediumpurple: "#9370db",
rebeccapurple: "#663399",
blueviolet: "#8a2be2",
darkviolet: "#9400d3",
darkorchid: "#9932cc",
darkmagenta: "#8b008b",
purple: "#800080",
indigo: "#4b0082",
slateblue: "#6a5acd",
darkslateblue: "#483d8b",
mediumslateblue: "#7b68ee",
greenyellow: "#adff2f",
chartreuse: "#7fff00",
lawngreen: "#7cfc00",
lime: "#00ff00",
limegreen: "#32cd32",
palegreen: "#98fb98",
lightgreen: "#90ee90",
mediumspringgreen: "#00fa9a",
springgreen: "#00ff7f",
mediumseagreen: "#3cb371",
seagreen: "#2e8b57",
forestgreen: "#228b22",
green: "#008000",
darkgreen: "#006400",
yellowgreen: "#9acd32",
olivedrab: "#6b8e23",
olive: "#808000",
darkolivegreen: "#556b2f",
mediumaquamarine: "#66cdaa",
darkseagreen: "#8fbc8f",
lightseagreen: "#20b2aa",
darkcyan: "#008b8b",
teal: "#008080",
aqua: "#00ffff",
cyan: "#00ffff",
lightcyan: "#e0ffff",
paleturquoise: "#afeeee",
aquamarine: "#7fffd4",
turquoise: "#40e0d0",
mediumturquoise: "#48d1cc",
darkturquoise: "#00ced1",
cadetblue: "#5f9ea0",
steelblue: "#4682b4",
lightsteelblue: "#b0c4de",
powderblue: "#b0e0e6",
lightblue: "#add8e6",
skyblue: "#87ceeb",
lightskyblue: "#87cefa",
deepskyblue: "#00bfff",
dodgerblue: "#1e90ff",
cornflowerblue: "#6495ed",
royalblue: "#4169e1",
blue: "#0000ff",
mediumblue: "#0000cd",
darkblue: "#00008b",
navy: "#000080",
midnightblue: "#191970",
cornsilk: "#fff8dc",
blanchedalmond: "#ffebcd",
bisque: "#ffe4c4",
navajowhite: "#ffdead",
wheat: "#f5deb3",
burlywood: "#deb887",
tan: "#d2b48c",
rosybrown: "#bc8f8f",
sandybrown: "#f4a460",
goldenrod: "#daa520",
darkgoldenrod: "#b8860b",
peru: "#cd853f",
chocolate: "#d2691e",
saddlebrown: "#8b4513",
sienna: "#a0522d",
brown: "#a52a2a",
maroon: "#800000",
white: "#ffffff",
snow: "#fffafa",
honeydew: "#f0fff0",
mintcream: "#f5fffa",
azure: "#f0ffff",
aliceblue: "#f0f8ff",
ghostwhite: "#f8f8ff",
whitesmoke: "#f5f5f5",
seashell: "#fff5ee",
beige: "#f5f5dc",
oldlace: "#fdf5e6",
floralwhite: "#fffaf0",
ivory: "#fffff0",
antiquewhite: "#faebd7",
linen: "#faf0e6",
lavenderblush: "#fff0f5",
mistyrose: "#ffe4e1",
gainsboro: "#dcdcdc",
lightgray: "#d3d3d3",
lightgrey: "#d3d3d3",
silver: "#c0c0c0",
darkgray: "#a9a9a9",
darkgrey: "#a9a9a9",
gray: "#808080",
grey: "#808080",
dimgray: "#696969",
dimgrey: "#696969",
lightslategray: "#778899",
lightslategrey: "#778899",
slategray: "#708090",
slategrey: "#708090",
darkslategray: "#2f4f4f",
darkslategrey: "#2f4f4f",
black: "#000000",
transparent: "#00000000"
};
function withKnownColor(c) {
if (typeof c !== "string" || !reOnlyLetters.test(c)) return c;
const name = c.toLowerCase();
if (name in defaultColors) return defaultColors[name];
return c;
}
const reOnlyLetters = /^[a-zA-Z]+$/;
const corePaletteKeys = [
"primary",
"secondary",
"tertiary",
"neutral",
"neutralVariant",
"error"
];
extend([mixPlugin]);
const isObjectColor = (c) => {
if (c === null || typeof c !== "object") return false;
else if (c instanceof Hct || c instanceof Colord) return false;
else if ("r" in c && "g" in c && "b" in c || "h" in c && "c" in c && "t" in c || "h" in c && "s" in c && "l" in c || "h" in c && "s" in c && "v" in c || "h" in c && "w" in c && "b" in c || "x" in c && "y" in c && "z" in c || "l" in c && "a" in c && "b" in c || "l" in c && "c" in c && "h" in c || "c" in c && "m" in c && "y" in c && "k" in c) return true;
else return false;
};
function normalizeAlpha(a) {
if (a === void 0) return;
const n = a > 1 ? a / 255 : a;
return Math.min(Math.max(n, 0), 1);
}
function withNormalizedAlpha(c) {
if ("a" in c && c.a !== void 0) {
const a = normalizeAlpha(c.a);
return {
...c,
a
};
}
return c;
}
const rgbFromRgbaColor = (c) => {
const r255 = uint8(c.r);
const g255 = uint8(c.g);
const b255 = uint8(c.b);
return uint32(r255 << 16 | g255 << 8 | b255);
};
const rgbaFromHctColor = (c) => splitArgb(argbFromHctColor(c));
const rgba = (c) => splitArgb(argb(c));
const argbFromHct = (c) => c.toInt();
const argbFromRgbaColor = (c) => {
const a = normalizeAlpha(c.a) ?? 1;
return uint32(uint8(Math.round(a * 255)) << 24 | rgbFromRgbaColor(c));
};
const argbFromHctColor = (c) => {
const argb = argbFromHct(Hct.from(c.h, c.c, c.t));
if (c.a === void 0) return argb;
const a = normalizeAlpha(c.a);
return uint32(uint8(Math.round(a * 255)) << 24 | argb & 16777215);
};
const argbFromColord = (c) => {
if (!c.isValid()) throw new Error("Invalid color");
return argbFromRgbaColor(c.rgba);
};
const argbFromString = (s) => argbFromColord(colordFromString(s));
const splitArgb = (argb) => {
const a255 = alphaFromArgb(argb);
return {
r: redFromArgb(argb),
g: greenFromArgb(argb),
b: blueFromArgb(argb),
...a255 > 0 ? { a: a255 / 255 } : {}
};
};
const argb = (c) => {
if (c instanceof Hct) return argbFromHct(c);
else if (c instanceof Colord) return argbFromRgbaColor(c.rgba);
else if (typeof c === "number") return c;
else if (typeof c === "string") return argbFromString(c);
else if ("h" in c && "c" in c && "t" in c) return argbFromHctColor(c);
else return argbFromColord(colord(c));
};
const colordFromArgb = (argb) => colord$1(splitArgb(argb));
const colordFromHct = (c) => colordFromArgb(argbFromHct(c));
const colordFromHctColor = (c) => colordFromArgb(argbFromHctColor(c));
const colordFromString = (c) => {
const c1 = colord$1(withKnownColor(c));
if (!c1.isValid()) throw new Error(`Invalid color '${c}'`);
return c1;
};
const colord = (c) => {
if (c instanceof Colord) return c;
else if (c instanceof Hct) return colordFromHct(c);
else if (typeof c === "number") return colordFromArgb(c);
else if (typeof c === "string") return colordFromString(c);
else if ("h" in c && "c" in c && "t" in c) return colordFromHctColor(c);
else if (!isObjectColor(c)) throw new Error("Invalid color");
else if ("a" in c && c.a !== void 0) {
const a = normalizeAlpha(c.a);
return colord$1({
...c,
a
});
} else return colord$1(c);
};
const hctFromArgb = (argb) => Hct.fromInt(argb);
const hctFromRgbaColor = (c) => Hct.fromInt(argbFromRgbaColor(c));
const hctFromColord = (c) => {
if (!c.isValid()) throw new Error("Invalid color");
return hctFromRgbaColor(c.rgba);
};
const hctFromString = (s) => hctFromColord(colordFromString(s));
const splitHct = (c) => {
return {
h: c.hue,
c: c.chroma,
t: c.tone
};
};
const hct = (c) => {
if (c instanceof Hct) return c;
else if (c instanceof Colord) return hctFromColord(c);
else if (typeof c === "number") return hctFromArgb(c);
else if (typeof c === "string") return hctFromString(c);
else if ("h" in c && "c" in c && "t" in c) return Hct.from(c.h, c.c, c.t);
else return hctFromColord(colord(c));
};
const hslFromColord = (c) => {
if (!c.isValid()) throw new Error("Invalid color");
return c.toHsl();
};
const hslFromArgb = (argb) => hslFromColord(colord(splitArgb(argb)));
const hslFromHct = (c) => hslFromArgb(argbFromHct(c));
const hslFromHctColor = (c) => hslFromColord(colord(rgbaFromHctColor(c)));
const hslFromString = (s) => hslFromColord(colordFromString(s));
const hsl = (c) => {
if (c instanceof Hct) return hslFromHct(c);
else if (c instanceof Colord) return hslFromColord(c);
else if (typeof c === "number") return hslFromArgb(c);
else if (typeof c === "string") return hslFromString(c);
else if ("h" in c && "c" in c && "t" in c) return hslFromHctColor(c);
else return hslFromColord(colord(c));
};
const hexFromColord = (c) => {
if (!c.isValid()) throw new Error("Invalid color");
return c.toHex();
};
const hexFromArgb = (argb) => hexFromColord(colord(splitArgb(argb)));
const hexFromHct = (c) => hexFromArgb(argbFromHct(c));
const hexFromHctColor = (c) => hexFromColord(colord$1(rgbaFromHctColor(c)));
function colorFormatter(v = "rgb") {
if (typeof v === "function") return v;
if (v === "numbers") return (c) => {
const { r, g, b } = rgba(c);
return `${r} ${g} ${b}`;
};
if (v === "hsl") return hslString;
if (v === "hex") return hexString;
return rgbaString;
}
const hexString = (c) => {
if (c instanceof Hct) return hexFromHct(c);
else if (typeof c === "number") return hexFromArgb(c);
const c1 = colord(c);
if (!c1.isValid) throw new Error("Invalid color");
return hexFromColord(c1);
};
function hslString(c, alpha = true) {
const c1 = colord(c);
if (!c1.isValid) throw new Error("Invalid color");
const { h, s, l, a: a0 } = c1.toHsl();
const a = alpha === false ? 1 : a0;
if (a < 1) return `hsla(${h}, ${s}%, ${l}%, ${a})`;
return `hsl(${h}, ${s}%, ${l}%)`;
}
const rgbaString = (c, alpha = true) => {
const { r, g, b, a: a0 = 1 } = rgba(c);
const a = alpha === false ? 1 : a0;
if (a < 1) return `rgb(${r} ${g} ${b} / ${a.toFixed(2)})`;
return `rgb(${r} ${g} ${b})`;
};
function makeColorMix(base, other, ratios) {
const c0 = colord(base);
const c1 = colord(other);
if (typeof ratios === "number") return hctFromColord(c0.mix(c1, ratios));
if (Array.isArray(ratios)) {
const out = [];
for (const r of ratios) {
const c = c0.mix(c1, r);
out.push(hctFromColord(c));
}
return out;
}
const out = {};
for (const k of unsafeKeys(ratios)) out[k] = hctFromColord(c0.mix(c1, ratios[k]));
return out;
}
function makeTonalPalette(color, harmonizeTo, isKeyColor = true) {
let c = hct(color);
if (harmonizeTo) c = hct(Blend.harmonize(c.toInt(), harmonizeTo.toInt()));
if (isKeyColor) return TonalPalette.fromHct(c);
return TonalPalette.fromHueAndChroma(c.hue, c.chroma);
}
function makeCustomColor(color, harmonizeTo, name, isKeyColor = true) {
return makeCustomColorFromPalette(makeTonalPalette(color, harmonizeTo, isKeyColor), name);
}
function makeCustomColorFromPalette(tones, name) {
return {
name,
tones,
light: {
color: tones.getHct(40),
onColor: tones.getHct(100),
colorContainer: tones.getHct(90),
onColorContainer: tones.getHct(10)
},
dark: {
color: tones.getHct(80),
onColor: tones.getHct(20),
colorContainer: tones.getHct(30),
onColorContainer: tones.getHct(90)
}
};
}
const stateLayerOpacities = {
hover: .08,
focus: .12,
pressed: .12,
dragged: .16,
disabled: .12,
onDisabled: .38
};
function getStateColorMixParams(colorName, state, prefix = "") {
const opacity = stateLayerOpacities[state];
const isOnColor = colorName.startsWith("on-");
const actualOpacity = state === "disabled" && isOnColor ? stateLayerOpacities.onDisabled : opacity;
let baseColor;
let onColor;
if (isOnColor) {
baseColor = colorName.replace("on-", "");
onColor = colorName;
} else {
baseColor = colorName;
onColor = `on-${colorName}`;
}
return {
state,
baseColor: prefix ? `${prefix}${baseColor}` : baseColor,
onColor: prefix ? `${prefix}${onColor}` : onColor,
opacityPercent: Math.round(actualOpacity * 100)
};
}
function makeStateLayerColors(baseColor, onColor) {
return makeColorMix(hct(baseColor), hct(onColor), {
hover: stateLayerOpacities.hover,
focus: stateLayerOpacities.focus,
pressed: stateLayerOpacities.pressed,
dragged: stateLayerOpacities.dragged,
disabled: stateLayerOpacities.disabled,
onDisabled: stateLayerOpacities.onDisabled
});
}
function makeStateVariants(colors, onColors) {
const result = {};
for (const colorName in colors) {
const baseColor = colors[colorName];
const onColorKey = `on-${colorName}`;
const onColor = onColors[onColorKey];
if (!onColor) throw new Error(`Missing on-color for ${colorName}. Expected key: ${onColorKey}`);
const states = makeStateLayerColors(baseColor, onColor);
result[`${colorName}-hover`] = states.hover;
result[`${colorName}-focus`] = states.focus;
result[`${colorName}-pressed`] = states.pressed;
result[`${colorName}-dragged`] = states.dragged;
result[`${colorName}-disabled`] = states.disabled;
result[`on-${colorName}-disabled`] = states.onDisabled;
}
return result;
}
const hexColorPattern = /^#([\da-f]{3}|[\da-f]{6}|[\da-f]{8})$/i;
const isHexColor = (s = "") => !!hexColorPattern.test(s || "");
export { Colord, DynamicScheme, Hct, TonalPalette, Variant, argb, argbFromColord, argbFromHct, argbFromHctColor, argbFromRgbaColor, argbFromString, colorFormatter, colord, colordFromArgb, colordFromHct, colordFromHctColor, colordFromString, corePaletteKeys, defaultColors, formatCSSRules, formatCSSRulesArray, generateCSSRules, generateCSSRulesArray, getStateColorMixParams, hct, hctFromArgb, hctFromColord, hctFromRgbaColor, hctFromString, hexColorPattern, hexFromArgb, hexFromColord, hexFromHct, hexFromHctColor, hexString, hsl, hslFromArgb, hslFromColord, hslFromHct, hslFromHctColor, hslFromString, hslString, isHexColor, isObjectColor, makeColorMix, makeCustomColor, makeCustomColorFromPalette, makeStateLayerColors, makeStateVariants, makeTonalPalette, normalizeAlpha, rgbFromRgbaColor, rgba, rgbaFromHctColor, rgbaString, splitArgb, splitHct, stateLayerOpacities, withKnownColor, withNormalizedAlpha };
//# sourceMappingURL=index.mjs.map