DEV Community

simprl
simprl

Posted on • Edited on

Simplify SVG Management: Convert Paths to a Single JS File of Constants

When building React.js applications, managing SVG icons efficiently is crucial. SVGs provide the scalability and flexibility needed for responsive design, but handling them in large projects can become cumbersome. That’s where svg-path-constants comes in, a CLI tool designed to streamline your SVG workflow by converting SVG paths into reusable constants.

Why SVGs and Why Constants?

In a previous article, "A Comprehensive Comparison of SVG Icon Management Options in React.js Projects", I discussed various methods for managing SVG icons, including inline SVGs, SVG sprites, and using React components for each icon. While each method has its pros and cons, one challenge remains: keeping your SVG paths organized and reusable.

Using constants for SVG paths provide small bundle size and fast build time.

What is svg-path-constants?

svg-path-constants is a CLI tool that helps you generate constants from SVG files, making it easier to integrate and manage SVG icons in your React projects. It converts SVG paths into JS constants, supports flexible naming conventions, and allows for customizable output.

Key Features:

  • Generate Constants from SVG Files: Quickly convert SVG paths into constants.
  • Flexible Naming Conventions: Supports camelCase, PascalCase, snake_case, and SCREAMING_SNAKE_CASE.
  • Customizable Output: Generate constants with custom templates and file paths.
  • Attribute Conversion: Automatically converts SVG attributes like opacity, fill-opacity, stroke, and fill into path strings.
  • Single or Multiple Outputs: Generate a single output file or multiple files based on your input structure.

Getting Started with svg-path-constants

You can start using svg-path-constants immediately with npx:

npx svg-path-constants@latest
Enter fullscreen mode Exit fullscreen mode

Alternatively, you can install it globally or as a dev dependency:

npm install -g svg-path-constants
npm install --save-dev svg-path-constants
Enter fullscreen mode Exit fullscreen mode

Example Usage

Basic Usage

Let’s say you have SVG files in src/assets/icons and want to generate constants in src/components/Icon/paths.js:

npx svg-path-constants@latest -i src/assets/icons -o src/components/Icon/paths.js
Enter fullscreen mode Exit fullscreen mode

Output Example:

// src/components/Icon/paths.js
export const folderIcon1 = "M10 10 H 90 V 90 H 10 Z"; // Example SVG path
export const folderIcon2 = "M20 20 H 80 V 80 H 20 Z"; // Example SVG path
Enter fullscreen mode Exit fullscreen mode

Custom Naming Format

Specify a different naming format, like PascalCase:

npx svg-path-constants@latest -i src/assets/icons -o src/components/Icon/paths.js -f PascalCase
Enter fullscreen mode Exit fullscreen mode

Output Example:

// src/components/Icon/paths.js
export const FolderIcon1 = "M10 10 H 90 V 90 H 10 Z"; // Example SVG path
export const FolderIcon2 = "M20 20 H 80 V 80 H 20 Z"; // Example SVG path
Enter fullscreen mode Exit fullscreen mode

Using a Template for Output

Control the naming and file output with a custom template:

npx svg-path-constants@latest -i src/assets/icons -o src/components/Icon/{-2,-1}/{0}.js -t "{1,-3}"
Enter fullscreen mode Exit fullscreen mode

Output Example:

// src/components/Icon/folder/icon1.js
export const folderIcon1 = "M10 10 H 90 V 90 H 10 Z"; // Example SVG path

// src/components/Icon/folder/icon2.js
export const folderIcon2 = "M20 20 H 80 V 80 H 20 Z"; // Example SVG path
Enter fullscreen mode Exit fullscreen mode

Handling SVG Attributes

svg-path-constants can convert SVG attributes like opacity, fill-opacity, stroke, and fill into components of the path string.

Example SVG:

<svg>
    <path d="M10 10 H 90 V 90 H 10 Z" opacity="0.5" fill-opacity="0.8" stroke="#ff0000" fill="#00ff00"/>
</svg>
Enter fullscreen mode Exit fullscreen mode

Generated Path Constant:

export const myIcon = "o0.5 O0.8 fff000 F00ff00 M10 10 H 90 V 90 H 10 Z";
Enter fullscreen mode Exit fullscreen mode
  • opacity="0.5" becomes o0.5
  • fill-opacity="0.8" becomes O0.8
  • stroke="#ff0000" becomes fff000
  • fill="#00ff00" becomes F00ff00

This feature allows you to keep essential style information directly within the path string, maintaining a compact and informative representation.

Example: Using SVG Path Constants in a React Component

