UNPKG

@maizzle/framework

Version:

Maizzle is a framework that helps you quickly build HTML emails with Tailwind CSS.

92 lines (91 loc) 3.28 kB
import { RenderContextKey } from "./renderContext.js"; import { inject } from "vue"; //#region src/composables/useFont.ts const FAMILY_CATEGORIES = { "Roboto": "sans", "Open Sans": "sans", "Inter": "sans", "Lato": "sans", "Montserrat": "sans", "Merriweather": "serif", "Playfair Display": "serif", "Lora": "serif", "PT Serif": "serif", "Noto Serif": "serif", "Oswald": "display", "Bebas Neue": "display", "Anton": "display", "Lobster": "display", "Pacifico": "display", "Dancing Script": "handwriting", "Caveat": "handwriting", "Shadows Into Light": "handwriting", "Satisfy": "handwriting", "Great Vibes": "handwriting", "Roboto Mono": "mono", "Source Code Pro": "mono", "JetBrains Mono": "mono", "Fira Code": "mono", "Inconsolata": "mono" }; const DEFAULT_FALLBACKS = { sans: "ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif", serif: "ui-serif, Georgia, Cambria, \"Times New Roman\", Times, serif", mono: "ui-monospace, Menlo, Consolas, monospace", display: "Impact, \"Arial Black\", system-ui, sans-serif", handwriting: "\"Segoe Script\", \"Brush Script MT\", cursive" }; const PROVIDER_BASE_URL = { google: "https://fonts.googleapis.com/css2", bunny: "https://fonts.bunny.net/css2" }; function slugify(family) { return family.trim().toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9-]/g, ""); } function buildProviderUrl(opts) { const familyParam = opts.family.trim().replace(/\s+/g, "+"); const weights = [...opts.weights].sort((a, b) => a - b); const hasItalic = opts.styles.includes("italic"); const hasNormal = opts.styles.includes("normal"); const axis = hasItalic ? `:ital,wght@${weights.flatMap((w) => [...hasNormal ? [`0,${w}`] : [], `1,${w}`]).join(";")}` : `:wght@${weights.join(";")}`; return `${PROVIDER_BASE_URL[opts.provider]}?family=${familyParam}${axis}&display=${opts.display}`; } /** * Register a font for the current email template. * * Builds a Google Fonts stylesheet URL from `family`/`weights`/`display`/`styles` * (or uses `url` as-is). The renderer injects a `<link>` tag into `<head>` * and merges `--font-{slug}` declarations into the template's existing * `@import "tailwindcss"` style block so a `font-{slug}` utility class * is generated. If no Tailwind import is found, falls back to a `:root` * declaration so the CSS variable is still available. * * Usage in SFC <script setup>: * ```ts * useFont({ family: 'Roboto', fallback: 'Verdana, sans-serif', weights: [400, 600] }) * ``` */ function useFont(options) { const ctx = inject(RenderContextKey); if (!ctx) return; ctx.fonts = ctx.fonts ?? []; if (ctx.fonts.some((f) => f.family === options.family)) return; const url = options.url ?? buildProviderUrl({ family: options.family, provider: options.provider ?? "google", weights: options.weights ?? [400], display: options.display ?? "swap", styles: options.styles ?? ["normal"] }); const fallback = options.fallback ?? DEFAULT_FALLBACKS[FAMILY_CATEGORIES[options.family] ?? "sans"]; const declaration = `${/\s/.test(options.family) ? `"${options.family}"` : options.family}, ${fallback}`; ctx.fonts.push({ family: options.family, slug: slugify(options.family), declaration, url }); } //#endregion export { useFont }; //# sourceMappingURL=useFont.js.map