One SVG to Rule Them All: The Dynamic Way
Andreas Bergström
Posted on April 13, 2023
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
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"],
},
};
})();
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>
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;
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.
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
November 15, 2024