Icon system in React

Very often, when developing a React application, we have to work with a large number of icons in the project. Probably every developer strives to simplify and automate such routine tasks as much as possible. There are several ways to work with icons in web applications, but I want to share with you the one that seems most convenient to me. This article will help frontend developers make working with icons more comfortable by using them as React components.

What is it for?

Our icons will be embedded directly into HTML markup in the form of svg elements, which in turn will allow us to interact with their attributes and styles. Also, all icons will be imported from one component, thereby keeping our imports clean and tidy.

How to implement this?

In order to deploy such an icon system, we will need to use the package SVGRwhich is responsible for the main transformation of the svg icon into a react component.

Step 1

The first step in the project is to create a folder where we will store the original svg icons, for example src/assets/icons.

Step 2

Install SVGR according to the official documentationor copy this line to the command line:

npm install --save-dev @svgr/webpack @svgr/cli @svgr/core

Step 3

After we have installed the necessary packages, we need to create a file called svgr.config.js. In the config, we need to specify the final folder where the converted icons will be stored in the form of components and set a template for how the final components will look. More details about template customization can also be read in the official documentation.

// svgr.config.js

const path = require('path');
const outDir="./src/ui/icons"; // путь, до папки, где будут храниться преобразованные иконки

// Шаблон компонента с иконкой
const iconTemplate = (variables, { tpl }) => tpl`
${variables.imports};

${variables.interfaces};

const ${variables.componentName} = (${variables.props}) => (
  ${variables.jsx}
);
 
${variables.exports};
`;


// Шаблон файла index.js, который будет экспортировать все сгенерированные компоненты иконок
function indexTemplate(files) {
  const compoundExportEntries = [];

  const importEntries = files.map(file => {
    const componentName = path.basename(file.path, path.extname(file.path));
    compoundExportEntries.push(componentName);

    return `import { default as ${componentName} } from './${componentName}';`;
  });

  return `${importEntries.join('\n')}

    export const Icons = {
      ${compoundExportEntries.join(',\n  ')}
    };
  `;
}

// Базовая настройка конфига
module.exports = {
  outDir,
  icon: true,
  typescript: false,
  replaceAttrValues: {
    '#000': 'currentColor',
  },
  indexTemplate,
  template: iconTemplate,
};

Step 4

All that remains to be done is to update the list of npm commands. We need to add a new command that will run the SVGR conversion, like this npm run icons. For convenience, we will add the execution of this command every time we assemble a build or launch our project, so that at these stages we always have up-to-date icon components.

// package.json
...
"icons": "svgr ./src/assets/icons",
"dev": "npm run icons && webpack serve",
"build": "npm run icons && webpack --config somebuild.webpack.js"

I also recommend adding a folder with converted icons to .gitignoresince every time we start the project, the files will be generated anew and there is little point in pulling them into the repository.

Conclusion

This system can be expanded and modified, for example, you can attach some small gulp script that will monitor the folder with the source svg icons and automatically start the conversion, while updating the components. But even this version will be enough for comfortable interaction with icons, allowing you to avoid duplicates and use more convenient import in the form of components.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *