@blacksquareui/compiler
Version:
This is a package for creating css file from classes
162 lines • 7.78 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.forTesting = exports.createCSSBundle = void 0;
const node_fs_1 = require("node:fs");
const node_path_1 = __importDefault(require("node:path"));
const utils_1 = require("./utils");
const createCSSBundle = (config) => __awaiter(void 0, void 0, void 0, function* () {
const { sourceDir, outputFile } = config.content;
const css = yield createCSS(config);
(0, node_fs_1.writeFileSync)(`${sourceDir}/${outputFile}`, css);
});
exports.createCSSBundle = createCSSBundle;
const createCSS = (config) => __awaiter(void 0, void 0, void 0, function* () {
const { sourceDir, fileExtension } = config.content;
const allFilesContent = yield readTextFromDir(sourceDir, fileExtension);
const classNames = yield collectClasses(allFilesContent);
return createRootStyles(config.props) + createClassStyles(classNames, config);
});
const collectClasses = (text) => __awaiter(void 0, void 0, void 0, function* () {
const regex = /className=(?:"([^"]+)"|'([^']+)'|\{([^}]+)\})/g;
return (0, utils_1.getUniqueItems)(Array.from(text.matchAll(regex))
.map((match) => match.slice(1).find(Boolean))
.filter(Boolean)
.flatMap(extractStaticClasses));
});
const extractStaticClasses = (className) => className ? className.split(" ") : [];
const walkSync = (dir) => {
if (!(0, node_fs_1.existsSync)(dir))
return [];
const files = (0, node_fs_1.readdirSync)(dir, { withFileTypes: true });
return [].concat(files
.map(file => file.isDirectory() ? walkSync(node_path_1.default.join(dir, file.name)) : [node_path_1.default.join(dir, file.name)])
.flat());
};
const readTextFromDir = (dir, fileExtension) => __awaiter(void 0, void 0, void 0, function* () {
const haveExtension = (filePath) => filePath.includes(fileExtension);
const combineFilesContents = (acc, filePath) => acc += (0, node_fs_1.readFileSync)(filePath, 'utf-8');
return walkSync(dir)
.filter(haveExtension)
.reduce(combineFilesContents, "");
});
const createRootStyles = (props) => `:root{${props.map(({ name, val, type }) => `--${name}: ${val}${type === 'range' ? 'rem' : ''};`).join('')}}`;
const createRangeStyles = (className, props) => {
const [property, multiplier] = className.includes("_") ? className.split("_") : [className];
const classProps = getPropByClassName(className, props);
const pos = getDirectionFromClassName(property, props);
if (!classProps || pos === false)
return "";
return `.${className} {${classProps.property}${pos}:calc(var(--oo-${classProps.name})${multiplier ? ` * ${multiplier}` : ""});}`;
};
const createColorStyles = (className, props) => {
const { property, name } = getPropByClassName(className, props);
return `.${className} {${property}:var(--oo-${name});}`;
};
const getClassesByPrefix = (classNames, prefix) => classNames.filter(c => c.includes(prefix));
const processEEClass = (className) => {
if (!className.includes("_"))
return "";
const [name, prop] = className.split("_");
return `.${className}{${name.split("ee-")[1]}:${parseInt(prop) ? prop + "rem" : prop}}`;
};
const processOOClass = (props) => (className) => {
const prop = getPropByClassName(className, props);
const createStylesByType = {
range: createRangeStyles,
color: createColorStyles
};
return prop ? createStylesByType[prop.type](className, props) : "";
};
const getStyleTypeOrDefault = (styleType, defaultType) => styleType || defaultType;
const processOEClass = (className) => {
const classNameWithoutPrefix = removePrefix(className);
const [prop, styleType] = classNameWithoutPrefix.split("-");
const styleTypeOrDefault = getStyleTypeOrDefault(styleType, "primary");
return (0, utils_1.removeSpaces)(`.oe-${prop}-${styleTypeOrDefault}:${prop}{
color:var(--oo-background-color-${styleTypeOrDefault});
background-color:var(--oo-text-color-${styleTypeOrDefault})
}`);
};
const addSeparator = (className) => className + "__";
const withoutMediaClass = (className) => className.replace(/.*__/, "");
const getClassType = (className) => ["oo", "oe", "ee"].reduce((acc, type) => className.includes(type) ? acc + type : acc, "");
const addMediaPrefixToClassName = (className, mediaPrefix) => className.split(".").join(mediaPrefix);
const createClassInsideMediaScreen = (size, cssClass) => `@media only screen and (max-width: ${size}) {.${cssClass}}`;
const processThoughtMediaClasses = (className, { screens, props }) => {
if (!isValidClassName(className, props))
return "";
return screens.reduce((acc, { name, size }) => {
const withSeparator = addSeparator(name);
if (className.includes(withSeparator)) {
const classWithoutMediaPrefix = withoutMediaClass(className);
const cssClass = addMediaPrefixToClassName(processClassName(classWithoutMediaPrefix, props), withSeparator);
return acc + createClassInsideMediaScreen(size, cssClass);
}
return acc + processClassName(className, props);
}, "");
};
const processClassName = (className, props) => {
const classType = getClassType(className);
if (!classType)
return "";
const classTypeProcessors = {
oe: processOEClass,
oo: processOOClass(props),
ee: processEEClass
};
return classTypeProcessors[classType](className) || "";
};
const isValidClassName = (className, props) => {
const classType = getClassType(className);
if (!className || !classType)
return false;
if (classType === "oo") {
if (!getPropByClassName(className, props))
return false;
}
return true;
};
const createClassStyles = (classNames, config) => classNames.reduce((acc, className) => acc + processThoughtMediaClasses(className, config), "");
const removePrefix = (className) => className.replace(/^ee-|oo-|oe-/, "");
const getPropByClassName = (className, props) => props.find(cl => className.includes(cl.name));
const getDirectionFromClassName = (className, props) => {
const classNameWithoutPrefix = removePrefix(className);
const classProps = getPropByClassName(classNameWithoutPrefix, props);
const pos = classProps.direction.filter((dir) => classProps.property + dir === classNameWithoutPrefix);
return (0, utils_1.arrCount)(pos) === 1 ? pos[0] : false;
};
exports.forTesting = {
getClassType,
processThoughtMediaClasses,
createCSS,
extractStaticClasses,
collectClasses,
createColorStyles,
createRootStyles,
createClassStyles,
removePrefix,
getPropByClassName,
getDirectionFromClassName,
createCSSBundle,
readTextFromDir,
walkSync,
createRangeStyles,
getClassesByPrefix,
processEEClass,
processClassName,
processOEClass,
processOOClass
};
//# sourceMappingURL=styleProcessor.js.map