2
0
mirror of https://github.com/iconify/iconify.git synced 2024-12-12 21:57:50 +00:00
iconify/iconify-icon/icon/src/render/icon.ts
2024-02-04 09:39:57 +02:00

68 lines
1.6 KiB
TypeScript

import { defaultIconProps } from '@iconify/utils/lib/icon/defaults';
import { iconToSVG } from '@iconify/utils/lib/svg/build';
import type { RenderedState } from '../state';
import { renderSPAN } from './span';
import { renderSVG } from './svg';
/**
* Find icon node
*/
export function findIconElement(
parent: Element | ShadowRoot
): HTMLElement | undefined {
return Array.from(parent.childNodes).find((node) => {
const tag =
(node as HTMLElement).tagName &&
(node as HTMLElement).tagName.toUpperCase();
return tag === 'SPAN' || tag === 'SVG';
}) as HTMLElement | undefined;
}
/**
* Render icon
*/
export function renderIcon(parent: Element | ShadowRoot, state: RenderedState) {
const iconData = state.icon.data;
const customisations = state.customisations;
// Render icon
const renderData = iconToSVG(iconData, customisations);
if (customisations.preserveAspectRatio) {
renderData.attributes['preserveAspectRatio'] =
customisations.preserveAspectRatio;
}
const mode = state.renderedMode;
let node: Element;
switch (mode) {
case 'svg':
node = renderSVG(renderData);
break;
default:
node = renderSPAN(
renderData,
{
...defaultIconProps,
...iconData,
},
mode === 'mask'
);
}
// Set element
const oldNode = findIconElement(parent);
if (oldNode) {
// Replace old element
if (node.tagName === 'SPAN' && oldNode.tagName === node.tagName) {
// Swap style instead of whole node
oldNode.setAttribute('style', node.getAttribute('style'));
} else {
parent.replaceChild(node, oldNode);
}
} else {
// Add new element
parent.appendChild(node);
}
}