generate iconFont
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

90 lines
4.3 KiB

"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.generateReactIcons = exports.generateIconsSource = void 0;
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const svgo_1 = require("svgo");
const utils_1 = require("./utils");
/**
* Generate Icon SVG Path Source
* <font-name>.json
*/
async function generateIconsSource(options = {}) {
const ICONS_PATH = (0, utils_1.filterSvgFiles)(options.src);
const data = await buildPathsObject(ICONS_PATH, options);
const outPath = path_1.default.join(options.dist, `${options.fontName}.json`);
await fs_extra_1.default.outputFile(outPath, `{${data}\n}`);
return outPath;
}
exports.generateIconsSource = generateIconsSource;
/**
* Loads SVG file for each icon, extracts path strings `d="path-string"`,
* and constructs map of icon name to array of path strings.
* @param {array} files
*/
async function buildPathsObject(files, options = {}) {
const svgoOptions = options.svgoOptions || {};
return Promise.all(files.map(async (filepath) => {
const name = path_1.default.basename(filepath, '.svg');
const svg = fs_extra_1.default.readFileSync(filepath, 'utf-8');
const pathStrings = (0, svgo_1.optimize)(svg, Object.assign(Object.assign({ path: filepath }, options), { plugins: [
'convertTransform',
...(svgoOptions.plugins || [])
// 'convertShapeToPath'
] }));
const str = (pathStrings.data.match(/ d="[^"]+"/g) || []).map(s => s.slice(3));
return `\n"${name}": [${str.join(',\n')}]`;
}));
}
const reactSource = (name, size, fontName, source) => `import React from 'react';
export const ${name} = props => (
<svg viewBox="0 0 20 20" width="${size}" height="${size}" {...props} className={\`${fontName} \${props.className ? props.className : ''}\`}>${source}</svg>
);
`;
const reactTypeSource = (name) => `import React from 'react';
export declare const ${name}: (props: React.SVGProps<SVGSVGElement>) => JSX.Element;
`;
/**
* Generate React Icon
* <font-name>.json
*/
async function generateReactIcons(options = {}) {
const ICONS_PATH = (0, utils_1.filterSvgFiles)(options.src);
const data = await outputReactFile(ICONS_PATH, options);
const outPath = path_1.default.join(options.dist, 'react', 'index.js');
fs_extra_1.default.outputFileSync(outPath, data.join('\n'));
fs_extra_1.default.outputFileSync(outPath.replace(/\.js$/, '.d.ts'), data.join('\n'));
return outPath;
}
exports.generateReactIcons = generateReactIcons;
async function outputReactFile(files, options = {}) {
const svgoOptions = options.svgoOptions || {};
const fontSize = options.css && typeof options.css !== 'boolean' && options.css.fontSize ? options.css.fontSize : '16px';
const fontName = options.classNamePrefix || options.fontName;
return Promise.all(files.map(async (filepath) => {
let name = (0, utils_1.toPascalCase)(path_1.default.basename(filepath, '.svg'));
if (/^[rR]eact$/.test(name)) {
name = name + (0, utils_1.toPascalCase)(fontName);
}
const svg = fs_extra_1.default.readFileSync(filepath, 'utf-8');
const pathData = (0, svgo_1.optimize)(svg, Object.assign(Object.assign({ path: filepath }, svgoOptions), { plugins: [
'removeXMLNS',
'removeEmptyAttrs',
'convertTransform',
// 'convertShapeToPath',
// 'removeViewBox'
...(svgoOptions.plugins || [])
] }));
const str = (pathData.data.match(/ d="[^"]+"/g) || []).map(s => s.slice(3));
const outDistPath = path_1.default.join(options.dist, 'react', `${name}.js`);
const pathStrings = str.map((d, i) => `<path d=${d} fillRule="evenodd" />`);
const comName = isNaN(Number(name.charAt(0))) ? name : (0, utils_1.toPascalCase)(fontName) + name;
fs_extra_1.default.outputFileSync(outDistPath, reactSource(comName, fontSize, fontName, pathStrings.join(',\n')));
fs_extra_1.default.outputFileSync(outDistPath.replace(/\.js$/, '.d.ts'), reactTypeSource(comName));
return `export * from './${name}';`;
}));
}
//# sourceMappingURL=generate.js.map