via-icons/scripts/generateIconsOld.js

227 lines
6.1 KiB
JavaScript

import fs from "fs";
import path from "path";
import { optimize } from "svgo";
import { fileURLToPath } from "url";
import { dirname } from "path";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const mapSvgAttributes = (svgContent) =>
svgContent
.replace(/fill-rule/g, "fillRule")
.replace(/clip-rule/g, "clipRule");
const generateIconComponent = (
name,
svgContent,
description = "",
usage = [],
isDeprecated = false,
aliases = [],
appendIconSuffix = true
) => {
const componentName = appendIconSuffix ? `${name}Icon` : name;
return `import * as React from 'react';
interface IconProps extends React.SVGAttributes<SVGElement> {
children?: never;
color?: string;
}
/**
* @name ${componentName}
${aliases.length ? `* @alias ${aliases.join(", ")}` : ""}
*
* @description
* ${description}
*
* ${isDeprecated ? "@deprecated\n * " : ""}
* @usage
* ${usage.map((item) => `- ${item}`).join("\n * ")}
*
* @accessibility
* Asegurarse de incluir un atributo \`aria-label\` o \`aria-hidden="true"\` si el ícono es decorativo.
*
* @returns {JSX.Element} Componente SVG.
*/
const ${componentName} = React.forwardRef<SVGSVGElement, IconProps>(
({ ...props }, forwardedRef) => {
return (
${mapSvgAttributes(svgContent).replace(
"<svg",
"<svg {...props} ref={forwardedRef}"
)}
);
}
);
${componentName}.displayName = '${componentName}';
export { ${componentName} };
`;
};
const generateIndexFile = (components, outputDir, prefix = "") => {
const exports = components
.map(({ name }) =>
prefix
? `export { ${name} as ${prefix}${name} } from "./${name}";`
: `export { ${name} } from "./${name}";`
)
.join("\n");
fs.writeFileSync(path.resolve(outputDir, "index.ts"), exports, "utf-8");
};
const processIcons = async ({
inputDir,
outputDir,
prefix = "",
iconMetadata,
deprecatedIcons,
appendIconSuffix = true,
}) => {
fs.mkdirSync(outputDir, { recursive: true });
const files = fs.readdirSync(inputDir);
const components = await Promise.all(
files.map(async (file) => {
const filePath = path.resolve(inputDir, file);
if (fs.lstatSync(filePath).isDirectory()) return null;
const svgContent = fs.readFileSync(filePath, "utf-8");
const { data } = await optimize(svgContent, { plugins: [] });
const baseName = file.replace(".svg", "");
const componentBaseName = baseName.replace(/(^\w|-\w)/g, clearAndUpper);
const componentName = appendIconSuffix
? `${componentBaseName}Icon`
: componentBaseName;
const metadata = iconMetadata[componentBaseName] || {};
const description = metadata.description || "";
const usage = metadata.usage || [];
const aliases = metadata.aliases || [];
const isDeprecated = deprecatedIcons.includes(componentBaseName);
const componentContent = generateIconComponent(
componentBaseName,
data,
description,
usage,
isDeprecated,
aliases,
appendIconSuffix
);
fs.writeFileSync(
path.resolve(outputDir, `${componentName}.tsx`),
componentContent,
"utf-8"
);
return { name: componentName, aliases };
})
);
generateIndexFile(components.filter(Boolean), outputDir, prefix);
};
const clearAndUpper = (text) => text.replace(/-/, "").toUpperCase();
(async () => {
const iconSets = [
{
inputDir: path.resolve(__dirname, "../src/svgs/fc"),
outputDir: path.resolve(__dirname, "../src/fc"),
prefix: "Fc",
iconMetadataPath: "../jsons/IconsList/flatColorIconsList.json",
},
{
inputDir: path.resolve(__dirname, "../src/svgs/fa"),
outputDir: path.resolve(__dirname, "../src/fa"),
prefix: "Fa",
iconMetadataPath: "../jsons/IconsList/fontAwesomeIconsList.json",
},
{
inputDir: path.resolve(__dirname, "../src/svgs/rx"),
outputDir: path.resolve(__dirname, "../src/rx"),
prefix: "Rx",
iconMetadataPath: "../jsons/IconsList/radixIconsList.json",
},
{
inputDir: path.resolve(__dirname, "../src/svgs/tfi"),
outputDir: path.resolve(__dirname, "../src/tfi"),
prefix: "Tfi",
iconMetadataPath: "../jsons/IconsList/themifyIconsList.json",
},
{
inputDir: path.resolve(__dirname, "../src/svgs/hi/solid"),
outputDir: path.resolve(__dirname, "../src/hi/solid"),
iconMetadataPath: "../jsons/IconsList/heroiconsList.json",
},
{
inputDir: path.resolve(__dirname, "../src/svgs/hi/outline"),
outputDir: path.resolve(__dirname, "../src/hi/outline"),
iconMetadataPath: "../jsons/IconsList/heroiconsList.json",
isOutline: true,
},
];
const deprecatedIcons = JSON.parse(
fs.readFileSync(
path.resolve(__dirname, "../jsons/IconsList/deprecated.json"),
"utf-8"
)
);
for (const { inputDir, outputDir, iconMetadataPath, prefix } of iconSets) {
const iconMetadataFullPath = path.resolve(__dirname, iconMetadataPath);
if (!fs.existsSync(iconMetadataFullPath)) {
console.error(
`Error: El archivo de metadatos no existe en ${iconMetadataFullPath}`
);
continue;
}
const iconMetadata = JSON.parse(
fs.readFileSync(iconMetadataFullPath, "utf-8")
);
await processIcons({
inputDir,
outputDir,
iconMetadata,
deprecatedIcons,
prefix,
});
}
const hiSolidComponents = fs
.readdirSync(path.resolve(__dirname, "../src/hi/solid"))
.filter((file) => file.endsWith(".tsx"))
.map((file) => ({ name: file.replace(".tsx", "") }));
const hiOutlineComponents = fs
.readdirSync(path.resolve(__dirname, "../src/hi/outline"))
.filter((file) => file.endsWith(".tsx"))
.map((file) => ({ name: file.replace(".tsx", "") }));
const hiIndexExports = hiSolidComponents
.map(({ name }) => `export { ${name} as Hi${name} } from "./solid";`)
.concat(
hiOutlineComponents.map(
({ name }) => `export { ${name} as HiOutline${name} } from "./outline";`
)
)
.join("\n");
fs.writeFileSync(
path.resolve(__dirname, "../src/hi/index.ts"),
hiIndexExports,
"utf-8"
);
})();