gatsby-plugin-material-symbols
Version:
Easily add Material Symbols to your Gatsby site, with various Gatsby-specific performance optimizations built-in.
225 lines (224 loc) • 9.7 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.onPreBuild = void 0;
const path_1 = __importDefault(require("path"));
const fs_1 = __importDefault(require("fs"));
const fetch_remote_file_1 = require("gatsby-core-utils/fetch-remote-file");
const preprocessSource_1 = require("./preprocessSource");
const onPreBuild = async ({ reporter, cache }, PluginOptions) => {
const pluginOptions = PluginOptions;
const symbolsObject = Object.values(preprocessSource_1.staticAnalysisCache).flat();
let symbols = symbolsObject.map(symbol => symbol.symbol);
let symbolStyles = symbolsObject.filter(symbol => symbol.symbolStyle).map(symbol => symbol.symbolStyle);
if (pluginOptions.extraStyles) {
if (Array.isArray(pluginOptions.extraStyles)) {
pluginOptions.extraStyles.forEach((style) => {
if (!symbolStyles.includes(style)) {
symbolStyles.push(style);
}
});
}
else if (typeof pluginOptions.extraStyles === "object") {
pluginOptions.extraStyles.outlined && symbolStyles.push("outlined");
pluginOptions.extraStyles.rounded && symbolStyles.push("rounded");
pluginOptions.extraStyles.sharp && symbolStyles.push("sharp");
}
}
symbolStyles = [...new Set(symbolStyles)];
let url = "https://fonts.googleapis.com/css2?family=";
function variableFontSubset(style) {
let url = "";
let fills = symbolsObject
.filter(symbol => symbol.symbolStyle === style && symbol.fill)
.map(symbol => symbol.fill);
let weights = symbolsObject
.filter(symbol => symbol.symbolStyle === style && symbol.weight)
.map(symbol => symbol.weight);
let grades = symbolsObject
.filter(symbol => symbol.symbolStyle === style && symbol.grade)
.map(symbol => symbol.grade);
let sizes = symbolsObject
.filter(symbol => symbol.symbolStyle === style && symbol.size)
.map(symbol => symbol.size);
if (pluginOptions.sizeRange) {
sizes = sizes.concat(pluginOptions.sizeRange);
}
if (pluginOptions.weightRange) {
weights = weights.concat(pluginOptions.weightRange);
}
if (pluginOptions.includeFill) {
fills = fills.concat(true);
}
if (pluginOptions.gradeRange) {
grades = grades.concat(pluginOptions.gradeRange);
}
if (sizes?.length > 0 || weights?.length > 0 || fills?.length > 0 || grades?.length > 0) {
const doSizes = sizes.length > 0;
const doWeights = weights.length > 0;
const doFills = fills.length > 0;
const doGrades = grades.length > 0;
function smallestLargestValues(values, min, max) {
const minValue = Math.min(...values);
const maxValue = Math.max(...values);
return `${min ? Math.max(min, minValue) : minValue}..${max ? Math.min(max, maxValue) : maxValue}`;
}
;
url += ":";
let properties = [];
doSizes && properties.push("opsz");
doWeights && properties.push("wght");
doFills && properties.push("FILL");
doGrades && properties.push("GRAD");
url += properties.join(",");
url += "@";
const hasTrueFill = fills.some(fill => fill === true);
const trueFillsOnly = fills.every(fill => fill === true);
let values = [];
doSizes && (() => {
if (sizes.length === 1) {
if (sizes[0] > 24) {
values.push(`24..${sizes[0]}`);
}
else if (sizes[0] < 24) {
values.push(`${sizes[0]}..24`);
}
}
else if (sizes.every(size => size === sizes[0])) {
values.push(`${sizes[0]}`);
}
else {
values.push(smallestLargestValues(sizes, 20, 48));
}
})();
doWeights && (() => {
if (weights.length === 1) {
if (weights[0] > 400) {
values.push(`400..${weights[0]}`);
}
else if (weights[0] < 400) {
values.push(`${weights[0]}..400`);
}
}
else if (weights.every(weight => weight === weights[0])) {
values.push(`${weights[0]}`);
}
else {
values.push(smallestLargestValues(weights, 100, 700));
}
})();
doFills && (() => {
if (trueFillsOnly) {
values.push("1");
}
else if (hasTrueFill) {
values.push("1");
}
})();
doGrades && (() => {
if (grades.length === 1) {
if (grades[0] > 0) {
values.push(`0..${grades[0]}`);
}
else if (grades[0] < 0) {
values.push(`${grades[0]}..0`);
}
}
else if (grades.every(grade => grade === grades[0])) {
values.push(`${grades[0]}`);
}
else {
values.push(smallestLargestValues(grades, -25, 200));
}
})();
url += values.join(",");
}
return url;
}
;
let families = [];
symbolStyles.includes("outlined") && families.push(`Material+Symbols+Outlined${variableFontSubset("outlined")}`);
symbolStyles.includes("rounded") && families.push(`Material+Symbols+Rounded${variableFontSubset("rounded")}`);
symbolStyles.includes("sharp") && families.push(`Material+Symbols+Sharp${variableFontSubset("sharp")}`);
url += families.join("&family=");
if (pluginOptions.extraIcons) {
if (Array.isArray(pluginOptions.extraIcons)) {
pluginOptions.extraIcons.forEach((icon) => {
if (!symbols.includes(icon)) {
symbols.push(icon);
}
});
}
else {
Object.values(pluginOptions.extraIcons).forEach((iconArray) => {
iconArray.forEach((icon) => {
if (!symbols.includes(icon)) {
symbols.push(icon);
}
});
});
}
}
symbols = [...new Set(symbols)];
symbols.sort();
url += "&icon_names=" + symbols.join(",");
url += "&display=block";
const filename = await (0, fetch_remote_file_1.fetchRemoteFile)({ url, cache, ext: ".css", name: "material-symbols", httpHeaders: {
"user-agent": `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0`,
} });
reporter.verbose(`gatsby-plugin-material-symbols: Downloaded ${url} and saved to ${filename}`);
let cssFile;
try {
cssFile = fs_1.default.readFileSync(filename).toString();
}
catch (error) {
reporter.error(`gatsby-plugin-material-symbols: ${error}`);
}
let fontUrls = [];
if (pluginOptions.embedFonts) {
fontUrls = cssFile.match(/(?<=url\()[^)]+/g);
if (fontUrls) {
for (const fontUrl of fontUrls) {
const fontFilename = await (0, fetch_remote_file_1.fetchRemoteFile)({ url: fontUrl, cache, ext: ".woff2", name: "material-symbols" });
const base64Font = fs_1.default.readFileSync(fontFilename).toString("base64");
cssFile = cssFile.replace(fontUrl, `data:font/woff2;base64,${base64Font}`);
}
}
}
cssFile = cssFile.replace(/\.material-symbols-(outlined|rounded|sharp) {.*?$/gs, `.material-symbol {
font-weight: normal;
font-style: normal;
font-size: inherit;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-smoothing: antialiased;
}
.material-symbol.material-symbols-outlined {
font-family: 'Material Symbols Outlined';
}
.material-symbol.material-symbols-rounded {
font-family: 'Material Symbols Rounded';
}
.material-symbol.material-symbols-sharp {
font-family: 'Material Symbols Sharp';
}`);
fs_1.default.writeFileSync(filename, cssFile);
const cacheDir = path_1.default.join(__dirname, "..", ".cache");
if (!fs_1.default.existsSync(cacheDir)) {
fs_1.default.mkdirSync(cacheDir);
}
const cacheFilePath = path_1.default.join(cacheDir, "material-symbols.css");
fs_1.default.writeFileSync(cacheFilePath, cssFile);
pluginOptions.verbose
? reporter.info(`gatsby-plugin-material-symbols: Found ${symbols.length} symbols and wrote CSS ${pluginOptions.embedFonts && `with ${fontUrls.length} embedded fonts`} from ${url} to ${cacheFilePath}`)
: reporter.verbose(`gatsby-plugin-material-symbols: Found ${symbols.length} symbols and wrote CSS ${pluginOptions.embedFonts && `with ${fontUrls.length} embedded fonts`} from ${url} to ${cacheFilePath}`);
};
exports.onPreBuild = onPreBuild;
//# sourceMappingURL=onPreBuild.js.map