@@ -14,9 +14,17 @@ interface PluginProps {
14
14
outputDir : string ;
15
15
fileName ?: string ;
16
16
cwd ?: string ;
17
+ iconNameTransformer ?: ( fileName : string ) => string ;
17
18
}
18
19
19
- const generateIcons = async ( { withTypes = false , inputDir, outputDir, cwd, fileName = "sprite.svg" } : PluginProps ) => {
20
+ const generateIcons = async ( {
21
+ withTypes = false ,
22
+ inputDir,
23
+ outputDir,
24
+ cwd,
25
+ fileName = "sprite.svg" ,
26
+ iconNameTransformer,
27
+ } : PluginProps ) => {
20
28
const cwdToUse = cwd ?? process . cwd ( ) ;
21
29
const inputDirRelative = path . relative ( cwdToUse , inputDir ) ;
22
30
const outputDirRelative = path . relative ( cwdToUse , outputDir ) ;
@@ -35,15 +43,21 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file
35
43
inputDir,
36
44
outputPath : path . join ( outputDir , fileName ) ,
37
45
outputDirRelative,
46
+ iconNameTransformer,
38
47
} ) ;
39
48
if ( withTypes ) {
40
49
await generateTypes ( {
41
- names : files . map ( ( file : string ) => fileNameToCamelCase ( file . replace ( / \. s v g $ / , "" ) ) ) ,
50
+ names : files . map ( ( file : string ) => transformIconName ( file , iconNameTransformer ?? fileNameToCamelCase ) ) ,
42
51
outputPath : path . join ( outputDir , "types.ts" ) ,
43
52
} ) ;
44
53
}
45
54
} ;
46
55
56
+ const transformIconName = ( fileName : string , transformer : ( iconName : string ) => string ) => {
57
+ const iconName = fileName . replace ( / \. s v g $ / , "" ) ;
58
+ return transformer ( iconName ) ;
59
+ } ;
60
+
47
61
function fileNameToCamelCase ( fileName : string ) : string {
48
62
const words = fileName . split ( "-" ) ;
49
63
const capitalizedWords = words . map ( ( word ) => word . charAt ( 0 ) . toUpperCase ( ) + word . slice ( 1 ) ) ;
@@ -57,16 +71,18 @@ async function generateSvgSprite({
57
71
inputDir,
58
72
outputPath,
59
73
outputDirRelative,
74
+ iconNameTransformer,
60
75
} : {
61
76
files : string [ ] ;
62
77
inputDir : string ;
63
78
outputPath : string ;
64
79
outputDirRelative ?: string ;
80
+ iconNameTransformer ?: ( fileName : string ) => string ;
65
81
} ) {
66
82
// Each SVG becomes a symbol and we wrap them all in a single SVG
67
83
const symbols = await Promise . all (
68
84
files . map ( async ( file ) => {
69
- const fileName = fileNameToCamelCase ( file . replace ( / \. s v g $ / , "" ) ) ;
85
+ const fileName = transformIconName ( file , iconNameTransformer ?? fileNameToCamelCase ) ;
70
86
const input = await fs . readFile ( path . join ( inputDir , file ) , "utf8" ) ;
71
87
72
88
const root = parse ( input ) ;
@@ -86,8 +102,8 @@ async function generateSvgSprite({
86
102
} )
87
103
) ;
88
104
const output = [
89
- " <?xml version=\ "1.0\ " encoding=\ "UTF-8\ "?>" ,
90
- " <svg xmlns=\ "http://www.w3.org/2000/svg\ " xmlns:xlink=\ "http://www.w3.org/1999/xlink\ " width=\"0\ " height=\"0\">" ,
105
+ ' <?xml version="1.0" encoding="UTF-8"?>' ,
106
+ ' <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0 " height="0">' ,
91
107
"<defs>" , // for semantics: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
92
108
...symbols . filter ( Boolean ) ,
93
109
"</defs>" ,
@@ -136,39 +152,41 @@ async function writeIfChanged(filepath: string, newContent: string, message: str
136
152
}
137
153
}
138
154
139
- export const iconsSpritesheet : ( args : PluginProps ) => Plugin = ( { withTypes, inputDir, outputDir, fileName, cwd } ) => ( {
140
- name : "icon-spritesheet-generator" ,
141
- apply ( config ) {
142
- return config . mode === "development" ;
143
- } ,
144
- async configResolved ( ) {
145
- await generateIcons ( {
155
+ export const iconsSpritesheet : ( args : PluginProps ) => Plugin = ( {
156
+ withTypes,
157
+ inputDir,
158
+ outputDir,
159
+ fileName,
160
+ cwd,
161
+ iconNameTransformer,
162
+ } ) => {
163
+ const iconGenerator = async ( ) =>
164
+ generateIcons ( {
146
165
withTypes,
147
166
inputDir,
148
167
outputDir,
149
168
fileName,
169
+ iconNameTransformer,
150
170
} ) ;
151
- } ,
152
- async watchChange ( file , type ) {
153
- const inputPath = normalizePath ( path . join ( cwd ?? process . cwd ( ) , inputDir ) ) ;
154
- if ( file . includes ( inputPath ) && file . endsWith ( ".svg" ) && [ "create" , "delete" ] . includes ( type . event ) ) {
155
- await generateIcons ( {
156
- withTypes,
157
- inputDir,
158
- outputDir,
159
- fileName,
160
- } ) ;
161
- }
162
- } ,
163
- async handleHotUpdate ( { file } ) {
164
- const inputPath = normalizePath ( path . join ( cwd ?? process . cwd ( ) , inputDir ) ) ;
165
- if ( file . includes ( inputPath ) && file . endsWith ( ".svg" ) ) {
166
- await generateIcons ( {
167
- withTypes,
168
- inputDir,
169
- outputDir,
170
- fileName,
171
- } ) ;
172
- }
173
- } ,
174
- } ) ;
171
+ return {
172
+ name : "icon-spritesheet-generator" ,
173
+ apply ( config ) {
174
+ return config . mode === "development" ;
175
+ } ,
176
+ async configResolved ( ) {
177
+ await iconGenerator ( ) ;
178
+ } ,
179
+ async watchChange ( file , type ) {
180
+ const inputPath = normalizePath ( path . join ( cwd ?? process . cwd ( ) , inputDir ) ) ;
181
+ if ( file . includes ( inputPath ) && file . endsWith ( ".svg" ) && [ "create" , "delete" ] . includes ( type . event ) ) {
182
+ await iconGenerator ( ) ;
183
+ }
184
+ } ,
185
+ async handleHotUpdate ( { file } ) {
186
+ const inputPath = normalizePath ( path . join ( cwd ?? process . cwd ( ) , inputDir ) ) ;
187
+ if ( file . includes ( inputPath ) && file . endsWith ( ".svg" ) ) {
188
+ await iconGenerator ( ) ;
189
+ }
190
+ } ,
191
+ } ;
192
+ } ;
0 commit comments