vira
Version:
A simple and highly versatile design system using element-vir.
78 lines (77 loc) • 2.59 kB
JavaScript
import { html, unsafeHTML } from 'element-vir';
import * as lucideStaticImport from 'lucide-static';
import { viraIconCssVars } from './icon-css-vars.js';
const defaultLucideAttributes = {
fill: String(viraIconCssVars['vira-icon-fill-color'].value),
stroke: String(viraIconCssVars['vira-icon-stroke-color'].value),
'stroke-width': String(viraIconCssVars['vira-icon-stroke-width'].value),
};
function setSvgAttribute({ svgString, attributeName, value, }) {
const escapedName = attributeName.replace(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
const regex = new RegExp(String.raw `(\s)${escapedName}="[^"]*"`);
return regex.test(svgString)
? svgString.replace(regex, `$1${attributeName}="${value}"`)
: svgString.replace(/<svg\b/, `<svg ${attributeName}="${value}"`);
}
function applySvgAttributes(svgString, attributes) {
return Object.entries(attributes).reduce((result, [key, value,]) => setSvgAttribute({
svgString: result,
attributeName: key,
value,
}), svgString);
}
function isLucideIconKey(key) {
return key in lucideStaticImport;
}
function getLucideIconSvg(key) {
const svg = lucideStaticImport[key];
if (typeof svg !== 'string') {
throw new TypeError(`Lucide icon "${key}" is not a valid SVG string.`);
}
return svg;
}
function createLucideIconEntry(iconKey) {
return {
name: iconKey,
svgTemplate: html `
${unsafeHTML(applySvgAttributes(getLucideIconSvg(iconKey), defaultLucideAttributes))}
`,
};
}
const lucideIconCache = new Map();
/**
* All [Lucide icons](https://lucide.dev) in a format compatible with `ViraIcon`. Each icon entry
* can be accessed directly as a {@link ViraIconSvg}.
*
* @category Icon
*/
export const lucideIcons = new Proxy({}, {
get(_target, property) {
if (!isLucideIconKey(property)) {
return undefined;
}
const cached = lucideIconCache.get(property);
if (cached) {
return cached;
}
const entry = createLucideIconEntry(property);
lucideIconCache.set(property, entry);
return entry;
},
has(_target, property) {
return isLucideIconKey(property);
},
ownKeys() {
return Object.keys(lucideStaticImport);
},
getOwnPropertyDescriptor(_target, property) {
if (isLucideIconKey(property)) {
return {
configurable: true,
enumerable: true,
writable: false,
};
}
return undefined;
},
});