Skip to content

Commit d2d7e85

Browse files
authored
feat: [MAW-257] svgImage support tintColor on web (#2667)
* feat: [MAW-257] svgImage support tintColor on web * use StyleSheet.flatten
1 parent ba7fa37 commit d2d7e85

File tree

2 files changed

+26
-38
lines changed

2 files changed

+26
-38
lines changed

src/components/svgImage/index.web.tsx

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React, {useState} from 'react';
2+
import {StyleSheet} from 'react-native';
23
import Image from '../image';
34
import {isSvg, isSvgUri, isBase64ImageContent} from '../../utils/imageUtils';
45

5-
const EMPTY_STYLE = '{}';
66
const DEFAULT_SIZE = 16;
77
export interface SvgImageProps {
88
/**
@@ -14,22 +14,23 @@ export interface SvgImageProps {
1414
}
1515

1616
function SvgImage(props: SvgImageProps) {
17-
const {data, style = {}, tintColor, ...others} = props;
18-
const [svgStyleCss, setSvgStyleCss] = useState<string>(EMPTY_STYLE);
17+
const {data, style = [], tintColor, ...others} = props;
18+
const [svgStyleCss, setSvgStyleCss] = useState<string | undefined>(undefined);
1919
const [postCssStyleCalled, setPostCssStyleCalled] = useState(false);
2020

21-
const styleObj = JSON.parse(JSON.stringify(style));
22-
23-
const createStyleSvgCss = async (PostCssPackage: {postcss: any; cssjs: any}) => {
21+
const createStyleSvgCss = async (PostCssPackage: {postcss: any; cssjs: any}, styleObj?: Record<string, any>) => {
2422
setPostCssStyleCalled(true);
2523
const {postcss, cssjs} = PostCssPackage;
2624
postcss()
2725
.process(styleObj, {parser: cssjs})
28-
.then((style: {css: any}) => setSvgStyleCss(`{${style.css}}`));
26+
.then((style: {css: any}) => {
27+
const svgPathCss = (styleObj?.tintColor) ? `svg path {fill: ${styleObj?.tintColor}}` : '';
28+
setSvgStyleCss(`svg {${style.css}} ${svgPathCss}}`);
29+
});
2930
};
3031

3132
if (isSvgUri(data)) {
32-
return <img {...others} src={data.uri} style={styleObj}/>;
33+
return <img {...others} src={data.uri} style={StyleSheet.flatten(style)}/>;
3334
} else if (isBase64ImageContent(data)) {
3435
if (tintColor) {
3536
return (
@@ -42,23 +43,26 @@ function SvgImage(props: SvgImageProps) {
4243
/>
4344
);
4445
}
45-
return <img {...others} src={data} style={styleObj}/>;
46+
return <img {...others} src={data} style={StyleSheet.flatten(style)}/>;
4647
} else if (data) {
48+
4749
const PostCssPackage = require('../../optionalDependencies').PostCssPackage;
4850
if (PostCssPackage) {
4951
if (!postCssStyleCalled) {
50-
createStyleSvgCss(PostCssPackage);
52+
createStyleSvgCss(PostCssPackage, StyleSheet.flatten(style));
5153
return null;
5254
}
53-
const svgStyleTag = `<style> svg ${svgStyleCss} </style>`;
54-
55-
return (
56-
<div
57-
{...others}
58-
// eslint-disable-next-line react/no-danger
59-
dangerouslySetInnerHTML={{__html: svgStyleTag + data}}
60-
/>
61-
);
55+
56+
if (svgStyleCss) {
57+
const svgStyleTag = `<style> ${svgStyleCss} </style>`;
58+
return (
59+
<div
60+
{...others}
61+
// eslint-disable-next-line react/no-danger
62+
dangerouslySetInnerHTML={{__html: svgStyleTag + data}}
63+
/>
64+
);
65+
}
6266
}
6367
}
6468
return null;

webDemo/src/App.tsx

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,7 @@ interface ItemToRender {
3838
title: string,
3939
FC: React.FC
4040
}
41-
const svgData = `<?xml version="1.0" encoding="UTF-8"?>
42-
<svg data-bbox="2 2 28 28" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" height="800" width="800" data-type="ugc">
43-
<g>
44-
<defs>
45-
<linearGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(.893 0 0 .893 -64.139 -782.556)" y2="878.134" x2="105.452" y1="910.226" x1="73.714" id="1c6ca7ff-eba0-4dd0-82e3-63fdfa256791">
46-
<stop stop-color="#0296d8" offset="0"/>
47-
<stop stop-color="#8371d9" offset="1"/>
48-
</linearGradient>
49-
<linearGradient gradientUnits="userSpaceOnUse" gradientTransform="matrix(.893 0 0 .893 -64.139 -782.556)" y2="875.745" x2="102.279" y1="905.226" x1="69.813" id="85cd62d4-a6c1-4ded-b1ca-e6c438f49e1b">
50-
<stop stop-color="#cb55c0" offset="0"/>
51-
<stop stop-color="#f28e0e" offset="1"/>
52-
</linearGradient>
53-
</defs>
54-
<path d="M2 2v28h28v-.047l-6.95-7-6.95-7.007 6.95-7.012L29.938 2Z" fill="url(#1c6ca7ff-eba0-4dd0-82e3-63fdfa256791)"/>
55-
<path d="M16.318 2 2 16.318V30h.124l14.008-14.008-.031-.031L23.05 8.95 29.938 2Z" fill="url(#85cd62d4-a6c1-4ded-b1ca-e6c438f49e1b)"/>
56-
</g>
57-
</svg>
58-
`;
41+
const svgData = '<svg data-bbox="18.5 31.5 163.1 137.2" viewBox="0 0 200 200" height="200" width="200" xmlns="http://www.w3.org/2000/svg" data-type="color">\n <g>\n <path d="M18.5 99.5c0-5.7 2.3-10.8 6-14.5L72 37.5c3.7-3.7 8.8-6 14.5-6 11.4 0 20.5 9.2 20.5 20.5 0 5.7-2.3 10.8-6 14.5L88.1 79.4h72.3c11.7 0 21.2 9.5 21.2 21.2s-9.5 21.2-21.2 21.2H89.1l11.9 11.9c3.7 3.7 6 8.8 6 14.5 0 11.3-9.2 20.5-20.5 20.5-5.7 0-10.8-2.3-14.5-6L24.5 115c-3.7-3.7-6-8.8-6-14.5 0-.2 0-.4.1-.6 0 0-.1-.3-.1-.4z" fill="#000010" data-color="1"/>\n </g>\n</svg>\n';
5942

6043
const itemsToRender: ItemToRender[] = [
6144
{
@@ -118,7 +101,8 @@ const itemsToRender: ItemToRender[] = [
118101
iconSource={svgData}
119102
iconStyle={{
120103
width: 24,
121-
height: 24
104+
height: 24,
105+
tintColor: 'red'
122106
}}
123107
/>
124108
)

0 commit comments

Comments
 (0)