nimiq-vitepress-theme
Version:
Nimiq UI theme for VitePress
36 lines (35 loc) • 1.48 kB
JavaScript
import { icons } from "@iconify-json/vscode-icons";
import { encodeSvgForCss, getIconData, iconToHTML, iconToSVG } from "@iconify/utils";
import { builtinIcons } from "./builtin-icons.mjs";
export async function generateCSS(labels) {
const mergedIcons = { ...builtinIcons };
const matched = getMatchedLabels(labels, mergedIcons);
const css = await generateIconCSS(matched);
return { css };
}
function getMatchedLabels(labels, icons2) {
const matched = {};
const sortedKeys = Object.keys(icons2).sort((a, b) => b.length - a.length);
for (const label of labels) {
const key = sortedKeys.find((k) => label?.toLowerCase().includes(k));
if (key) {
matched[icons2[key]] = (matched[icons2[key]] || []).concat(label);
}
}
return matched;
}
async function generateIconCSS(matched) {
const iconCSS = await Promise.all(Object.entries(matched).map(async ([icon, labels]) => {
const [, iconName] = icon.split(":");
const iconData = getIconData(icons, iconName);
if (!iconData)
throw new Error(`Icon not found: ${iconName}`);
const { attributes, body } = iconToSVG(iconData);
const svg = encodeSvgForCss(iconToHTML(body, attributes));
const selector = labels.map((l) => l.replace(".", "")).map(
(label) => `:where([data-title$='${label}' i], [class$='language-${label}' i] .lang)::before`
).join(", ");
return `${selector} {--logo: url("data:image/svg+xml,${svg}");}`;
}));
return iconCSS.sort().join("");
}