vira
Version:
A simple and highly versatile design system using element-vir.
45 lines (44 loc) • 1.67 kB
JavaScript
import { check } from '@augment-vir/assert';
import { getObjectTypedKeys, getOrSetFromMap } from '@augment-vir/common';
import { css, html, unsafeCSS } from 'element-vir';
import { viraIconCssVars } from './icon-css-vars.js';
import { defineIcon } from './icon-svg.js';
/**
* Caches colored icons keyed first by the source icon and then by the generated color styles. The
* outer `WeakMap` lets the entire cache for a given icon be garbage collected once that icon is no
* longer referenced, preventing a memory leak from unbounded icon definitions.
*/
const coloredIconCache = new WeakMap();
/**
* Wraps an existing icon with a specific color and outputs another icon that can be used anywhere
* the original icon can be used. Results are cached per source icon and color combination.
*
* @category Icon
*/
export function createColoredIcon(icon, colors) {
const colorStyles = getObjectTypedKeys(colors)
.map((cssVarName) => {
if (colors[cssVarName]) {
return `${viraIconCssVars[cssVarName].name}: ${String(colors[cssVarName])};`;
}
else {
return undefined;
}
})
.filter(check.isTruthy)
.join(' ');
const iconCache = getOrSetFromMap(coloredIconCache, icon, () => new Map());
return getOrSetFromMap(iconCache, colorStyles, () => {
const styles = css `
${unsafeCSS(colorStyles)}
display: inline-flex;
vertical-align: middle;
`;
return defineIcon({
name: icon.name,
svgTemplate: html `
<div style=${styles}>${icon.svgTemplate}</div>
`,
});
});
}