UNPKG

@poupe/theme-builder

Version:

Design token management and theme generation system for Poupe UI framework

441 lines (440 loc) 14.4 kB
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