UNPKG

@uinamic/colors

Version:

CSS color token generator centered on HSL lightness (HSL 기반 명도 중심 CSS 색상 토큰 생성기)

194 lines (187 loc) 6.58 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.js var index_exports = {}; __export(index_exports, { generateColorTokens: () => generateColorTokens }); module.exports = __toCommonJS(index_exports); var import_fs = __toESM(require("fs"), 1); // src/logic/spectrum.js function getFullSpectrumFromCenter(centerL, limit = 5) { const splitRange = centerL <= 22 || centerL >= 78; const getLimit = getDynamicLimit(splitRange, limit); const maxL = 100 - getLimit; const isLowRange = centerL <= 50; const lowRange = isLowRange ? centerL - getLimit : maxL - centerL; const highRange = isLowRange ? maxL - centerL : centerL - getLimit; if (splitRange) { const lowRange2 = isLowRange ? centerL - getLimit : maxL - centerL; const highRange2 = lowRange2 * 4; const result = calculateSpectrum(centerL, lowRange2, highRange2, isLowRange); return result; } else { const result = calculateSpectrum(centerL, lowRange, highRange, isLowRange); return result; } } function getDynamicLimit(splitRange, defaultLimit = 5) { if (splitRange) return 3; return defaultLimit; } function calculateSpectrum(centerL, lowRange, highRange, isLowRange) { let lowBias = Math.floor(lowRange * 0.1); lowBias += (lowRange - lowBias) % 4; const lowDelta = lowRange - lowBias; let highBias = Math.floor(highRange * 0.1); highBias += (highRange - highBias) % 4; const highDelta = highRange - highBias; let lowSteps; let lowValues; let highSteps; let highValues; if (isLowRange) { lowSteps = smartLowBias(lowBias).map((w) => lowDelta / 4 + w); lowValues = accumulateReverse(centerL, lowSteps); highSteps = smartHighBias(highBias).map((w) => highDelta / 4 + w).reverse(); highValues = accumulate(centerL, highSteps); } else { lowSteps = smartLowBias(lowBias).map((w) => lowDelta / 4 + w).reverse(); lowValues = accumulate(centerL, lowSteps); highSteps = smartHighBias(highBias).map((w) => highDelta / 4 + w); highValues = accumulateReverse(centerL, highSteps); } const spectrum = [.../* @__PURE__ */ new Set([...lowValues, ...highValues])].sort((a, b) => a - b); return spectrum; } function smartLowBias(total) { const result = [0, 0, 0, 0]; for (let i = 0; i < total; i++) { const index = 3 - i % 4; result[index]++; } return result; } function smartHighBias(n) { const result = [0, 0, 0, 0]; const weights = [3, 2, 1, 0]; for (let i = 0; i < n; i++) { const idx = weights[i % 4]; result[idx]++; } return result; } function accumulate(start, steps) { return steps.reduce( (acc, curr) => { const last = acc[acc.length - 1]; return [...acc, +(last + curr).toFixed(1)]; }, [start] ); } function accumulateReverse(end, steps) { return steps.reduceRight( (acc, curr) => { const next = acc[0]; return [+(next - curr).toFixed(1), ...acc]; }, [end] ); } // src/logic/writeCss.js function writeCss(map, spectrumFn, options = {}) { const { format = "css", prefix = "--color-", limit = 5 } = options; const baseColors = [` ${prefix}black: hsl(0, 0%, 0%);`, ` ${prefix}white: hsl(0, 0%, 100%);`]; const baseColorsBlock = baseColors.join("\n"); const groupBlocks = []; const groupFlatJson = {}; for (const [name, [h, s, l]] of Object.entries(map)) { const ramp = spectrumFn(l, limit); const group = ramp.map((lightness, i) => { const level = (i + 1) * 100; const key = `${name}-${level}`; const value = `hsl(${h}, ${s}%, ${lightness}%)`; if (format === "json") { groupFlatJson[key] = value; return null; } return ` ${prefix}${key}: ${value};`; }).filter(Boolean); groupBlocks.push(group.join("\n")); } if (format === "json") { return JSON.stringify(groupFlatJson, null, 2); } if (format === "scss") { return [baseColorsBlock, "", ...groupBlocks].join("\n\n"); } return `:root { ${baseColorsBlock} ${groupBlocks.join("\n\n")} }`; } // src/colorMap.js var defaultColorHSLMap = { red: [0, 100, 50], blue: [240, 100, 50], yellow: [60, 100, 50], orange: [39, 100, 50], green: [120, 100, 40], purple: [270, 100, 60], pink: [340, 100, 88], teal: [180, 100, 45], gray: [0, 0, 50], darkgray: [0, 0, 30], lightgray: [0, 0, 70], coral: [16, 100, 65], mint: [160, 100, 50], cyan: [190, 100, 60], violet: [290, 76, 72], indigo: [225, 100, 45], amber: [45, 100, 50] }; // src/index.js function generateColorTokens(map = defaultColorHSLMap, options = {}) { const { format = "css", name = "uinamic-color", path: outputPath = "./theme", prefix = "color", limit = 5 } = options; const resolvedPrefix = format === "scss" ? `$${prefix}-` : `--${prefix}-`; const content = writeCss(map, getFullSpectrumFromCenter, { format, prefix: resolvedPrefix, limit }); const ext = format === "json" ? "json" : format === "scss" ? "scss" : "css"; const filePath = `${outputPath}/${name}.${ext}`; import_fs.default.mkdirSync(outputPath, { recursive: true }); import_fs.default.writeFileSync(filePath, content, "utf-8"); return content; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { generateColorTokens });