mirror of
https://github.com/lensapp/lens.git
synced 2024-09-20 05:47:24 +03:00
Fix crash when using an inline svg Icon (#5450)
This commit is contained in:
parent
c8cf300e9b
commit
41d4daded7
@ -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
|
||||
|
6
types/mocks.d.ts
vendored
6
types/mocks.d.ts
vendored
@ -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";
|
||||
|
@ -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)$/,
|
||||
|
Loading…
Reference in New Issue
Block a user