@itwin/core-react
Version:
A react component library of iTwin.js UI general purpose components
74 lines • 3.35 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Icon
*/
import "./IconComponent.scss";
import * as React from "react";
import classnames from "classnames";
import { ConditionalStringValue } from "@itwin/appui-abstract";
import DOMPurify from "dompurify";
import { ConditionalIconItem } from "./ConditionalIconItem.js";
/** Get the SVG Source from an svg-loader IconSpec */
function getWebComponentSource(iconSpec) {
if (iconSpec.startsWith("webSvg:") && iconSpec.length > 7) {
return iconSpec.slice(7);
}
return undefined;
}
/** Icon Functional component displays an icon based on an [[IconSpec]].
* @public
* @deprecated in 4.16.0. Used to render a deprecated {@link IconSpec} type. Use {@link https://itwinui.bentley.com/ iTwinUI Icon} instead.
*/
export function Icon(props) {
if (!props.iconSpec)
return null;
const iconSpecValue = getIconSpecValue(props.iconSpec);
if (typeof iconSpecValue === "string") {
const iconString = iconSpecValue;
const webComponentString = getWebComponentSource(iconString);
if (iconString.startsWith("data:") ||
iconString.endsWith(".svg") ||
webComponentString) {
const definitiveIconString = webComponentString
? webComponentString
: iconString;
const svgLoader = `<svg-loader src="${definitiveIconString}"></svg-loader>`;
const svgDiv = `<div>${svgLoader}</div>`;
const sanitizerConfig = {
ALLOWED_TAGS: ["svg-loader"],
ADD_URI_SAFE_ATTR: definitiveIconString.startsWith("data:")
? ["src"]
: [],
};
const sanitizedIconString = DOMPurify.sanitize(svgDiv, sanitizerConfig);
const webComponentNode = (
// we can safely disable jam3/no-sanitizer-with-danger as we are sanitizing above
// eslint-disable-next-line jam3/no-sanitizer-with-danger
React.createElement("div", { dangerouslySetInnerHTML: { __html: sanitizedIconString } }));
return (React.createElement("i", { className: classnames("icon", "core-svg-icon", props.className) }, webComponentNode));
}
// CSS icon
return (React.createElement("i", { className: classnames("icon", "core-css-icon", iconString, props.className), style: props.style }));
}
// ReactNode icon
return (React.createElement("i", { className: classnames("icon", "core-svg-icon", props.className), style: props.style }, iconSpecValue));
}
function getIconSpecValue(iconSpec) {
let value = iconSpec;
while (true) {
if (value instanceof ConditionalIconItem) {
value = ConditionalIconItem.getValue(value);
continue;
}
if (value instanceof ConditionalStringValue) {
value = ConditionalStringValue.getValue(value);
break;
}
break;
}
return value;
}
//# sourceMappingURL=IconComponent.js.map