@open-xchange/vite-plugin-icon-sprite

0.0.4 • Public • Published

@open-xchange/vite-plugin-icon-sprite

A Vite plugin that builds icon sprites from multiple SVG or PNG icon files.

Usage

This plugin collects multiple SVG or PNG image files, assembles them into a single icon sprite file, and provides virtual modules that can be imported in source code.

In Vite server mode, the icon sprite files will be generated on demand. When bundling the project, all icon sprite files referenced in source code will be generated and bundled.

It is possible to instantiate this plugin repeatedly, e.g. in order to generate an SVG sprite and a PNG sprite in the same project.

Common Options

Common configuration options for SVG sprites and PNG sprites.

Option format

  • Type: "svg" | "png"
  • required

The file format specifier of the icon sprite, and the source images. Depending on the value of this option, the plugin expects various file-format specific options (see below).

Option imagesPath

  • Type: string
  • required

Path to root directory with all image resource files to be processed.

Option mappingPath

  • Type: string
  • required

Path to the JSON or YAML configuration file containing the mapping between icon identifiers and SVG source file names (see below).

SVG Sprites

The plugin collects multiple SVG files, and generates a virtual import for an SVG sprite file with multiple <symbol> elements that can be imported from source code.

Example how to consume the SVG sprite in source code:

// path/to/source.ts

import svgSprite from "virtual:svg/my-icons.svg"

// insert the SVG sprite into the DOM to be able to refer to the <symbol> elements
document.createElement("div").innerHTML = svgSprite

// create an SVG element referring to an icon in the sprite
function createIcon(id: string): SVGElement {
  const useEl = document.createElementNS("http://www.w3.org/2000/svg", "use")
  useEl.setAttribute("href", "#my-icon")
  const iconEl = document.createElementNS("http://www.w3.org/2000/svg", "svg")
  iconEl.append(useEl)
  return iconEl
}

Option spriteName

  • Type: string
  • required

The module name of the SVG sprite to be generated (with ".svg" extension).

The SVG markup of the sprite can be imported from the virtual module path "virtual:svg/[spriteName]".

Option idPrefix

  • Type: string
  • optional

A prefix to be added to all icon identifiers declared in the mapping file. By default, no prefix will be added.

SVG Sprite Example

// vite.config.ts

import { defineConfig } from "vite" // or "vitest/config"
import spritePlugin from "@open-xchange/vite-plugin-icon-sprite"

export default defineConfig(() => {
  plugins: [
    spritePlugin({
      format: "svg",
      imagesPath: "src/icons/images",
      mappingPath: "src/icons/svg-mapping.yaml",
      spriteName: "icons.svg",
      idPrefix: "svg-",
    }),
  ],
})
  • Collects all SVG files in the directory src/icons/images.
  • Uses the icon mapping in src/icons/svg-mapping.yaml.
  • Creates a virtual import "virtual:svg/icons.svg".
  • Prefixes all icon identifiers with svg-, e.g. the icon key my-icon in the mapping file will result in the icon identifier "svg-my-icon" in source code.

PNG Sprites

The plugin collects multiple PNG files, and generates a virtual imports for one or more sprite files with different icon sizes and a CSS file that can be imported from source code.

Option cssName

  • Type: string
  • required

The module name for the CSS file (with ".css" extension). The generated CSS markup can be imported from "virtual:png/[cssName]".

Option cssIconSize

  • Type: number
  • required

Base size of all icons, in CSS pixels.

Option cssIconPadding

  • Type: number
  • Default: 0

Additional padding around all icons to be generated in the sprites, in CSS pixels.

Option cssIconSelector

  • Type: string
  • Default: "i.png-icon"

The CSS selector for a PNG icon element to be used in all generated CSS rules.

Option rootLocaleAttr

  • Type: string
  • Default: "lang"

Name of the root element's attribute containing the locale identifier. Needed to generate CSS selectors for localized icons.

Option spriteColorType

  • Type: "source" | "monochrome" | "alpha"
  • Default: "source"

Specifies how to generate the sprite PNG files.

Value Description
"source" The source PNGs will be copied into the generated sprites unmodified. They will contain three color channels, and an alpha channel.
"monochrome" The generated sprites will be converted to monochrome. They will contain a gray channel and an alpha channel.
"alpha" Only the alpha channels of the source PNGs will be copied into the generated sprites. They will contain a single gray channel representing the original alpha channels.

Option spriteFillType

  • Type: "background" | "mask"
  • Default: "background"

Specifies how the sprites are supposed to be used in CSS rules.

| Value | Description | | "background" | The sprites will be attached via "background-image". | | "mask" | The sprites will be attached via "mask-image". |

All related CSS properties (e.g. background-position vs. mask-position etc.) will be generated accordingly.

Option sprites

  • Type: Record<string, { factor: number; src: string }>
  • required

List of all icon sprites with different icon sizes to be generated.

  • The keys of the dictionary are the module names of the PNG sprites (with ".png" extension). The generated PNG sprite can be imported from "virtual:png/[key]".

  • The values of the dictionary contain configuration options for the PNG sprite:

    Option Type Default Description
    factor number required Icon scaling factor (a multiplier for plugin option cssIconSize). All source PNG files must have the effective pixel size (cssIconSize * factor).
    src string required The pattern used to build the path of the source PNG files. MUST contain the placeholder [path] that will be replaced with the base paths contained in the icon mapping file.

PNG Sprite Example

// vite.config.ts

import { defineConfig } from "vite" // or "vitest/config"
import spritePlugin from "@open-xchange/vite-plugin-icon-sprite"

