@svelte-put/inline-svg
Version:
solution to inline SVGs in svelte land
87 lines (81 loc) • 2.42 kB
JavaScript
import { calculateDimensions } from './internals.js';
/**
*
*Svelte action for dynamically inlining remote-fetched SVG into DOM
* @example
*
* ```html
* <script>
* import { inlineSvg } from '@svelte-put/inline-svg;
* </script>
*
* <svg use:inlineSvg={"http://example.com/icon.svg"}></svg>
* ```
* @param {SVGElement} node - SVGElement to inline SVG into
* @param {import('./types.d.ts').InlineSvgActionParameter} param - config for the action.
* @returns {import('./types.d.ts').InlineSvgActionReturn}
*/
export function inlineSvg(node, param) {
let config = resolveConfig(param);
async function op() {
if (config.src) {
const response = await fetch(config.src, { cache: config.cache });
const str = config.transform(await response.text());
const svg = new DOMParser().parseFromString(str, 'image/svg+xml').documentElement;
for (let i = 0; i < svg.attributes.length; i++) {
const attr = svg.attributes[i];
if (!node.hasAttribute(attr.name) && !['width', 'height'].includes(attr.name)) {
node.setAttribute(attr.name, attr.value);
}
}
if (config.autoDimensions) {
const dimensions = calculateDimensions(node, svg);
node.setAttribute('width', dimensions.width);
node.setAttribute('height', dimensions.height);
} else {
node.setAttribute('width', node.getAttribute('width') || '');
node.setAttribute('height', node.getAttribute('height') || '');
}
node.innerHTML = svg.innerHTML;
}
}
op();
return {
update(update) {
config = resolveConfig(update);
op();
},
};
}
/**
* @package
* @type {Required<import('./types.js').InlineSvgActionConfig>}
*/
export const DEFAULT_INLINE_SVG_ACTION_CONFIG = {
src: '',
cache: 'no-cache',
autoDimensions: true,
transform: (svg) => svg,
};
/**
* resolve the input parameters of `inlineSvg` action to an internally usable config
* @package
* @param {import('./types.js').InlineSvgActionParameter | undefined} param
* @returns {Required<import('./types.js').InlineSvgActionConfig>}
*/
export function resolveConfig(param = '') {
if (typeof param === 'string') {
return {
...DEFAULT_INLINE_SVG_ACTION_CONFIG,
src: param,
};
}
return {
...DEFAULT_INLINE_SVG_ACTION_CONFIG,
...param,
};
}
/**
* Deprecated, use `InlineSvgActionParameter` and `InlineSvgActionConfig` instead
* @typedef {import('./types.js').InlineSvgActionParameter} InlineSvgActionParameters
*/