@tinloof/typed-svg-sprite 0.0.1 → 0.1.1
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 +25 -13
- package/README.md +230 -190
- package/dist/astro.d.ts +63 -0
- package/dist/astro.js +47 -0
- package/dist/cli.js +15 -15
- package/dist/components.d.ts +5 -1
- package/dist/components.js +114 -40
- package/dist/core.js +3 -3
- package/dist/next.d.ts +2 -2
- package/dist/next.js +14 -123
- package/dist/shared.d.ts +6 -0
- package/dist/shared.js +129 -0
- package/dist/types.js +33 -33
- package/package.json +72 -64
package/dist/components.js
CHANGED
|
@@ -33,13 +33,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
36
|
+
exports.generateReactIconComponent = generateReactIconComponent;
|
|
37
|
+
exports.generateAstroIconComponent = generateAstroIconComponent;
|
|
37
38
|
const fs = __importStar(require("fs"));
|
|
38
39
|
const path = __importStar(require("path"));
|
|
39
40
|
/**
|
|
40
41
|
* Generate React Icon component file
|
|
41
42
|
*/
|
|
42
|
-
function
|
|
43
|
+
function generateReactIconComponent(options) {
|
|
43
44
|
const { outputFile, typesFileRelativePath, verbose = true } = options;
|
|
44
45
|
try {
|
|
45
46
|
const projectRoot = process.cwd();
|
|
@@ -48,54 +49,127 @@ function generateIconComponent(options) {
|
|
|
48
49
|
const normalizedImportPath = typesFileRelativePath
|
|
49
50
|
.replace(/\\/g, "/")
|
|
50
51
|
.replace(/\.tsx?$/, "");
|
|
51
|
-
const content = `// Auto-generated by typed-svg-sprite
|
|
52
|
-
// Do not edit this file manually
|
|
53
|
-
|
|
54
|
-
import { IconHref } from "${normalizedImportPath}";
|
|
55
|
-
|
|
56
|
-
export interface IconProps extends React.
|
|
57
|
-
/** The icon href (import from generated/icons.ts) */
|
|
58
|
-
href: IconHref;
|
|
59
|
-
/** Size shorthand for width and height */
|
|
60
|
-
size?: number | string;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export function Icon({
|
|
64
|
-
href,
|
|
65
|
-
size = 24,
|
|
66
|
-
width,
|
|
67
|
-
height,
|
|
68
|
-
className = "",
|
|
69
|
-
viewBox = "0 0 24 24",
|
|
70
|
-
fill = "currentColor",
|
|
71
|
-
...props
|
|
72
|
-
}: IconProps) {
|
|
73
|
-
return (
|
|
74
|
-
<svg
|
|
75
|
-
className={className}
|
|
76
|
-
width={width || size}
|
|
77
|
-
height={height || size}
|
|
78
|
-
viewBox={viewBox}
|
|
79
|
-
fill={fill}
|
|
80
|
-
aria-hidden="true"
|
|
81
|
-
{...props}
|
|
82
|
-
>
|
|
83
|
-
<use href={href} />
|
|
84
|
-
</svg>
|
|
85
|
-
);
|
|
86
|
-
}
|
|
52
|
+
const content = `// Auto-generated by typed-svg-sprite
|
|
53
|
+
// Do not edit this file manually
|
|
54
|
+
|
|
55
|
+
import type { IconHref } from "${normalizedImportPath}";
|
|
56
|
+
|
|
57
|
+
export interface IconProps extends React.ComponentPropsWithRef<"svg"> {
|
|
58
|
+
/** The icon href (import from generated/icons.ts) */
|
|
59
|
+
href: IconHref;
|
|
60
|
+
/** Size shorthand for width and height */
|
|
61
|
+
size?: number | string;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function Icon({
|
|
65
|
+
href,
|
|
66
|
+
size = 24,
|
|
67
|
+
width,
|
|
68
|
+
height,
|
|
69
|
+
className = "",
|
|
70
|
+
viewBox = "0 0 24 24",
|
|
71
|
+
fill = "currentColor",
|
|
72
|
+
...props
|
|
73
|
+
}: IconProps) {
|
|
74
|
+
return (
|
|
75
|
+
<svg
|
|
76
|
+
className={className}
|
|
77
|
+
width={width || size}
|
|
78
|
+
height={height || size}
|
|
79
|
+
viewBox={viewBox}
|
|
80
|
+
fill={fill}
|
|
81
|
+
aria-hidden="true"
|
|
82
|
+
{...props}
|
|
83
|
+
>
|
|
84
|
+
<use href={href} />
|
|
85
|
+
</svg>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
`;
|
|
89
|
+
// Write component file
|
|
90
|
+
const outputDir = path.dirname(absoluteOutputFile);
|
|
91
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
92
|
+
fs.writeFileSync(absoluteOutputFile, content, "utf8");
|
|
93
|
+
if (verbose) {
|
|
94
|
+
console.log(`[svg-sprite] ✅ Generated React Icon component → ${outputFile}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
if (verbose) {
|
|
99
|
+
console.error("[svg-sprite] Error generating React Icon component:", error);
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Generate Astro Icon component file
|
|
106
|
+
*/
|
|
107
|
+
function generateAstroIconComponent(options) {
|
|
108
|
+
const { outputFile, typesFileRelativePath, verbose = true } = options;
|
|
109
|
+
try {
|
|
110
|
+
const projectRoot = process.cwd();
|
|
111
|
+
const absoluteOutputFile = path.resolve(projectRoot, outputFile);
|
|
112
|
+
// Normalize the import path (ensure it uses / separator)
|
|
113
|
+
const normalizedImportPath = typesFileRelativePath
|
|
114
|
+
.replace(/\\/g, "/")
|
|
115
|
+
.replace(/\.tsx?$/, "");
|
|
116
|
+
const content = `---
|
|
117
|
+
// Auto-generated by typed-svg-sprite
|
|
118
|
+
// Do not edit this file manually
|
|
119
|
+
|
|
120
|
+
import type { IconHref } from "${normalizedImportPath}";
|
|
121
|
+
|
|
122
|
+
export interface Props {
|
|
123
|
+
/** The icon href (import from generated/icons.ts) */
|
|
124
|
+
href: IconHref;
|
|
125
|
+
/** Size shorthand for width and height */
|
|
126
|
+
size?: number | string;
|
|
127
|
+
/** CSS class */
|
|
128
|
+
class?: string;
|
|
129
|
+
/** viewBox attribute */
|
|
130
|
+
viewBox?: string;
|
|
131
|
+
/** fill attribute */
|
|
132
|
+
fill?: string;
|
|
133
|
+
/** Additional HTML attributes */
|
|
134
|
+
[key: string]: any;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const {
|
|
138
|
+
href,
|
|
139
|
+
size = 24,
|
|
140
|
+
class: className = "",
|
|
141
|
+
viewBox = "0 0 24 24",
|
|
142
|
+
fill = "currentColor",
|
|
143
|
+
...props
|
|
144
|
+
} = Astro.props;
|
|
145
|
+
|
|
146
|
+
const width = props.width || size;
|
|
147
|
+
const height = props.height || size;
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
<svg
|
|
151
|
+
class={className}
|
|
152
|
+
width={width}
|
|
153
|
+
height={height}
|
|
154
|
+
viewBox={viewBox}
|
|
155
|
+
fill={fill}
|
|
156
|
+
aria-hidden="true"
|
|
157
|
+
{...props}
|
|
158
|
+
>
|
|
159
|
+
<use href={href} />
|
|
160
|
+
</svg>
|
|
87
161
|
`;
|
|
88
162
|
// Write component file
|
|
89
163
|
const outputDir = path.dirname(absoluteOutputFile);
|
|
90
164
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
91
165
|
fs.writeFileSync(absoluteOutputFile, content, "utf8");
|
|
92
166
|
if (verbose) {
|
|
93
|
-
console.log(`[svg-sprite] ✅ Generated Icon component → ${outputFile}`);
|
|
167
|
+
console.log(`[svg-sprite] ✅ Generated Astro Icon component → ${outputFile}`);
|
|
94
168
|
}
|
|
95
169
|
}
|
|
96
170
|
catch (error) {
|
|
97
171
|
if (verbose) {
|
|
98
|
-
console.error("[svg-sprite] Error generating Icon component:", error);
|
|
172
|
+
console.error("[svg-sprite] Error generating Astro Icon component:", error);
|
|
99
173
|
}
|
|
100
174
|
throw error;
|
|
101
175
|
}
|
package/dist/core.js
CHANGED
|
@@ -143,7 +143,7 @@ function generateSpriteSvg(symbols, minify = true) {
|
|
|
143
143
|
if (symbols.length === 0) {
|
|
144
144
|
return minify
|
|
145
145
|
? '<svg xmlns="http://www.w3.org/2000/svg" style="display:none"></svg>'
|
|
146
|
-
: `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
|
|
146
|
+
: `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
|
|
147
147
|
</svg>`;
|
|
148
148
|
}
|
|
149
149
|
const symbolElements = symbols
|
|
@@ -158,8 +158,8 @@ function generateSpriteSvg(symbols, minify = true) {
|
|
|
158
158
|
if (minify) {
|
|
159
159
|
return `<svg xmlns="http://www.w3.org/2000/svg" style="display:none">${symbolElements}</svg>`;
|
|
160
160
|
}
|
|
161
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
|
|
162
|
-
${symbolElements}
|
|
161
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" class="svg-sprite" style="display: none;">
|
|
162
|
+
${symbolElements}
|
|
163
163
|
</svg>`;
|
|
164
164
|
}
|
|
165
165
|
/**
|
package/dist/next.d.ts
CHANGED
|
@@ -36,9 +36,9 @@ interface SpriteLoaderOptions {
|
|
|
36
36
|
*/
|
|
37
37
|
generateIconComponent?: boolean;
|
|
38
38
|
/**
|
|
39
|
-
* Output path for the Icon component file.
|
|
39
|
+
* Output path for the Icon component file (without extension).
|
|
40
40
|
* Relative to project root.
|
|
41
|
-
* @default "generated/Icon
|
|
41
|
+
* @default "generated/Icon"
|
|
42
42
|
*/
|
|
43
43
|
iconComponentOutputFile?: string;
|
|
44
44
|
}
|
package/dist/next.js
CHANGED
|
@@ -1,119 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
3
|
exports.withSpriteLoader = withSpriteLoader;
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
const types_js_1 = require("./types.js");
|
|
41
|
-
const components_js_1 = require("./components.js");
|
|
42
|
-
// Track if we've already started watching
|
|
43
|
-
let watcherInitialized = false;
|
|
44
|
-
function generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
|
|
45
|
-
// Generate sprite and get symbols
|
|
46
|
-
const symbols = (0, core_js_1.generateSprite)({
|
|
47
|
-
inputDir,
|
|
48
|
-
outputFile,
|
|
49
|
-
verbose: true,
|
|
50
|
-
minify: true,
|
|
51
|
-
optimize: true,
|
|
52
|
-
});
|
|
53
|
-
// Generate TypeScript types file if specified
|
|
54
|
-
if (typesOutputFile && symbols.length > 0) {
|
|
55
|
-
(0, types_js_1.generateTypesFile)({
|
|
56
|
-
symbols,
|
|
57
|
-
spriteUrl,
|
|
58
|
-
spriteFilename,
|
|
59
|
-
outputFile: typesOutputFile,
|
|
60
|
-
verbose: false,
|
|
61
|
-
});
|
|
62
|
-
// Generate Icon component if enabled
|
|
63
|
-
if (generateIcon && iconComponentOutputFile) {
|
|
64
|
-
// Calculate relative path from component to types file
|
|
65
|
-
const componentDir = path.dirname(path.resolve(process.cwd(), iconComponentOutputFile));
|
|
66
|
-
const typesFile = path.resolve(process.cwd(), typesOutputFile);
|
|
67
|
-
const typesDir = path.dirname(typesFile);
|
|
68
|
-
const typesFilename = path.basename(typesFile, path.extname(typesFile));
|
|
69
|
-
// Get relative path from component dir to types dir
|
|
70
|
-
const relativePath = path
|
|
71
|
-
.relative(componentDir, typesDir)
|
|
72
|
-
.replace(/\\/g, "/");
|
|
73
|
-
// Construct the import path
|
|
74
|
-
// If same directory, use ./filename
|
|
75
|
-
// If parent/child relationship, ensure proper path format
|
|
76
|
-
let importPath;
|
|
77
|
-
if (relativePath === "") {
|
|
78
|
-
importPath = `./${typesFilename}`;
|
|
79
|
-
}
|
|
80
|
-
else if (relativePath.startsWith("..")) {
|
|
81
|
-
// Parent directory - ensure proper path
|
|
82
|
-
importPath = `${relativePath}/${typesFilename}`.replace(/\/+/g, "/");
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
// Child directory - ensure it starts with ./
|
|
86
|
-
const normalizedPath = relativePath.startsWith("./")
|
|
87
|
-
? relativePath
|
|
88
|
-
: `./${relativePath}`;
|
|
89
|
-
importPath = `${normalizedPath}/${typesFilename}`.replace(/\/+/g, "/");
|
|
90
|
-
}
|
|
91
|
-
(0, components_js_1.generateIconComponent)({
|
|
92
|
-
outputFile: iconComponentOutputFile,
|
|
93
|
-
typesFileRelativePath: importPath,
|
|
94
|
-
verbose: false,
|
|
95
|
-
});
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
function startWatcher(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
|
|
100
|
-
if (watcherInitialized) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const projectRoot = process.cwd();
|
|
104
|
-
const absoluteInputDir = path.resolve(projectRoot, inputDir);
|
|
105
|
-
if (!fs.existsSync(absoluteInputDir)) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
watcherInitialized = true;
|
|
109
|
-
console.log(`[svg-sprite] 👀 Watching ${inputDir} for changes...`);
|
|
110
|
-
fs.watch(absoluteInputDir, { recursive: true }, (eventType, filename) => {
|
|
111
|
-
if (filename?.endsWith(".svg")) {
|
|
112
|
-
console.log(`[svg-sprite] Change detected: ${filename}`);
|
|
113
|
-
generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
}
|
|
4
|
+
const shared_js_1 = require("./shared.js");
|
|
5
|
+
// Prevent double generation when Next.js loads config multiple times
|
|
6
|
+
let hasGenerated = false;
|
|
117
7
|
/**
|
|
118
8
|
* Generates SVG sprite and TypeScript types for Next.js projects
|
|
119
9
|
*
|
|
@@ -185,16 +75,17 @@ function withSpriteLoader(nextConfig, options) {
|
|
|
185
75
|
const spriteUrl = options?.url ?? "/";
|
|
186
76
|
const spriteFilename = options?.filename ?? "sprite.svg";
|
|
187
77
|
const typesOutputFile = options?.typesOutputFile ?? "generated/icons.ts";
|
|
188
|
-
const generateIcon = options?.generateIconComponent
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
78
|
+
const generateIcon = options?.generateIconComponent === false ? false : { react: true };
|
|
79
|
+
const iconComponentOutputFile = options?.iconComponentOutputFile ?? "generated/Icon";
|
|
80
|
+
// Generate sprite and types on startup (only once)
|
|
81
|
+
if (!hasGenerated) {
|
|
82
|
+
hasGenerated = true;
|
|
83
|
+
(0, shared_js_1.generateSpriteAndTypes)(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
|
|
84
|
+
// Start watcher in dev mode
|
|
85
|
+
const isDev = process.env.NODE_ENV === "development";
|
|
86
|
+
if (isDev) {
|
|
87
|
+
(0, shared_js_1.startWatcher)(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
|
|
88
|
+
}
|
|
198
89
|
}
|
|
199
90
|
// Return config without loader modifications
|
|
200
91
|
// Users should import from the generated types file instead
|
package/dist/shared.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type GenerateIconOption = boolean | {
|
|
2
|
+
astro?: boolean;
|
|
3
|
+
react?: boolean;
|
|
4
|
+
};
|
|
5
|
+
export declare function generateSpriteAndTypes(inputDir: string, outputFile: string, spriteUrl: string, spriteFilename: string, typesOutputFile?: string, generateIcon?: GenerateIconOption, iconComponentOutputFile?: string): void;
|
|
6
|
+
export declare function startWatcher(inputDir: string, outputFile: string, spriteUrl: string, spriteFilename: string, typesOutputFile?: string, generateIcon?: GenerateIconOption, iconComponentOutputFile?: string): void;
|
package/dist/shared.js
ADDED
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.generateSpriteAndTypes = generateSpriteAndTypes;
|
|
37
|
+
exports.startWatcher = startWatcher;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const core_js_1 = require("./core.js");
|
|
41
|
+
const types_js_1 = require("./types.js");
|
|
42
|
+
const components_js_1 = require("./components.js");
|
|
43
|
+
// Track if we've already started watching
|
|
44
|
+
let watcherInitialized = false;
|
|
45
|
+
function getTypesImportPath(componentOutputFile, typesOutputFile) {
|
|
46
|
+
const componentDir = path.dirname(path.resolve(process.cwd(), componentOutputFile));
|
|
47
|
+
const typesFile = path.resolve(process.cwd(), typesOutputFile);
|
|
48
|
+
const typesDir = path.dirname(typesFile);
|
|
49
|
+
const typesFilename = path.basename(typesFile, path.extname(typesFile));
|
|
50
|
+
const relativePath = path
|
|
51
|
+
.relative(componentDir, typesDir)
|
|
52
|
+
.replace(/\\/g, "/");
|
|
53
|
+
if (relativePath === "") {
|
|
54
|
+
return `./${typesFilename}`;
|
|
55
|
+
}
|
|
56
|
+
else if (relativePath.startsWith("..")) {
|
|
57
|
+
return `${relativePath}/${typesFilename}`.replace(/\/+/g, "/");
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
const normalizedPath = relativePath.startsWith("./")
|
|
61
|
+
? relativePath
|
|
62
|
+
: `./${relativePath}`;
|
|
63
|
+
return `${normalizedPath}/${typesFilename}`.replace(/\/+/g, "/");
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
|
|
67
|
+
// Generate sprite and get symbols
|
|
68
|
+
const symbols = (0, core_js_1.generateSprite)({
|
|
69
|
+
inputDir,
|
|
70
|
+
outputFile,
|
|
71
|
+
verbose: true,
|
|
72
|
+
minify: true,
|
|
73
|
+
optimize: true,
|
|
74
|
+
});
|
|
75
|
+
// Generate TypeScript types file if specified
|
|
76
|
+
if (typesOutputFile && symbols.length > 0) {
|
|
77
|
+
(0, types_js_1.generateTypesFile)({
|
|
78
|
+
symbols,
|
|
79
|
+
spriteUrl,
|
|
80
|
+
spriteFilename,
|
|
81
|
+
outputFile: typesOutputFile,
|
|
82
|
+
verbose: false,
|
|
83
|
+
});
|
|
84
|
+
// Determine which components to generate
|
|
85
|
+
const shouldGenerateAstro = generateIcon === true ||
|
|
86
|
+
(typeof generateIcon === "object" && generateIcon.astro === true);
|
|
87
|
+
const shouldGenerateReact = generateIcon === true ||
|
|
88
|
+
(typeof generateIcon === "object" && generateIcon.react === true);
|
|
89
|
+
if (iconComponentOutputFile && (shouldGenerateAstro || shouldGenerateReact)) {
|
|
90
|
+
const baseOutputFile = iconComponentOutputFile.replace(/\.(tsx|astro)$/, "");
|
|
91
|
+
if (shouldGenerateAstro) {
|
|
92
|
+
const astroOutputFile = `${baseOutputFile}.astro`;
|
|
93
|
+
const importPath = getTypesImportPath(astroOutputFile, typesOutputFile);
|
|
94
|
+
(0, components_js_1.generateAstroIconComponent)({
|
|
95
|
+
outputFile: astroOutputFile,
|
|
96
|
+
typesFileRelativePath: importPath,
|
|
97
|
+
verbose: false,
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
if (shouldGenerateReact) {
|
|
101
|
+
const reactOutputFile = `${baseOutputFile}.tsx`;
|
|
102
|
+
const importPath = getTypesImportPath(reactOutputFile, typesOutputFile);
|
|
103
|
+
(0, components_js_1.generateReactIconComponent)({
|
|
104
|
+
outputFile: reactOutputFile,
|
|
105
|
+
typesFileRelativePath: importPath,
|
|
106
|
+
verbose: false,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function startWatcher(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile) {
|
|
113
|
+
if (watcherInitialized) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const projectRoot = process.cwd();
|
|
117
|
+
const absoluteInputDir = path.resolve(projectRoot, inputDir);
|
|
118
|
+
if (!fs.existsSync(absoluteInputDir)) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
watcherInitialized = true;
|
|
122
|
+
console.log(`[svg-sprite] 👀 Watching ${inputDir} for changes...`);
|
|
123
|
+
fs.watch(absoluteInputDir, { recursive: true }, (eventType, filename) => {
|
|
124
|
+
if (filename?.endsWith(".svg")) {
|
|
125
|
+
console.log(`[svg-sprite] Change detected: ${filename}`);
|
|
126
|
+
generateSpriteAndTypes(inputDir, outputFile, spriteUrl, spriteFilename, typesOutputFile, generateIcon, iconComponentOutputFile);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
package/dist/types.js
CHANGED
|
@@ -62,41 +62,41 @@ function generateTypesFile(options) {
|
|
|
62
62
|
return `export const ${constantName}: IconHref = "${spriteUrlWithFilename}#${s.id}";`;
|
|
63
63
|
})
|
|
64
64
|
.join("\n");
|
|
65
|
-
const content = `// Auto-generated by typed-svg-sprite
|
|
66
|
-
// Do not edit this file manually
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Available icon IDs in the sprite
|
|
70
|
-
*/
|
|
71
|
-
export enum IconId {
|
|
72
|
-
${enumEntries}
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Type-safe icon href (sprite URL + fragment identifier)
|
|
77
|
-
*/
|
|
78
|
-
export type IconHref = \`${spriteUrlWithFilename}#\${IconId}\`;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Get the full sprite URL for an icon ID
|
|
82
|
-
*/
|
|
83
|
-
export function getIconHref(iconId: IconId): IconHref {
|
|
84
|
-
return \`${spriteUrlWithFilename}#\${iconId}\` as IconHref;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Pre-built icon references
|
|
89
|
-
*/
|
|
90
|
-
${iconExports}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* All available icons as an array
|
|
94
|
-
*/
|
|
95
|
-
export const allIcons: IconId[] = [
|
|
65
|
+
const content = `// Auto-generated by typed-svg-sprite
|
|
66
|
+
// Do not edit this file manually
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Available icon IDs in the sprite
|
|
70
|
+
*/
|
|
71
|
+
export enum IconId {
|
|
72
|
+
${enumEntries}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Type-safe icon href (sprite URL + fragment identifier)
|
|
77
|
+
*/
|
|
78
|
+
export type IconHref = \`${spriteUrlWithFilename}#\${IconId}\`;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get the full sprite URL for an icon ID
|
|
82
|
+
*/
|
|
83
|
+
export function getIconHref(iconId: IconId): IconHref {
|
|
84
|
+
return \`${spriteUrlWithFilename}#\${iconId}\` as IconHref;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Pre-built icon references
|
|
89
|
+
*/
|
|
90
|
+
${iconExports}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* All available icons as an array
|
|
94
|
+
*/
|
|
95
|
+
export const allIcons: IconId[] = [
|
|
96
96
|
${symbols
|
|
97
97
|
.map((s) => ` IconId.${s.originalId.replace(/-/g, "_").toUpperCase()},`)
|
|
98
|
-
.join("\n")}
|
|
99
|
-
];
|
|
98
|
+
.join("\n")}
|
|
99
|
+
];
|
|
100
100
|
`;
|
|
101
101
|
// Write types file
|
|
102
102
|
const outputDir = path.dirname(absoluteOutputFile);
|