mirror of
https://github.com/iconify/iconify.git
synced 2024-12-12 21:57:50 +00:00
68 lines
1.6 KiB
TypeScript
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);
|
|
}
|
|
}
|