74 lines
1.9 KiB
TypeScript
74 lines
1.9 KiB
TypeScript
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<CSSStyleDeclaration> = {
|
|
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;
|
|
},
|
|
);
|