kristerkari / react-native-svg-transformer

Import SVG files in your React Native project the same way that you would in a Web application.
MIT License
1.61k stars 116 forks source link

fill prop not working for svg file! #105

Closed cmcodes1 closed 3 years ago

cmcodes1 commented 4 years ago

Hey! @kristerkari I was looking for a way to change the color of the svg icon ( just like in #4 ). Going through the docs, so far I've tried this:

Imported the svg file in the project. import Shop from '../Components/Assets/shop.svg';

Used the svg file. <Shop width={'100%'} height={'30%'} fill={'red'} />

Created a .svgrrc (no extension) file in the root of the project containing:

{
  "replaceAttrValues": {
    "#748A9D": "{props.fill}"
  }
}

My project dependencies: "react-native": "0.63.2", "react-native-svg": "^12.1.0", "react-native-svg-transformer": "^0.14.3", "semver": "^7.3.2" "@svgr/core": "^5.4.0", "path-dirname": "^1.0.2",

Am I missing something?

kristerkari commented 4 years ago

That looks correct to me. Any chance that you can upload your project somewhere, so that I can have a look at it?

burhan3759 commented 4 years ago

Same here, I have the same issue.

it only work with "#000" & "#000000"

Library: "react-native": "0.62.2", "react-native-svg": "^12.1.0", "react-native-svg-transformer": "^0.14.3",

kristerkari commented 4 years ago

@burhan3759 please provide some example of your problem, otherwise it's impossible to help you.

burhan3759 commented 4 years ago

Sure, sorry for giving with lack of info. I had the exact similar problem with @cmcodes1

  1. When I change the fill in "ArrowLeftIcon" to some color it does not work
  2. when i change the fill in SVG icon to #000000, then it works
  3. I already added the #ffffff in svgrrc

Here is my svgrrc:

{
  "replaceAttrValues": {
    "#000": "{props.fill}",
    "#000000": "{props.fill}",
    "#ffffff": "{props.fill}",
  }
}

Here is my SVG icon:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1"  width="24" height="24" viewBox="0 0 24 24">
   <path fill="#ffffff" d="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z" />
</svg> 

Here is how i use the icon:

<ArrowLeftIcon height="25" width="25" fill="#4D4D4D" />

Version of Libraries: "react-native": "0.62.2", "react-native-svg": "^12.1.0", "react-native-svg-transformer": "^0.14.3",

mofmn commented 4 years ago

I have a similar issue, mine works sometimes and i cant explain why, and i cant reliably control the colour. it seems to me like its an issues with the .svgrrc file being loaded, as i had a universal transformation { "replaceAttrValues": { "black": "red" } }

And one svg was following this rule while it no longer existed, i tried to restart everything. Perhaps did not run a clean build. but this rule seems to persist along with other rules created after. its a nightmare, its very hard to get consistent reproducibility. Otherwise i have the same set up as the others

jmlavoier commented 4 years ago

I had the same issue in Android, I'm not using expo. The resolution for me was

After I've done this, I didn't have to clean the build anymore. I just had to reset-cache when I had to add more configs.

sypl commented 4 years ago

Also having the same problem, this config:

{
  "replaceAttrValues": {
    "#02024D": "{props.fill}"
  }
}

... does not work with this

import Add from '~/assets/svg-icons/Add.svg'

...

<Add height={50} width={50} fill="red" />

I'm having to replace "#02024D" with "@fill" in svg file and then

{
  "replaceAttrValues": {
    "@fill": "{props.fill}"
  }
}
mhammerc commented 4 years ago

@KPS250 I exported my SVG from Figma and it set the property fill inside the <svg> to none.

<svg fill="none">

When that happen, every <path> (which are inside <svg>) are not getting colored, even if they are <path fill="#000000">.

To fix the issue, I had to change fill="none" to fill="#000000" from the <svg> element.

TLDR Ensure <svg> elements have fill="#000000" and nothing else

KPS250 commented 4 years ago

@mhammerc yeah I found this later. Thanks for the help

Wituz commented 3 years ago

In Expo, it works after I clear the cache.

expo r -c

It does not seem like the hot reload pick up changes in .svgrrc, so I have to clear the cache every time I make a change with the command above.

SohaibIbneAli commented 3 years ago

try all solutions but no one is working.

mohammadameer commented 3 years ago

In Expo, it works after I clear the cache.

expo r -c

It does not seem like the hot reload pick up changes in .svgrrc, so I have to clear the cache every time I make a change with the command above.

@Wintus thank you very much this worked for me

emirhankolver commented 3 years ago

@KPS250 I exported my SVG from Figma and it set the property fill inside the <svg> to none.

<svg fill="none">

When that happen, every <path> (which are inside <svg>) are not getting colored, even if they are <path fill="#000000">.

To fix the issue, I had to change fill="none" to fill="#000000" from the <svg> element.

TLDR Ensure <svg> elements have fill="#000000" and nothing else

Also I fixed my problem by removing fill="white" in the <path></path> line and changing the <svg fill="none"> to <svg fill="#000000"> also I restarted the react-native server and actual app

Example: Old

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.775 9...." fill="white"/>
</svg>

New

<svg width="24" height="24" viewBox="0 0 24 24" fill="#000000" xmlns="http://www.w3.org/2000/svg">
<path d="M17.775 9...."/>
</svg>
ivanjuliant commented 3 years ago

In Expo, it works after I clear the cache.

expo r -c

It does not seem like the hot reload pick up changes in .svgrrc, so I have to clear the cache every time I make a change with the command above.

this working for me , thank you.

henrhie commented 3 years ago

try all solutions but no one is working.

try removing all 'fill=...' from paths only and leave fill='none' in main svg tag

DevYuns commented 3 years ago

try all solutions but no one is working.

try removing all 'fill=...' from paths only and leave fill='none' in main svg tag

It works for me. Thanks!

stanislav-sidorov commented 3 years ago

in SVG children add fill="currentColor", then you can style

uwemneku commented 2 years ago

@KPS250 I exported my SVG from Figma and it set the property fill inside the <svg> to none.

<svg fill="none">

When that happen, every <path> (which are inside <svg>) are not getting colored, even if they are <path fill="#000000">.

To fix the issue, I had to change fill="none" to fill="#000000" from the <svg> element.

TLDR Ensure <svg> elements have fill="#000000" and nothing else

For bare react-native project adding a .svgrrc file to the root folder with the code { "replaceAttrValues": { "#000": "{props.fill}" } } worked for me

nabil-atechy commented 2 years ago

@KPS250 I exported my SVG from Figma and it set the property fill inside the <svg> to none.

<svg fill="none">

When that happen, every <path> (which are inside <svg>) are not getting colored, even if they are <path fill="#000000">.

To fix the issue, I had to change fill="none" to fill="#000000" from the <svg> element.

TLDR Ensure <svg> elements have fill="#000000" and nothing else

thanks you save my day

ritesh985 commented 2 years ago

try all solutions but no one is working.

try removing all 'fill=...' from paths only and leave fill='none' in main svg tag

It worked. Thanks!

rajAmukhliS commented 2 years ago

fill prop not working for svg file! || How to assign color to svg

Solution:

I solved this issue follow me to solve this

Steps

  1. Open the svg in editor as you can see in picture below image

  2. Remove all fill prop from paths only (Only from path tags) , And ensure that svg tag's prop fill ='null' as you can see in picture below image

  3. Save that changes in svg file

  4. Import that svg where you want to use

  5. Pass fill={Color of your Choice} prop to that svg e.g <NoStoreFoundSvg fill={'red'} />

  6. Save all files and you will get your desired result Happy Coding!

nabilcambiaso commented 2 years ago

i'm using react-native-svg-transformer without using react-native-svg which i found very heavy in term of size, so i can resize and change the stroke color also the fill color, but just instead of passing a fill prop, just pass color as seen below, it works perfectly

import React from 'react';
import {
  View,
  Text,
  StyleSheet,
  TouchableOpacity,
} from 'react-native';
import { StatusBar } from 'expo-status-bar';
import Logo from "../../assets/profile.svg";

function FirstScreen(props) {
  return (
    <View style={styles.container}>
      <TouchableOpacity
        onPress={() => { props.navigation.navigate('SecondScreen'); }}
      >
        <Text>Welcome</Text>
        <View style={{ aspectRatio: 1,justifyContent:"center",alignItems:"center", backgroundColor: 'blue',width:200,height:200 }}>
        <Logo color="white" stroke="black" height={50} width={50} />
        </View>
      </TouchableOpacity>
      <StatusBar style="auto" />
    </View>
  );
}
const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});
export default FirstScreen;

