@maizzle/framework
Version:
Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.
45 lines (44 loc) • 1.9 kB
JavaScript
import { decodeStyleEntities } from "../utils/decodeStyleEntities.js";
//#region src/render/injectFonts.ts
const TAILWIND_IMPORT_RE = /((@import|@reference)\s+["'](tailwindcss|@maizzle\/tailwindcss)|@tailwind\s)/;
function getText(el) {
return (el.children || []).filter((c) => c.type === "text").map((c) => c.data).join("");
}
/**
* Inject font `<link>` tags into `<head>` and merge `@theme` declarations
* into the template's existing Tailwind `<style>` block (so the
* `font-{slug}` utilities are generated in the same compilation unit
* as the Tailwind import). Without a Tailwind import, emits plain
* `.font-{slug}` class rules so the utility still works.
*/
function injectFonts(dom, fonts, parseDom, walk) {
if (!fonts.length) return;
let head;
let tailwindStyle;
walk(dom, (node) => {
const el = node;
if (!el.name) return;
if (el.name === "head" && !head) head = el;
if (el.name === "style" && !tailwindStyle && TAILWIND_IMPORT_RE.test(decodeStyleEntities(getText(el)))) tailwindStyle = el;
});
if (!head) return;
const linkNodes = parseDom(fonts.map((f) => `<link href="${f.url}" rel="stylesheet" media="screen">`).join(""));
for (const child of linkNodes) child.parent = head;
head.children = [...head.children || [], ...linkNodes];
if (tailwindStyle) {
const themeDecls = fonts.map((f) => ` --font-${f.slug}: ${f.declaration};`).join("\n");
const existing = getText(tailwindStyle);
tailwindStyle.children = [{
type: "text",
data: `${existing}\n@theme {\n${themeDecls}\n}\n`,
parent: tailwindStyle
}];
} else {
const styleNodes = parseDom(`<style>\n${fonts.map((f) => `.font-${f.slug} { font-family: ${f.declaration}; }`).join("\n")}\n</style>`);
for (const child of styleNodes) child.parent = head;
head.children = [...head.children || [], ...styleNodes];
}
}
//#endregion
export { injectFonts };
//# sourceMappingURL=injectFonts.js.map