UNPKG

@faire/mjml-react

Version:

React component library to generate the HTML emails on the fly

67 lines (66 loc) 2.14 kB
import kebabCase from "lodash.kebabcase"; const DANGEROUSLY_SET_INNER_HTML = "dangerouslySetInnerHTML"; export function convertPropsToMjmlAttributes(props) { const mjmlProps = Object.entries(props).reduce((mjmlProps, [prop, value]) => { const mjmlProp = prop === DANGEROUSLY_SET_INNER_HTML ? prop : kebabCase(prop); const mjmlValue = convertPropValueToMjml(mjmlProp, value); if (mjmlValue === undefined || prop === "className") { return mjmlProps; } if (prop === "mjmlClass") { mjmlProps["mj-class"] = mjmlValue; } else { mjmlProps[mjmlProp] = mjmlValue; } return mjmlProps; }, {}); // className is a special prop used extensively in react in place of the html class attribute. // mjml uses a different name (css-class) for the same thing. const className = props.className; if (typeof className === "string") { mjmlProps["css-class"] = typeof mjmlProps["css-class"] === "string" ? joinClassNames(mjmlProps["css-class"], className) : className; } return mjmlProps; } const booleanToString = ["inline", "full-width", "fluid-on-mobile"]; const numberToPixel = [ "width", "height", "border-radius", "border-width", "background-size", "padding", "padding-top", "padding-right", "padding-bottom", "padding-left", "font-size", "letter-spacing", "line-height", "icon-padding", "text-padding", "inner-padding", ]; function convertPropValueToMjml(name, value) { // This assumes that all numbers will be pixels which might not always be the case if (typeof value === "number" && numberToPixel.includes(name)) { return `${value}px`; } if (typeof value === "boolean" && booleanToString.includes(name)) { return name; } if (typeof value === "object" && value !== null) { return value; } if (typeof value === "string") { return value; } return; } function joinClassNames(...classNames) { return classNames.join(" ").trim(); }