@open-xchange/vite-plugin-icon-sprite 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/index.d.mts +1 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +8 -12
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -6
package/CHANGELOG.md
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Dict } from "@open-xchange/vite-helper/utils";
|
|
2
1
|
import { PluginHelper } from "@open-xchange/vite-helper";
|
|
3
2
|
import { Plugin } from "vite";
|
|
4
3
|
|
|
@@ -119,7 +118,7 @@ interface PngSpritePluginOptions extends SpritePluginBaseOptions<'png'> {
|
|
|
119
118
|
* the base paths contained in the icon mapping file referred in the option
|
|
120
119
|
* 'mappingFile'.
|
|
121
120
|
*/
|
|
122
|
-
sprites:
|
|
121
|
+
sprites: Record<string, {
|
|
123
122
|
factor: number;
|
|
124
123
|
src: string;
|
|
125
124
|
}>;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/helper.ts","../src/plugin-svg.ts","../src/plugin-png.ts","../src/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/helper.ts","../src/plugin-svg.ts","../src/plugin-png.ts","../src/index.ts"],"mappings":";;;;;;;AAYA;;;;UAAiB,uBAAA;EAKf;;;EAAA,MAAA,EAAQ,OAAO;EAWJ;AAAA;;EANX,UAAA;;ACRF;;;EDcE,WAAA;AAAA;;;;;AAhBF;UCEiB,sBAAA,SAA+B,uBAAuB;EDF/B;;;;;ECStC,UAAA;EDOA;;AAAW;;ECDX,QAAA;AAAA;;;;;ADfF;UECiB,sBAAA,SAA+B,uBAAuB;EFD/B;;;;EEOtC,OAAA;EFGA;;;EEEA,WAAA;;;;ADVF;;;ECkBE,cAAA;EDlB8C;;;;AAatC;;ECaR,eAAA;;AA3BF;;;;;EAmCE,cAAA;EAxBA;;;;;;;;;;;AAoE6C;;EA7B7C,eAAA;;ACnDF;;;;AAAqF;AAAA;;;;;EDgEnF,cAAA;EClD0E;;AAAM;;;;;;;;;;;;EDkEhF,OAAA,EAAS,MAAA;IAAiB,MAAA;IAAgB,GAAA;EAAA;AAAA;;;;AFhF5C;;;KGAY,uBAAA,GAA0B,sBAAA,GAAyB,sBAAsB;;;;;;;AHgBxE;;;;iBGFW,gBAAA,CAAiB,OAAA,EAAS,uBAAA,GAA0B,MAAM"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import { basename } from "node:path";
|
|
2
2
|
import SVGSprite from "svg-sprite";
|
|
3
|
-
import {
|
|
4
|
-
import { resolvePath } from "@open-xchange/vite-helper/file";
|
|
5
|
-
import { PluginHelper } from "@open-xchange/vite-helper";
|
|
3
|
+
import { PluginHelper, resolvePath } from "@open-xchange/vite-helper";
|
|
6
4
|
import { Jimp, PNGColorType } from "jimp";
|
|
7
|
-
import { Cache } from "@open-xchange/
|
|
5
|
+
import { Cache, onceFn } from "@open-xchange/rolldown-utils";
|
|
8
6
|
//#region src/helper.ts
|
|
9
7
|
/**
|
|
10
8
|
* Plugin helper for all icon file formats.
|
|
@@ -39,9 +37,9 @@ var SpritePluginHelper = class extends PluginHelper {
|
|
|
39
37
|
const schemaPath = resolvePath("./mapping-schema.json", import.meta.url);
|
|
40
38
|
const mappingDict = await this.readConfig(this.options.mappingPath, { schema: schemaPath });
|
|
41
39
|
const iconMapping = [];
|
|
42
|
-
for (const [iconId, entry] of
|
|
40
|
+
for (const [iconId, entry] of Object.entries(mappingDict)) {
|
|
43
41
|
const iconDict = typeof entry === "string" ? { "*": entry } : entry;
|
|
44
|
-
for (const [languages, iconPath] of
|
|
42
|
+
for (const [languages, iconPath] of Object.entries(iconDict)) for (const iconLang of languages.split(",")) if (iconLang === "*") iconMapping.push({
|
|
45
43
|
iconId,
|
|
46
44
|
iconPath
|
|
47
45
|
});
|
|
@@ -77,7 +75,7 @@ var SvgSpritePluginHelper = class extends SpritePluginHelper {
|
|
|
77
75
|
*/
|
|
78
76
|
async generateSpriteModule() {
|
|
79
77
|
const { imagesPath, idPrefix, spriteName } = this.options;
|
|
80
|
-
return await this.
|
|
78
|
+
return await this.generateJsonModule(spriteName, async () => {
|
|
81
79
|
this.info("compiling sprite %f", spriteName);
|
|
82
80
|
const iconIdMap = /* @__PURE__ */ new Map();
|
|
83
81
|
const spriter = new SVGSprite({
|
|
@@ -109,9 +107,8 @@ var SvgSpritePluginHelper = class extends SpritePluginHelper {
|
|
|
109
107
|
spriter.add(path, null, markup);
|
|
110
108
|
}
|
|
111
109
|
const spriteMarkup = (await spriter.compileAsync()).result.symbol.sprite.contents.toString("utf8");
|
|
112
|
-
const moduleCode = `export default ${JSON.stringify(spriteMarkup)};`;
|
|
113
110
|
this.info("sprite %f generated successfully", spriteName);
|
|
114
|
-
return
|
|
111
|
+
return spriteMarkup;
|
|
115
112
|
});
|
|
116
113
|
}
|
|
117
114
|
};
|
|
@@ -216,7 +213,7 @@ var PngSpritePluginHelper = class extends SpritePluginHelper {
|
|
|
216
213
|
const { imagesPath, cssIconSize, cssIconPadding, spriteColorType } = this.options;
|
|
217
214
|
this.ensure(factor > 0, "invalid scaling factor in configuration for sprite %f", spriteName);
|
|
218
215
|
this.ensure(srcPattern.includes("[path]"), "placeholder [path] expected in configuration for sprite %f", spriteName);
|
|
219
|
-
return await this.
|
|
216
|
+
return await this.generateJsonModule(spriteName, async () => {
|
|
220
217
|
this.info("generating sprite %f", spriteName);
|
|
221
218
|
const { cssSpriteWidth, cssSpriteHeight, entries } = await this.#parseMappingOnce();
|
|
222
219
|
const sprite = new Jimp({
|
|
@@ -247,9 +244,8 @@ var PngSpritePluginHelper = class extends SpritePluginHelper {
|
|
|
247
244
|
alpha: PNGColorType.GRAYSCALE
|
|
248
245
|
}[spriteColorType];
|
|
249
246
|
const spriteDataUrl = `data:image/png;base64,${(await sprite.getBuffer("image/png", { colorType })).toString("base64")}`;
|
|
250
|
-
const moduleSource = `export default ${JSON.stringify(spriteDataUrl)};`;
|
|
251
247
|
this.info("sprite %f generated successfully", spriteName);
|
|
252
|
-
return
|
|
248
|
+
return spriteDataUrl;
|
|
253
249
|
});
|
|
254
250
|
}
|
|
255
251
|
async #parseMapping() {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["#parseMappingOnce","#parseMapping"],"sources":["../src/helper.ts","../src/plugin-svg.ts","../src/plugin-png.ts","../src/index.ts"],"sourcesContent":["\nimport { type Dict, dictEntries } from '@open-xchange/vite-helper/utils'\nimport { resolvePath } from '@open-xchange/vite-helper/file'\nimport { type PluginHelperConfig, PluginHelper } from '@open-xchange/vite-helper'\n\n// types ======================================================================\n\n/**\n * Common configuration options (independent from the icon file format) for the\n * plugin '@open-xchange/vite-plugin-icon-sprite'.\n *\n * @template FormatT\n * The file format specifier of the icon sprite, and the source images.\n */\nexport interface SpritePluginBaseOptions<FormatT extends string> {\n\n /**\n * The file format specifier of the icon sprite, and the source images.\n */\n format: FormatT\n\n /**\n * Path to root directory with all image resource files to be processed.\n */\n imagesPath: string\n\n /**\n * Path to the JSON or YAML configuration file containing the mapping between\n * icon identifiers and SVG source file names.\n */\n mappingPath: string\n}\n\n/**\n * Internal configuration of a `SpritePluginHelper` instance.\n */\nexport type SpritePluginConfig = Required<Pick<PluginHelperConfig, 'pluginIndex' | 'virtualModules'>>\n\n/**\n * Represents a single entry in an icon mapping configuration file (a mapping\n * between icon identifier, path to source image, and language code for\n * localized icons).\n */\nexport interface IconMappingEntry {\n /** The icon identifier used in source code to select an icon. */\n iconId: string\n /** The path to the source image file to be inserted into the sprite. */\n iconPath: string\n /** Language code for a localized icon. */\n iconLang?: string\n}\n\n// class SpritePluginHelper ===================================================\n\n/**\n * Plugin helper for all icon file formats.\n *\n * @template OptionsT\n * Exact type of the options interface.\n */\nexport class SpritePluginHelper<OptionsT extends SpritePluginBaseOptions<string>> extends PluginHelper {\n\n /** Resolved configuration options. */\n readonly options: Required<Readonly<OptionsT>>\n\n // constructor ------------------------------------------------------------\n\n protected constructor(config: SpritePluginConfig, options: Required<OptionsT>) {\n super({\n ...config,\n virtualPrefix: options.format,\n loggerPrefix: options.format,\n logLevelEnvVar: 'PLUGIN_ICON_SPRITE_LOGLEVEL',\n cacheSrcFiles: [options.imagesPath + '/**/*.' + options.format, options.mappingPath],\n })\n this.options = options\n }\n\n // protected methods ------------------------------------------------------\n\n /**\n * Reads an icon mapping configuration file, and returns the entries as\n * array.\n *\n * @param path\n * The path to the icon mapping configuration file to be read.\n *\n * @returns\n * The entries of the configuration file.\n */\n protected async readIconMapping(): Promise<IconMappingEntry[]> {\n\n // read the icon mapping configuration file\n type IconMappingSchema = Dict<string | Dict<string>>\n const schemaPath = resolvePath('./mapping-schema.json', import.meta.url)\n const mappingDict = await this.readConfig<IconMappingSchema>(this.options.mappingPath, { schema: schemaPath })\n\n // convert to array of `IconMappingEntry`\n const iconMapping: IconMappingEntry[] = []\n for (const [iconId, entry] of dictEntries(mappingDict)) {\n const iconDict = (typeof entry === 'string') ? { '*': entry } : entry\n for (const [languages, iconPath] of dictEntries(iconDict)) {\n for (const iconLang of languages.split(',')) {\n if (iconLang === '*') {\n iconMapping.push({ iconId, iconPath })\n } else {\n iconMapping.push({ iconId, iconPath, iconLang })\n }\n }\n }\n }\n return iconMapping\n }\n}\n","\nimport { basename } from 'node:path'\n\nimport type { Plugin } from 'vite'\nimport SVGSprite from 'svg-sprite'\nimport type * as Vinyl from 'vinyl'\n\nimport type { ModuleDescriptor } from '@open-xchange/vite-helper'\n\nimport { type SpritePluginBaseOptions, SpritePluginHelper } from './helper.js'\n\n// types ======================================================================\n\n/**\n * Configuration options for generating an SVG sprite from SVG source images.\n */\nexport interface SvgSpritePluginOptions extends SpritePluginBaseOptions<'svg'> {\n\n /**\n * Module name of the SVG sprite to be generated (with '.svg' extension). The\n * SVG markup of the sprite can be imported from the virtual module path\n * `'virtual:svg/[spriteName]'`.\n */\n spriteName: string\n\n /**\n * A prefix to be added to all icon identifiers declared in the mapping file.\n * By default, no prefix will be added.\n */\n idPrefix?: string\n}\n\n// class SvgSpritePluginHelper ================================================\n\n/**\n * Implementation helper for SVG to sprite conversion.\n */\nclass SvgSpritePluginHelper extends SpritePluginHelper<SvgSpritePluginOptions> {\n\n constructor(index: string, options: SvgSpritePluginOptions) {\n super({\n pluginIndex: index,\n virtualModules: options.spriteName,\n }, {\n idPrefix: '',\n ...options,\n })\n }\n\n // public methods ---------------------------------------------------------\n\n /**\n * Generates the ES source module for an SVG sprite.\n *\n * @returns\n * The source module containing the SVG markup of the sprite.\n */\n async generateSpriteModule(): Promise<ModuleDescriptor> {\n\n // shortcuts to plugin options\n const { imagesPath, idPrefix, spriteName } = this.options\n\n // try to resolve cached version of generated file\n return await this.generateModule(spriteName, async () => {\n this.info('compiling sprite %f', spriteName)\n\n // create a reverse map from icon filenames to icon identifiers\n const iconIdMap = new Map<string, string>()\n\n // create the core SVG spriter\n const spriter = new SVGSprite({\n shape: {\n id: {\n generator: name => iconIdMap.get(name) ?? '',\n },\n spacing: {\n box: 'icon',\n },\n dimension: {\n maxWidth: 16,\n maxHeight: 16,\n },\n },\n svg: {\n xmlDeclaration: false,\n // - remove all <style> elements declaring a class with fill color\n // - remove all class attribute referring to the class from <style>\n // - add 'fill' attribute to all <symbol> elements\n transform: markup => markup\n .replace(/<style>.*?<\\/style>/g, '')\n .replace(/class=\".*?\" ?/g, '')\n .replace(/<symbol /g, '<symbol fill=\"currentColor\" '),\n },\n mode: {\n inline: true,\n symbol: {\n sprite: spriteName,\n render: { less: false },\n },\n },\n })\n\n // load all source SVG images\n for (const { iconId, iconPath, iconLang } of await this.readIconMapping()) {\n const path = `${imagesPath}/${iconPath}.svg`\n // icon identifier with configured prefix and language suffix\n const idSuffix = iconLang ? `;${iconLang}` : ''\n iconIdMap.set(basename(path), idPrefix + iconId + idSuffix)\n // read SVG source image, insert into spriter instance\n const markup = await this.readText(path)\n spriter.add(path, null, markup)\n }\n\n // '@types/svg-sprite' is missing type definitions for compilation result\n /** @ignore */\n interface SVGSpriteCompileResult {\n symbol: {\n sprite: Vinyl.BufferFile\n }\n shapes: Vinyl.BufferFile[]\n }\n\n // compile the SVG sprite\n const result = (await spriter.compileAsync()).result as SVGSpriteCompileResult\n const spriteMarkup = result.symbol.sprite.contents.toString('utf8')\n const moduleCode = `export default ${JSON.stringify(spriteMarkup)};`\n\n this.info('sprite %f generated successfully', spriteName)\n return moduleCode\n })\n }\n}\n\n// plugin =====================================================================\n\n/**\n * A plugin for Vite to generate an SVG sprite file from multiple SVG source\n * files.\n *\n * @param index\n * URL of the index source file of this plugin (`import.meta.url`).\n *\n * @param options\n * Plugin configuration options.\n *\n * @returns\n * The plugin instance.\n */\nexport function svgSpritePlugin(index: string, options: SvgSpritePluginOptions): Plugin {\n\n // helper instance for file system access, logging, etc.\n const helper = new SvgSpritePluginHelper(index, options)\n\n // create and return the plugin object\n return {\n name: '@open-xchange/vite-plugin-icon-sprite/svg',\n\n // initialize file system cache for generated modules\n async configResolved(viteConfig) {\n await helper.initializeCache(viteConfig)\n },\n\n // pick matching imports\n resolveId(source) {\n return helper.resolveVirtualModuleId(source)\n },\n\n // load the SVG icon files, generate final SVG sprite\n async load(moduleId) {\n\n // only handle the output file specified in 'resolveId'\n if (!helper.matchVirtualModuleId(moduleId)) {\n return null\n }\n\n // create an ES module that exports the SVG markup of the sprite\n return await helper.generateSpriteModule()\n },\n }\n}\n","\nimport type { Plugin } from 'vite'\nimport { Jimp, PNGColorType } from 'jimp'\n\nimport { type Dict, onceFn } from '@open-xchange/vite-helper/utils'\nimport { Cache } from '@open-xchange/vite-helper/cache'\nimport type { ModuleDescriptor } from '@open-xchange/vite-helper'\n\nimport { type SpritePluginBaseOptions, SpritePluginHelper } from './helper.js'\n\n// types ======================================================================\n\n/**\n * Configuration options for generating PNG sprites from PNG source images.\n */\nexport interface PngSpritePluginOptions extends SpritePluginBaseOptions<'png'> {\n\n /**\n * Module name for the CSS file (with '.css' extension). The generated CSS\n * markup can be imported from `'virtual:png/[cssName]'`.\n */\n cssName: string\n\n /**\n * Base size of all icons, in CSS pixels.\n */\n cssIconSize: number\n\n /**\n * Additional padding around all icons to be generated in the sprites, in CSS\n * pixels.\n *\n * @default 0\n */\n cssIconPadding?: number\n\n /**\n * The CSS selector for a PNG icon element to be used in all generated CSS\n * rules.\n *\n * @default 'i.png-icon'\n */\n cssIconSelector?: string\n\n /**\n * Name of the root element's attribute containing the locale identifier.\n * Needed to generate CSS selectors for localized icons.\n *\n * @default 'lang'\n */\n rootLocaleAttr?: string\n\n /**\n * Specifies how to generate the sprite PNG files.\n *\n * - `'source'`: The source PNGs will be copied into the generated sprites\n * unmodified. They will contain three color channels and an alpha channel.\n * - `'monochrome'`: The generated sprites will be converted to monochrome.\n * They will contain a gray channel and an alpha channel.\n * - `'alpha'`: Only the alpha channels of the source PNGs will be copied\n * into the generated sprites. They will contain a single gray channel\n * representing the original alpha channels.\n *\n * @default 'source'\n */\n spriteColorType?: 'source' | 'monochrome' | 'alpha'\n\n /**\n * Specifies how the sprites are supposed to be used in CSS rules.\n *\n * - `'background'`: The sprites will be attached via 'background-image'.\n * - `'mask'`: The sprites will be attached via 'mask-image'.\n *\n * All related CSS properties (e.g. '(background|mask)-position' etc.) will\n * be generated accordingly.\n *\n * @default 'background'\n */\n spriteFillType?: 'background' | 'mask'\n\n /**\n * List of all icon sprites to be generated.\n *\n * - The keys of the dictionary are the module names of the PNG sprites (with\n * '.png' extension). The generated sprite PNG file can be imported from\n * `'virtual:png/[key]'`.\n * - 'factor' is the scaling factor (a multiplier for 'cssIconSize'). All\n * source PNG files must have the effective pixel size (`cssIconSize *\n * factor`).\n * - 'src' specifies the pattern used to build the path of the source PNG\n * files. MUST contain the placeholder '[path]' that will be replaced with\n * the base paths contained in the icon mapping file referred in the option\n * 'mappingFile'.\n */\n sprites: Dict<{ factor: number, src: string }>\n}\n\n/**\n * Descriptor for a single entry in the resulting sprites.\n */\ninterface SpriteEntry {\n iconPath: string\n x: number\n y: number\n}\n\n/**\n * Generic descriptor for an entire sprite, independent from actual icon size.\n */\ninterface SpriteSettings {\n cssMarkup: string\n cssSpriteWidth: number\n cssSpriteHeight: number\n entries: readonly SpriteEntry[]\n}\n\n// constants ==================================================================\n\nconst FILL_VENDOR_PREFIXES: Record<NonNullable<PngSpritePluginOptions['spriteFillType']>, string[]> = {\n background: [],\n mask: ['webkit'],\n}\n\n// functions ==================================================================\n\n/**\n * Generates a CSS length string in pixels (omits unit for zero).\n *\n * @param value\n * The length to be emitted.\n *\n * @returns\n * The passed length with 'px' unit.\n */\nfunction px(value: number): string {\n return value ? `${value}px` : '0'\n}\n\n// class PngSpritePluginHelper ================================================\n\n/**\n * Implementation helper for PNG to sprite conversion.\n */\nclass PngSpritePluginHelper extends SpritePluginHelper<PngSpritePluginOptions> {\n\n readonly #parseMappingOnce: () => Promise<SpriteSettings>\n\n // constructor ------------------------------------------------------------\n\n constructor(index: string, options: PngSpritePluginOptions) {\n super({\n pluginIndex: index,\n virtualModules: [options.cssName, ...Object.keys(options.sprites)],\n }, {\n cssIconPadding: 0,\n cssIconSelector: 'i.png-icon',\n rootLocaleAttr: 'lang',\n spriteColorType: 'source',\n spriteFillType: 'background',\n ...options,\n })\n this.#parseMappingOnce = onceFn(() => this.#parseMapping())\n }\n\n // public methods ---------------------------------------------------------\n\n /**\n * Generates an ES source module with CSS markup code for all icons.\n *\n * @returns\n * The source module with CSS markup for all icons.\n */\n async generateCssMarkupModule(): Promise<ModuleDescriptor> {\n\n // shortcuts to plugin options\n const { cssName } = this.options\n\n // try to resolve cached version of generated file\n return await this.generateModule(cssName, async () => {\n this.info('generating CSS markup %f', cssName)\n\n // parse mapping file which collects icon paths, CSS selectors, and entry positions\n const cssMarkup = (await this.#parseMappingOnce()).cssMarkup\n\n this.info('CSS markup %f generated successfully', cssName)\n return cssMarkup\n })\n }\n\n /**\n * Generates the ES source module for a PNG sprite with a specific scaling\n * factor.\n *\n * @param spriteName\n * The name of the sprite.\n *\n * @param factor\n * The scaling factor.\n *\n * @param srcPattern\n * The pattern for the source PNG images.\n *\n * @returns\n * The source module exporting the PNG sprite as base-64 encoded data URL.\n */\n async generateSpriteModule(spriteName: string, factor: number, srcPattern: string): Promise<ModuleDescriptor> {\n\n // shortcuts to plugin options\n const { imagesPath, cssIconSize, cssIconPadding, spriteColorType } = this.options\n\n // check configuration\n this.ensure(factor > 0, 'invalid scaling factor in configuration for sprite %f', spriteName)\n this.ensure(srcPattern.includes('[path]'), 'placeholder [path] expected in configuration for sprite %f', spriteName)\n\n // try to resolve cached version of generated file\n return await this.generateModule(spriteName, async () => {\n this.info('generating sprite %f', spriteName)\n\n // parse mapping file which collects icon paths, CSS selectors, and entry positions\n const { cssSpriteWidth, cssSpriteHeight, entries } = await this.#parseMappingOnce()\n\n // new image data is not clean out-of-the-box, explicitly fill with zeros\n const sprite = new Jimp({ width: cssSpriteWidth * factor, height: cssSpriteHeight * factor, color: 0 })\n\n // process all entries in the mapping configuration\n for (const { iconPath, x, y } of entries) {\n\n // expected pixel size for the current scaling factor\n const size = cssIconSize * factor\n\n // load and parse the source image file\n const path = imagesPath + '/' + srcPattern.replace('[path]', iconPath)\n const buffer = await this.readBuffer(path)\n const image = await Jimp.fromBuffer(buffer)\n\n // validate the image size\n const { width, height } = image.bitmap\n this.ensure((width === size) && (height === size), 'wrong image width in %f (expected %s but got %s)', path, `${size}x${size}`, `${width}x${height}`)\n\n // insert source image into the sprite\n sprite.blit({ src: image, x: (x + cssIconPadding) * factor, y: (y + cssIconPadding) * factor })\n }\n\n // copy alpha of all pixels to RGB channels (alpha channel will be exported as greyscale without alpha)\n if (spriteColorType === 'alpha') {\n for (let d = sprite.bitmap.data, i = 0, l = d.length; i < l; i += 4) {\n d.fill(d[i + 3], i, i + 3) // copy A to RGB\n d[i + 3] = 255 // set A to full opacity\n }\n }\n\n // generate the binary PNG data (no preset constants for PNG color types in Jimp)\n const colorType = {\n source: PNGColorType.COLOR_ALPHA,\n monochrome: PNGColorType.GRAYSCALE_ALPHA,\n alpha: PNGColorType.GRAYSCALE,\n }[spriteColorType]\n const spriteBuffer = await sprite.getBuffer('image/png', { colorType })\n\n // convert to base64 encoded data URL\n const spriteDataUrl = `data:image/png;base64,${spriteBuffer.toString('base64')}`\n const moduleSource = `export default ${JSON.stringify(spriteDataUrl)};`\n\n this.info('sprite %f generated successfully', spriteName)\n return moduleSource\n })\n }\n\n // private methods --------------------------------------------------------\n\n // parses the mapping file once, generates a map from short icon paths to `SpriteEntry` descriptor objects\n async #parseMapping(): Promise<SpriteSettings> {\n\n // shortcuts to plugin options\n const { cssIconSize, cssIconPadding, cssIconSelector, rootLocaleAttr, spriteFillType } = this.options\n\n // CSS selectors for all sprite entries, mapped by short icon path (different icons may refer to the same source PNG)\n const selectorMap = new Cache<string[]>()\n\n // process all entries in the mapping configuration, collect CSS selectors for each entry in the sprite\n for (const { iconId, iconPath, iconLang } of await this.readIconMapping()) {\n const selectors = selectorMap.upsert(iconPath, () => [])\n const selector = `${cssIconSelector}[data-icon-id=\"${iconId}\"]`\n if (iconLang) {\n selectors.push(`:root[${rootLocaleAttr}=\"${iconLang}\"] ${selector}`)\n selectors.push(`:root[${rootLocaleAttr}^=\"${iconLang}_\"] ${selector}`)\n } else {\n selectors.push(selector)\n }\n }\n\n // the size of one icon occupied in the sprite including padding, for scaling factor 1\n const cssTileSize = cssIconSize + 2 * cssIconPadding\n // number of distinct icons in the sprites\n const iconCount = selectorMap.size\n // generate a square-shaped sprite\n const rowLength = Math.ceil(Math.sqrt(iconCount))\n // the resulting size of a sprite, for scaling factor 1\n const cssSpriteWidth = cssTileSize * rowLength\n const cssSpriteHeight = cssTileSize * Math.ceil(iconCount / rowLength)\n // additional vendor prefixes for background/fill attributes\n const prefixes = FILL_VENDOR_PREFIXES[spriteFillType]\n\n // generates a background/mask CSS property definition with correct vendor prefixes\n const fillProp = (name: string, value: string): string => {\n const prop = `${spriteFillType}-${name}: ${value};`\n return prefixes.map(prefix => `-${prefix}-${prop} `).join('') + prop\n }\n\n // the contents of the resulting CSS file with icon definitions\n const cssLines: string[] = [\n `${cssIconSelector} {`,\n ' display: inline-block;',\n ` width: ${px(cssTileSize)};`,\n ` height: ${px(cssTileSize)};`,\n ' flex: 0 0 auto;',\n ` ${fillProp('size', `${px(cssSpriteWidth)} ${px(cssSpriteHeight)}`)}`,\n ` ${fillProp('origin', 'content-box')}`,\n '}',\n `${cssIconSelector}[data-icon-id=\"none\"] { visibility: hidden; }`,\n ]\n\n // generate all sprite entries as an array\n const entries = Array.from(selectorMap, ([iconPath, selectors], index): SpriteEntry => {\n const x = cssTileSize * (index % rowLength)\n const y = cssTileSize * Math.floor(index / rowLength)\n const prop = fillProp('position', `${px(-x)} ${px(-y)}`)\n for (const selector of selectors) {\n cssLines.push(`${selector} { ${prop} }`)\n }\n return { iconPath, x, y }\n })\n\n // create the resulting CSS markup as string\n const cssMarkup = cssLines.join('\\n') + '\\n'\n return { cssMarkup, cssSpriteWidth, cssSpriteHeight, entries }\n }\n}\n\n// plugin =====================================================================\n\n/**\n * A plugin for Vite to generate PNG sprite files from multiple PNG source\n * files.\n *\n * @param index\n * URL of the index source file of this plugin (`import.meta.url`).\n *\n * @param options\n * Plugin configuration options.\n *\n * @returns\n * The plugin instance.\n */\nexport function pngSpritePlugin(index: string, options: PngSpritePluginOptions): Plugin {\n\n // resolved configuration options\n const { cssName, sprites } = options\n\n // helper instance for file system access, logging, etc.\n const helper = new PngSpritePluginHelper(index, options)\n\n // create and return the plugin object\n return {\n name: '@open-xchange/vite-plugin-icon-sprite/png',\n\n // initialize file system cache for generated modules\n async configResolved(viteConfig) {\n await helper.initializeCache(viteConfig)\n },\n\n // pick matching imports\n resolveId(source) {\n return helper.resolveVirtualModuleId(source)\n },\n\n // load the PNG icon files, generate final PNG sprites and CSS file\n async load(moduleId) {\n\n // only handle the target modules specified in 'resolveId'\n const target = helper.matchVirtualModuleId(moduleId)\n if (!target) { return }\n\n // generate the CSS markup\n if (target === cssName) {\n return await helper.generateCssMarkupModule()\n }\n\n // generate a PNG sprite (export binary data as plain Base64 encoded)\n if (target in sprites) {\n const { factor, src } = sprites[target]\n return await helper.generateSpriteModule(target, factor, src)\n }\n\n // invalid module identifier\n helper.fail('unknown output file %f', target)\n return undefined\n },\n }\n}\n","\nimport type { Plugin } from 'vite'\n\nimport { type SvgSpritePluginOptions, svgSpritePlugin } from './plugin-svg.js'\nimport { type PngSpritePluginOptions, pngSpritePlugin } from './plugin-png.js'\n\n// types ======================================================================\n\n/**\n * Configuration options for generating icon sprites from SVG or PNG source\n * images.\n */\nexport type IconSpritePluginOptions = SvgSpritePluginOptions | PngSpritePluginOptions\n\n// plugin =====================================================================\n\n/**\n * A plugin for Vite to generate an icon sprite file from multiple SVG or PNG\n * source files.\n *\n * @param options\n * Plugin configuration options.\n *\n * @returns\n * The plugin instance.\n */\nexport default function iconSpritePlugin(options: IconSpritePluginOptions): Plugin {\n switch (options.format) {\n case 'svg': return svgSpritePlugin(import.meta.url, options)\n case 'png': return pngSpritePlugin(import.meta.url, options)\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["#parseMappingOnce","#parseMapping"],"sources":["../src/helper.ts","../src/plugin-svg.ts","../src/plugin-png.ts","../src/index.ts"],"sourcesContent":["\nimport { type PluginHelperConfig, resolvePath, PluginHelper } from '@open-xchange/vite-helper'\n\n// types ======================================================================\n\n/**\n * Common configuration options (independent from the icon file format) for the\n * plugin '@open-xchange/vite-plugin-icon-sprite'.\n *\n * @template FormatT\n * The file format specifier of the icon sprite, and the source images.\n */\nexport interface SpritePluginBaseOptions<FormatT extends string> {\n\n /**\n * The file format specifier of the icon sprite, and the source images.\n */\n format: FormatT\n\n /**\n * Path to root directory with all image resource files to be processed.\n */\n imagesPath: string\n\n /**\n * Path to the JSON or YAML configuration file containing the mapping between\n * icon identifiers and SVG source file names.\n */\n mappingPath: string\n}\n\n/**\n * Internal configuration of a `SpritePluginHelper` instance.\n */\nexport type SpritePluginConfig = Required<Pick<PluginHelperConfig, 'pluginIndex' | 'virtualModules'>>\n\n/**\n * Represents a single entry in an icon mapping configuration file (a mapping\n * between icon identifier, path to source image, and language code for\n * localized icons).\n */\nexport interface IconMappingEntry {\n /** The icon identifier used in source code to select an icon. */\n iconId: string\n /** The path to the source image file to be inserted into the sprite. */\n iconPath: string\n /** Language code for a localized icon. */\n iconLang?: string\n}\n\n// class SpritePluginHelper ===================================================\n\n/**\n * Plugin helper for all icon file formats.\n *\n * @template OptionsT\n * Exact type of the options interface.\n */\nexport class SpritePluginHelper<OptionsT extends SpritePluginBaseOptions<string>> extends PluginHelper {\n\n /** Resolved configuration options. */\n readonly options: Required<Readonly<OptionsT>>\n\n // constructor ------------------------------------------------------------\n\n protected constructor(config: SpritePluginConfig, options: Required<OptionsT>) {\n super({\n ...config,\n virtualPrefix: options.format,\n loggerPrefix: options.format,\n logLevelEnvVar: 'PLUGIN_ICON_SPRITE_LOGLEVEL',\n cacheSrcFiles: [options.imagesPath + '/**/*.' + options.format, options.mappingPath],\n })\n this.options = options\n }\n\n // protected methods ------------------------------------------------------\n\n /**\n * Reads an icon mapping configuration file, and returns the entries as\n * array.\n *\n * @param path\n * The path to the icon mapping configuration file to be read.\n *\n * @returns\n * The entries of the configuration file.\n */\n protected async readIconMapping(): Promise<IconMappingEntry[]> {\n\n // read the icon mapping configuration file\n type IconMappingSchema = Record<string, string | Record<string, string>>\n const schemaPath = resolvePath('./mapping-schema.json', import.meta.url)\n const mappingDict = await this.readConfig<IconMappingSchema>(this.options.mappingPath, { schema: schemaPath })\n\n // convert to array of `IconMappingEntry`\n const iconMapping: IconMappingEntry[] = []\n for (const [iconId, entry] of Object.entries(mappingDict)) {\n const iconDict = (typeof entry === 'string') ? { '*': entry } : entry\n for (const [languages, iconPath] of Object.entries(iconDict)) {\n for (const iconLang of languages.split(',')) {\n if (iconLang === '*') {\n iconMapping.push({ iconId, iconPath })\n } else {\n iconMapping.push({ iconId, iconPath, iconLang })\n }\n }\n }\n }\n return iconMapping\n }\n}\n","\nimport { basename } from 'node:path'\n\nimport type { Plugin, Rolldown } from 'vite'\nimport SVGSprite from 'svg-sprite'\nimport type * as Vinyl from 'vinyl'\n\nimport { type SpritePluginBaseOptions, SpritePluginHelper } from './helper.js'\n\n// types ======================================================================\n\n/**\n * Configuration options for generating an SVG sprite from SVG source images.\n */\nexport interface SvgSpritePluginOptions extends SpritePluginBaseOptions<'svg'> {\n\n /**\n * Module name of the SVG sprite to be generated (with '.svg' extension). The\n * SVG markup of the sprite can be imported from the virtual module path\n * `'virtual:svg/[spriteName]'`.\n */\n spriteName: string\n\n /**\n * A prefix to be added to all icon identifiers declared in the mapping file.\n * By default, no prefix will be added.\n */\n idPrefix?: string\n}\n\n// class SvgSpritePluginHelper ================================================\n\n/**\n * Implementation helper for SVG to sprite conversion.\n */\nclass SvgSpritePluginHelper extends SpritePluginHelper<SvgSpritePluginOptions> {\n\n constructor(index: string, options: SvgSpritePluginOptions) {\n super({\n pluginIndex: index,\n virtualModules: options.spriteName,\n }, {\n idPrefix: '',\n ...options,\n })\n }\n\n // public methods ---------------------------------------------------------\n\n /**\n * Generates the ES source module for an SVG sprite.\n *\n * @returns\n * The source module containing the SVG markup of the sprite.\n */\n async generateSpriteModule(): Promise<Rolldown.SourceDescription> {\n\n // shortcuts to plugin options\n const { imagesPath, idPrefix, spriteName } = this.options\n\n // try to resolve cached version of generated file\n return await this.generateJsonModule(spriteName, async () => {\n this.info('compiling sprite %f', spriteName)\n\n // create a reverse map from icon filenames to icon identifiers\n const iconIdMap = new Map<string, string>()\n\n // create the core SVG spriter\n const spriter = new SVGSprite({\n shape: {\n id: {\n generator: name => iconIdMap.get(name) ?? '',\n },\n spacing: {\n box: 'icon',\n },\n dimension: {\n maxWidth: 16,\n maxHeight: 16,\n },\n },\n svg: {\n xmlDeclaration: false,\n // - remove all <style> elements declaring a class with fill color\n // - remove all class attribute referring to the class from <style>\n // - add 'fill' attribute to all <symbol> elements\n transform: markup => markup\n .replace(/<style>.*?<\\/style>/g, '')\n .replace(/class=\".*?\" ?/g, '')\n .replace(/<symbol /g, '<symbol fill=\"currentColor\" '),\n },\n mode: {\n inline: true,\n symbol: {\n sprite: spriteName,\n render: { less: false },\n },\n },\n })\n\n // load all source SVG images\n for (const { iconId, iconPath, iconLang } of await this.readIconMapping()) {\n const path = `${imagesPath}/${iconPath}.svg`\n // icon identifier with configured prefix and language suffix\n const idSuffix = iconLang ? `;${iconLang}` : ''\n iconIdMap.set(basename(path), idPrefix + iconId + idSuffix)\n // read SVG source image, insert into spriter instance\n const markup = await this.readText(path)\n spriter.add(path, null, markup)\n }\n\n // '@types/svg-sprite' is missing type definitions for compilation result\n /** @ignore */\n interface SVGSpriteCompileResult {\n symbol: {\n sprite: Vinyl.BufferFile\n }\n shapes: Vinyl.BufferFile[]\n }\n\n // compile the SVG sprite\n const result = (await spriter.compileAsync()).result as SVGSpriteCompileResult\n const spriteMarkup = result.symbol.sprite.contents.toString('utf8')\n\n this.info('sprite %f generated successfully', spriteName)\n return spriteMarkup\n })\n }\n}\n\n// plugin =====================================================================\n\n/**\n * A plugin for Vite to generate an SVG sprite file from multiple SVG source\n * files.\n *\n * @param index\n * URL of the index source file of this plugin (`import.meta.url`).\n *\n * @param options\n * Plugin configuration options.\n *\n * @returns\n * The plugin instance.\n */\nexport function svgSpritePlugin(index: string, options: SvgSpritePluginOptions): Plugin {\n\n // helper instance for file system access, logging, etc.\n const helper = new SvgSpritePluginHelper(index, options)\n\n // create and return the plugin object\n return {\n name: '@open-xchange/vite-plugin-icon-sprite/svg',\n\n // initialize file system cache for generated modules\n async configResolved(viteConfig) {\n await helper.initializeCache(viteConfig)\n },\n\n // pick matching imports\n resolveId(source) {\n return helper.resolveVirtualModuleId(source)\n },\n\n // load the SVG icon files, generate final SVG sprite\n async load(moduleId) {\n\n // only handle the output file specified in 'resolveId'\n if (!helper.matchVirtualModuleId(moduleId)) {\n return null\n }\n\n // create an ES module that exports the SVG markup of the sprite\n return await helper.generateSpriteModule()\n },\n }\n}\n","\nimport type { Plugin, Rolldown } from 'vite'\nimport { Jimp, PNGColorType } from 'jimp'\n\nimport { onceFn, Cache } from '@open-xchange/rolldown-utils'\n\nimport { type SpritePluginBaseOptions, SpritePluginHelper } from './helper.js'\n\n// types ======================================================================\n\n/**\n * Configuration options for generating PNG sprites from PNG source images.\n */\nexport interface PngSpritePluginOptions extends SpritePluginBaseOptions<'png'> {\n\n /**\n * Module name for the CSS file (with '.css' extension). The generated CSS\n * markup can be imported from `'virtual:png/[cssName]'`.\n */\n cssName: string\n\n /**\n * Base size of all icons, in CSS pixels.\n */\n cssIconSize: number\n\n /**\n * Additional padding around all icons to be generated in the sprites, in CSS\n * pixels.\n *\n * @default 0\n */\n cssIconPadding?: number\n\n /**\n * The CSS selector for a PNG icon element to be used in all generated CSS\n * rules.\n *\n * @default 'i.png-icon'\n */\n cssIconSelector?: string\n\n /**\n * Name of the root element's attribute containing the locale identifier.\n * Needed to generate CSS selectors for localized icons.\n *\n * @default 'lang'\n */\n rootLocaleAttr?: string\n\n /**\n * Specifies how to generate the sprite PNG files.\n *\n * - `'source'`: The source PNGs will be copied into the generated sprites\n * unmodified. They will contain three color channels and an alpha channel.\n * - `'monochrome'`: The generated sprites will be converted to monochrome.\n * They will contain a gray channel and an alpha channel.\n * - `'alpha'`: Only the alpha channels of the source PNGs will be copied\n * into the generated sprites. They will contain a single gray channel\n * representing the original alpha channels.\n *\n * @default 'source'\n */\n spriteColorType?: 'source' | 'monochrome' | 'alpha'\n\n /**\n * Specifies how the sprites are supposed to be used in CSS rules.\n *\n * - `'background'`: The sprites will be attached via 'background-image'.\n * - `'mask'`: The sprites will be attached via 'mask-image'.\n *\n * All related CSS properties (e.g. '(background|mask)-position' etc.) will\n * be generated accordingly.\n *\n * @default 'background'\n */\n spriteFillType?: 'background' | 'mask'\n\n /**\n * List of all icon sprites to be generated.\n *\n * - The keys of the dictionary are the module names of the PNG sprites (with\n * '.png' extension). The generated sprite PNG file can be imported from\n * `'virtual:png/[key]'`.\n * - 'factor' is the scaling factor (a multiplier for 'cssIconSize'). All\n * source PNG files must have the effective pixel size (`cssIconSize *\n * factor`).\n * - 'src' specifies the pattern used to build the path of the source PNG\n * files. MUST contain the placeholder '[path]' that will be replaced with\n * the base paths contained in the icon mapping file referred in the option\n * 'mappingFile'.\n */\n sprites: Record<string, { factor: number, src: string }>\n}\n\n/**\n * Descriptor for a single entry in the resulting sprites.\n */\ninterface SpriteEntry {\n iconPath: string\n x: number\n y: number\n}\n\n/**\n * Generic descriptor for an entire sprite, independent from actual icon size.\n */\ninterface SpriteSettings {\n cssMarkup: string\n cssSpriteWidth: number\n cssSpriteHeight: number\n entries: readonly SpriteEntry[]\n}\n\n// constants ==================================================================\n\nconst FILL_VENDOR_PREFIXES: Record<NonNullable<PngSpritePluginOptions['spriteFillType']>, string[]> = {\n background: [],\n mask: ['webkit'],\n}\n\n// functions ==================================================================\n\n/**\n * Generates a CSS length string in pixels (omits unit for zero).\n *\n * @param value\n * The length to be emitted.\n *\n * @returns\n * The passed length with 'px' unit.\n */\nfunction px(value: number): string {\n return value ? `${value}px` : '0'\n}\n\n// class PngSpritePluginHelper ================================================\n\n/**\n * Implementation helper for PNG to sprite conversion.\n */\nclass PngSpritePluginHelper extends SpritePluginHelper<PngSpritePluginOptions> {\n\n readonly #parseMappingOnce: () => Promise<SpriteSettings>\n\n // constructor ------------------------------------------------------------\n\n constructor(index: string, options: PngSpritePluginOptions) {\n super({\n pluginIndex: index,\n virtualModules: [options.cssName, ...Object.keys(options.sprites)],\n }, {\n cssIconPadding: 0,\n cssIconSelector: 'i.png-icon',\n rootLocaleAttr: 'lang',\n spriteColorType: 'source',\n spriteFillType: 'background',\n ...options,\n })\n this.#parseMappingOnce = onceFn(() => this.#parseMapping())\n }\n\n // public methods ---------------------------------------------------------\n\n /**\n * Generates an ES source module with CSS markup code for all icons.\n *\n * @returns\n * The source module with CSS markup for all icons.\n */\n async generateCssMarkupModule(): Promise<Rolldown.SourceDescription> {\n\n // shortcuts to plugin options\n const { cssName } = this.options\n\n // try to resolve cached version of generated file\n return await this.generateModule(cssName, async () => {\n this.info('generating CSS markup %f', cssName)\n\n // parse mapping file which collects icon paths, CSS selectors, and entry positions\n const cssMarkup = (await this.#parseMappingOnce()).cssMarkup\n\n this.info('CSS markup %f generated successfully', cssName)\n return cssMarkup\n })\n }\n\n /**\n * Generates the ES source module for a PNG sprite with a specific scaling\n * factor.\n *\n * @param spriteName\n * The name of the sprite.\n *\n * @param factor\n * The scaling factor.\n *\n * @param srcPattern\n * The pattern for the source PNG images.\n *\n * @returns\n * The source module exporting the PNG sprite as base-64 encoded data URL.\n */\n async generateSpriteModule(spriteName: string, factor: number, srcPattern: string): Promise<Rolldown.SourceDescription> {\n\n // shortcuts to plugin options\n const { imagesPath, cssIconSize, cssIconPadding, spriteColorType } = this.options\n\n // check configuration\n this.ensure(factor > 0, 'invalid scaling factor in configuration for sprite %f', spriteName)\n this.ensure(srcPattern.includes('[path]'), 'placeholder [path] expected in configuration for sprite %f', spriteName)\n\n // try to resolve cached version of generated file\n return await this.generateJsonModule(spriteName, async () => {\n this.info('generating sprite %f', spriteName)\n\n // parse mapping file which collects icon paths, CSS selectors, and entry positions\n const { cssSpriteWidth, cssSpriteHeight, entries } = await this.#parseMappingOnce()\n\n // new image data is not clean out-of-the-box, explicitly fill with zeros\n const sprite = new Jimp({ width: cssSpriteWidth * factor, height: cssSpriteHeight * factor, color: 0 })\n\n // process all entries in the mapping configuration\n for (const { iconPath, x, y } of entries) {\n\n // expected pixel size for the current scaling factor\n const size = cssIconSize * factor\n\n // load and parse the source image file\n const path = imagesPath + '/' + srcPattern.replace('[path]', iconPath)\n const buffer = await this.readBuffer(path)\n const image = await Jimp.fromBuffer(buffer)\n\n // validate the image size\n const { width, height } = image.bitmap\n this.ensure((width === size) && (height === size), 'wrong image width in %f (expected %s but got %s)', path, `${size}x${size}`, `${width}x${height}`)\n\n // insert source image into the sprite\n sprite.blit({ src: image, x: (x + cssIconPadding) * factor, y: (y + cssIconPadding) * factor })\n }\n\n // copy alpha of all pixels to RGB channels (alpha channel will be exported as greyscale without alpha)\n if (spriteColorType === 'alpha') {\n for (let d = sprite.bitmap.data, i = 0, l = d.length; i < l; i += 4) {\n d.fill(d[i + 3], i, i + 3) // copy A to RGB\n d[i + 3] = 255 // set A to full opacity\n }\n }\n\n // generate the binary PNG data (no preset constants for PNG color types in Jimp)\n const colorType = {\n source: PNGColorType.COLOR_ALPHA,\n monochrome: PNGColorType.GRAYSCALE_ALPHA,\n alpha: PNGColorType.GRAYSCALE,\n }[spriteColorType]\n const spriteBuffer = await sprite.getBuffer('image/png', { colorType })\n\n // convert to base64 encoded data URL\n const spriteDataUrl = `data:image/png;base64,${spriteBuffer.toString('base64')}`\n\n this.info('sprite %f generated successfully', spriteName)\n return spriteDataUrl\n })\n }\n\n // private methods --------------------------------------------------------\n\n // parses the mapping file once, generates a map from short icon paths to `SpriteEntry` descriptor objects\n async #parseMapping(): Promise<SpriteSettings> {\n\n // shortcuts to plugin options\n const { cssIconSize, cssIconPadding, cssIconSelector, rootLocaleAttr, spriteFillType } = this.options\n\n // CSS selectors for all sprite entries, mapped by short icon path (different icons may refer to the same source PNG)\n const selectorMap = new Cache<string[]>()\n\n // process all entries in the mapping configuration, collect CSS selectors for each entry in the sprite\n for (const { iconId, iconPath, iconLang } of await this.readIconMapping()) {\n const selectors = selectorMap.upsert(iconPath, () => [])\n const selector = `${cssIconSelector}[data-icon-id=\"${iconId}\"]`\n if (iconLang) {\n selectors.push(`:root[${rootLocaleAttr}=\"${iconLang}\"] ${selector}`)\n selectors.push(`:root[${rootLocaleAttr}^=\"${iconLang}_\"] ${selector}`)\n } else {\n selectors.push(selector)\n }\n }\n\n // the size of one icon occupied in the sprite including padding, for scaling factor 1\n const cssTileSize = cssIconSize + 2 * cssIconPadding\n // number of distinct icons in the sprites\n const iconCount = selectorMap.size\n // generate a square-shaped sprite\n const rowLength = Math.ceil(Math.sqrt(iconCount))\n // the resulting size of a sprite, for scaling factor 1\n const cssSpriteWidth = cssTileSize * rowLength\n const cssSpriteHeight = cssTileSize * Math.ceil(iconCount / rowLength)\n // additional vendor prefixes for background/fill attributes\n const prefixes = FILL_VENDOR_PREFIXES[spriteFillType]\n\n // generates a background/mask CSS property definition with correct vendor prefixes\n const fillProp = (name: string, value: string): string => {\n const prop = `${spriteFillType}-${name}: ${value};`\n return prefixes.map(prefix => `-${prefix}-${prop} `).join('') + prop\n }\n\n // the contents of the resulting CSS file with icon definitions\n const cssLines: string[] = [\n `${cssIconSelector} {`,\n ' display: inline-block;',\n ` width: ${px(cssTileSize)};`,\n ` height: ${px(cssTileSize)};`,\n ' flex: 0 0 auto;',\n ` ${fillProp('size', `${px(cssSpriteWidth)} ${px(cssSpriteHeight)}`)}`,\n ` ${fillProp('origin', 'content-box')}`,\n '}',\n `${cssIconSelector}[data-icon-id=\"none\"] { visibility: hidden; }`,\n ]\n\n // generate all sprite entries as an array\n const entries = Array.from(selectorMap, ([iconPath, selectors], index): SpriteEntry => {\n const x = cssTileSize * (index % rowLength)\n const y = cssTileSize * Math.floor(index / rowLength)\n const prop = fillProp('position', `${px(-x)} ${px(-y)}`)\n for (const selector of selectors) {\n cssLines.push(`${selector} { ${prop} }`)\n }\n return { iconPath, x, y }\n })\n\n // create the resulting CSS markup as string\n const cssMarkup = cssLines.join('\\n') + '\\n'\n return { cssMarkup, cssSpriteWidth, cssSpriteHeight, entries }\n }\n}\n\n// plugin =====================================================================\n\n/**\n * A plugin for Vite to generate PNG sprite files from multiple PNG source\n * files.\n *\n * @param index\n * URL of the index source file of this plugin (`import.meta.url`).\n *\n * @param options\n * Plugin configuration options.\n *\n * @returns\n * The plugin instance.\n */\nexport function pngSpritePlugin(index: string, options: PngSpritePluginOptions): Plugin {\n\n // resolved configuration options\n const { cssName, sprites } = options\n\n // helper instance for file system access, logging, etc.\n const helper = new PngSpritePluginHelper(index, options)\n\n // create and return the plugin object\n return {\n name: '@open-xchange/vite-plugin-icon-sprite/png',\n\n // initialize file system cache for generated modules\n async configResolved(viteConfig) {\n await helper.initializeCache(viteConfig)\n },\n\n // pick matching imports\n resolveId(source) {\n return helper.resolveVirtualModuleId(source)\n },\n\n // load the PNG icon files, generate final PNG sprites and CSS file\n async load(moduleId) {\n\n // only handle the target modules specified in 'resolveId'\n const target = helper.matchVirtualModuleId(moduleId)\n if (!target) return\n\n // generate the CSS markup\n if (target === cssName) {\n return await helper.generateCssMarkupModule()\n }\n\n // generate a PNG sprite (export binary data as plain Base64 encoded)\n if (target in sprites) {\n const { factor, src } = sprites[target]\n return await helper.generateSpriteModule(target, factor, src)\n }\n\n // invalid module identifier\n helper.fail('unknown output file %f', target)\n return undefined\n },\n }\n}\n","\nimport type { Plugin } from 'vite'\n\nimport { type SvgSpritePluginOptions, svgSpritePlugin } from './plugin-svg.js'\nimport { type PngSpritePluginOptions, pngSpritePlugin } from './plugin-png.js'\n\n// types ======================================================================\n\n/**\n * Configuration options for generating icon sprites from SVG or PNG source\n * images.\n */\nexport type IconSpritePluginOptions = SvgSpritePluginOptions | PngSpritePluginOptions\n\n// plugin =====================================================================\n\n/**\n * A plugin for Vite to generate an icon sprite file from multiple SVG or PNG\n * source files.\n *\n * @param options\n * Plugin configuration options.\n *\n * @returns\n * The plugin instance.\n */\nexport default function iconSpritePlugin(options: IconSpritePluginOptions): Plugin {\n switch (options.format) {\n case 'svg': return svgSpritePlugin(import.meta.url, options)\n case 'png': return pngSpritePlugin(import.meta.url, options)\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-xchange/vite-plugin-icon-sprite",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Vite plugin that builds icon sprites from SVG or PNG icon files",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
},
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"engines": {
|
|
12
|
-
"node": ">=
|
|
12
|
+
"node": ">=22.18"
|
|
13
13
|
},
|
|
14
14
|
"type": "module",
|
|
15
15
|
"exports": {
|
|
@@ -23,15 +23,16 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"jimp": "^1.6.1",
|
|
25
25
|
"svg-sprite": "^2.0.4",
|
|
26
|
-
"@open-xchange/
|
|
26
|
+
"@open-xchange/rolldown-utils": "^1.2.0",
|
|
27
|
+
"@open-xchange/vite-helper": "^2.1.0"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"@types/pngjs": "^6.0.5",
|
|
30
31
|
"@types/svg-sprite": "^0.0.39",
|
|
31
32
|
"@types/vinyl": "^2.0.12",
|
|
32
|
-
"vite": "^8.0.
|
|
33
|
-
"@open-xchange/linter-presets": "^1.
|
|
34
|
-
"@open-xchange/tsconfig": "^0.0
|
|
33
|
+
"vite": "^8.0.12",
|
|
34
|
+
"@open-xchange/linter-presets": "^1.24.0",
|
|
35
|
+
"@open-xchange/tsconfig": "^0.1.0"
|
|
35
36
|
},
|
|
36
37
|
"peerDependencies": {
|
|
37
38
|
"vite": "^6.0.0 || ^7.0.0 || ^8.0.0"
|