@lorenzo.franzone/tws
Version:
Tailwind 4 Styles Generator
135 lines (134 loc) • 5.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.toKebabCase = void 0;
exports.pxToRem = pxToRem;
exports.processNestedObject = processNestedObject;
exports.processObject = processObject;
exports.convertToCSS = convertToCSS;
const clamp_1 = require("./clamp");
const logger_1 = require("./logger");
/**
* ==================================================
* toKebabCase
* ==================================================
* Converts a string to kebab-case.
* Replaces spaces, underscores, and special characters
* with hyphens while keeping only lowercase letters and numbers.
*/
const toKebabCase = (str) => str
.trim()
.toLowerCase()
.replace(/\s+|_+/g, '-')
.replace(/[^a-z0-9-]/g, '');
exports.toKebabCase = toKebabCase;
/**
* ==================================================
* pxToRem
* ==================================================
* Converts a value in pixels (px) to rem based on a given base value.
* Optionally, the result can include the 'rem' unit as a string or just
* return the numeric value.
*
* @param px - The value in pixels that needs to be converted to rem.
* @param base - The base value to convert pixels to rem (default is 16px).
* @param withUnit - A flag indicating whether to include the 'rem' unit in the result (default is false).
* @returns - The equivalent value in rem, either as a string with 'rem' unit or as a number.
*/
function pxToRem(px, base = 16, withUnit = false) {
if (px === 0)
return 0;
const remValue = px / base;
return withUnit
? `${parseFloat(remValue.toFixed(4)).toString()}rem`
: parseFloat(remValue.toFixed(4));
}
const warnedPaths = new Set();
function processNestedObject(obj, callback, prefix, maxDepth) {
function recurse(current, keyPath = []) {
const currentDepth = keyPath.length;
if (maxDepth !== undefined && currentDepth > maxDepth) {
const path = keyPath.join(".");
if (!warnedPaths.has(path)) {
(0, logger_1.logWarn)(`Skipping property at "${path}" - exceeded max depth (${maxDepth})`);
warnedPaths.add(path);
}
return undefined;
}
if (Array.isArray(current)) {
if (prefix && keyPath.length > 0) {
keyPath.splice(-1, 0, prefix);
}
const key = keyPath.join("-");
return { [key]: callback(current) };
}
else if (typeof current === "object" && current !== null) {
return Object.fromEntries(Object.entries(current).flatMap(([key, value]) => {
const kebabKey = (0, exports.toKebabCase)(key);
const newKeyPath = [...keyPath, kebabKey];
const result = recurse(value, newKeyPath);
return result && typeof result === "object"
? Object.entries(result)
: result !== undefined
? [[kebabKey, result]]
: [];
}));
}
return callback(current);
}
return recurse(obj);
}
/**
* ==================================================
* processObject
* ==================================================
* Processes an object, applying transformations to its values.
* If the value is an array of numbers, it applies a clamp function
* to ensure the values are within a defined range.
* This function uses the processNestedObject to process nested structures.
*
* @param data - The object to be processed.
* @returns The processed object with clamped values where necessary.
*/
function processObject(data) {
// Process the data and apply clamping to arrays of numbers
return processNestedObject(data, (value) => {
if (Array.isArray(value) &&
value.length > 0 &&
typeof value[0] === 'number') {
// Apply the clamp function to arrays of numbers
return (0, clamp_1.clamp)(value);
}
return value; // Return the value unmodified if it's not an array of numbers
});
}
function convertToCSS(arr) {
let cssOutput = '';
function processObject(obj, indentLevel) {
Object.keys(obj).forEach((key) => {
const value = obj[key];
const indent = ' '.repeat(indentLevel);
if (typeof value === 'object') {
cssOutput += `${indent}${key} {\n`;
processObject(value, indentLevel + 2);
cssOutput += `${indent}}\n`;
}
else {
cssOutput += `${indent}${key}: ${value};\n`;
}
});
}
arr.forEach((item) => {
if (typeof item === 'string') {
// Se l'elemento è una stringa, aggiungila direttamente al CSS
cssOutput += `${item}\n`;
}
else {
Object.keys(item).forEach((key) => {
cssOutput += `${key} {\n`;
processObject(item[key], 2);
cssOutput += '}\n';
});
}
});
return cssOutput;
}