@veracity/vui
Version:
Veracity UI is a React component library crafted for use within Veracity applications and pages. Based on Styled Components and @xstyled.
77 lines (75 loc) • 2.26 kB
JavaScript
import { cs } from "../utils/styles.js";
import styled, { css } from "../core/styled.js";
import vui from "../core/vui.js";
import cache from "./cache.js";
import { getAttributes, getSvgContent, initState, stringToHTML } from "./helpers.js";
import { useEffect, useRef, useState } from "react";
import { jsx } from "react/jsx-runtime";
//#region src/svg/svg.tsx
const SvgBase = styled.svgBox(({ pathFill }) => {
return css`
${pathFill !== void 0 && (Array.isArray(pathFill) ? pathFill.map((fill, index) => `
& > path:nth-child(${index + 1}) {
fill: ${fill};
}
`).join() : `
& > path {
fill: ${pathFill};
}
`)}
`;
});
/**
* Displays an svg element based on provided children or 'src' prop.
*
* When using src, it loads the content from the given URL and saves in in cache.
*
* Then, renders the svg by parsing loaded content (Review potential for XSS due to innerHTML).
*/
const Svg = vui((props, ref) => {
const { children, className, src, ...rest } = props;
const [svgState, setSvgState] = useState(() => initState());
const isMountedRef = useRef(false);
const srcRef = useRef(src);
const { content = "", svgAttributes = {} } = svgState;
const innerHTML = !children ? { __html: content } : void 0;
useEffect(() => {
isMountedRef.current = true;
return () => {
isMountedRef.current = false;
};
}, []);
useEffect(() => {
srcRef.current = src;
async function loadSvg(src) {
try {
const response = await cache.get(src);
const content = getSvgContent(response);
const svgAttributes = getAttributes(stringToHTML(response));
svgAttributes["data-src"] = src ?? "";
if (srcRef.current === src && isMountedRef.current) setSvgState({
content,
svgAttributes
});
} catch (error) {
console.error(error);
if (isMountedRef.current) setSvgState(initState());
}
}
src && loadSvg(src);
}, [src]);
return /* @__PURE__ */ jsx(SvgBase, {
className: cs("vui-svg", className),
dangerouslySetInnerHTML: innerHTML,
ref,
xmlns: "http://www.w3.org/2000/svg",
...svgAttributes,
...rest,
children
});
});
Svg.displayName = "Svg";
//#endregion
export { SvgBase, Svg as default };
globalThis.__vuiVersion__ = "5.3.0-alpha.2"
//# sourceMappingURL=svg.js.map