diff --git a/packages/mint-components/src/global/global.ts b/packages/mint-components/src/global/global.ts index d7881902e..37ac185bd 100644 --- a/packages/mint-components/src/global/global.ts +++ b/packages/mint-components/src/global/global.ts @@ -133,10 +133,10 @@ import { insertCSS } from "../insertcss"; import { insertFont } from "../insertfont"; import { parseBrandingConfig } from "./styles"; -const applyStyles = (css: string, font: string) => { +const applyStyles = (css: string, font: string, customFontUrl?: string) => { try { insertCSS(css); - insertFont(font); + insertFont(font, customFontUrl); } catch (error) { debug(error); } @@ -147,10 +147,14 @@ if (getEnvironmentSDK().type === "None") { if (!data?.brandingConfig) return; window.SquatchBrandingConfig = data.brandingConfig; - const { styles, font } = parseBrandingConfig(data.brandingConfig); - applyStyles(styles, font); + const { styles, font, customFontUrl } = parseBrandingConfig( + data.brandingConfig + ); + applyStyles(styles, font, customFontUrl); }); } -const { styles, font } = parseBrandingConfig(window.SquatchBrandingConfig); -applyStyles(styles, font); +const { styles, font, customFontUrl } = parseBrandingConfig( + window.SquatchBrandingConfig +); +applyStyles(styles, font, customFontUrl); diff --git a/packages/mint-components/src/global/styles.ts b/packages/mint-components/src/global/styles.ts index 38637a4ea..8aec93f87 100644 --- a/packages/mint-components/src/global/styles.ts +++ b/packages/mint-components/src/global/styles.ts @@ -1064,4 +1064,5 @@ sl-icon::part(base):hover { `, font: config?.main?.brandFont, + customFontUrl: config?.main?.customFontUrl, }); diff --git a/packages/mint-components/src/insertfont.ts b/packages/mint-components/src/insertfont.ts index ab37be712..b12f1ae7a 100644 --- a/packages/mint-components/src/insertfont.ts +++ b/packages/mint-components/src/insertfont.ts @@ -1,21 +1,63 @@ import { buildFontsCssUrl } from "./fonts/GoogleFonts"; -export function insertFont(font: string) { +const STYLESHEET_ID = "brandFontStylesheet"; + +function inferFontFormat(url: string): string | undefined { + const ext = url.split("?")[0].split("#")[0].split(".").pop()?.toLowerCase(); + if (ext === "woff2") return "woff2"; + if (ext === "woff") return "woff"; + if (ext === "ttf") return "truetype"; + if (ext === "otf") return "opentype"; + return undefined; +} + +function buildFontFaceCss(family: string, url: string): string { + const format = inferFontFormat(url); + const src = format + ? `url("${url}") format("${format}")` + : `url("${url}")`; + return `@font-face { font-family: "${family}"; src: ${src}; font-display: swap; }`; +} + +function removeExisting(container: HTMLElement) { + const existing = container.querySelector(`#${STYLESHEET_ID}`); + if (existing) container.removeChild(existing); +} + +export function insertFont(font: string, customFontUrl?: string) { if (font === undefined) { throw new Error("insert-font: No font was provided"); } const container = document.querySelector("head"); - const url = buildFontsCssUrl(font); - const existingLink = container.querySelector(`link#brandFontStylesheet`); + if (customFontUrl) { + const css = buildFontFaceCss(font, customFontUrl); + const existing = container.querySelector( + `style#${STYLESHEET_ID}` + ) as HTMLStyleElement | null; + if (existing && existing.textContent === css) return; + + removeExisting(container); + + const style = document.createElement("style"); + style.setAttribute("id", STYLESHEET_ID); + style.textContent = css; + container.appendChild(style); + return; + } + + const url = buildFontsCssUrl(font); + const existingLink = container.querySelector( + `link#${STYLESHEET_ID}` + ) as HTMLLinkElement | null; if (existingLink?.getAttribute("href") === url) return; - if (existingLink) container.removeChild(existingLink); + removeExisting(container); const link = document.createElement("link"); link.setAttribute("rel", "stylesheet"); link.setAttribute("href", url); - link.setAttribute("id", "brandFontStylesheet"); + link.setAttribute("id", STYLESHEET_ID); container.appendChild(link); } diff --git a/packages/mint-components/src/saasquatch.d.ts b/packages/mint-components/src/saasquatch.d.ts index 77d06a0da..f41433220 100644 --- a/packages/mint-components/src/saasquatch.d.ts +++ b/packages/mint-components/src/saasquatch.d.ts @@ -213,6 +213,7 @@ export interface BrandingConfiguration { main?: { brandColor?: string; brandFont?: string; + customFontUrl?: string; }; color?: { backgroundColor?: string;