@usefui/svgjsx
Version:
Open Source Command Line Interfaces to generate JSX Icon Components from SVGs.
113 lines • 4.35 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateExportList = exports.generateHeader = exports.createTsxComponent = exports.processSvgContent = exports.replaceColorsWithCurrentColor = exports.sanitizeComponentName = exports.isInvalidComponentName = void 0;
const reserved_words_1 = require("../utils/reserved-words");
const isInvalidComponentName = (name) => !name ||
name.length === 0 ||
/^[^a-zA-Z]/.test(name) ||
reserved_words_1.RESERVED_WORDS.has(name.toLowerCase()) ||
name.length > 128;
exports.isInvalidComponentName = isInvalidComponentName;
const sanitizeComponentName = (filename) => {
const name = filename
.replace(/\.svg$/i, "")
.replace(/[^a-zA-Z0-9]/g, " ")
.split(" ")
.filter((word) => word.length > 0)
.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
.join("")
.replace(/^[^a-zA-Z]*/, "");
return (0, exports.isInvalidComponentName)(name) ? "" : name;
};
exports.sanitizeComponentName = sanitizeComponentName;
const replaceColorsWithCurrentColor = (content) => {
const colorAttributes = [
"fill",
"stroke",
"stop-color",
"flood-color",
"lighting-color",
];
const attributePattern = colorAttributes.join("|");
const colorPatterns = [
/#[0-9a-fA-F]{3,8}/,
/rgba?\s*\(\s*[^)]+\)/,
/hsla?\s*\(\s*[^)]+\)/,
/\b(?:black|white|red|green|blue|yellow|orange|purple|pink|brown|gray|grey|cyan|magenta|lime|navy|maroon|olive|teal|silver|aqua|fuchsia|transparent)\b/i,
];
const allColorPattern = new RegExp(colorPatterns.map((p) => p.source).join("|"), "gi");
const regex = new RegExp(`(${attributePattern})\\s*=\\s*["']([^"']*?)["']`, "gi");
return content.replace(regex, (match, attribute, value) => {
if (allColorPattern.test(value))
return `${attribute}="currentColor"`;
return match;
});
};
exports.replaceColorsWithCurrentColor = replaceColorsWithCurrentColor;
const processSvgContent = (content) => {
let processed = content;
processed = processed
.replace(/<\?xml[^>]*\?>/g, "")
.replace(/<!--[\s\S]*?-->/g, "");
processed = (0, exports.replaceColorsWithCurrentColor)(processed);
processed = processed.replace(/([a-zA-Z]+)-([a-zA-Z])/g, (_, p1, p2) => p1 + p2.toUpperCase());
processed = processed
.replace(/class=/g, "className=")
.replace(/for=/g, "htmlFor=");
processed = processed.replace(/\s+/g, " ").trim();
if (processed.includes("<svg") && !processed.includes("{...props}")) {
processed = processed.replace(/<svg([^>]*?)>/i, "<React.Fragment>");
}
if (processed.includes("</svg>") && !processed.includes("{...props}")) {
processed = processed.replace("</svg>", "</React.Fragment>");
}
return processed;
};
exports.processSvgContent = processSvgContent;
const createTsxComponent = (svgFile) => {
const componentName = (0, exports.sanitizeComponentName)(svgFile.name);
if (!componentName)
return null;
const processedSvg = (0, exports.processSvgContent)(svgFile.content);
const content = `
export const ${componentName} = () => (
${processedSvg}
);
${componentName}.displayName = "Icon.${componentName}";
`;
return { name: componentName, content };
};
exports.createTsxComponent = createTsxComponent;
const generateHeader = () => `
/* Auto-generated by: https://github.com/foundation-ui/svgjsx */\n
import React from 'react';\n
export const Icon = ({ children, ...restProps }: React.ComponentProps<"svg">) => {
return (
<svg
focusable="false"
aria-hidden="true"
viewBox="0 0 24 24"
width={16}
height={16}
fill="currentColor"
{...restProps}
>
{children}
</svg>
);
}
Icon.displayName = "Icon";\n
`;
exports.generateHeader = generateHeader;
const generateExportList = (componentNames) => {
if (componentNames.length === 0)
return "";
const parentComponentName = "Icon";
const assignments = componentNames
.sort()
.map((name) => `${parentComponentName}.${name} = ${name};`)
.join("\n");
return "\n" + assignments;
};
exports.generateExportList = generateExportList;
//# sourceMappingURL=transformers.js.map