import { customElement, noShadowDOM } from "solid-element"; import { onCleanup } from "solid-js"; import { registerStyle } from "./utils/article-style-manager"; export interface FontProps { /** Font source: "google" (Google Fonts), "emfont" (emtech.cc), * or "local" (already loaded, just set fontFamily) */ source?: "google" | "emfont" | "local"; /** Font weight (for google and emfont sources) */ weight?: string; /** Font color (CSS color value, e.g. #ff00dd, rgb(255,0,0)) */ color?: string; } function buildLinkHref( font: string, source: FontProps["source"], weight: string, ): string | null { if (source === "google") { const family = font.replace(/\s+/g, "+"); return `https://fonts.googleapis.com/css2?family=${family}:wght@${weight}&display=swap`; } if (source === "emfont") { return `https://font.emtech.cc/css/${font}?weight=${weight}`; } return null; } customElement( "md-font", { source: "local", weight: "400", color: undefined }, (props, { element }) => { noShadowDOM(); const font = element?.textContent?.trim() || ""; // Hide original text content if (element) { element.textContent = ""; } const articleEl = element?.closest("article") as HTMLElement; if (!articleEl) return null; const source = (props.source as FontProps["source"]) || "google"; const weight = props.weight || "400"; const href = buildLinkHref(font, source, weight); const links = href ? [{ href, dataset: { mdFontSource: source, mdFontName: font } }] : []; const styles: Partial = { fontFamily: `"${font}", sans-serif`, } as any; if (props.color) { (styles as any).color = props.color; } const handle = registerStyle({ key: "fontFamily", article: articleEl, styles, links, }); onCleanup(() => handle.dispose()); return null; }, );