@open-xchange/vite-plugin-icon-sprite 1.1.1 → 1.3.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/LICENSE +21 -0
- package/README.md +50 -49
- package/dist/index.d.mts +147 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +363 -0
- package/dist/index.mjs.map +1 -0
- package/dist/mapping-schema.json +29 -29
- package/package.json +18 -22
- package/dist/helper.d.ts +0 -62
- package/dist/helper.js +0 -56
- package/dist/index.d.ts +0 -19
- package/dist/index.js +0 -19
- package/dist/plugin-png.d.ts +0 -97
- package/dist/plugin-png.js +0 -237
- package/dist/plugin-svg.d.ts +0 -32
- package/dist/plugin-svg.js +0 -119
- package/dist/tsconfig.json +0 -7
package/dist/helper.js
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { dictEntries } from "@open-xchange/vite-helper/utils";
|
|
2
|
-
import { resolvePath } from "@open-xchange/vite-helper/file";
|
|
3
|
-
import { PluginHelper } from "@open-xchange/vite-helper";
|
|
4
|
-
// class SpritePluginHelper ===================================================
|
|
5
|
-
/**
|
|
6
|
-
* Plugin helper for all icon file formats.
|
|
7
|
-
*
|
|
8
|
-
* @template OptionsT
|
|
9
|
-
* Exact type of the options interface.
|
|
10
|
-
*/
|
|
11
|
-
export class SpritePluginHelper extends PluginHelper {
|
|
12
|
-
/** Resolved configuration options. */
|
|
13
|
-
options;
|
|
14
|
-
// constructor ------------------------------------------------------------
|
|
15
|
-
constructor(config, options) {
|
|
16
|
-
super({
|
|
17
|
-
...config,
|
|
18
|
-
virtualPrefix: options.format,
|
|
19
|
-
loggerPrefix: options.format,
|
|
20
|
-
logLevelEnvVar: "PLUGIN_ICON_SPRITE_LOGLEVEL",
|
|
21
|
-
cacheSrcFiles: [options.imagesPath + "/**/*." + options.format, options.mappingPath],
|
|
22
|
-
});
|
|
23
|
-
this.options = options;
|
|
24
|
-
}
|
|
25
|
-
// protected methods ------------------------------------------------------
|
|
26
|
-
/**
|
|
27
|
-
* Reads an icon mapping configuration file, and returns the entries as
|
|
28
|
-
* array.
|
|
29
|
-
*
|
|
30
|
-
* @param path
|
|
31
|
-
* The path to the icon mapping configuration file to be read.
|
|
32
|
-
*
|
|
33
|
-
* @returns
|
|
34
|
-
* The entries of the configuration file.
|
|
35
|
-
*/
|
|
36
|
-
async readIconMapping() {
|
|
37
|
-
const schemaPath = resolvePath("./mapping-schema.json", import.meta.url);
|
|
38
|
-
const mappingDict = await this.readConfig(this.options.mappingPath, { schema: schemaPath });
|
|
39
|
-
// convert to array of `IconMappingEntry`
|
|
40
|
-
const iconMapping = [];
|
|
41
|
-
for (const [iconId, entry] of dictEntries(mappingDict)) {
|
|
42
|
-
const iconDict = (typeof entry === "string") ? { "*": entry } : entry;
|
|
43
|
-
for (const [languages, iconPath] of dictEntries(iconDict)) {
|
|
44
|
-
for (const iconLang of languages.split(",")) {
|
|
45
|
-
if (iconLang === "*") {
|
|
46
|
-
iconMapping.push({ iconId, iconPath });
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
iconMapping.push({ iconId, iconPath, iconLang });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return iconMapping;
|
|
55
|
-
}
|
|
56
|
-
}
|
package/dist/index.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import { type SvgSpritePluginOptions } from "./plugin-svg.js";
|
|
3
|
-
import { type PngSpritePluginOptions } from "./plugin-png.js";
|
|
4
|
-
/**
|
|
5
|
-
* Configuration options for generating icon sprites from SVG or PNG source
|
|
6
|
-
* images.
|
|
7
|
-
*/
|
|
8
|
-
export type IconSpritePluginOptions = SvgSpritePluginOptions | PngSpritePluginOptions;
|
|
9
|
-
/**
|
|
10
|
-
* A plugin for Vite to generate an icon sprite file from multiple SVG or PNG
|
|
11
|
-
* source files.
|
|
12
|
-
*
|
|
13
|
-
* @param options
|
|
14
|
-
* Plugin configuration options.
|
|
15
|
-
*
|
|
16
|
-
* @returns
|
|
17
|
-
* The plugin instance.
|
|
18
|
-
*/
|
|
19
|
-
export default function iconSpritePlugin(options: IconSpritePluginOptions): Plugin;
|
package/dist/index.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { svgSpritePlugin } from "./plugin-svg.js";
|
|
2
|
-
import { pngSpritePlugin } from "./plugin-png.js";
|
|
3
|
-
// plugin =====================================================================
|
|
4
|
-
/**
|
|
5
|
-
* A plugin for Vite to generate an icon sprite file from multiple SVG or PNG
|
|
6
|
-
* source files.
|
|
7
|
-
*
|
|
8
|
-
* @param options
|
|
9
|
-
* Plugin configuration options.
|
|
10
|
-
*
|
|
11
|
-
* @returns
|
|
12
|
-
* The plugin instance.
|
|
13
|
-
*/
|
|
14
|
-
export default function iconSpritePlugin(options) {
|
|
15
|
-
switch (options.format) {
|
|
16
|
-
case "svg": return svgSpritePlugin(import.meta.url, options);
|
|
17
|
-
case "png": return pngSpritePlugin(import.meta.url, options);
|
|
18
|
-
}
|
|
19
|
-
}
|
package/dist/plugin-png.d.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import { type Dict } from "@open-xchange/vite-helper/utils";
|
|
3
|
-
import { type SpritePluginBaseOptions } from "./helper.js";
|
|
4
|
-
/**
|
|
5
|
-
* Configuration options for generating PNG sprites from PNG source images.
|
|
6
|
-
*/
|
|
7
|
-
export interface PngSpritePluginOptions extends SpritePluginBaseOptions<"png"> {
|
|
8
|
-
/**
|
|
9
|
-
* Module name for the CSS file (with ".css" extension). The generated CSS
|
|
10
|
-
* markup can be imported from `"virtual:png/[cssName]"`.
|
|
11
|
-
*/
|
|
12
|
-
cssName: string;
|
|
13
|
-
/**
|
|
14
|
-
* Base size of all icons, in CSS pixels.
|
|
15
|
-
*/
|
|
16
|
-
cssIconSize: number;
|
|
17
|
-
/**
|
|
18
|
-
* Additional padding around all icons to be generated in the sprites, in
|
|
19
|
-
* CSS pixels.
|
|
20
|
-
*
|
|
21
|
-
* @default 0
|
|
22
|
-
*/
|
|
23
|
-
cssIconPadding?: number;
|
|
24
|
-
/**
|
|
25
|
-
* The CSS selector for a PNG icon element to be used in all generated CSS
|
|
26
|
-
* rules.
|
|
27
|
-
*
|
|
28
|
-
* @default "i.png-icon"
|
|
29
|
-
*/
|
|
30
|
-
cssIconSelector?: string;
|
|
31
|
-
/**
|
|
32
|
-
* Name of the root element's attribute containing the locale identifier.
|
|
33
|
-
* Needed to generate CSS selectors for localized icons.
|
|
34
|
-
*
|
|
35
|
-
* @default "lang"
|
|
36
|
-
*/
|
|
37
|
-
rootLocaleAttr?: string;
|
|
38
|
-
/**
|
|
39
|
-
* Specifies how to generate the sprite PNG files.
|
|
40
|
-
*
|
|
41
|
-
* - `"source"`: The source PNGs will be copied into the generated sprites
|
|
42
|
-
* unmodified. They will contain three color channels and an alpha
|
|
43
|
-
* channel.
|
|
44
|
-
* - `"monochrome"`: The generated sprites will be converted to monochrome.
|
|
45
|
-
* They will contain a gray channel and an alpha channel.
|
|
46
|
-
* - `"alpha"`: Only the alpha channels of the source PNGs will be copied
|
|
47
|
-
* into the generated sprites. They will contain a single gray channel
|
|
48
|
-
* representing the original alpha channels.
|
|
49
|
-
*
|
|
50
|
-
* @default "source"
|
|
51
|
-
*/
|
|
52
|
-
spriteColorType?: "source" | "monochrome" | "alpha";
|
|
53
|
-
/**
|
|
54
|
-
* Specifies how the sprites are supposed to be used in CSS rules.
|
|
55
|
-
*
|
|
56
|
-
* - `"background"`: The sprites will be attached via "background-image".
|
|
57
|
-
* - `"mask"`: The sprites will be attached via "mask-image".
|
|
58
|
-
*
|
|
59
|
-
* All related CSS properties (e.g. "(background|mask)-position" etc.) will
|
|
60
|
-
* be generated accordingly.
|
|
61
|
-
*
|
|
62
|
-
* @default "background"
|
|
63
|
-
*/
|
|
64
|
-
spriteFillType?: "background" | "mask";
|
|
65
|
-
/**
|
|
66
|
-
* List of all icon sprites to be generated.
|
|
67
|
-
*
|
|
68
|
-
* - The keys of the dictionary are the module names of the PNG sprites
|
|
69
|
-
* (with ".png" extension). The generated sprite PNG file can be imported
|
|
70
|
-
* from `"virtual:png/[key]"`.
|
|
71
|
-
* - "factor" is the scaling factor (a multiplier for "cssIconSize"). All
|
|
72
|
-
* source PNG files must have the effective pixel size (`cssIconSize *
|
|
73
|
-
* factor`).
|
|
74
|
-
* - "src" specifies the pattern used to build the path of the source PNG
|
|
75
|
-
* files. MUST contain the placeholder "[path]" that will be replaced
|
|
76
|
-
* with the base paths contained in the icon mapping file referred in the
|
|
77
|
-
* option "mappingFile".
|
|
78
|
-
*/
|
|
79
|
-
sprites: Dict<{
|
|
80
|
-
factor: number;
|
|
81
|
-
src: string;
|
|
82
|
-
}>;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* A plugin for Vite to generate PNG sprite files from multiple PNG source
|
|
86
|
-
* files.
|
|
87
|
-
*
|
|
88
|
-
* @param index
|
|
89
|
-
* URL of the index source file of this plugin.
|
|
90
|
-
*
|
|
91
|
-
* @param options
|
|
92
|
-
* Plugin configuration options.
|
|
93
|
-
*
|
|
94
|
-
* @returns
|
|
95
|
-
* The plugin instance.
|
|
96
|
-
*/
|
|
97
|
-
export declare function pngSpritePlugin(index: string, options: PngSpritePluginOptions): Plugin;
|
package/dist/plugin-png.js
DELETED
|
@@ -1,237 +0,0 @@
|
|
|
1
|
-
import { Jimp, PNGColorType } from "jimp";
|
|
2
|
-
import { onceFn } from "@open-xchange/vite-helper/utils";
|
|
3
|
-
import { Cache } from "@open-xchange/vite-helper/cache";
|
|
4
|
-
import { SpritePluginHelper } from "./helper.js";
|
|
5
|
-
// constants ==================================================================
|
|
6
|
-
const FILL_VENDOR_PREFIXES = {
|
|
7
|
-
background: [],
|
|
8
|
-
mask: ["webkit"],
|
|
9
|
-
};
|
|
10
|
-
// functions ==================================================================
|
|
11
|
-
/**
|
|
12
|
-
* Generates a CSS length string in pixels (omits unit for zero).
|
|
13
|
-
*
|
|
14
|
-
* @param value
|
|
15
|
-
* The length to be emitted.
|
|
16
|
-
*
|
|
17
|
-
* @returns
|
|
18
|
-
* The passed length with "px" unit.
|
|
19
|
-
*/
|
|
20
|
-
function px(value) {
|
|
21
|
-
return value ? `${value}px` : "0";
|
|
22
|
-
}
|
|
23
|
-
// class PngSpritePluginHelper ================================================
|
|
24
|
-
class PngSpritePluginHelper extends SpritePluginHelper {
|
|
25
|
-
#parseMappingOnce;
|
|
26
|
-
// constructor ------------------------------------------------------------
|
|
27
|
-
constructor(index, options) {
|
|
28
|
-
super({
|
|
29
|
-
pluginIndex: index,
|
|
30
|
-
virtualModules: [options.cssName, ...Object.keys(options.sprites)],
|
|
31
|
-
}, {
|
|
32
|
-
cssIconPadding: 0,
|
|
33
|
-
cssIconSelector: "i.png-icon",
|
|
34
|
-
rootLocaleAttr: "lang",
|
|
35
|
-
spriteColorType: "source",
|
|
36
|
-
spriteFillType: "background",
|
|
37
|
-
...options,
|
|
38
|
-
});
|
|
39
|
-
this.#parseMappingOnce = onceFn(() => this.#parseMapping());
|
|
40
|
-
}
|
|
41
|
-
// public methods ---------------------------------------------------------
|
|
42
|
-
/**
|
|
43
|
-
* Generates an ES source module with CSS markup code for all icons.
|
|
44
|
-
*
|
|
45
|
-
* @returns
|
|
46
|
-
* The source module with CSS markup for all icons.
|
|
47
|
-
*/
|
|
48
|
-
async generateCssMarkupModule() {
|
|
49
|
-
// shortcuts to plugin options
|
|
50
|
-
const { cssName } = this.options;
|
|
51
|
-
// try to resolve cached version of generated file
|
|
52
|
-
return await this.generateModule(cssName, async () => {
|
|
53
|
-
this.info("generating CSS markup %f", cssName);
|
|
54
|
-
// parse mapping file which collects icon paths, CSS selectors, and entry positions
|
|
55
|
-
const cssMarkup = (await this.#parseMappingOnce()).cssMarkup;
|
|
56
|
-
this.info("CSS markup %f generated successfully", cssName);
|
|
57
|
-
return cssMarkup;
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Generates the ES source module for a PNG sprite with a specific scaling
|
|
62
|
-
* factor.
|
|
63
|
-
*
|
|
64
|
-
* @param spriteName
|
|
65
|
-
* The name of the sprite.
|
|
66
|
-
*
|
|
67
|
-
* @param factor
|
|
68
|
-
* The scaling factor.
|
|
69
|
-
*
|
|
70
|
-
* @param srcPattern
|
|
71
|
-
* The pattern for the source PNG images.
|
|
72
|
-
*
|
|
73
|
-
* @returns
|
|
74
|
-
* The source module exporting the PNG sprite as base-64 encoded data URL.
|
|
75
|
-
*/
|
|
76
|
-
async generateSpriteModule(spriteName, factor, srcPattern) {
|
|
77
|
-
// shortcuts to plugin options
|
|
78
|
-
const { imagesPath, cssIconSize, cssIconPadding, spriteColorType } = this.options;
|
|
79
|
-
// check configuration
|
|
80
|
-
this.ensure(factor > 0, "invalid scaling factor in configuration for sprite %f", spriteName);
|
|
81
|
-
this.ensure(srcPattern.includes("[path]"), "placeholder [path] expected in configuration for sprite %f", spriteName);
|
|
82
|
-
// try to resolve cached version of generated file
|
|
83
|
-
return await this.generateModule(spriteName, async () => {
|
|
84
|
-
this.info("generating sprite %f", spriteName);
|
|
85
|
-
// parse mapping file which collects icon paths, CSS selectors, and entry positions
|
|
86
|
-
const { cssSpriteWidth, cssSpriteHeight, entries } = await this.#parseMappingOnce();
|
|
87
|
-
// new image data is not clean out-of-the-box, explicitly fill with zeros
|
|
88
|
-
const sprite = new Jimp({ width: cssSpriteWidth * factor, height: cssSpriteHeight * factor, color: 0 });
|
|
89
|
-
// process all entries in the mapping configuration
|
|
90
|
-
for (const { iconPath, x, y } of entries) {
|
|
91
|
-
// expected pixel size for the current scaling factor
|
|
92
|
-
const size = cssIconSize * factor;
|
|
93
|
-
// load and parse the source image file
|
|
94
|
-
const path = imagesPath + "/" + srcPattern.replace("[path]", iconPath);
|
|
95
|
-
const buffer = await this.readBuffer(path);
|
|
96
|
-
const image = await Jimp.fromBuffer(buffer);
|
|
97
|
-
// validate the image size
|
|
98
|
-
const { width, height } = image.bitmap;
|
|
99
|
-
this.ensure((width === size) && (height === size), "wrong image width in %f (expected %s but got %s)", path, `${size}x${size}`, `${width}x${height}`);
|
|
100
|
-
// insert source image into the sprite
|
|
101
|
-
sprite.blit({ src: image, x: (x + cssIconPadding) * factor, y: (y + cssIconPadding) * factor });
|
|
102
|
-
}
|
|
103
|
-
// copy alpha of all pixels to RGB channels (alpha channel will be exported as greyscale without alpha)
|
|
104
|
-
if (spriteColorType === "alpha") {
|
|
105
|
-
for (let d = sprite.bitmap.data, i = 0, l = d.length; i < l; i += 4) {
|
|
106
|
-
d.fill(d[i + 3], i, i + 3); // copy A to RGB
|
|
107
|
-
d[i + 3] = 255; // set A to full opacity
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
// generate the binary PNG data (no preset constants for PNG color types in Jimp)
|
|
111
|
-
const colorType = {
|
|
112
|
-
source: PNGColorType.COLOR_ALPHA,
|
|
113
|
-
monochrome: PNGColorType.GRAYSCALE_ALPHA,
|
|
114
|
-
alpha: PNGColorType.GRAYSCALE,
|
|
115
|
-
}[spriteColorType];
|
|
116
|
-
const spriteBuffer = await sprite.getBuffer("image/png", { colorType });
|
|
117
|
-
// convert to base64 encoded data URL
|
|
118
|
-
const spriteDataUrl = `data:image/png;base64,${spriteBuffer.toString("base64")}`;
|
|
119
|
-
const moduleSource = `export default ${JSON.stringify(spriteDataUrl)};`;
|
|
120
|
-
this.info("sprite %f generated successfully", spriteName);
|
|
121
|
-
return moduleSource;
|
|
122
|
-
});
|
|
123
|
-
}
|
|
124
|
-
// private methods --------------------------------------------------------
|
|
125
|
-
// parses the mapping file once, generates a map from short icon paths to `SpriteEntry` descriptor objects
|
|
126
|
-
async #parseMapping() {
|
|
127
|
-
// shortcuts to plugin options
|
|
128
|
-
const { cssIconSize, cssIconPadding, cssIconSelector, rootLocaleAttr, spriteFillType } = this.options;
|
|
129
|
-
// CSS selectors for all sprite entries, mapped by short icon path (different icons may refer to the same source PNG)
|
|
130
|
-
const selectorMap = new Cache();
|
|
131
|
-
// process all entries in the mapping configuration, collect CSS selectors for each entry in the sprite
|
|
132
|
-
for (const { iconId, iconPath, iconLang } of await this.readIconMapping()) {
|
|
133
|
-
const selectors = selectorMap.upsert(iconPath, () => []);
|
|
134
|
-
const selector = `${cssIconSelector}[data-icon-id="${iconId}"]`;
|
|
135
|
-
if (iconLang) {
|
|
136
|
-
selectors.push(`:root[${rootLocaleAttr}="${iconLang}"] ${selector}`);
|
|
137
|
-
selectors.push(`:root[${rootLocaleAttr}^="${iconLang}_"] ${selector}`);
|
|
138
|
-
}
|
|
139
|
-
else {
|
|
140
|
-
selectors.push(selector);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// the size of one icon occupied in the sprite including padding, for scaling factor 1
|
|
144
|
-
const cssTileSize = cssIconSize + 2 * cssIconPadding;
|
|
145
|
-
// number of distinct icons in the sprites
|
|
146
|
-
const iconCount = selectorMap.size;
|
|
147
|
-
// generate a square-shaped sprite
|
|
148
|
-
const rowLength = Math.ceil(Math.sqrt(iconCount));
|
|
149
|
-
// the resulting size of a sprite, for scaling factor 1
|
|
150
|
-
const cssSpriteWidth = cssTileSize * rowLength;
|
|
151
|
-
const cssSpriteHeight = cssTileSize * Math.ceil(iconCount / rowLength);
|
|
152
|
-
// additional vendor prefixes for background/fill attributes
|
|
153
|
-
const prefixes = FILL_VENDOR_PREFIXES[spriteFillType];
|
|
154
|
-
// generates a background/mask CSS property definition with correct vendor prefixes
|
|
155
|
-
const fillProp = (name, value) => {
|
|
156
|
-
const prop = `${spriteFillType}-${name}: ${value};`;
|
|
157
|
-
return prefixes.map(prefix => `-${prefix}-${prop} `).join("") + prop;
|
|
158
|
-
};
|
|
159
|
-
// the contents of the resulting CSS file with icon definitions
|
|
160
|
-
const cssLines = [
|
|
161
|
-
`${cssIconSelector} {`,
|
|
162
|
-
" display: inline-block;",
|
|
163
|
-
` width: ${px(cssTileSize)};`,
|
|
164
|
-
` height: ${px(cssTileSize)};`,
|
|
165
|
-
" flex: 0 0 auto;",
|
|
166
|
-
` ${fillProp("size", `${px(cssSpriteWidth)} ${px(cssSpriteHeight)}`)}`,
|
|
167
|
-
` ${fillProp("origin", "content-box")}`,
|
|
168
|
-
"}",
|
|
169
|
-
`${cssIconSelector}[data-icon-id="none"] { visibility: hidden; }`,
|
|
170
|
-
];
|
|
171
|
-
// generate all sprite entries as an array
|
|
172
|
-
const entries = Array.from(selectorMap, ([iconPath, selectors], index) => {
|
|
173
|
-
const x = cssTileSize * (index % rowLength);
|
|
174
|
-
const y = cssTileSize * Math.floor(index / rowLength);
|
|
175
|
-
const prop = fillProp("position", `${px(-x)} ${px(-y)}`);
|
|
176
|
-
for (const selector of selectors) {
|
|
177
|
-
cssLines.push(`${selector} { ${prop} }`);
|
|
178
|
-
}
|
|
179
|
-
return { iconPath, x, y };
|
|
180
|
-
});
|
|
181
|
-
// create the resulting CSS markup as string
|
|
182
|
-
const cssMarkup = cssLines.join("\n") + "\n";
|
|
183
|
-
return { cssMarkup, cssSpriteWidth, cssSpriteHeight, entries };
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
// plugin =====================================================================
|
|
187
|
-
/**
|
|
188
|
-
* A plugin for Vite to generate PNG sprite files from multiple PNG source
|
|
189
|
-
* files.
|
|
190
|
-
*
|
|
191
|
-
* @param index
|
|
192
|
-
* URL of the index source file of this plugin.
|
|
193
|
-
*
|
|
194
|
-
* @param options
|
|
195
|
-
* Plugin configuration options.
|
|
196
|
-
*
|
|
197
|
-
* @returns
|
|
198
|
-
* The plugin instance.
|
|
199
|
-
*/
|
|
200
|
-
export function pngSpritePlugin(index, options) {
|
|
201
|
-
// resolved configuration options
|
|
202
|
-
const { cssName, sprites } = options;
|
|
203
|
-
// helper instance for file system access, logging, etc.
|
|
204
|
-
const helper = new PngSpritePluginHelper(index, options);
|
|
205
|
-
// create and return the plugin object
|
|
206
|
-
return {
|
|
207
|
-
name: "@open-xchange/vite-plugin-icon-sprite/png",
|
|
208
|
-
// initialize file system cache for generated modules
|
|
209
|
-
async configResolved(viteConfig) {
|
|
210
|
-
await helper.initializeCache(viteConfig);
|
|
211
|
-
},
|
|
212
|
-
// pick matching imports
|
|
213
|
-
resolveId(source) {
|
|
214
|
-
return helper.resolveVirtualModuleId(source);
|
|
215
|
-
},
|
|
216
|
-
// load the PNG icon files, generate final PNG sprites and CSS file
|
|
217
|
-
async load(moduleId) {
|
|
218
|
-
// only handle the target modules specified in "resolveId"
|
|
219
|
-
const target = helper.matchVirtualModuleId(moduleId);
|
|
220
|
-
if (!target) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
// generate the CSS markup
|
|
224
|
-
if (target === cssName) {
|
|
225
|
-
return await helper.generateCssMarkupModule();
|
|
226
|
-
}
|
|
227
|
-
// generate a PNG sprite (export binary data as plain Base64 encoded)
|
|
228
|
-
if (target in sprites) {
|
|
229
|
-
const { factor, src } = sprites[target];
|
|
230
|
-
return await helper.generateSpriteModule(target, factor, src);
|
|
231
|
-
}
|
|
232
|
-
// invalid module identifier
|
|
233
|
-
helper.fail("unknown output file %f", target);
|
|
234
|
-
return undefined;
|
|
235
|
-
},
|
|
236
|
-
};
|
|
237
|
-
}
|
package/dist/plugin-svg.d.ts
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "vite";
|
|
2
|
-
import { type SpritePluginBaseOptions } from "./helper.js";
|
|
3
|
-
/**
|
|
4
|
-
* Configuration options for generating an SVG sprite from SVG source images.
|
|
5
|
-
*/
|
|
6
|
-
export interface SvgSpritePluginOptions extends SpritePluginBaseOptions<"svg"> {
|
|
7
|
-
/**
|
|
8
|
-
* Module name of the SVG sprite to be generated (with ".svg" extension).
|
|
9
|
-
* The SVG markup of the sprite can be imported from the virtual module
|
|
10
|
-
* path `"virtual:svg/[spriteName]"`.
|
|
11
|
-
*/
|
|
12
|
-
spriteName: string;
|
|
13
|
-
/**
|
|
14
|
-
* A prefix to be added to all icon identifiers declared in the mapping
|
|
15
|
-
* file. By default, no prefix will be added.
|
|
16
|
-
*/
|
|
17
|
-
idPrefix?: string;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* A plugin for Vite to generate an SVG sprite file from multiple SVG source
|
|
21
|
-
* files.
|
|
22
|
-
*
|
|
23
|
-
* @param index
|
|
24
|
-
* URL of the index source file of this plugin.
|
|
25
|
-
*
|
|
26
|
-
* @param options
|
|
27
|
-
* Plugin configuration options.
|
|
28
|
-
*
|
|
29
|
-
* @returns
|
|
30
|
-
* The plugin instance.
|
|
31
|
-
*/
|
|
32
|
-
export declare function svgSpritePlugin(index: string, options: SvgSpritePluginOptions): Plugin;
|
package/dist/plugin-svg.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { basename } from "node:path";
|
|
2
|
-
import SVGSprite from "svg-sprite";
|
|
3
|
-
import { SpritePluginHelper } from "./helper.js";
|
|
4
|
-
// class SvgSpritePluginHelper ================================================
|
|
5
|
-
class SvgSpritePluginHelper extends SpritePluginHelper {
|
|
6
|
-
constructor(index, options) {
|
|
7
|
-
super({
|
|
8
|
-
pluginIndex: index,
|
|
9
|
-
virtualModules: options.spriteName,
|
|
10
|
-
}, {
|
|
11
|
-
idPrefix: "",
|
|
12
|
-
...options,
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
// public methods ---------------------------------------------------------
|
|
16
|
-
/**
|
|
17
|
-
* Generates the ES source module for an SVG sprite.
|
|
18
|
-
*
|
|
19
|
-
* @returns
|
|
20
|
-
* The source module containing the SVG markup of the sprite.
|
|
21
|
-
*/
|
|
22
|
-
async generateSpriteModule() {
|
|
23
|
-
// shortcuts to plugin options
|
|
24
|
-
const { imagesPath, idPrefix, spriteName } = this.options;
|
|
25
|
-
// try to resolve cached version of generated file
|
|
26
|
-
return await this.generateModule(spriteName, async () => {
|
|
27
|
-
this.info("compiling sprite %f", spriteName);
|
|
28
|
-
// create a reverse map from icon filenames to icon identifiers
|
|
29
|
-
const iconIdMap = new Map();
|
|
30
|
-
// create the core SVG spriter
|
|
31
|
-
const spriter = new SVGSprite({
|
|
32
|
-
shape: {
|
|
33
|
-
id: {
|
|
34
|
-
generator: name => iconIdMap.get(name) ?? "",
|
|
35
|
-
},
|
|
36
|
-
spacing: {
|
|
37
|
-
box: "icon",
|
|
38
|
-
},
|
|
39
|
-
dimension: {
|
|
40
|
-
maxWidth: 16,
|
|
41
|
-
maxHeight: 16,
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
svg: {
|
|
45
|
-
xmlDeclaration: false,
|
|
46
|
-
// - remove all <style> elements declaring a class with fill color
|
|
47
|
-
// - remove all class attribute referring to the class from <style>
|
|
48
|
-
// - add "fill" attribute to all <symbol> elements
|
|
49
|
-
transform: markup => markup
|
|
50
|
-
.replace(/<style>.*?<\/style>/g, "")
|
|
51
|
-
.replace(/class=".*?" ?/g, "")
|
|
52
|
-
.replace(/<symbol /g, '<symbol fill="currentColor" '),
|
|
53
|
-
},
|
|
54
|
-
mode: {
|
|
55
|
-
inline: true,
|
|
56
|
-
symbol: {
|
|
57
|
-
sprite: spriteName,
|
|
58
|
-
render: { less: false },
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
});
|
|
62
|
-
// load all source SVG images
|
|
63
|
-
for (const { iconId, iconPath, iconLang } of await this.readIconMapping()) {
|
|
64
|
-
const path = `${imagesPath}/${iconPath}.svg`;
|
|
65
|
-
// icon identifier with configured prefix and language suffix
|
|
66
|
-
const idSuffix = iconLang ? `;${iconLang}` : "";
|
|
67
|
-
iconIdMap.set(basename(path), idPrefix + iconId + idSuffix);
|
|
68
|
-
// read SVG source image, insert into spriter instance
|
|
69
|
-
const markup = await this.readText(path);
|
|
70
|
-
spriter.add(path, null, markup);
|
|
71
|
-
}
|
|
72
|
-
// compile the SVG sprite
|
|
73
|
-
const result = (await spriter.compileAsync()).result;
|
|
74
|
-
const spriteMarkup = result.symbol.sprite.contents.toString("utf8");
|
|
75
|
-
const moduleCode = `export default ${JSON.stringify(spriteMarkup)};`;
|
|
76
|
-
this.info("sprite %f generated successfully", spriteName);
|
|
77
|
-
return moduleCode;
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
// plugin =====================================================================
|
|
82
|
-
/**
|
|
83
|
-
* A plugin for Vite to generate an SVG sprite file from multiple SVG source
|
|
84
|
-
* files.
|
|
85
|
-
*
|
|
86
|
-
* @param index
|
|
87
|
-
* URL of the index source file of this plugin.
|
|
88
|
-
*
|
|
89
|
-
* @param options
|
|
90
|
-
* Plugin configuration options.
|
|
91
|
-
*
|
|
92
|
-
* @returns
|
|
93
|
-
* The plugin instance.
|
|
94
|
-
*/
|
|
95
|
-
export function svgSpritePlugin(index, options) {
|
|
96
|
-
// helper instance for file system access, logging, etc.
|
|
97
|
-
const helper = new SvgSpritePluginHelper(index, options);
|
|
98
|
-
// create and return the plugin object
|
|
99
|
-
return {
|
|
100
|
-
name: "@open-xchange/vite-plugin-icon-sprite/svg",
|
|
101
|
-
// initialize file system cache for generated modules
|
|
102
|
-
async configResolved(viteConfig) {
|
|
103
|
-
await helper.initializeCache(viteConfig);
|
|
104
|
-
},
|
|
105
|
-
// pick matching imports
|
|
106
|
-
resolveId(source) {
|
|
107
|
-
return helper.resolveVirtualModuleId(source);
|
|
108
|
-
},
|
|
109
|
-
// load the SVG icon files, generate final SVG sprite
|
|
110
|
-
async load(moduleId) {
|
|
111
|
-
// only handle the output file specified in "resolveId"
|
|
112
|
-
if (!helper.matchVirtualModuleId(moduleId)) {
|
|
113
|
-
return null;
|
|
114
|
-
}
|
|
115
|
-
// create an ES module that exports the SVG markup of the sprite
|
|
116
|
-
return await helper.generateSpriteModule();
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
}
|