1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

Fix crash when using an inline svg Icon

Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
Sebastian Malton 2022-05-25 15:29:13 -04:00
parent 58ffb38d74
commit 4a6fe3b55d
3 changed files with 68 additions and 11 deletions

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 {
/**
@ -78,8 +128,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 +181,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

6
types/mocks.d.ts vendored
View File

@ -25,7 +25,11 @@ declare module "*.scss" {
// Declare everything what's bundled as webpack's type="asset/resource"
// Should be mocked for tests support in jestConfig.moduleNameMapper (currently in "/package.json")
declare module "*.svg";
declare module "*.svg" {
const content: string;
export = content;
}
declare module "*.jpg";
declare module "*.png";
declare module "*.eot";

View File

@ -132,7 +132,7 @@ export function iconsAndImagesWebpackRules(): webpack.RuleSetRule[] {
return [
{
test: /\.svg$/,
type: "asset/inline", // data:image/svg+xml;base64,...
type: "asset/source", // exports the source code of the asset, so we get XML
},
{
test: /\.(jpg|png|ico)$/,