export default defineConfig(() => {
  plugins: [
    spritePlugin({
      format: "png",
      imagesPath: "src/icons/images",
      mappingPath: "src/icons/png-mapping.yaml",
      cssName: "icons.css",
      cssIconSize: 16,
      cssIconPadding: 1,
      cssIconSelector: "i.my-icon",
      rootLocaleAttr: "data-icon-locale",
      spriteColorType: "alpha",
      spriteFillType: "mask",
      sprites: {
        "icons1.png": { factor: 1, src: "[path]_16.png" },
        "icons2.png": { factor: 2, src: "[path]_32.png" },
      },
    }),
  ]
})
  • Collects all PNG files in the directory src/icons/images. The images must exist in two sizes (16px and 32px), their file names must end with _16.png and _32.png respectively (according to the options cssIconSize and sprites->factor).
  • Uses the icon mapping in src/icons/png-mapping.yaml.
  • Creates the virtual imports "virtual:svg/icons.css", "virtual:svg/icons1.png", and "virtual:svg/icons2.png".
  • Adds one pixel padding around all icons in the PNG sprites.
  • Generates CSS selectors for <i> elements with CSS class my-icon.
  • Generates :root[data-icon-locale] CSS selectors for localized icons (i.e., the UI locale code must be stored in the root element's attribute "data-icon-locale").
  • Generates PNG sprites consisting of an 8-bit alpha channel only.
  • Generates CSS rules using CSS mask (instead of background).

Icon Mapping File

The plugin expects an icon mapping file (plugin option mappingPath) which is a JSON or YAML configuration file containing a mapping from arbitrary icon identifiers to the paths of the source images. The icon identifiers can be used later in source code to refer to a specific icon in the generated sprite.

  • The name of the configuration file can be chosen freely.

  • The configuration file must consist of a single object map.

  • Each entry maps a unique icon identifier (used in source code) to a source image to be used for that icon.

  • The source image file can be specified directly as string, or as dictionary for localized icons (more details below).

  • Only the base name of the source image file must be specified relative to the configured root directory of the image files. It must not contain the image size suffix (PNG only), nor a file extension (.svg or .png). See examples below.

  • Localized icons will be described by a dictionary mapping the ISO language identifiers (as comma-separated strings) to the image base names (as described above). The special locale code "*" is mandatory, and defines a default icon for unlisted locales. See examples below.

Icon Mapping Examples

In all examples, the configured image root directory (plugin option imagesPath) shall be path/to/images.

Example 1: Simple SVG Icons
  • Assign the icon with the identifier my-icon to the SVG image path/to/images/commons/icon1.svg.
  • Assign the icon with the identifier other-icon to the SVG image path/to/images/commons/icon2.svg.
# svg-mapping.yaml

my-icon: commons/icon1
other-icon: commons/icon2

In source code, the icons can be used with the identifiers "my-icon" and "other-icon".

Example 2: Simple PNG Icons

Assuming that the plugin will generate PNG sprites for icons with sizes of 16px and 32px.

  • Assign the icon with the identifier my-icon to the PNG images path/to/images/commons/icon1_16.png (16x16 pixels) and path/to/images/commons/icon1_32.png (32x32 pixels).
  • Respectively, assign an icon with the identifier other-icon to the PNG images path/to/images/commons/icon2_*.png.

The resulting mapping file looks exactly as the former mapping file for SVG icons:

# png-mapping.yaml

my-icon: commons/icon1
other-icon: commons/icon2
Example 3: Localized Icons
  • Assign the icon with the identifier my-icon to the SVG image path/to/images/commons/icon1.svg by default.
  • Use the SVG image path/to/images/commons/icon2.svg in German and French UI instead.
  • Use the SVG image path/to/images/commons/icon3.svg in Swedish UI instead.
# svg-mapping.yaml

my-icon:
  "*": commons/icon1
  de,fr: commons/icon2
  sv: commons/icon3

The same applies to PNG icons as well.

Schema Validation

This package provides a JSON schema that can be used for validation in editors.

JSON Mapping File

Add the path to the schema file as property "$schema" to the mapping file:

// mapping.json

{
  "$schema": "../../node_modules/@open-xchange/vite-plugin-icon-sprite/dist/mapping-schema.json",
  // ...
}

Adjust the number of parent path fragments according to the location of the mapping file in the project.

YAML Mapping File

Add the path to the schema file in a yaml-language-server directive to the mapping file:

# mapping.yaml

# yaml-language-server: $schema=../../node_modules/@open-xchange/vite-plugin-icon-sprite/dist/mapping-schema.json

# ...

Adjust the number of parent path fragments according to the location of the mapping file in the project.

In VS Code, the plugin redhat.vscode-yaml needs to be installed to support this directive.

Logging

By default, warning messages and error messages will be logged to the shell. The environment variable PLUGIN_REPLACE_ICON_SPRITE can be used to change the log level of this plugin. Possible values are info, warn, error, and silent.

Readme

Keywords

none

Package Sidebar

Install

npm i @open-xchange/vite-plugin-icon-sprite

Weekly Downloads

213

Version

0.0.4

License

MIT

Unpacked Size

40 kB

Total Files

12

Last publish

Collaborators

  • tran-dong.tran
  • bjoern.koester
  • hydrair
  • moritz.bach
  • andree
  • anne.matthes
  • johnyb
  • davidbauer
  • solygen
  • daniel.rentz
  • alexquast
  • d.haus
  • maik.schaefer
  • jjacobsohn