UNPKG

@esri/calcite-ui-icons

Version:

A collection of UI SVG icons created by Esri for applications.

137 lines (128 loc) 5.03 kB
const camelCase = require('camelcase'); const fs = require('fs-extra'); const glob = require('glob-promise'); const path = require('path'); const util = require('util'); const svgson = util.promisify(require('svgson')); const version = require('../package.json').version; /** * Gets all important information about an icon. * @param {string} svg - Path to icon file. * @return {object} - Formatted object with all icon metadata */ function formatSVG (svg) { let file = path.basename(svg.file); let filled = file.indexOf('-f.svg') > -1; return { file, filled, paths: getPaths(svg.contents), size: getSize(file), variant: getVariant(file, filled) }; } /** * Find the path(s) from an icon's svgson data * @param {object} svg - Object as returned from svgson. * @return {array} - Array of paths */ function getPaths (svg) { const bbPaths = ['M0 0h16v16H0z', 'M0 0h24v24H0z', 'M0 0h32v32H0z']; return svg.childs .filter(child => child.name === 'path' && bbPaths.indexOf(child.attrs.d) === -1) // filter out bounding box paths .map(child => ({ opacity: child.attrs.opacity, d: child.attrs.d })); } /** * Find the base icon name * @param {string} name - Icon filename * @param {boolean} filled - Icon filename * @return {array} - Icon filename without size, fill, or file extension */ function getVariant (name, filled) { var noF = name.replace('-f.svg', '.svg'); return noF.substring(0, noF.length - 7) + (filled ? "-f" : ""); } /** * Find an icon's size * @param {string} name - Icon filename * @return {integer} - 16, 24, 36 */ function getSize(name) { var noF = name.replace('-f.svg', '.svg'); return parseInt(noF.substring(noF.length - 4, noF.length - 6), 10); } /** * Read an icon from disc and get data as json * @param {string} fileName - Icon filename (full path) * @return {Promise} - Promise resolving to object which includes name and svgson data */ function readSVG (fileName) { return new Promise(function(resolve, reject) { fs.readFile(fileName, 'utf-8').then(function (svg) { svgson(svg, {}, function (contents) { resolve({file: fileName, contents}); }); }); }); } module.exports = function generatePathFile () { let banner = '// File generated automatically by path-data.js, do not edit directly\n'; let jsFile = `${banner}`; let tsFile = ` ${banner} interface CalciteMultiPathEntry { d: string; opacity?: string; } export type CalciteIconPath = string | CalciteMultiPathEntry[]; `; return glob('icons/*.svg') .then(filePaths => Promise.all(filePaths.map(readSVG))) .then(files => files.map(formatSVG)) .then(files => { let icons = {}; let keywords = JSON.parse(fs.readFileSync('docs/keywords.json', 'utf-8')); files.forEach(file => { // add to json file icons[file.variant] = icons[file.variant] || keywords[file.variant] || { alias: [], category: "", release: "" }; var icon = icons[file.variant]; const firstPath = file.paths[0] || { d: "" }; // back up for "blank" icon const paths = file.paths.length > 1 ? file.paths : firstPath.d; icon[file.size] = paths; var base = file.variant.substring(0, file.variant.length - 2); // make sure filled variants get the keywords from their standard counterpart if (file.filled && !icon.release) { const variantKeywords = keywords[base]; if (variantKeywords) { icon.alias = variantKeywords.alias; icon.category = variantKeywords.category; icon.release = variantKeywords.release; } } // add to ts and js files const variant = file.variant.match(/^\d/) ? `i${file.variant}`: file.variant; const camelCaseName = camelCase(`${file.filled ? base: variant }-${file.size}${ file.filled ? "-f" : ""}`); jsFile += `export {${camelCaseName}} from "./js/${camelCaseName}.js";\n`; let contents, tsContents; if (typeof paths === "string") { tsFile += `export const ${camelCaseName}: string;\n`; contents = `export const ${camelCaseName} = "${paths}";\n`; tsContents = `export const ${camelCaseName}: string;\n`; } else { icon.multiPath = true; tsFile += `export const ${camelCaseName}: CalciteMultiPathEntry[];\n`; contents = `export const ${camelCaseName} = ${JSON.stringify(paths)};\n`; tsContents = `export const ${camelCaseName}: CalciteMultiPathEntry[];\n`; } fs.writeFile(`js/${camelCaseName}.js`, contents, 'utf8'); fs.writeFile(`js/${camelCaseName}.d.ts`, tsContents, 'utf8'); fs.writeFile(`js/${camelCaseName}.json`, JSON.stringify(paths), 'utf8'); }); let promises = [ fs.writeFile('docs/icons.json', JSON.stringify({ version, icons }), 'utf8'), fs.writeFile('index.d.ts', tsFile, 'utf8'), fs.writeFile('index.js', jsFile, 'utf8') ]; return Promise.all(promises); }); };