Skip to content

Commit 87da244

Browse files
authored
Merge pull request #6 from forge42dev/5-request-to-make-filenametocamelcase-optional
Added ability to change the icon name convention
2 parents 1bdd0f6 + d2ea81b commit 87da244

File tree

1 file changed

+54
-36
lines changed

1 file changed

+54
-36
lines changed

src/index.ts

Lines changed: 54 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,17 @@ interface PluginProps {
1414
outputDir: string;
1515
fileName?: string;
1616
cwd?: string;
17+
iconNameTransformer?: (fileName: string) => string;
1718
}
1819

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) => {
2028
const cwdToUse = cwd ?? process.cwd();
2129
const inputDirRelative = path.relative(cwdToUse, inputDir);
2230
const outputDirRelative = path.relative(cwdToUse, outputDir);
@@ -35,15 +43,21 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file
3543
inputDir,
3644
outputPath: path.join(outputDir, fileName),
3745
outputDirRelative,
46+
iconNameTransformer,
3847
});
3948
if (withTypes) {
4049
await generateTypes({
41-
names: files.map((file: string) => fileNameToCamelCase(file.replace(/\.svg$/, ""))),
50+
names: files.map((file: string) => transformIconName(file, iconNameTransformer ?? fileNameToCamelCase)),
4251
outputPath: path.join(outputDir, "types.ts"),
4352
});
4453
}
4554
};
4655

56+
const transformIconName = (fileName: string, transformer: (iconName: string) => string) => {
57+
const iconName = fileName.replace(/\.svg$/, "");
58+
return transformer(iconName);
59+
};
60+
4761
function fileNameToCamelCase(fileName: string): string {
4862
const words = fileName.split("-");
4963
const capitalizedWords = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1));
@@ -57,16 +71,18 @@ async function generateSvgSprite({
5771
inputDir,
5872
outputPath,
5973
outputDirRelative,
74+
iconNameTransformer,
6075
}: {
6176
files: string[];
6277
inputDir: string;
6378
outputPath: string;
6479
outputDirRelative?: string;
80+
iconNameTransformer?: (fileName: string) => string;
6581
}) {
6682
// Each SVG becomes a symbol and we wrap them all in a single SVG
6783
const symbols = await Promise.all(
6884
files.map(async (file) => {
69-
const fileName = fileNameToCamelCase(file.replace(/\.svg$/, ""));
85+
const fileName = transformIconName(file, iconNameTransformer ?? fileNameToCamelCase);
7086
const input = await fs.readFile(path.join(inputDir, file), "utf8");
7187

7288
const root = parse(input);
@@ -86,8 +102,8 @@ async function generateSvgSprite({
86102
})
87103
);
88104
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">',
91107
"<defs>", // for semantics: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
92108
...symbols.filter(Boolean),
93109
"</defs>",
@@ -136,39 +152,41 @@ async function writeIfChanged(filepath: string, newContent: string, message: str
136152
}
137153
}
138154

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({
146165
withTypes,
147166
inputDir,
148167
outputDir,
149168
fileName,
169+
iconNameTransformer,
150170
});
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

Comments
 (0)