Skip to content

Commit

Permalink
v1.1.0 Improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
AlemTuzlak committed May 12, 2024
1 parent 22ab3c1 commit a6fd307
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 19 deletions.
12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "vite-plugin-icons-spritesheet",
"version": "1.0.0",
"version": "1.1.0",
"description": "Vite plugin that generates a spritesheet out of your icons.",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
Expand Down Expand Up @@ -58,7 +58,7 @@
"dependencies": {
"chalk": "^4.1.2",
"glob": "^10.3.12",
"vite": "^5.2.10",
"vite": "5.2.11",
"node-html-parser": "^6.1.13"
},
"devDependencies": {
Expand Down
45 changes: 37 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file
cwd: inputDir,
});
if (files.length === 0) {
console.log(`⚠️ No SVG files found in ${chalk.red(inputDirRelative)}`);
console.log(`⚠️ No SVG files found in ${chalk.red(inputDirRelative)}`);
return;
}

Expand All @@ -34,8 +34,8 @@ const generateIcons = async ({ withTypes = false, inputDir, outputDir, cwd, file
files,
inputDir,
outputPath: path.join(outputDir, fileName),
outputDirRelative,
});
console.log(`🖼️ Generated SVG spritesheet in ${chalk.green(outputDirRelative)}`);
if (withTypes) {
await generateTypes({
names: files.map((file: string) => fileNameToCamelCase(file.replace(/\.svg$/, ""))),
Expand All @@ -56,10 +56,12 @@ async function generateSvgSprite({
files,
inputDir,
outputPath,
outputDirRelative,
}: {
files: string[];
inputDir: string;
outputPath: string;
outputDirRelative?: string;
}) {
// Each SVG becomes a symbol and we wrap them all in a single SVG
const symbols = await Promise.all(
Expand All @@ -84,17 +86,18 @@ async function generateSvgSprite({
})
);
const output = [
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"0\" height=\"0\">",
'<?xml version="1.0" encoding="UTF-8"?>',
'<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="0" height="0">',
"<defs>", // for semantics: https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs
...symbols.filter(Boolean),
"</defs>",
"</svg>",
].join("\n");
return fs.writeFile(outputPath, output, "utf8");

return writeIfChanged(outputPath, output, `🖼️ Generated SVG spritesheet in ${chalk.green(outputDirRelative)}`);
}

function generateTypes({ names, outputPath }: { names: string[]; outputPath: string }) {
async function generateTypes({ names, outputPath }: { names: string[]; outputPath: string }) {
const output = [
"// This file is generated by icon spritesheet generator",
"",
Expand All @@ -107,16 +110,42 @@ function generateTypes({ names, outputPath }: { names: string[]; outputPath: str
"",
].join("\n");

const file = fs.writeFile(outputPath, output, "utf8");
console.log(`${chalk.blueBright("TS")} Generated icon types in ${chalk.green(outputPath)}`);
const file = await writeIfChanged(
outputPath,
output,
`${chalk.blueBright("TS")} Generated icon types in ${chalk.green(outputPath)}`
);
return file;
}

/**
* Each write can trigger dev server reloads
* so only write if the content has changed
*/
async function writeIfChanged(filepath: string, newContent: string, message: string) {
const currentContent = await fs.readFile(filepath, "utf8");
if (currentContent !== newContent) {
await fs.writeFile(filepath, newContent, "utf8");
console.log(message);
}
}

export const iconsSpritesheet: (args: PluginProps) => Plugin = ({ withTypes, inputDir, outputDir, fileName, cwd }) => ({
name: "icon-spritesheet-generator",
apply(config) {
return config.mode === "development";
},
async watchChange(file, type) {
const inputPath = normalizePath(path.join(cwd ?? process.cwd(), inputDir));
if (file.includes(inputPath) && file.endsWith(".svg") && ["create", "delete"].includes(type.event)) {
await generateIcons({
withTypes,
inputDir,
outputDir,
fileName,
});
}
},
async handleHotUpdate({ file }) {
const inputPath = normalizePath(path.join(cwd ?? process.cwd(), inputDir));
if (file.includes(inputPath) && file.endsWith(".svg")) {
Expand Down
2 changes: 1 addition & 1 deletion test-apps/remix-vite-cjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"typescript": "^5.1.6",
"vite": "^5.1.0",
"vite": "^5.2.11",
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
Expand Down
1 change: 1 addition & 0 deletions test-apps/remix-vite/icons/a.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test-apps/remix-vite/icons/b.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test-apps/remix-vite/icons/c.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions test-apps/remix-vite/icons/d.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion test-apps/remix-vite/icons/test.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion test-apps/remix-vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"typescript": "^5.1.6",
"vite": "^5.1.0",
"vite": "^5.2.11",
"vite-tsconfig-paths": "^4.2.1"
},
"engines": {
Expand Down
5 changes: 5 additions & 0 deletions test-apps/remix-vite/public/icons/sprite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions test-apps/remix-vite/public/icons/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,17 @@

export type IconName =
| "Test"
| "De"
| "D"
| "C"
| "B"
| "A"

export const iconNames = [
"Test",
"De",
"D",
"C",
"B",
"A",
] as const

0 comments on commit a6fd307

Please sign in to comment.