Fix crash when using an inline svg Icon (#5450)

This commit is contained in:
Sebastian Malton authored and GitHub committed 2022-05-26 09:46:50 -04:00
1 parent c8cf300e9b
commit 41d4daded7
3 files changed
+90 -12

No files matched your search

+84 -10
View File
@@ -12,7 +12,57 @@ import type { LocationDescriptor } from "history";
import { cssNames } from "../../utils";
import { withTooltip } from "../tooltip";
import isNumber from "lodash/isNumber";
import { decode } from "../../../common/utils/base64";
import Configuration from "./configuration.svg";
import Crane from "./crane.svg";
import Group from "./group.svg";
import Helm from "./helm.svg";
import Install from "./install.svg";
import Kube from "./kube.svg";
import LensLogo from "./lens-logo.svg";
import License from "./license.svg";
import LogoLens from "./logo-lens.svg";
import Logout from "./logout.svg";
import Nodes from "./nodes.svg";
import PushOff from "./push_off.svg";
import PushPin from "./push_pin.svg";
import Spinner from "./spinner.svg";
import Ssh from "./ssh.svg";
import Storage from "./storage.svg";
import Terminal from "./terminal.svg";
import User from "./user.svg";
import Users from "./users.svg";
import Wheel from "./wheel.svg";
import Workloads from "./workloads.svg";
/**
* Mapping between the local file names and the svgs
*
* Because we only really want a fixed list of bundled icons, this is safer so that consumers of
* `<Icon>` cannot pass in a `../some/path`.
*/
const localSvgIcons = new Map([
["configuration", Configuration],
["crane", Crane],
["group", Group],
["helm", Helm],
["install", Install],
["kube", Kube],
["lens-logo", LensLogo],
["license", License],
["logo-lens", LogoLens],
["logout", Logout],
["nodes", Nodes],
["push_off", PushOff],
["push_pin", PushPin],
["spinner", Spinner],
["ssh", Ssh],
["storage", Storage],
["terminal", Terminal],
["user", User],
["users", Users],
["wheel", Wheel],
["workloads", Workloads],
]);
export interface BaseIconProps {
/**
@@ -21,7 +71,28 @@ export interface BaseIconProps {
material?: string;
/**
* Either an SVG data URL or one of the following strings
* Either an SVG XML or one of the following names
* - configuration
* - crane
* - group
* - helm
* - install
* - kube
* - lens-logo
* - license
* - logo-lens
* - logout
* - nodes
* - push_off
* - push_pin
* - spinner
* - ssh
* - storage
* - terminal
* - user
* - users
* - wheel
* - workloads
*/
svg?: string;
@@ -78,8 +149,8 @@ export interface BaseIconProps {
export interface IconProps extends React.HTMLAttributes<any>, BaseIconProps {}
export function isSvg(content: string): boolean {
// data-url for raw svg-icon
return String(content).includes("svg+xml");
// source code of the asset
return String(content).includes("<svg");
}
const RawIcon = withTooltip((props: IconProps) => {
@@ -131,13 +202,16 @@ const RawIcon = withTooltip((props: IconProps) => {
// render as inline svg-icon
if (typeof svg === "string") {
const dataUrlPrefix = "data:image/svg+xml;base64,";
const svgIconDataUrl = svg.startsWith(dataUrlPrefix) ? svg : require(`./${svg}.svg`);
const svgIconText = typeof svgIconDataUrl == "string" // decode xml from data-url
? decode(svgIconDataUrl.replace(dataUrlPrefix, ""))
: "";
const svgIconText = isSvg(svg)
? svg
: localSvgIcons.get(svg) ?? "";
iconContent = <span className="icon" dangerouslySetInnerHTML={{ __html: svgIconText }} />;
iconContent = (
<span
className="icon"
dangerouslySetInnerHTML={{ __html: svgIconText }}
/>
);
}
// render as material-icon