One SVG to Rule Them All: The Dynamic Way

andreasbergstrom

Andreas Bergström

Posted on April 13, 2023

One SVG to Rule Them All: The Dynamic Way

When working with SVG icons in a React Native app, it's quite common to end up with numerous variations of the same icon, differing only in stroke width, color, or other styling attributes. This can lead to an ever-growing list of assets, making it difficult to manage and maintain your icons. Instead, we can leverage the power of SVG's dynamic nature by using strokeWidth and currentColor to make our icons flexible and adaptable.

In this blog post, we'll explore how to dynamically configure SVG elements in a React Native app using strokeWidth and currentColor. By doing so, you can easily change the appearance of your SVG components by passing props to them, eliminating the need for multiple variations of the same icon. This approach results in a cleaner codebase and improves maintainability. We'll be using the react-native-svg and react-native-svg-transformer packages to accomplish this.

The Benefits of a Dynamic Approach

There are several advantages to dynamically configuring SVG elements compared to using multiple inline SVGs or separate icon files:

Reduced Asset Management: Instead of creating a separate icon file for each variation, you can maintain a single SVG file that adapts its appearance based on the props you pass. This simplifies your codebase and reduces the number of files you need to manage.

Improved Performance: Using a single SVG file reduces the number of assets that need to be fetched and rendered, which can improve the performance of your app.

Easier Theming and Styling: By passing props like color and strokeWidth, you can easily change the appearance of your icons across your entire app, making it easier to implement themes and adjust styles.

Greater Flexibility: Using a dynamic approach makes it easier to update the appearance of your icons in response to user interactions, such as changing colors on hover or focus events.

Now, let's dive into the implementation details and create a flexible SVG component that dynamically adapts to the props passed.

Getting Started

First, let's install the necessary packages:

npm install react-native-svg
npm install --save-dev react-native-svg-transformer
Enter fullscreen mode Exit fullscreen mode

Now, configure the metro.config.js file to use the react-native-svg-transformer:

const { getDefaultConfig } = require("metro-config");

module.exports = (async () => {
  const {
    resolver: { sourceExts, assetExts },
  } = await getDefaultConfig();
  return {
    transformer: {
      babelTransformerPath: require.resolve("react-native-svg-transformer"),
      getTransformOptions: async () => ({
        transform: {
          experimentalImportSupport: false,
          inlineRequires: false,
        },
      }),
    },
    resolver: {
      assetExts: assetExts.filter((ext) => ext !== "svg"),
      sourceExts: [...sourceExts, "svg"],
    },
  };
})();
Enter fullscreen mode Exit fullscreen mode

Creating an SVG Component

Let's create an SVG file called MyIcon.svg with a path element that accepts strokeWidth and currentColor:

<!-- MyIcon.svg -->
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
  <path stroke="currentColor" strokeWidth="{strokeWidth}" d="M7 7l10 10M7 17l10-10" />
</svg>
Enter fullscreen mode Exit fullscreen mode

Here, we use the currentColor value to make the stroke color inherit the color from the color CSS property. We also use a placeholder value {strokeWidth} to accept the stroke width as a prop.

Using the SVG Component

Now, let's import the SVG file as a component in our React Native component and pass color and strokeWidth props to it:

import React from 'react';
import { View } from 'react-native';
import MyIcon from './path/to/MyIcon.svg';

const App = () => {
  return (
    <View>
      <MyIcon width={24} height={24} color="red" strokeWidth={2} />
    </View>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

With this setup, the imported SVG component's stroke color and stroke width will be dynamically set to the values of the color and strokeWidth props, respectively.

By using the currentColor and strokeWidth attributes in your SVG elements, you can create flexible and dynamic components that easily adapt to your design requirements. This approach can be extended to other stroke-related properties like strokeLinecap, strokeLinejoin, and strokeOpacity. Just add the corresponding attributes to your SVG file and pass them as props to your imported SVG component.

💖 💪 🙅 🚩
andreasbergstrom
Andreas Bergström

Posted on April 13, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related