react-icons-sprite 1.3.0 → 1.4.0-rc1
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/README.md +41 -28
- package/dist/build-sprite-DEOFEWm0.mjs +472 -0
- package/dist/{collector-dvzR3TG1.mjs → collector-1bZHiz4N.mjs} +1 -1
- package/dist/compute-icon-id-C42PyoDX.mjs +84 -0
- package/dist/icon.d.mts +3 -4
- package/dist/index.d.mts +2 -2
- package/dist/plugin-options-DYfIgasR.d.mts +17 -0
- package/dist/transform-module-Cabatwdp.mjs +471 -0
- package/dist/vite/plugin.d.mts +4 -5
- package/dist/vite/plugin.mjs +5 -4
- package/dist/webpack/loader.d.mts +4 -1
- package/dist/webpack/loader.mjs +6 -4
- package/dist/webpack/plugin.d.mts +4 -5
- package/dist/webpack/plugin.mjs +3 -3
- package/package.json +44 -31
- package/dist/build-sprite-Dci5SlWn.mjs +0 -217
- package/dist/compute-icon-id-1Gop_fRM.mjs +0 -113
- package/dist/plugin-options-ByGrVpdG.d.mts +0 -9
- package/dist/transform-module-BakS0Tzh.mjs +0 -854
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://www.schemastore.org/package.json",
|
|
3
3
|
"name": "react-icons-sprite",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.4.0-rc1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "A lightweight Vite, Rsbuild and Webpack plugin for popular icon libraries that builds a single SVG sprite and rewrites icons to <use>, reducing bundle size and runtime overhead.",
|
|
7
7
|
"author": "Jure Rotar <hello@jurerotar.com>",
|
|
@@ -22,6 +22,9 @@
|
|
|
22
22
|
"module": "dist/index.mjs",
|
|
23
23
|
"types": "dist/index.d.mts",
|
|
24
24
|
"sideEffects": false,
|
|
25
|
+
"engines": {
|
|
26
|
+
"node": ">=22.12.0"
|
|
27
|
+
},
|
|
25
28
|
"exports": {
|
|
26
29
|
".": {
|
|
27
30
|
"types": "./dist/index.d.mts",
|
|
@@ -63,43 +66,53 @@
|
|
|
63
66
|
"release": "npm publish --access public"
|
|
64
67
|
},
|
|
65
68
|
"peerDependencies": {
|
|
66
|
-
"@ant-design/icons": ">=
|
|
67
|
-
"@carbon/icons-react": ">=
|
|
68
|
-
"@fluentui/react-icons": ">=
|
|
69
|
-
"@fortawesome/free-solid-svg-icons": ">=
|
|
70
|
-
"@fortawesome/react-fontawesome": ">=
|
|
71
|
-
"@heroicons/react": ">=2",
|
|
72
|
-
"@hugeicons/core-free-icons": ">=
|
|
69
|
+
"@ant-design/icons": ">=4",
|
|
70
|
+
"@carbon/icons-react": ">=10.4",
|
|
71
|
+
"@fluentui/react-icons": ">=0.1.1",
|
|
72
|
+
"@fortawesome/free-solid-svg-icons": ">=5.1.0-0",
|
|
73
|
+
"@fortawesome/react-fontawesome": ">=0.1",
|
|
74
|
+
"@heroicons/react": ">=0.1 || >=2.0.0-0",
|
|
75
|
+
"@hugeicons/core-free-icons": ">=1",
|
|
73
76
|
"@hugeicons/react": ">=1",
|
|
74
|
-
"@mui/icons-material": ">=
|
|
75
|
-
"@phosphor-icons/react": ">=2",
|
|
76
|
-
"@primer/octicons-react": ">=
|
|
77
|
-
"@radix-ui/react-icons": ">=1",
|
|
78
|
-
"@remixicon/react": ">=
|
|
79
|
-
"@tabler/icons-react": ">=3",
|
|
80
|
-
"devicons-react": ">=1",
|
|
81
|
-
"grommet-icons": ">=
|
|
82
|
-
"lucide-react": ">=
|
|
83
|
-
"phosphor-react": ">=1",
|
|
84
|
-
"react-bootstrap-icons": ">=1",
|
|
85
|
-
"react-feather": ">=2",
|
|
86
|
-
"react-icons": ">=5",
|
|
77
|
+
"@mui/icons-material": ">=5.0.0-0",
|
|
78
|
+
"@phosphor-icons/react": ">=2.0.3 || >=2.1.8-rc.0",
|
|
79
|
+
"@primer/octicons-react": ">=10",
|
|
80
|
+
"@radix-ui/react-icons": ">=1 || >=2.0.0-0",
|
|
81
|
+
"@remixicon/react": ">=0.0.2",
|
|
82
|
+
"@tabler/icons-react": ">=2.0.0-0 || >=3.0.0-beta.2",
|
|
83
|
+
"devicons-react": ">=0.1 || >=1.2.3-canary-0.0.1",
|
|
84
|
+
"grommet-icons": ">=0.1",
|
|
85
|
+
"lucide-react": ">=0.0.0-0",
|
|
86
|
+
"phosphor-react": ">=0.1",
|
|
87
87
|
"react": ">= 16",
|
|
88
|
-
"react-
|
|
88
|
+
"react-bootstrap-icons": ">=1.0.0-0",
|
|
89
|
+
"react-dom": ">= 16",
|
|
90
|
+
"react-feather": ">=1.0.2 <1.0.9 || >=1.1.0",
|
|
91
|
+
"react-icons": ">=3"
|
|
89
92
|
},
|
|
90
93
|
"dependencies": {
|
|
91
|
-
"magic-string": "1.
|
|
94
|
+
"magic-string": "1.4.3",
|
|
95
|
+
"oxc-parser": "0.154.0",
|
|
96
|
+
"semver": "7.8.5"
|
|
92
97
|
},
|
|
93
98
|
"devDependencies": {
|
|
94
|
-
"@
|
|
95
|
-
"@
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
+
"@ant-design/icons": "6.3.4",
|
|
100
|
+
"@babel/parser": "8.0.7",
|
|
101
|
+
"@biomejs/biome": "2.5.15",
|
|
102
|
+
"@hugeicons/core-free-icons": "4.3.5",
|
|
103
|
+
"@pillage-first/graphics": "0.4.0-rc8",
|
|
104
|
+
"@types/node": "26.6.4",
|
|
105
|
+
"@types/react": "19.3.0",
|
|
106
|
+
"@types/react-dom": "19.3.0",
|
|
107
|
+
"@types/semver": "7.8.0",
|
|
108
|
+
"lucide-react": "1.53.0",
|
|
109
|
+
"react": "19.3.0",
|
|
110
|
+
"react-dom": "19.3.0",
|
|
111
|
+
"tsdown": "0.23.1",
|
|
99
112
|
"typescript": "7.0.2",
|
|
100
|
-
"vite": "8.
|
|
101
|
-
"vitest": "
|
|
102
|
-
"webpack": "5.
|
|
113
|
+
"vite": "8.3.4",
|
|
114
|
+
"vitest": "5.0.4",
|
|
115
|
+
"webpack": "5.111.1"
|
|
103
116
|
},
|
|
104
117
|
"keywords": [
|
|
105
118
|
"vite",
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { o as resolveIconImport, t as computeIconId } from "./compute-icon-id-1Gop_fRM.mjs";
|
|
2
|
-
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { pathToFileURL } from "node:url";
|
|
5
|
-
import { createElement } from "react";
|
|
6
|
-
import { renderToStaticMarkup } from "react-dom/server";
|
|
7
|
-
//#region src/sprite/render-icon.ts
|
|
8
|
-
const SVG_INNER_RE = /<svg\b[^>]*>([\s\S]*?)<\/svg>/i;
|
|
9
|
-
const VIEWBOX_RE = /viewBox=["']([^"']+)["']/i;
|
|
10
|
-
const SVG_OPEN_RE = /<svg\b([^>]*)>/i;
|
|
11
|
-
const SVG_ATTR_RE = /([:\w-]+)=("[^"]*"|'[^']*')/g;
|
|
12
|
-
const OMITTED_SVG_ATTRIBUTES = /* @__PURE__ */ new Set([
|
|
13
|
-
"xmlns",
|
|
14
|
-
"viewBox",
|
|
15
|
-
"width",
|
|
16
|
-
"height"
|
|
17
|
-
]);
|
|
18
|
-
const parsePackageSpecifier = (specifier) => {
|
|
19
|
-
if (specifier.startsWith(".") || path.isAbsolute(specifier)) return null;
|
|
20
|
-
const parts = specifier.split("/");
|
|
21
|
-
const packageName = specifier.startsWith("@") ? `${parts[0]}/${parts[1]}` : parts[0];
|
|
22
|
-
const rest = parts.slice(specifier.startsWith("@") ? 2 : 1).join("/");
|
|
23
|
-
return {
|
|
24
|
-
packageName,
|
|
25
|
-
subpath: rest ? `./${rest}` : "."
|
|
26
|
-
};
|
|
27
|
-
};
|
|
28
|
-
const findPackageRoot = (packageName, baseDir) => {
|
|
29
|
-
let current = path.resolve(baseDir);
|
|
30
|
-
while (true) {
|
|
31
|
-
const candidate = path.join(current, "node_modules", packageName);
|
|
32
|
-
if (existsSync(path.join(candidate, "package.json"))) return candidate;
|
|
33
|
-
const parent = path.dirname(current);
|
|
34
|
-
if (parent === current) return null;
|
|
35
|
-
current = parent;
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
const pickExportTarget = (value) => {
|
|
39
|
-
if (typeof value === "string") return value;
|
|
40
|
-
if (!value || typeof value !== "object") return null;
|
|
41
|
-
const record = value;
|
|
42
|
-
return pickExportTarget(record.import) ?? pickExportTarget(record.default) ?? pickExportTarget(record.module) ?? pickExportTarget(record.require);
|
|
43
|
-
};
|
|
44
|
-
const resolveExportTarget = (exportsField, subpath) => {
|
|
45
|
-
if (typeof exportsField === "string" || Array.isArray(exportsField)) return subpath === "." ? pickExportTarget(exportsField) : null;
|
|
46
|
-
if (!exportsField || typeof exportsField !== "object") return null;
|
|
47
|
-
const exportsRecord = exportsField;
|
|
48
|
-
const exact = pickExportTarget(exportsRecord[subpath]);
|
|
49
|
-
if (exact) return exact;
|
|
50
|
-
for (const [key, value] of Object.entries(exportsRecord)) {
|
|
51
|
-
if (!key.includes("*")) continue;
|
|
52
|
-
const [prefix, suffix] = key.split("*");
|
|
53
|
-
if (!subpath.startsWith(prefix) || !subpath.endsWith(suffix)) continue;
|
|
54
|
-
const matched = subpath.slice(prefix.length, subpath.length - suffix.length);
|
|
55
|
-
const target = pickExportTarget(value);
|
|
56
|
-
if (target) return target.replaceAll("*", matched);
|
|
57
|
-
}
|
|
58
|
-
return null;
|
|
59
|
-
};
|
|
60
|
-
const fileExists = (filePath) => {
|
|
61
|
-
try {
|
|
62
|
-
return statSync(filePath).isFile();
|
|
63
|
-
} catch {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
};
|
|
67
|
-
const resolveFileCandidate = (filePath) => {
|
|
68
|
-
return [
|
|
69
|
-
filePath,
|
|
70
|
-
`${filePath}.mjs`,
|
|
71
|
-
`${filePath}.js`,
|
|
72
|
-
`${filePath}.cjs`,
|
|
73
|
-
`${filePath}.jsx`,
|
|
74
|
-
`${filePath}.ts`,
|
|
75
|
-
`${filePath}.tsx`,
|
|
76
|
-
path.join(filePath, "index.mjs"),
|
|
77
|
-
path.join(filePath, "index.js"),
|
|
78
|
-
path.join(filePath, "index.cjs"),
|
|
79
|
-
path.join(filePath, "index.jsx"),
|
|
80
|
-
path.join(filePath, "index.ts"),
|
|
81
|
-
path.join(filePath, "index.tsx")
|
|
82
|
-
].find(fileExists) ?? null;
|
|
83
|
-
};
|
|
84
|
-
const resolveFromBaseDir = (specifier, baseDir) => {
|
|
85
|
-
const parsed = parsePackageSpecifier(specifier);
|
|
86
|
-
if (!parsed) return null;
|
|
87
|
-
const packageRoot = findPackageRoot(parsed.packageName, baseDir);
|
|
88
|
-
if (!packageRoot) return null;
|
|
89
|
-
const packageJson = JSON.parse(readFileSync(path.join(packageRoot, "package.json"), "utf8"));
|
|
90
|
-
const exportTarget = resolveExportTarget(packageJson.exports, parsed.subpath);
|
|
91
|
-
if (exportTarget) {
|
|
92
|
-
const resolved = resolveFileCandidate(path.join(packageRoot, exportTarget));
|
|
93
|
-
if (resolved) return resolved;
|
|
94
|
-
}
|
|
95
|
-
if (parsed.subpath === ".") {
|
|
96
|
-
const entry = packageJson.module ?? packageJson.main;
|
|
97
|
-
if (entry) return resolveFileCandidate(path.join(packageRoot, entry));
|
|
98
|
-
}
|
|
99
|
-
return resolveFileCandidate(path.join(packageRoot, parsed.subpath));
|
|
100
|
-
};
|
|
101
|
-
const resolveImportSpecifier = (specifier, options) => {
|
|
102
|
-
if (path.isAbsolute(specifier)) {
|
|
103
|
-
const resolved = resolveFileCandidate(specifier);
|
|
104
|
-
return pathToFileURL(resolved ?? specifier).href;
|
|
105
|
-
}
|
|
106
|
-
if (specifier.startsWith(".") && options.importer) {
|
|
107
|
-
const importerPath = options.importer.split("?", 1)[0];
|
|
108
|
-
const resolved = resolveFileCandidate(path.resolve(path.dirname(importerPath), specifier));
|
|
109
|
-
if (resolved) return pathToFileURL(resolved).href;
|
|
110
|
-
}
|
|
111
|
-
if (!options.baseDir) return specifier;
|
|
112
|
-
const resolved = resolveFromBaseDir(specifier, options.baseDir);
|
|
113
|
-
return resolved ? pathToFileURL(resolved).href : specifier;
|
|
114
|
-
};
|
|
115
|
-
const extractSymbolAttributes = (svgMarkup) => {
|
|
116
|
-
const openingAttributes = SVG_OPEN_RE.exec(svgMarkup)?.[1];
|
|
117
|
-
if (!openingAttributes) return "";
|
|
118
|
-
const attributes = [];
|
|
119
|
-
for (const [, name, value] of openingAttributes.matchAll(SVG_ATTR_RE)) {
|
|
120
|
-
if (OMITTED_SVG_ATTRIBUTES.has(name)) continue;
|
|
121
|
-
attributes.push(`${name}=${value}`);
|
|
122
|
-
}
|
|
123
|
-
return attributes.join(" ");
|
|
124
|
-
};
|
|
125
|
-
const pickExport = (moduleExports, exportName) => {
|
|
126
|
-
if (exportName === "default") return moduleExports.default;
|
|
127
|
-
return moduleExports[exportName] ?? moduleExports.default;
|
|
128
|
-
};
|
|
129
|
-
const unwrapNestedDefaultExport = (value) => {
|
|
130
|
-
if (!value || typeof value !== "object" || !("default" in value)) return value;
|
|
131
|
-
if ("$$typeof" in value) return value;
|
|
132
|
-
return value.default;
|
|
133
|
-
};
|
|
134
|
-
const isRenderableComponent = (value) => {
|
|
135
|
-
if (typeof value === "function") return true;
|
|
136
|
-
if (!value || typeof value !== "object") return false;
|
|
137
|
-
return "$$typeof" in value;
|
|
138
|
-
};
|
|
139
|
-
const isFontAwesomeIconDefinition = (value) => {
|
|
140
|
-
if (!value || typeof value !== "object") return false;
|
|
141
|
-
const icon = value.icon;
|
|
142
|
-
if (!Array.isArray(icon) || icon.length < 5) return false;
|
|
143
|
-
return typeof icon[0] === "number" && typeof icon[1] === "number";
|
|
144
|
-
};
|
|
145
|
-
const isHugeiconsIconDefinition = (value) => {
|
|
146
|
-
if (!Array.isArray(value)) return false;
|
|
147
|
-
return value.every((item) => {
|
|
148
|
-
if (!Array.isArray(item) || item.length < 2) return false;
|
|
149
|
-
return typeof item[0] === "string" && typeof item[1] === "object";
|
|
150
|
-
});
|
|
151
|
-
};
|
|
152
|
-
const renderFontAwesomeIconDefinition = (iconDefinition) => {
|
|
153
|
-
const [width, height, , , svgPathData] = iconDefinition.icon;
|
|
154
|
-
return {
|
|
155
|
-
symbolBody: (Array.isArray(svgPathData) ? svgPathData : [svgPathData]).map((d) => `<path d="${d}"/>`).join(""),
|
|
156
|
-
viewBox: `0 0 ${width} ${height}`,
|
|
157
|
-
symbolAttributes: ""
|
|
158
|
-
};
|
|
159
|
-
};
|
|
160
|
-
const renderHugeiconsIconDefinition = (iconDefinition) => {
|
|
161
|
-
const children = [...iconDefinition].sort(([, a], [, b]) => {
|
|
162
|
-
const hasOpacityA = a.opacity !== void 0;
|
|
163
|
-
return b.opacity !== void 0 ? 1 : hasOpacityA ? -1 : 0;
|
|
164
|
-
}).map(([tag, attributes]) => {
|
|
165
|
-
const { key, ...rest } = attributes;
|
|
166
|
-
return createElement(tag, {
|
|
167
|
-
...rest,
|
|
168
|
-
key
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
const svgMarkup = renderToStaticMarkup(createElement("svg", {
|
|
172
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
173
|
-
viewBox: "0 0 24 24",
|
|
174
|
-
fill: "none",
|
|
175
|
-
color: "currentColor"
|
|
176
|
-
}, children));
|
|
177
|
-
const svgInner = SVG_INNER_RE.exec(svgMarkup)?.[1];
|
|
178
|
-
if (!svgInner) throw new Error("[react-icons-sprite] Unable to extract SVG content for Hugeicons icon.");
|
|
179
|
-
return {
|
|
180
|
-
symbolBody: svgInner,
|
|
181
|
-
viewBox: "0 0 24 24",
|
|
182
|
-
symbolAttributes: extractSymbolAttributes(svgMarkup)
|
|
183
|
-
};
|
|
184
|
-
};
|
|
185
|
-
const renderIcon = async (pack, exportName, options = {}) => {
|
|
186
|
-
const importPath = options.importPath ?? resolveIconImport(pack, exportName);
|
|
187
|
-
const imported = await import(resolveImportSpecifier(importPath, options));
|
|
188
|
-
const iconComponent = unwrapNestedDefaultExport(pickExport(imported, exportName));
|
|
189
|
-
if (isFontAwesomeIconDefinition(iconComponent)) return renderFontAwesomeIconDefinition(iconComponent);
|
|
190
|
-
if (isHugeiconsIconDefinition(iconComponent)) return renderHugeiconsIconDefinition(iconComponent);
|
|
191
|
-
if (!isRenderableComponent(iconComponent)) throw new Error(`[react-icons-sprite] Unable to render icon "${exportName}" from "${pack}". Expected a React component export.`);
|
|
192
|
-
const svgMarkup = renderToStaticMarkup(createElement(iconComponent));
|
|
193
|
-
const svgInner = SVG_INNER_RE.exec(svgMarkup)?.[1];
|
|
194
|
-
if (!svgInner) throw new Error(`[react-icons-sprite] Unable to extract SVG content for "${exportName}" from "${pack}".`);
|
|
195
|
-
return {
|
|
196
|
-
symbolBody: svgInner,
|
|
197
|
-
viewBox: VIEWBOX_RE.exec(svgMarkup)?.[1] ?? "0 0 24 24",
|
|
198
|
-
symbolAttributes: extractSymbolAttributes(svgMarkup)
|
|
199
|
-
};
|
|
200
|
-
};
|
|
201
|
-
//#endregion
|
|
202
|
-
//#region src/sprite/build-sprite.ts
|
|
203
|
-
const buildSprite = async (icons, options = {}) => {
|
|
204
|
-
if (!icons.length) return "<svg xmlns=\"http://www.w3.org/2000/svg\" style=\"display:none\"></svg>";
|
|
205
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" style="display:none">${(await Promise.all(icons.map(async ({ pack, exportName, importer, importPath }) => {
|
|
206
|
-
const rendered = await renderIcon(pack, exportName, {
|
|
207
|
-
baseDir: options.baseDir,
|
|
208
|
-
importer,
|
|
209
|
-
importPath
|
|
210
|
-
});
|
|
211
|
-
const id = computeIconId(pack, exportName);
|
|
212
|
-
const symbolAttributes = rendered.symbolAttributes ? ` ${rendered.symbolAttributes}` : "";
|
|
213
|
-
return `<symbol id="${id}" viewBox="${rendered.viewBox}"${symbolAttributes}>${rendered.symbolBody}</symbol>`;
|
|
214
|
-
}))).join("")}</svg>`;
|
|
215
|
-
};
|
|
216
|
-
//#endregion
|
|
217
|
-
export { buildSprite as t };
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
//#region src/collector/create-collector.ts
|
|
2
|
-
const createCollectedIconKey = (icon) => {
|
|
3
|
-
const resolutionKey = icon.importPath ?? (icon.pack.startsWith(".") ? icon.importer : void 0);
|
|
4
|
-
return JSON.stringify([
|
|
5
|
-
icon.pack,
|
|
6
|
-
icon.exportName,
|
|
7
|
-
resolutionKey
|
|
8
|
-
]);
|
|
9
|
-
};
|
|
10
|
-
const createCollector = () => {
|
|
11
|
-
const collected = /* @__PURE__ */ new Map();
|
|
12
|
-
return {
|
|
13
|
-
add(pack, exportName, options = {}) {
|
|
14
|
-
const item = {
|
|
15
|
-
pack,
|
|
16
|
-
exportName,
|
|
17
|
-
...options
|
|
18
|
-
};
|
|
19
|
-
collected.set(createCollectedIconKey(item), item);
|
|
20
|
-
},
|
|
21
|
-
toList() {
|
|
22
|
-
return [...collected.values()];
|
|
23
|
-
},
|
|
24
|
-
clear() {
|
|
25
|
-
collected.clear();
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
};
|
|
29
|
-
//#endregion
|
|
30
|
-
//#region src/utils/kebab-case.ts
|
|
31
|
-
const kebabCase = (value) => {
|
|
32
|
-
return value.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-z0-9]+/gi, "-").replace(/-{2,}/g, "-").replace(/^-|-$/g, "").toLowerCase();
|
|
33
|
-
};
|
|
34
|
-
//#endregion
|
|
35
|
-
//#region src/packs/icon-resolvers.ts
|
|
36
|
-
const DEFAULT_ICON_SOURCES = [
|
|
37
|
-
/^react-icons\/[\w-]+$/,
|
|
38
|
-
/^@fortawesome\/[\w-]+-svg-icons$/,
|
|
39
|
-
/^lucide-react$/,
|
|
40
|
-
/^@heroicons\/react(?:\/.*)?$/,
|
|
41
|
-
/^@tabler\/icons-react$/,
|
|
42
|
-
/^@radix-ui\/react-icons$/,
|
|
43
|
-
/^phosphor-react$/,
|
|
44
|
-
/^@phosphor-icons\/react$/,
|
|
45
|
-
/^react-feather$/,
|
|
46
|
-
/^react-bootstrap-icons$/,
|
|
47
|
-
/^grommet-icons$/,
|
|
48
|
-
/^@remixicon\/react$/,
|
|
49
|
-
/^devicons-react$/,
|
|
50
|
-
/^@mui\/icons-material(?:\/.*)?$/,
|
|
51
|
-
/^@carbon\/icons-react$/,
|
|
52
|
-
/^@ant-design\/icons(?:\/.*)?$/,
|
|
53
|
-
/^@fluentui\/react-icons(?:\/svg\/[\w-]+)?$/,
|
|
54
|
-
/^@primer\/octicons-react$/,
|
|
55
|
-
/^@hugeicons\/core-free-icons(?:\/.*)?$/,
|
|
56
|
-
/^@pillage-first\/graphics$/
|
|
57
|
-
];
|
|
58
|
-
const phosphorIconPathName = (name) => name.endsWith("Icon") ? name.slice(0, -4) : name;
|
|
59
|
-
const fluentIconPathName = (name) => {
|
|
60
|
-
const unsizedName = name.replace(/(?:12|16|20|24|28|32|48)?(?:Regular|Filled|Light|Resizable|Color)$/, "");
|
|
61
|
-
return kebabCase(unsizedName);
|
|
62
|
-
};
|
|
63
|
-
const exactResolvers = {
|
|
64
|
-
"lucide-react": (pack, name) => `${pack}/dist/esm/icons/${kebabCase(name)}.mjs`,
|
|
65
|
-
"@radix-ui/react-icons": (pack) => `${pack}/dist/react-icons.esm.js`,
|
|
66
|
-
"@tabler/icons-react": (pack, name) => `${pack}/dist/esm/icons/${name}.mjs`,
|
|
67
|
-
"@phosphor-icons/react": (pack, name) => `${pack}/dist/ssr/${phosphorIconPathName(name)}`,
|
|
68
|
-
"phosphor-react": (pack, name) => `${pack}/dist/icons/${name}.esm.js`,
|
|
69
|
-
"react-bootstrap-icons": (pack, name) => `${pack}/dist/icons/${kebabCase(name)}.js`,
|
|
70
|
-
"react-feather": (pack, name) => `${pack}/dist/icons/${kebabCase(name)}.js`,
|
|
71
|
-
"grommet-icons": (pack, name) => `${pack}/icons/${name}.js`,
|
|
72
|
-
"devicons-react": (pack, name) => `${pack}/icons/${name}`,
|
|
73
|
-
"@carbon/icons-react": (pack, name) => `${pack}/es/${name}.js`,
|
|
74
|
-
"@ant-design/icons": (pack, name) => `${pack}/lib/icons/${name}.js`,
|
|
75
|
-
"@fluentui/react-icons": (pack, name) => `${pack}/lib/atoms/svg/${fluentIconPathName(name)}`,
|
|
76
|
-
"@primer/octicons-react": (pack) => pack,
|
|
77
|
-
"@hugeicons/core-free-icons": (pack, name) => `${pack}/${name}`
|
|
78
|
-
};
|
|
79
|
-
const resolveIconImport = (pack, exportName) => {
|
|
80
|
-
const exactResolver = exactResolvers[pack];
|
|
81
|
-
if (exactResolver) return exactResolver(pack, exportName);
|
|
82
|
-
if (/^@mui\/icons-material(?:\/.*)?$/.test(pack)) return pack.split("/").length > 2 ? pack : `${pack}/${exportName}`;
|
|
83
|
-
if (/^@ant-design\/icons\/.+$/.test(pack)) return `@ant-design/icons/lib/icons/${exportName === "default" ? pack.split("/").at(-1) : exportName}.js`;
|
|
84
|
-
const fluentSubpath = /^@fluentui\/react-icons\/svg\/(.+)$/.exec(pack);
|
|
85
|
-
if (fluentSubpath) return `@fluentui/react-icons/lib/atoms/svg/${fluentSubpath[1]}`;
|
|
86
|
-
if (/^@hugeicons\/core-free-icons\/.+$/.test(pack)) return pack;
|
|
87
|
-
if (/^@heroicons\/react\/(?:\d{2})\/(?:outline|solid)$/.test(pack)) return `${pack}/${exportName}`;
|
|
88
|
-
if (/^@fortawesome\/[\w-]+-svg-icons$/.test(pack)) return `${pack}/${exportName}`;
|
|
89
|
-
return pack;
|
|
90
|
-
};
|
|
91
|
-
//#endregion
|
|
92
|
-
//#region src/plugin-options.ts
|
|
93
|
-
const normalizeOutputPathSegment = (value) => {
|
|
94
|
-
return value.replace(/\\/g, "/").replace(/^\/+/, "").replace(/\/+$/, "");
|
|
95
|
-
};
|
|
96
|
-
const createIconSources = () => {
|
|
97
|
-
return DEFAULT_ICON_SOURCES;
|
|
98
|
-
};
|
|
99
|
-
const createSpriteAssetName = (fileName, outputDir) => {
|
|
100
|
-
const normalizedOutputDir = outputDir ? normalizeOutputPathSegment(outputDir) : "";
|
|
101
|
-
const normalizedFileName = normalizeOutputPathSegment(fileName);
|
|
102
|
-
return normalizedOutputDir ? `${normalizedOutputDir}/${normalizedFileName}` : normalizedFileName;
|
|
103
|
-
};
|
|
104
|
-
//#endregion
|
|
105
|
-
//#region src/utils/compute-icon-id.ts
|
|
106
|
-
const normalizePackAlias = (pack) => {
|
|
107
|
-
return kebabCase(pack.replace(/^@/, ""));
|
|
108
|
-
};
|
|
109
|
-
const computeIconId = (pack, iconName) => {
|
|
110
|
-
return `ri-${normalizePackAlias(pack)}-${iconName}`;
|
|
111
|
-
};
|
|
112
|
-
//#endregion
|
|
113
|
-
export { DEFAULT_ICON_SOURCES as a, createSpriteAssetName as i, normalizePackAlias as n, resolveIconImport as o, createIconSources as r, createCollector as s, computeIconId as t };
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
//#region src/plugin-options.d.ts
|
|
2
|
-
type ReactIconsSpritePluginOptions = {
|
|
3
|
-
/**
|
|
4
|
-
* Optional directory inside the bundler output where the sprite asset should be emitted.
|
|
5
|
-
*/
|
|
6
|
-
outputDir?: string;
|
|
7
|
-
};
|
|
8
|
-
//#endregion
|
|
9
|
-
export { ReactIconsSpritePluginOptions as t };
|