From 4bef27dd62df1e4caf92dbfea57d07f7483429ae Mon Sep 17 00:00:00 2001
From: Phillip <69114037+Flips2001@users.noreply.github.com>
Date: Thu, 22 Feb 2024 14:13:46 +0100
Subject: [PATCH] Refactor `@comet/admin-icons` generator to accept a broader
variation of SVGs (#1732)
COM-366
Change the icon generator to accept icons with more than one path, as
well as circles etc. and more complex structures like:
```
```
The new icons have the same structure as the input svg files but without
the `fill` prop. All other props are kept.
I tested resizing and coloring, both work.
---------
Co-authored-by: Phillip Lechenauer
---
packages/admin/admin-icons/generate-icons.ts | 29 ++++++++++++--------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/packages/admin/admin-icons/generate-icons.ts b/packages/admin/admin-icons/generate-icons.ts
index da4d50d87f..9ba85f7d09 100644
--- a/packages/admin/admin-icons/generate-icons.ts
+++ b/packages/admin/admin-icons/generate-icons.ts
@@ -1,6 +1,6 @@
import { Presets, SingleBar } from "cli-progress";
import { ESLint } from "eslint";
-import { XMLParser } from "fast-xml-parser";
+import { XMLBuilder, XMLParser } from "fast-xml-parser";
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "fs";
import { pascalCase, pascalCaseTransformMerge } from "pascal-case";
import * as path from "path";
@@ -48,9 +48,12 @@ const main = async () => {
bar.increment(1, {
title: `Generate icons ${icon.name}`,
});
- const pathData = getPathData(icon);
+ const svgData = getSVGData(icon);
- return writeComponent(icon, pathData);
+ const builder = new XMLBuilder({ ignoreAttributes: false });
+ const svgString = builder.build(svgData);
+
+ return writeComponent(icon, svgString);
}),
);
bar.stop();
@@ -60,15 +63,17 @@ const main = async () => {
const getComponentName = (fileName: string) => pascalCase(fileName.split(".")[0], { transform: pascalCaseTransformMerge });
-const getPathData = (icon: Icon) => {
+const getSVGData = (icon: Icon) => {
const fileContents = readFileSync(icon.path);
- const parsedXml = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: "" }).parse(fileContents.toString());
-
- if (parsedXml?.svg?.path?.d === undefined) {
- throw new Error(`The file ${icon.name} must contain a element with a d attribute`);
- }
+ const parsedXml = new XMLParser({
+ ignoreAttributes: false,
+ updateTag(_, __, attrs) {
+ delete attrs["@_fill"];
+ return true;
+ },
+ }).parse(fileContents.toString());
- return parsedXml.svg.path.d;
+ return parsedXml.svg;
};
const getFormattedText = async (text: string) => {
@@ -81,7 +86,7 @@ const getFormattedText = async (text: string) => {
return results[0].output;
};
-const writeComponent = async (icon: Icon, pathData: string) => {
+const writeComponent = async (icon: Icon, svgString: string) => {
const component = await getFormattedText(`
import { SvgIcon, SvgIconProps } from "@mui/material";
import * as React from "react";
@@ -96,7 +101,7 @@ const writeComponent = async (icon: Icon, pathData: string) => {
export const ${icon.componentName} = React.forwardRef((props, ref) => {
return (
-
+ ${svgString}
);
});