Once you have generated SVG path constants with svg-path-constants, you can easily integrate them into your React components. This not only keeps your code clean but also allows for easy reuse of SVG paths across your application.

Step 1: Generate SVG Path Constants

Let’s assume you’ve already run the following command to generate constants from your SVG files:

npx svg-path-constants@latest -i src/assets/icons -o src/components/Icon/paths.js
Enter fullscreen mode Exit fullscreen mode

This command generates a file src/components/Icon/paths.js with constants like:

// src/components/Icon/paths.js
export const folderIcon1 = "M10 10 H 90 V 90 H 10 Z"; // Example SVG path
export const folderIcon2 = "M20 20 H 80 V 80 H 20 Z"; // Example SVG path
Enter fullscreen mode Exit fullscreen mode

Step 2: Create a React Component to Render SVGs

Now, let’s create a React component that renders these SVG icons using the generated constants.

import React from 'react';
import { folderIcon1, folderIcon2 } from './paths'; // Import the generated SVG path constants

const parsePathData = (d) => {
    const pathElements = [];
    const pathCommands = d.split(/(o[\d.]+|O[\d.]+|f[0-9a-fA-F]+|F[0-9a-fA-F]+)/); // Split by style commands
    let attributes = null;

    pathCommands.forEach((text, i) => {
        const isCommand = Boolean(i % 2);
        if (isCommand) {
            if (!attributes) {
                attributes = {};
            }
            const match = text.match(/^(o([\d.]+))?(O([\d.]+))?(f([0-9a-fA-F]+))?(F([0-9a-fA-F]+))?$/);

            const [, , opacity, , fillOpacity, , stroke, , fill] = match;
            if (opacity) attributes.opacity = opacity;
            if (fillOpacity) attributes["fill-opacity"] = fillOpacity;
            if (stroke) attributes.stroke = `#${stroke}`;
            if (fill) attributes.fill = `#${fill}`;
            return;
        }
        if (text.trim().length) {
            pathElements.push({ ...attributes, d: text });
        }
    });

    return pathElements;
};


const SvgIcon = ({ d, size = 24, color = 'currentColor', ...props }) => {
    const pathElements = parsePathData(d);

    return (
        <svg
            width={size}
            height={size}
            viewBox="0 0 24 24"
            fill={color}
            xmlns="http://www.w3.org/2000/svg"
            {...props}
        >
            {pathElements.map((attrs, index) => (
                <path key={index} {...attrs} />
            ))}
        </svg>
    );
};

const IconDemo = () => (
    <div>
        <h2>SVG Icon Examples</h2>
        <div>
            <h3>Folder Icon 1</h3>
            <SvgIcon path={folderIcon1} size={48} color="blue" />
        </div>
        <div>
            <h3>Folder Icon 2</h3>
            <SvgIcon path={folderIcon2} size={48} color="green" />
        </div>
    </div>
);

export default IconDemo;
Enter fullscreen mode Exit fullscreen mode

Step 3: Use the Component in Your Application

You can now use the IconDemo component anywhere in your React application to display the SVG icons:

import React from 'react';
import ReactDOM from 'react-dom';
import IconDemo from './components/Icon/IconDemo';

ReactDOM.render(
    <React.StrictMode>
        <IconDemo />
    </React.StrictMode>,
    document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

Explanation:

  1. parsePathData Function:

    • It is needed only if you have opacity or multiple colors in the SVG file.
    • The parsePathData function processes the extended d attribute string, extracting commands like o (opacity), F (fill color), and f (stroke color).
    • It splits the string based on these commands, applies the corresponding attributes, and returns an array of path elements.
  2. SvgIcon Component:

    • This component takes a d attribute string, parses it with parsePathData, and renders the SVG paths.
    • The component allows customization through props like size and color.
  3. IconDemo Component:

    • This is a demo component that shows how to use the SvgIcon component with different d strings, sizes, and colors.

What's Next? Adding Raster Images to Constants

I’m currently working on an npm library that will enhance svg-path-constants by adding raster images (PNGs) as comments above each generated constant. This will provide a visual representation of the icon directly in your code, making it easier to identify and manage SVG paths.

Conclusion

Managing SVG paths in React projects doesn’t have to be a hassle. With svg-path-constants, you can keep your icons organized, your code clean, and your workflow efficient. And soon, with the upcoming library for adding raster images to icon comments, you'll have an even more visual and intuitive way to manage your SVG assets.

Try svg-path-constants today:

npx svg-path-constants@latest
Enter fullscreen mode Exit fullscreen mode

And stay tuned for more updates!

Top comments (0)