the svg code <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 64 64"><title>profile</title><g fill="currentColor" class="nc-icon-wrapper"><path d="M38,37H26A19.021,19.021,0,0,0,7,56a1,1,0,0,0,.594.914C7.97,57.081,16.961,61,32,61s24.03-3.919,24.406-4.086A1,1,0,0,0,57,56,19.021,19.021,0,0,0,38,37Z"></path><path data-color="color-2" d="M32,32c8.013,0,14-8.412,14-15.933a14,14,0,1,0-28,0C18,23.588,23.987,32,32,32Z"></path></g></svg>

dependencies

  "dependencies": {
    "@expo/webpack-config": "~0.16.2",
    "@react-navigation/native": "^6.0.10",
    "@react-navigation/native-stack": "^6.6.2",
    "expo": "~45.0.0",
    "expo-font": "^10.1.0",
    "expo-status-bar": "~1.3.0",
    "react": "17.0.2",
    "react-dom": "17.0.2",
    "react-native": "0.68.2",
    "react-native-svg-transformer": "^1.0.0",
  },

metro.config.js file to add in the root

const { getDefaultConfig } = require('expo/metro-config');

module.exports = (() => {
  const config = getDefaultConfig(__dirname);

  const { transformer, resolver } = config;

  config.transformer = {
    ...transformer,
    babelTransformerPath: require.resolve('react-native-svg-transformer'),
  };
  config.resolver = {
    ...resolver,
    assetExts: resolver.assetExts.filter((ext) => ext !== 'svg'),
    sourceExts: [...resolver.sourceExts, 'svg'],
  };

  return config;
})();
kimkyeseung commented 2 years ago

