npm package: @genexus/svg-sass-generator
Description: SVG Icon Generator: A Node.js tool for creating customizable SVG icons with color states like hover and active effects. It generates SVG icons and Sass placeholder selectors, simplifying integration into projects with generated CSS class names for scalabl
Author: GeneXus
Latest version: 1.2.0

# svg-sass-generator

- [What is this tool about?](#what-is-this-tool-about)
- [Key aspects this tools resolves](#key-aspects-this-tools-resolves)
- [Ice-cream icons transformation example](#ice-cream-icons-transformation-example)
  - [Monochrome icons example](#monochrome-icons-example)
  - [Multicolor icons example](#multicolor-icons-example)
- [Configuration file](#configuration-file)
  - [Overriding Config parameters](#overriding-config-parameters)
- [Common questions](#common-questions)
- [Final comments](#final-comments)
  - [SVG export figma plugin](#svg-export-plugin)
  - [This readme showcase](#this-readme-showcase)

## What is this tool about?

**Svg Sass Generator** ('ssg' for short) is a tool that helps you manage multi-color or mono-chrome SVG icons across different UI states: `enabled`, `hover`, `active`, and `disabled`. It was created for managing icons on GeneXus Next, or for developers that collaborate with custom plugins.

It specially solves the common issue where masking + background color isn't enough when icons contain multiple figures with different colors. For any of both types (multi-color or mono-chrome) You define your colors palette for each state (`enabled`, `hover`, `active`, and `disabled`) and the tool generates new SVG's with the proper styling, that work also with dark or light themes.

Think of it like a modern SVG sprite system: one master file holds all stateful variations, and you simply use the version you need.

![View use demo](./docs/readme/view-use.png)

<small>_This shows how the icons work after being processed._</small>

---

## Key aspects this tools resolves:

#### 1. Icons with one or multiple colors, in different states:

You give the tool your color choices and some SVG icons. It then creates SVG files ready to show these icons in different states like: `enabled`, `hover`, `active`, and `disabled`. It can also make versions for light and dark themes if you want.

#### 2. CSS Custom Variables:

The tool creates special CSS variables for each icon’s state. For example, there’s a variable for the `hover` state of the `system/user` icon that you can use easily in your styles.

```css
:root.light {
  --icon__system_user--hover: url("#{$icons-path}system/light/user.svg#hover");
}
:root.dark {
  --icon__system_user--hover: url("#{$icons-path}system/dark/user.svg#hover");
}
```

#### 3. An assets file for Chameleon

The Chameleon library includes a `ch-image` control that displays different icons based on state (e.g., focus, hover, active, disabled). This tool generates a TypeScript file with all icon definitions, allowing `ch-image` to automatically resolve the correct icon for each state.

Showing a multi-state icon with `ch-image` is really simple:

```ts
const USER_ICON = getIconPath({
  category: "system",
  name: "user",
}, "your-vendor-alias");
<ch-image src={USER_ICON}>
```

> 🤔 **What is Chameleon?**  
> [Chameleon](https://github.com/genexuslabs/chameleon-controls-library?tab=readme-ov-file#chameleon) is a collection of ready-made web components.  
> They are easy to customize, fast, lightweight, and work well for everyone.
> Chameleon is developed and maintained by GeneXus, and is the main components library used in GeneXus Next.

<sub>[↑ Go back to index](#svg-sass-generator)

---

## Ice Cream Icons Transformation Example

This example shows how to process both single-color and multi-color icons.  
We picked ice cream icons because their scoops are a great way to show multi-color icons—or just one color if you want a one flavor ice cream!

> 📝 **`Configuration file parameters`**  
> Whether you’re processing single-color or multi-color icons, the tool needs a `.js` config file with some settings and color palettes. In the examples below, we’ll focus on the color palettes. Other settings will be explained later.

### Monochrome icons example

It’s best to keep icons organized in folders by category. We recommend creating one folder for each category of icons. Here, we have a folder called `/ice-cream-cones` with one single-color icon named `regular-cone.svg`:

```
/src
└── ice-cream-cones/
    └── regular-cone.svg
```

Next, in the configuration file, list the monochrome colors you want to use:

#### Monochrome palette:

```js
export default {
  config: {
    // ... (details about config later)
  },
  icons: {
    monochrome: {
      colors: [
        {
          name: "blueberry",
          states: {
            enabled: { light: "#7a6ed3", dark: "#9d90ff" },
            hover: { light: "#a59dec", dark: "#c1baff" },
            active: { light: "#5a4fb8", dark: "#7a6ae6" },
            disabled: { light: "#b1abc9", dark: "#48445c" },
          },
        },
        {
          name: "chocolate",
          states: {
            enabled: { light: "#7b4a1c", dark: "#b26b34" },
            hover: { light: null, dark: null },
            active: { light: null, dark: null },
            disabled: { light: null, dark: null },
          },
        },
        {
          name: "chocolate-chip",
          states: {
            enabled: { light: "#9e7b6a", dark: "#bb9b89" },
            hover: { light: null, dark: null },
            active: { light: null, dark: null },
            disabled: { light: null, dark: null },
          },
        },
        {
          name: "mango",
          states: {
            enabled: { light: "#ffb84c", dark: "#ffc266" },
            hover: { light: "#ffd08b", dark: "#ffd999" },
            active: { light: "#e6931a", dark: "#e6a23f" },
            disabled: { light: "#d9c3a0", dark: "#5b4f38" },
          },
        },
        {
          name: "mint",
          states: {
            enabled: { light: "#5ec5a2", dark: "#8de4c2" },
            hover: { light: "#a2e5d0", dark: "#c3f8e6" },
            active: { light: "#3e9e7d", dark: "#64b89b" },
            disabled: { light: "#aacac0", dark: "#45504e" },
          },
        },
        {
          name: "pineapple",
          states: {
            enabled: { light: "#fbe96a", dark: "#ffeb84" },
            hover: { light: "#fef4a7", dark: "#fff3bb" },
            active: { light: "#e5cb27", dark: "#ffd83d" },
            disabled: { light: "#d1c58d", dark: "#5e583e" },
          },
        },
        {
          name: "strawberry",
          states: {
            enabled: { light: "#e85c85", dark: "#ff94b4" },
            hover: { light: "#f5a0b7", dark: "#ffd0dd" },
            active: { light: "#b03b64", dark: "#e2568e" },
            disabled: { light: "#c9a2ab", dark: "#574f53" },
          },
        },
      ],
    },
  },
};
```

> 🤔 **Why are some values null for `chocolate` and `chocolate-chip`?**  
> A null means that state is not available. So, `chocolate` and `chocolate-chip` only have the `enabled` state.

Finally, tell the tool which icon folders are monochrome by listing them in the `icons.categories` array:

```js
export default {
  config: {
    // ... (details about config later)
  },
  icons: {
    monochrome: {
      colors: [
        // (Already provided above)
      ],
      categories: [
        {
          name: "ice-cream-cones",
          ignoredColors: ["mint", "pineapple"],
        },
        {
          name: "other-direcoty-a",
          ignoredColors: [],
        },
        {
          name: "other-direcotry-b",
          ignoredColors: [`mint`],
        },
      ],
    },
  },
};
```

> 🤔 **What is `ignoredColors` for?**  
> It’s a list of colors the tool should skip for a specific folder.  
> In the example, the tool ignores `mint` and `pineapple` colors in the "ice-cream-cones" folder.  
> The `other-directory-a` folder uses all colors, and `other-directory-b` only ignores `mint`.
> This helps you avoid extra XML or CSS you don’t need for certain categories.

#### svg source: `src/ice-cream-cones/regular-cone.svg`

This is the source icon, before being processed:

![Choco overload icon source](./test/icons/src/ice-cream-cones/regular-cone.svg)

```xml
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <path fill="#9C9C9C" d="M43.57... continues"/>
</svg>
```

#### svg output: `generated/ice-cream-cones/light/regular-cone.svg`

This is the output icon, after being processed:

| Icon             | Enabled                                                                            | Hover                                                                      | Active                                                                       | Disabled                                                                         |
| ---------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| `blueberry`      | ![Enabled](./docs/readme/ice-cream-cones/regular-cone.svg#blueberry--enabled)      | ![Hover](./docs/readme/ice-cream-cones/regular-cone.svg#blueberry--hover)  | ![Active](./docs/readme/ice-cream-cones/regular-cone.svg#blueberry--active)  | ![Disabled](./docs/readme/ice-cream-cones/regular-cone.svg#blueberry--disabled)  |
| `chocolate`      | ![Enabled](./docs/readme/ice-cream-cones/regular-cone.svg#chocolate--enabled)      | <div style="align:center; line-height:64px;">✖️</div>                      | <div style="align:center; line-height:64px;">✖️</div>                        | <div style="align:center; line-height:64px;">✖️</div>                            |
| `chocolate-chip` | ![Enabled](./docs/readme/ice-cream-cones/regular-cone.svg#chocolate-chip--enabled) | <div style="align:center; line-height:64px;">✖️</div>                      | <div style="align:center; line-height:64px;">✖️</div>                        | <div style="align:center; line-height:64px;">✖️</div>                            |
| `mango`          | ![Enabled](./docs/readme/ice-cream-cones/regular-cone.svg#mango--enabled)          | ![Hover](./docs/readme/ice-cream-cones/regular-cone.svg#mango--hover)      | ![Active](./docs/readme/ice-cream-cones/regular-cone.svg#mango--active)      | ![Disabled](./docs/readme/ice-cream-cones/regular-cone.svg#mango--disabled)      |
| `strawberry`     | ![Enabled](./docs/readme/ice-cream-cones/regular-cone.svg#strawberry--enabled)     | ![Hover](./docs/readme/ice-cream-cones/regular-cone.svg#strawberry--hover) | ![Active](./docs/readme/ice-cream-cones/regular-cone.svg#strawberry--active) | ![Disabled](./docs/readme/ice-cream-cones/regular-cone.svg#strawberry--disabled) |

```xml
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <defs>
    <g id="icon-def">
      <path fill="var(--color)" d="M43.57... continues"></path>
    </g>
  </defs>

  <view id="blueberry--enabled" viewBox="0 0 64 64" />
  <use href="#icon-def" x="0" y="0" style="--color:#7a6ed3" />

  <view id="blueberry--hover" viewBox="64 0 64 64" />
  <use href="#icon-def" x="64" y="0" style="--color:#a59dec" />

  <view id="blueberry--active" viewBox="128 0 64 64" />
  <use href="#icon-def" x="128" y="0" style="--color:#5a4fb8" />

  <view id="blueberry--disabled" viewBox="192 0 64 64" />
  <use href="#icon-def" x="192" y="0" style="--color:#b1abc9" />

  <view id="chocolate--enabled" viewBox="0 64 64 64" />
  <use href="#icon-def" x="0" y="64" style="--color:#7b4a1c" />

  <view id="chocolate-chip--enabled" viewBox="0 128 64 64" />
  <use href="#icon-def" x="0" y="128" style="--color:#9e7b6a" />

  <view id="mango--enabled" viewBox="0 192 64 64" />
  <use href="#icon-def" x="0" y="192" style="--color:#ffb84c" />

  <view id="mango--hover" viewBox="64 192 64 64" />
  <use href="#icon-def" x="64" y="192" style="--color:#ffd08b" />

  <view id="mango--active" viewBox="128 192 64 64" />
  <use href="#icon-def" x="128" y="192" style="--color:#e6931a" />

  <view id="mango--disabled" viewBox="192 192 64 64" />
  <use href="#icon-def" x="192" y="192" style="--color:#d9c3a0" />

  <view id="strawberry--enabled" viewBox="0 256 64 64" />
  <use href="#icon-def" x="0" y="256" style="--color:#e85c85" />

  <view id="strawberry--hover" viewBox="64 256 64 64" />
  <use href="#icon-def" x="64" y="256" style="--color:#f5a0b7" />

  <view id="strawberry--active" viewBox="128 256 64 64" />
  <use href="#icon-def" x="128" y="256" style="--color:#b03b64" />

  <view id="strawberry--disabled" viewBox="192 256 64 64" />
  <use href="#icon-def" x="192" y="256" style="--color:#c9a2ab" />
</svg>
```

### Multicolor icons example

It’s best to make one folder for each icon category. We recommend creating one folder for each category of icons. Here, we have a folder `/ice-cream-bowls` with five different icons:

> 📝 These five icons look alike, but each has different colors, so they are treated as separate icons.

```
/src
└── ice-cream-bowls/
    └── berry-patch.svg
    └── choco-overload.svg
    └── minty-breeze.svg
    └── neapolitan-classic.svg
    └── tropical-trio.svg
```

Next, in the configuration file, list the multicolor colors you want to use:

#### Multicolor palette:

```js
export default {
  config: {
    // ... (details about config later)
  },
  icons: {
    multicolor: {
      colors: [
        {
          name: "chocolate-chip",
          states: {
            enabled: { light: "#9e7b6a", dark: "#bb9b89" },
            hover: { light: "#b89a8c", dark: "#d1b7a8" },
            active: { light: "#7a5947", dark: "#9e7967" },
            disabled: { light: "#c7bab2", dark: "#4f463f" },
          },
        },
        {
          name: "coconut",
          states: {
            enabled: { light: "#fefefe", dark: "#d9d9d9" },
            hover: { light: "#f2f2f2", dark: "#bbbbbb" },
            active: { light: "#e6e6e6", dark: "#ffffff" },
            disabled: { light: "#cccccc", dark: "#666666" },
          },
        },
        {
          name: "cookies-cream",
          states: {
            enabled: { light: "#f3f1ef", dark: "#d8d5d2" },
            hover: { light: "#e4e2e0", dark: "#c2bebc" },
            active: { light: "#cfcac5", dark: "#a7a29e" },
            disabled: { light: "#bcb8b3", dark: "#5b5752" },
          },
        },
        // and so on...
      ],
    },
  },
};
```

#### 🍨 Berry Patch:

**Before processing**: This is the original "Berry Patch" ice cream icon:
`src/ice-cream-bolws/berry-patch.svg`

![Berry patch icon source](./test/icons/src/ice-cream-bowls/berry-patch.svg)

```xml
<svg class="berry-patch" xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <g class="group">
    <path class="cherry" fill="#9C9C9C" d="M33.2... continues"/>
    <path class="blueberry" fill="#9C9C9C" d="M14.4... continues"/>
    <path class="strawberry" fill="#9C9C9C" d="M40.8... continues"/>
    <path class="bowl" fill="#9C9C9C" d="M42.6... continues"/>
  </g>
</svg>
```

**After processing**: This is the "Berry Patch" icon after the tool has prepared it for use:
`generated/ice-cream-bolws/light/berry-patch.svg`

| ![Enabled](./docs/readme/ice-cream-bowls/berry-patch.svg#enabled) | ![Hover](./docs/readme/ice-cream-bowls/berry-patch.svg#hover) | ![Active](./docs/readme/ice-cream-bowls/berry-patch.svg#active) | ![Disabled](./docs/readme/ice-cream-bowls/berry-patch.svg#disabled) |
| :---------------------------------------------------------------: | :-----------------------------------------------------------: | :-------------------------------------------------------------: | :-----------------------------------------------------------------: |
|                              Enabled                              |                             Hover                             |                             Active                              |                              Disabled                               |

<br>

#### 🍨 Choco Overload:

**Before processing**: This is the original "Choco Overload" ice cream icon:
`src/ice-cream-bolws/choco-overload.svg`

![Berry patch icon source](./test/icons/src/ice-cream-bowls/choco-overload.svg)

```xml
<svg class="choco-overload" xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <g class="group">
    <path class="cookies-cream" fill="#9C9C9C" d="M33.2... continues"/>
    <path class="milk-chocolate" fill="#9C9C9C" d="M14.4... continues"/>
    <path class="dark-chocolate" fill="#9C9C9C" d="M40.8... continues"/>
    <path class="bowl" fill="#9C9C9C" d="M42.6... continues"/>
  </g>
</svg>
```

**After processing**: This is the "Choco Overload" icon after the tool has prepared it for use:
`generated/ice-cream-bolws/light/choco-overload.svg`

| ![Enabled](./docs/readme/ice-cream-bowls/choco-overload.svg#enabled) | ![Hover](./docs/readme/ice-cream-bowls/choco-overload.svg#hover) | ![Active](./docs/readme/ice-cream-bowls/choco-overload.svg#active) | ![Disabled](./docs/readme/ice-cream-bowls/choco-overload.svg#disabled) |
| :------------------------------------------------------------------: | :--------------------------------------------------------------: | :----------------------------------------------------------------: | :--------------------------------------------------------------------: |
|                               Enabled                                |                              Hover                               |                               Active                               |                                Disabled                                |

<br>

#### 🍨 Minty Breeze:

**Before processing**: This is the original "Minty Breeze" ice cream icon:
`src/ice-cream-bolws/minty-breeze.svg`

![Berry patch icon source](./test/icons/src/ice-cream-bowls/minty-breeze.svg)

```xml
<svg class="minty-breeze" xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <g class="group">
    <path class="blueberry" fill="#9C9C9C" d="M33.28..."/>
    <path class="milk-chocolate" fill="#9C9C9C" d="M14.44..."/>
    <path class="mint" fill="#9C9C9C" d="M40.86..."/>
    <path class="bowl" fill="#9C9C9C" d="M42.68..."/>
  </g>
</svg>
```

**After processing**: This is the "Minty Breeze" icon after the tool has prepared it for use:
`generated/ice-cream-bolws/light/minty-breeze.svg`

| ![Enabled](./docs/readme/ice-cream-bowls/minty-breeze.svg#enabled) | ![Hover](./docs/readme/ice-cream-bowls/minty-breeze.svg#hover) | ![Active](./docs/readme/ice-cream-bowls/minty-breeze.svg#active) | ![Disabled](./docs/readme/ice-cream-bowls/minty-breeze.svg#disabled) |
| :----------------------------------------------------------------: | :------------------------------------------------------------: | :--------------------------------------------------------------: | :------------------------------------------------------------------: |
|                              Enabled                               |                             Hover                              |                              Active                              |                               Disabled                               |

<br>

#### 🍨 Neapolitan Classic:

**Before processing**: This is the original "Neapolitan Classic" ice cream icon:
`src/ice-cream-bolws/neapolitan-classic.svg`

![Berry patch icon source](./test/icons/src/ice-cream-bowls/neapolitan-classic.svg)

```xml
<svg class="neapolitan-classic" xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <g class="group">
    <path class="vanilla" fill="#9C9C9C" d="M33.28..."/>
    <path class="chocolate" fill="#9C9C9C" d="M14.44..."/>
    <path class="strawberry" fill="#9C9C9C" d="M40.86..."/>
    <path class="bowl" fill="#9C9C9C" d="M42.68..."/>
  </g>
</svg>
```

**After processing**: This is the "Neapolitan Classic" icon after the tool has prepared it for use:
`generated/ice-cream-bolws/light/neapolitan-classic.svg`

| ![Enabled](./docs/readme/ice-cream-bowls/neapolitan-classic.svg#enabled) | ![Hover](./docs/readme/ice-cream-bowls/neapolitan-classic.svg#hover) | ![Active](./docs/readme/ice-cream-bowls/neapolitan-classic.svg#active) | ![Disabled](./docs/readme/ice-cream-bowls/neapolitan-classic.svg#disabled) |
| :----------------------------------------------------------------------: | :------------------------------------------------------------------: | :--------------------------------------------------------------------: | :------------------------------------------------------------------------: |
|                                 Enabled                                  |                                Hover                                 |                                 Active                                 |                                  Disabled                                  |

<br>

#### 🍨 Tropical Trio:

**Before processing**: This is the original "Tropical Trio" ice cream icon:
`src/ice-cream-bolws/tropical-trio.svg`

![Berry patch icon source](./test/icons/src/ice-cream-bowls/tropical-trio.svg)

```xml
<svg class="tropical-trio" xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <g class="group">
    <path class="pineapple" fill="#9C9C9C" d="M33.28..."/>
    <path class="coconut" fill="#9C9C9C" d="M14.44..."/>
    <path class="mango" fill="#9C9C9C" d="M40.86..."/>
    <path class="bowl" fill="#9C9C9C" d="M42.68..."/>
  </g>
</svg>
```

**After processing**: This is the "Tropical Trio" icon after the tool has prepared it for use:
`generated/ice-cream-bolws/light/tropical-trio.svg`

| ![Enabled](./docs/readme/ice-cream-bowls/tropical-trio.svg#enabled) | ![Hover](./docs/readme/ice-cream-bowls/tropical-trio.svg#hover) | ![Active](./docs/readme/ice-cream-bowls/tropical-trio.svg#active) | ![Disabled](./docs/readme/ice-cream-bowls/tropical-trio.svg#disabled) |
| :-----------------------------------------------------------------: | :-------------------------------------------------------------: | :---------------------------------------------------------------: | :-------------------------------------------------------------------: |
|                               Enabled                               |                              Hover                              |                              Active                               |                               Disabled                                |

<sub>[↑ Go back to index](#svg-sass-generator)

---

## Configuration file

The tool requires a `.js` configuration file, that defines a set of parameters, and the colors values for the icons. You can name the file as you like, since you will have to run a script referncing this file. In the following example, we are calling this file `config.js`.

> 📂 **Note about paths:** All paths in `config.js` should be relative to the current working directory—that is, the directory from which you run the SVG Sass generator script. This is usually the root of your project, typically where `package.json` is located.

### `config.js:`

```js
export default {
  config: {
    enableLight: true, // If true, it will process light icons
    enableDark: true, // If true, it will process dark icons
    svgSrcDir: "./test/icons/src/", // The directory where your source icons/folders reside
    svgOutDir: "./docs/readme/", // The output directory where your icons will be generated
    sassOutDir: "./test/sass/", // The output directory where your sass files will be generated
    showcaseFilePath: "./test/showcase.html", // The .html filepath for output icons showcase
    objectFilePath: "./test/ICON_ASSETS.ts", // The .ts filepath for the icons assets file
    logFilePath: "./test/output.log", // The .log filepath for the log file. It keeps track of what happened during the process.
    defaultMonochromeColor: "chocolate", // The default color used for monochrome icons.
    // This is especially useful when using the Chameleon `ch-image` component,
    // as omitting the `colorType` will apply the `defaultMonochromeColor` to the icon.
    vendorAlias: null, // An optional vendor alias prefixed to the icon’s CSS variables.
    // Useful for preventing naming collisions between icons from different libraries.
  },
  icons: {
    monochrome: {
      colors: [
        {
          name: "sky-blue",
          states: {
            enabled: { light: "#4a6fa5", dark: "#3c5b84" },
            hover: { light: "#6c8fc0", dark: "#5c79a1" },
            active: { light: "#3a5c8a", dark: "#2f4a6d" },
            disabled: { light: "#a3b7cd", dark: "#404e62" },
          },
        },
        {
          name: "fire-red",
          states: {
            enabled: { light: "#ff6b3d", dark: "#cc5430" },
            hover: { light: "#ff8a61", dark: "#e26547" },
            active: { light: "#e6532d", dark: "#b24528" },
            disabled: { light: "#f3b09a", dark: "#4a342f" },
          },
        },
        {
          name: "candy-pink",
          states: {
            enabled: { light: "#da5ca2", dark: "#b04985" },
            hover: { light: "#e57db5", dark: "#c6629a" },
            active: { light: "#b64c85", dark: "#903c6c" },
            disabled: { light: "#e3a7c8", dark: "#51384f" },
          },
        },
        // add more as needed...
      ],
      categories: [
        // List each monochrome icon directory here along with the colors it should ignore.
        {
          name: "system",
          ignoredColors: ["fire-red", "candy-pink"],
        },
        {
          name: "backend",
          ignoredColors: [],
        },
        {
          name: "navigation",
          ignoredColors: ["sky-blue"],
        },
      ],
    },
    multicolor: {
      colors: [
        {
          name: "leaf-green",
          states: {
            enabled: { light: "#5caa69", dark: "#3e814b" },
            hover: { light: "#78c182", dark: "#509c60" },
            active: { light: "#459357", dark: "#2e6a3d" },
            disabled: { light: "#a6d1aa", dark: "#3a4e3c" },
          },
        },
        {
          name: "leaf-green",
          states: {
            enabled: { light: "#5caa69", dark: "#3e814b" },
            hover: { light: "#78c182", dark: "#509c60" },
            active: { light: "#459357", dark: "#2e6a3d" },
            disabled: { light: "#a6d1aa", dark: "#3a4e3c" },
          },
        },
        {
          name: "honey-yellow",
          states: {
            enabled: { light: "#f6c744", dark: "#c6a836" },
            hover: { light: "#f8d76d", dark: "#d7ba55" },
            active: { light: "#e3b832", dark: "#a88e25" },
            disabled: { light: "#f3dea5", dark: "#554b2e" },
          },
        },
        // add more as needed...
      ],
    },
  },
};
```

> 📝 **Tip:** If you’re using the same colors for both monochrome and multicolor, consider defining a shared color array and referencing it in both places to avoid duplication:

```js
const mySharedColors = [
  {
    name: "sky-blue",
    states: {
      enabled: { light: "#4a6fa5", dark: "#3c5b84" },
      hover: { light: "#6c8fc0", dark: "#5c79a1" },
      active: { light: "#3a5c8a", dark: "#2f4a6d" },
      disabled: { light: "#a3b7cd", dark: "#404e62" },
    },
  },
  {
    name: "fire-red",
    states: {
      enabled: { light: "#ff6b3d", dark: "#cc5430" },
      hover: { light: "#ff8a61", dark: "#e26547" },
      active: { light: "#e6532d", dark: "#b24528" },
      disabled: { light: "#f3b09a", dark: "#4a342f" },
    },
  },
  {
    name: "candy-pink",
    states: {
      enabled: { light: "#da5ca2", dark: "#b04985" },
      hover: { light: "#e57db5", dark: "#c6629a" },
      active: { light: "#b64c85", dark: "#903c6c" },
      disabled: { light: "#e3a7c8", dark: "#51384f" },
    },
  },
];
export default {
  config: {
    // config properties here
  },
  icons: {
    monochrome: {
      colors: myColors,
      categories: [
        {
          name: "system",
          ignoredColors: ["fire-red", "candy-pink"],
        },
        {
          name: "backend",
          ignoredColors: [],
        },
        {
          name: "navigation",
          ignoredColors: ["sky-blue"],
        },
      ],
    },
    multicolor: {
      colors: myColors,
    },
  },
};
```

### Overriding config. parameters

Sometimes you may need to set a dynamic value for a configuration property. In these cases, it's useful to override one or more parameters by passing them as arguments to the script that runs the tool.

For example, to override the source directory defined in the config file, you can do the following:

**`package.json`**

```json
"scripts": {
  "process-icons": "ssg --configPath=./src/config.js --svgSrcDir=other-directory/my-icons/src"
},
```

**`config.js`**

```js
config: {
    svgSrcDir: "./src/icons/src/", // This path will have no effect. It is overrided by "other-directory/my-icons/src"
    // other parameters...
  },
```

or you can override all of them:

**`package.json`**

```json
"scripts": {
  "process-icons": "ssg --configPath=./src/config.js--enableLight --enableDark --svgSrcDir=other-directory/icons/src/ --svgOutDir=other-directory/icons/_generated/ --sassOutDir=other-directory/sass/ --showcaseFilePath=other-directory/showcase.html --objectFilePath=other-directory/ICON_ASSETS.ts --logFilePath=other-directory/output.log --defaultMonochromeColor=chocolate --vendorAlias=mac"
},
```

> 📝 **Memo:** Defining configuration parameters in the config.js file is cleaner and preferred. However, if you need to override a value, you can pass it as an argument through the script.

<sub>[↑ Go back to index](#svg-sass-generator)

---

## Common questions:

**Q: Does the tool generate one SVG file per state?**  
A: No. Each icon is one SVG file that includes all states: enabled, hover, active, and disabled.

**Q: Does each SVG file include both light and dark themes?**  
A: No. You get one SVG for the light theme and another separate SVG for the dark theme. This helps load only what the user needs.

**Q: Do I have to create both light and dark themes?**  
A: No. You can choose to generate one or both themes by switching a setting.

**Q: Can I create more themes besides light and dark?**  
A: Not yet.

**Q: Does the tool support fill and stroke colors?**  
A: Yes, it handles shapes with fill, stroke, or both.

**Q: My output icons appear will a full background color, something seems not working. What is happening?**  
A: Probably, you have a container element (a box) with a fill on your source icon, and because of this the tool is also filling this element with a color. Try setting setting opacity 0% on this container element.

**Q: What settings do I need to configure to use this tool?**
A: This tool is designed for GeneXus Next, so no setup is needed for general use. However, if you're developing plugins for GeneXus Next, you should define your own vendor alias in this tool’s configuration file and use that alias when referencing your icons.

ie.:

**`config.js`**

```js
export default {
  config: {
    // ... other settings
    vendorAlias: "your-vendor-alias",
  },
```

**`your component`**

```ts
const USER_ICON = getIconPath({
  category: "system",
  name: "user",
}, "your-vendor-alias");
<ch-image src={USER_ICON}>
```

**Q: I want to report a bug or suggest an improvement. How can I get in touch?**  
A: For now, you can email [bsastre@genexus.com](mailto:bsastre@genexus.com)

<sub>[↑ Go back to index](#svg-sass-generator)

---

## Final comments

### SVG Export Plugin

Since multicolor icons require each element to have a class name that matches a color, we recommend designing your icons in Figma and exporting them using the [SVG Export Plugin](https://www.figma.com/community/plugin/814345141907543603/svg-export). This plugin automatically applies layer names as class names in the exported SVG, saving you time and ensuring consistency. For example:

![Icon figma layers](./docs/readme/figma-icon-layers.webp)

`choco-overload.svg` (exported with **SVG Export**)

```xml
<svg class="choco-overload" xmlns="http://www.w3.org/2000/svg" width="64" height="64" fill="none" viewBox="0 0 64 64">
  <g class="group">
    <path class="dark-chocolate" fill="#9C9C9C" d="M40.8... continues"/>
    <path class="milk-chocolate" fill="#9C9C9C" d="M14.4... continues"/>
    <path class="cookies-cream" fill="#9C9C9C" d="M33.2... continues"/>
    <path class="bowl" fill="#9C9C9C" d="M42.6... continues"/>
  </g>
</svg>
```

As you can see, exporting your icons with **SVG Export** allows you to automatically use your vector names as CSS class names in the SVGs. This streamlines the workflow and eliminates the need to rename classes manually. Additionally, using this plugin significantly reduces the SVG file size.

### This readme showcase

Checkout this readme icons example showcase [on this link](https://ssg-readme-showcase.netlify.app/).

<sub>[↑ Go back to index](#svg-sass-generator)