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 { cssNames } from "../../utils";
|
||||||
import { withTooltip } from "../tooltip";
|
import { withTooltip } from "../tooltip";
|
||||||
import isNumber from "lodash/isNumber";
|
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 {
|
export interface BaseIconProps {
|
||||||
/**
|
/**
|
||||||
@ -21,7 +71,28 @@ export interface BaseIconProps {
|
|||||||
material?: string;
|
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;
|
svg?: string;
|
||||||
|
|
||||||
@ -78,8 +149,8 @@ export interface BaseIconProps {
|
|||||||
export interface IconProps extends React.HTMLAttributes<any>, BaseIconProps {}
|
export interface IconProps extends React.HTMLAttributes<any>, BaseIconProps {}
|
||||||
|
|
||||||
export function isSvg(content: string): boolean {
|
export function isSvg(content: string): boolean {
|
||||||
// data-url for raw svg-icon
|
// source code of the asset
|
||||||
return String(content).includes("svg+xml");
|
return String(content).includes("<svg");
|
||||||
}
|
}
|
||||||
|
|
||||||
const RawIcon = withTooltip((props: IconProps) => {
|
const RawIcon = withTooltip((props: IconProps) => {
|
||||||
@ -131,13 +202,16 @@ const RawIcon = withTooltip((props: IconProps) => {
|
|||||||
|
|
||||||
// render as inline svg-icon
|
// render as inline svg-icon
|
||||||
if (typeof svg === "string") {
|
if (typeof svg === "string") {
|
||||||
const dataUrlPrefix = "data:image/svg+xml;base64,";
|
const svgIconText = isSvg(svg)
|
||||||
const svgIconDataUrl = svg.startsWith(dataUrlPrefix) ? svg : require(`./${svg}.svg`);
|
? svg
|
||||||
const svgIconText = typeof svgIconDataUrl == "string" // decode xml from data-url
|
: localSvgIcons.get(svg) ?? "";
|
||||||
? decode(svgIconDataUrl.replace(dataUrlPrefix, ""))
|
|
||||||
: "";
|
|
||||||
|
|
||||||
iconContent = <span className="icon" dangerouslySetInnerHTML={{ __html: svgIconText }} />;
|
iconContent = (
|
||||||
|
<span
|
||||||
|
className="icon"
|
||||||
|
dangerouslySetInnerHTML={{ __html: svgIconText }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// render as material-icon
|
// 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"
|
// Declare everything what's bundled as webpack's type="asset/resource"
|
||||||
// Should be mocked for tests support in jestConfig.moduleNameMapper (currently in "/package.json")
|
// 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 "*.jpg";
|
||||||
declare module "*.png";
|
declare module "*.png";
|
||||||
declare module "*.eot";
|
declare module "*.eot";
|
||||||
|
@ -132,7 +132,7 @@ export function iconsAndImagesWebpackRules(): webpack.RuleSetRule[] {
|
|||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
test: /\.svg$/,
|
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)$/,
|
test: /\.(jpg|png|ico)$/,
|
||||||
|
Loading…
Reference in New Issue
Block a user