replace width, height and fill to 'current' in `<svg ~ ..

Rakxhit commented 1 year ago

try all solutions but no one is working.

try removing all 'fill=...' from paths only and leave fill='none' in main svg tag

This is how i achieved.

no need of .svgrrc file in your svg file remove all fills then your svg will be invisible, then you can use the fill prop and change the colors,

YaBuLiang commented 1 year ago

已解决 记事本或者编辑器打开svg文件 删除svg图片文件里面的所有"fill="xxx"" 这样fill属性才会生效 可以改为你想要的颜色

lada commented 1 year ago

I can confirm that the color replacements do not work if you have fill="none" on the svg tag. To solve it, you can either remove the attribute manually or enable svgo in your .svgrrc file

{
  "replaceAttrValues": {
    "#000": "{props.fill}"
  },
  "svgo": true
}

The default SVGO config includes the removeUselessStrokeAndFill plugin which will remove the fill="none" from the svg tag. The color replacements then work.

rgomezp commented 1 year ago

Nothing I have tried has worked.

I'm using Expo and the cache clearing solution did not work for me (looks like outdated command).

<svg
   version="1.1"
   id="svg1"
   width="256"
   height="640"
   viewBox="0 0 256 640"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:svg="http://www.w3.org/2000/svg">
  <defs
     id="defs1" />
  <g
     id="layer7"
     style="display:inline">
    <path
      fill="#999999"
       style="display:inline;fill:#999999"
       d="m 182.88897,129.91589 c 0,0 2.15728,-4.07485 7.67032,-3.59546 5.51303,0.4794 7.91,3.11607 7.91,3.11607 0,0 5.51304,3.35576 6.71153,13.18334 1.19848,9.82759 1.43818,33.79731 1.43818,33.79731 0,0 -0.4794,5.27334 -3.83516,1.19849 -3.35576,-4.07486 -11.98486,-29.00337 -12.70395,-33.07822 -0.71909,-4.07485 -3.11606,-11.50547 -7.19092,-14.62153 z"
       id="path8" />
    <path
      fill="#999999"
       style="display:inline;fill:#999999"
       d="m 182.88897,129.91589 c 0,0 2.15728,-4.07485 7.67032,-3.59546 5.51303,0.4794 7.91,3.11607 7.91,3.11607 0,0 5.51304,3.35576 6.71153,13.18334 1.19848,9.82759 1.43818,33.79731 1.43818,33.79731 0,0 -0.4794,5.27334 -3.83516,1.19849 -3.35576,-4.07486 -11.98486,-29.00337 -12.70395,-33.07822 -0.71909,-4.07485 -3.11606,-11.50547 -7.19092,-14.62153 z"
       id="path33"
       transform="matrix(-1.0093018,0,0,1,257.44455,-0.33898305)" />
  </g>
</svg>

I created the SVG with inkscape so maybe has something to do with it?

faizanali1192 commented 1 year ago

Just removed the fill prop inside path and give path="none" in the parent svg tag like this.

<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
// Other svg path ...
</svg>

If you want to give the default color to svg or want to fill prop working as well you can give the default color in the fill prop

<svg width="20" height="20" viewBox="0 0 20 20" fill="#5B5B5F" xmlns="http://www.w3.org/2000/svg">
</svg>
YqxLzx commented 11 months ago

@KPS250 I exported my SVG from Figma and it set the property fill inside the <svg> to none.

<svg fill="none">

When that happen, every <path> (which are inside <svg>) are not getting colored, even if they are <path fill="#000000">. To fix the issue, I had to change fill="none" to fill="#000000" from the <svg> element. TLDR Ensure <svg> elements have fill="#000000" and nothing else

Also I fixed my problem by removing fill="white" in the <path></path> line and changing the <svg fill="none"> to <svg fill="#000000"> also I restarted the react-native server and actual app

Example: Old

<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M17.775 9...." fill="white"/>
</svg>

New

<svg width="24" height="24" viewBox="0 0 24 24" fill="#000000" xmlns="http://www.w3.org/2000/svg">
<path d="M17.775 9...."/>
</svg>

Thank you giving me a large inspiration , i both set "fill=none" to svg and path , that have work .

here is my code `

<svg fill="none" ... ><path fill="none" ...  /><svg/>

import IotIcon from '@assets/icons/app.svg'   

function IotIconBar(){
  return   <IotIcon fill={'red'} width="30" height="30" />
}

`

Thank you again 😊

matinzd commented 4 months ago

For those who are looking for setting a default value you can do this:

{
  "replaceAttrValues": {
    "#000": "{props?.fill ?? '#000'}"
  }
}

In this case if you don't pass fill, color will still be passed to the transformer and the default value will apply.

CR4ZED commented 1 month ago

expo r -c

thanks for sharing