UNPKG

react-style-stringify

Version:

A utility for converting React CSSProperties and style maps into CSS strings, designed to simplify the management of inline styles in HTML email templates and React projects.

91 lines (88 loc) 3.37 kB
// src/helpers.ts import unitless from "@emotion/unitless"; var DEFAULT_UNIT = "px"; var isCSSPropertyValue = (value) => typeof value === "number" || typeof value === "string"; function camelToKebab(str) { return str.replace(/[A-Z]/g, (match) => `-${match.toLowerCase()}`); } function trimCssSelector(selector) { return selector.replace(/\s*([+~>])\s*/g, "$1").replace(/\s{2,}/g, " ").trim(); } function applyCssUnits(property, value, unit = DEFAULT_UNIT) { if (typeof value !== "string" && typeof value !== "number") { throw new Error( "Invalid input: value of 'cssProperties' must be string or number." ); } const isUnitless = unitless[property] === 1; if (typeof value === "string" || value === 0 || isUnitless) { return `${value}`; } const resolvedUnit = (typeof unit === "string" ? unit : unit[property]) || DEFAULT_UNIT; return `${value}${resolvedUnit}`; } // src/stringifyStyleDeclaration.ts function stringifyStyleDeclaration(styleDeclaration, options) { if (typeof styleDeclaration !== "object" || styleDeclaration === null) { throw new TypeError( `[stringifyStyleDeclaration]: Expected 'styleDeclaration' to be a non-null object, but received ${styleDeclaration} (type:${typeof styleDeclaration}).` ); } const importantSuffix = options?.important ? "!important" : ""; return Object.entries(styleDeclaration).filter(([_, value]) => isCSSPropertyValue(value)).map( ([property, value]) => `${camelToKebab(property)}:${applyCssUnits( property, value, options?.unit )}${importantSuffix};` ).join(""); } // src/stringifyStyleRule.ts function stringifyStyleRule(styleRule, options) { if (typeof styleRule !== "object" || styleRule === null) { throw new TypeError( `[stringifyStyleRule]: Expected 'styleRule' to be a non-null object, but received ${styleRule} (type:${typeof styleRule}).` ); } return Object.entries(styleRule).reduce((result, [selector, declaration]) => { if (Object.keys(declaration).length > 0) { result.push( `${trimCssSelector(selector)}{${stringifyStyleDeclaration( declaration, options )}}` ); } return result; }, []).join(""); } // src/stringify-react-styles.ts function stringifyCSSProperties(cssProperties, optionsOrImportant = false) { if (typeof cssProperties !== "object" || cssProperties === null) { throw new TypeError( `[stringifyCSSProperties]: Expected 'cssProperties' to be a non-null object, but received ${cssProperties} (type:${typeof cssProperties}).` ); } const options = typeof optionsOrImportant === "boolean" ? { important: optionsOrImportant } : optionsOrImportant; return stringifyStyleDeclaration(cssProperties, options); } function stringifyStyleMap(styleMap, optionsOrImportant = false) { if (typeof styleMap !== "object" || styleMap === null) { throw new TypeError( `[stringifyStyleMap]: Expected 'styleMap' to be a non-null object, but received ${styleMap} (type:${typeof styleMap}).` ); } const options = typeof optionsOrImportant === "boolean" ? { important: optionsOrImportant } : optionsOrImportant; return stringifyStyleRule(styleMap, options); } export { stringifyCSSProperties, stringifyStyleDeclaration, stringifyStyleMap, stringifyStyleRule }; //# sourceMappingURL=index.mjs.map