@thangk/easythemer
Version:
Easily generate shades from a colour palette for use in your app
153 lines (152 loc) • 6.93 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.mergeObjects = exports.generateShades = exports.merger = void 0;
const constants_1 = require("./constants");
const converters_1 = require("./converters");
const validators_1 = require("./validators");
function limiter(input, limitStringArray) {
const mode = limitStringArray.split("-")[0];
const limit = parseInt(limitStringArray.split("-")[1]);
// for max mode
if (mode === "max")
return input > limit ? limit : input;
if (mode === "min")
return input < limit ? limit : input;
// for neither mode
return input;
}
function getChannelValue({ shadeMultiplier, HSL_channel, HSL_letter, workingObj }) {
const { upperboundDivider, lowerboundDivider, upperboundPadding, lowerboundPadding } = workingObj;
let HSL_letter_MAX;
switch (HSL_letter) {
case "h":
HSL_letter_MAX = constants_1._HSL.MAX_H;
break;
case "s":
HSL_letter_MAX = constants_1._HSL.MAX_S;
break;
case "l":
HSL_letter_MAX = constants_1._HSL.MAX_L;
break;
default:
HSL_letter_MAX = 0;
break;
}
const upperbound = HSL_letter_MAX - HSL_channel;
const lowerbound = HSL_channel;
const upperboundStep = upperboundDivider && upperboundPadding ? Math.round((upperbound / upperboundDivider) * upperboundPadding) : 0;
const lowerboundStep = lowerboundDivider && lowerboundPadding ? Math.round((lowerbound / lowerboundDivider) * lowerboundPadding) : 0;
if (shadeMultiplier > 0)
HSL_channel = limiter(HSL_channel + upperboundStep * shadeMultiplier, `max-${HSL_letter_MAX - 5}`);
if (shadeMultiplier < 0)
HSL_channel = limiter(HSL_channel + lowerboundStep * shadeMultiplier, `min-${0 + 15}`);
return HSL_channel;
}
function merger(customOptions, defaultOptions) {
const customOptionsKeys = Object.keys(customOptions);
const defaultOptionsKeys = Object.keys(defaultOptions);
// look for same keys to check if they're both the same object type (not the best method but for this 1 case it works)
const hasSameKeys = customOptionsKeys.every((key) => {
if (defaultOptionsKeys.includes(key))
return true;
});
if (hasSameKeys)
return { ...defaultOptions, ...customOptions };
const mergedOptions = {};
for (const key in customOptions) {
mergedOptions[key] = { ...constants_1.defaultThemeOption, ...customOptions[key] };
}
return mergedOptions;
}
exports.merger = merger;
function getBoundSteps2(HSLInput, inputThemeOption, shadeMultiplier) {
const hslArray = ["h", "s", "l"];
let hslArrayIndex = 0;
for (const [key, value] of Object.entries(inputThemeOption)) {
if (key === `params_${hslArray[hslArrayIndex]}`) {
// if useDefault is true, then use the defaultThemeParams
if (value.useDefault) {
HSLInput[hslArray[hslArrayIndex]] = getChannelValue({
shadeMultiplier,
HSL_channel: HSLInput[hslArray[hslArrayIndex]],
HSL_letter: hslArray[hslArrayIndex],
workingObj: constants_1.defaultThemeParams,
});
}
}
// if useDefault is false, then use the inputThemeOption params
if (value.useDefault === false) {
const mergedParams = Object.assign(constants_1.defaultThemeParams, value.params);
HSLInput[hslArray[hslArrayIndex]] = getChannelValue({
shadeMultiplier,
HSL_channel: HSLInput[hslArray[hslArrayIndex]],
HSL_letter: hslArray[hslArrayIndex],
workingObj: mergedParams,
});
}
hslArrayIndex++;
}
return HSLInput;
}
function getBoundSteps({ h, s, l }, inputThemeOption, shadeMultiplier) {
if (inputThemeOption.params_h?.useDefault === false) {
const params = inputThemeOption.params_s?.params;
const workingObj = Object.assign(constants_1.defaultThemeParams, params);
h = getChannelValue({ shadeMultiplier, HSL_channel: h, HSL_letter: "h", workingObj });
}
if (inputThemeOption.params_s?.useDefault === false) {
const params = inputThemeOption.params_s?.params;
const workingObj = Object.assign(constants_1.defaultThemeParams, params);
s = getChannelValue({ shadeMultiplier, HSL_channel: s, HSL_letter: "s", workingObj });
}
if (inputThemeOption.params_l?.useDefault === false) {
const params = inputThemeOption.params_l?.params;
const workingObj = Object.assign(constants_1.defaultThemeParams, params);
l = getChannelValue({ shadeMultiplier, HSL_channel: l, HSL_letter: "l", workingObj });
}
if (inputThemeOption.params_h?.useDefault === true || undefined) {
h = getChannelValue({ shadeMultiplier, HSL_channel: h, HSL_letter: "h", workingObj: constants_1.defaultThemeParams });
}
if (inputThemeOption.params_s?.useDefault === true || undefined) {
s = getChannelValue({ shadeMultiplier, HSL_channel: s, HSL_letter: "s", workingObj: constants_1.defaultThemeParams });
}
if (inputThemeOption.params_l?.useDefault === true || undefined) {
l = getChannelValue({ shadeMultiplier, HSL_channel: l, HSL_letter: "l", workingObj: constants_1.defaultThemeParams });
}
return { h, s, l };
}
function generateShades(input, shades) {
let shadeSet = {};
const { hex, generateShades } = input;
if (!generateShades)
return { normal: hex };
if (!shades)
shades = constants_1.defaultShadeMultipliers;
for (const [key, value] of Object.entries(shades)) {
if (!value) {
const { h, s, l } = (0, converters_1.HexToHSL)(hex);
shadeSet[key] = hex;
continue;
}
const { h, s, l } = getBoundSteps((0, converters_1.HexToHSL)(hex), input, value);
shadeSet[key] = (0, converters_1.HSLToHex)({ h, s, l });
}
return shadeSet;
}
exports.generateShades = generateShades;
function mergeObjects(object1, object2) {
if (!object2)
return;
const workingObject = structuredClone(object1);
for (const key of Object.keys(workingObject)) {
const isValueAnObject = new validators_1.ValidateIsObject(workingObject[key][0]);
const valueKeysLen = Object.keys(workingObject[key]).length;
if (valueKeysLen && isValueAnObject.getResult) {
workingObject[key] = mergeObjects(workingObject[key], object2[key]);
continue;
}
workingObject[key] = object2[key] ?? workingObject[key];
}
return workingObject;
}
exports.mergeObjects = mergeObjects;