Skip to content

feat: [MAW-257] svgImage support tintColor on web #2667

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions src/components/svgImage/index.web.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React, {useState} from 'react';
import {StyleSheet} from 'react-native';
import Image from '../image';
import {isSvg, isSvgUri, isBase64ImageContent} from '../../utils/imageUtils';

const EMPTY_STYLE = '{}';
const DEFAULT_SIZE = 16;
export interface SvgImageProps {
/**
Expand All @@ -14,22 +14,23 @@ export interface SvgImageProps {
}

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

const styleObj = JSON.parse(JSON.stringify(style));

const createStyleSvgCss = async (PostCssPackage: {postcss: any; cssjs: any}) => {
const createStyleSvgCss = async (PostCssPackage: {postcss: any; cssjs: any}, styleObj?: Record<string, any>) => {
setPostCssStyleCalled(true);
const {postcss, cssjs} = PostCssPackage;
postcss()
.process(styleObj, {parser: cssjs})
.then((style: {css: any}) => setSvgStyleCss(`{${style.css}}`));
.then((style: {css: any}) => {
const svgPathCss = (styleObj?.tintColor) ? `svg path {fill: ${styleObj?.tintColor}}` : '';
setSvgStyleCss(`svg {${style.css}} ${svgPathCss}}`);
});
};

if (isSvgUri(data)) {
return <img {...others} src={data.uri} style={styleObj}/>;
return <img {...others} src={data.uri} style={StyleSheet.flatten(style)}/>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that the flatter is not necessary here.. only for the postCSS thing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we need that, its not supported on React

tested in:
https://playcode.io/react

import React from 'react';

export function App(props) {
  return (
    <div className='App'>
      <img src="https://reactjs.org/logo-og.png" alt="react logo" style={[{ width: '400px'}]}/>
    </div>
  );
}

} else if (isBase64ImageContent(data)) {
if (tintColor) {
return (
Expand All @@ -42,23 +43,26 @@ function SvgImage(props: SvgImageProps) {
/>
);
}
return <img {...others} src={data} style={styleObj}/>;
return <img {...others} src={data} style={StyleSheet.flatten(style)}/>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also here, not sure Flatten is necessary here...

} else if (data) {

const PostCssPackage = require('../../optionalDependencies').PostCssPackage;
if (PostCssPackage) {
if (!postCssStyleCalled) {
createStyleSvgCss(PostCssPackage);
createStyleSvgCss(PostCssPackage, StyleSheet.flatten(style));
return null;
}
const svgStyleTag = `<style> svg ${svgStyleCss} </style>`;

return (
<div
{...others}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: svgStyleTag + data}}
/>
);

if (svgStyleCss) {
const svgStyleTag = `<style> ${svgStyleCss} </style>`;
return (
<div
{...others}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{__html: svgStyleTag + data}}
/>
);
}
}
}
return null;
Expand Down
22 changes: 3 additions & 19 deletions webDemo/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,24 +38,7 @@ interface ItemToRender {
title: string,
FC: React.FC
}
const svgData = `<?xml version="1.0" encoding="UTF-8"?>
<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">
<g>
<defs>
<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">
<stop stop-color="#0296d8" offset="0"/>
<stop stop-color="#8371d9" offset="1"/>
</linearGradient>
<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">
<stop stop-color="#cb55c0" offset="0"/>
<stop stop-color="#f28e0e" offset="1"/>
</linearGradient>
</defs>
<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)"/>
<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)"/>
</g>
</svg>
`;
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';

const itemsToRender: ItemToRender[] = [
{
Expand Down Expand Up @@ -118,7 +101,8 @@ const itemsToRender: ItemToRender[] = [
iconSource={svgData}
iconStyle={{
width: 24,
height: 24
height: 24,
tintColor: 'red'
}}
/>
)
Expand Down