Search code examples
reactjsreact-nativesvgsvg-rect

SVGR React Native .svg file


I have a confusing .svg file, where vectors are created with strokes and fill. And I want to customize my local .svg file's color. For example if I write

<TestIconFlexible width='100%' height='100%' fill='red' />

My React Native will change real vector colors into red.

My testing .svg file is this

<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M19 12.5H23" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M9 12.5H13" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M11 10.5V14.5" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M21.5022 5.96747L10.5004 5.99999C8.9722 6.00011 7.49286 6.53852 6.32207 7.52073C5.15129 8.50293 4.3639 9.86615 4.09811 11.3711L4.09918 11.3713L2.05363 21.8916C1.92442 22.6247 2.03227 23.3798 2.36151 24.0474C2.69074 24.715 3.22422 25.2602 3.88446 25.6039C4.5447 25.9476 5.29732 26.0719 6.03301 25.9587C6.7687 25.8455 7.44915 25.5008 7.97553 24.9745L7.97533 24.9743L13.3798 19L21.5022 18.9675C23.2261 18.9675 24.8794 18.2826 26.0984 17.0637C27.3173 15.8447 28.0022 14.1914 28.0022 12.4675C28.0022 10.7436 27.3173 9.09026 26.0984 7.87127C24.8794 6.65229 23.2261 5.96747 21.5022 5.96747V5.96747Z" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
    <path d="M27.9035 11.3387L29.9474 21.8916C30.0766 22.6247 29.9688 23.3798 29.6395 24.0474C29.3103 24.715 28.7768 25.2602 28.1166 25.6039C27.4563 25.9476 26.7037 26.0719 25.968 25.9587C25.2323 25.8455 24.5519 25.5008 24.0255 24.9745L24.0257 24.9743L18.625 18.979" stroke="#000" stroke-width="2.3" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

I have set all necessary configurations to React Native project, for rendering my local .svg files. And this is my .svgrrc file configuration.

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

Which I think that sees if I pass a fill property from my TestIconFlexible "component", and there are #000 colors, it will change into my passed color. In other words #000 is a keyword which I can change from props.

When I run the project I get fully red svg icon.

These are my all dependencies of React Native App.

"dependencies": {
    "@expo/metro-config": "^0.1.64",
    "@react-native-community/masked-view": "0.1.10",
    "@react-navigation/bottom-tabs": "^5.11.10",
    "@react-navigation/native": "^5.9.4",
    "@react-navigation/stack": "^5.14.4",
    "expo": "~41.0.1",
    "expo-app-loading": "^1.0.3",
    "expo-font": "~9.1.0",
    "expo-status-bar": "~1.0.4",
    "react": "16.13.1",
    "react-dom": "16.13.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
    "react-native-collapsible": "^1.5.3",
    "react-native-gesture-handler": "~1.10.2",
    "react-native-iphone-x-helper": "^1.3.1",
    "react-native-raw-bottom-sheet": "^2.2.0",
    "react-native-reanimated": "~2.1.0",
    "react-native-safe-area-context": "3.2.0",
    "react-native-screens": "~3.0.0",
    "react-native-svg": "12.1.0",
    "react-native-web": "~0.13.12"
  },
  "devDependencies": {
    "@babel/core": "^7.9.0",
    "@react-native-community/eslint-config": "^2.0.0",
    "eslint": "^7.25.0",
    "eslint-config-airbnb": "^18.2.1",
    "eslint-config-airbnb-base": "^14.2.1",
    "eslint-config-react-app": "^6.0.0",
    "eslint-plugin-import": "^2.22.1",
    "eslint-plugin-jsx-a11y": "^6.4.1",
    "react-native-svg-transformer": "^0.14.3"
  },

Solution

  • In my experience working with svgs is quite tricky. So what i do is usually convert them to react components using react-native-svg in combination with online SVGR tool.

    simply copy paste your svg to SVGR playground input, check 'react-native' tick expand props to 'none' and copy paste the result into your code as an react component, then add props and functions etc. But delete xmlns="http://www.w3.org/2000/svg" line, this gives me errors every time for some reason.

    here's an example of how svg component looks in one of my projects:

    import { colors } from '@src/style/colors';
    import React from 'react';
    import Svg, { Path } from 'react-native-svg';
    
    interface Props {
      fill?: string;
    }
    const Check = ({ fill = colors.greenAccent }: Props) => {
      return (
        <Svg width="18" height="18" viewBox="0 0 18 18" fill="none">
          <Path
            d="M8.99995 0C4.03741 ..." // i deleted the long path here for simplicity fo example
            fill={fill}
          />
        </Svg>
      );
    };
    
    export default Check;
    

    and then use it in my JSX like this:

    import { Check } from '@src/assets/icons';
    
    ... //other code
    
    <View style={styles.textWrap}>
      <Check />
        <Paragraph style={styles.text}>{text}</Paragraph>
    </View>
    
    ... //other code