@area17/a17-boilerplate
Version:
The official AREA 17 boilerplate
91 lines (76 loc) • 2.97 kB
JavaScript
/*
Icons
=====
Icons are combined into one SVG as symbols.
This also generates a SCSS file detailing the dimensions of each icon with a corresponding CSS class name.
The compiled symbols SVG is ajax'd into the document in the head.js.
Read more about our suggested accessibility approaches [here](https://code.area17.com/a17/fe-boilerplate/wikis/svg-sprite).
*/
const SVGO = require('svgo');
const svgstore = require('svgstore');
const path = require('path');
const fs = require('fs-extra');
const utils = require('../utils');
const chalk = require('chalk');
const data = require(utils.getManifestPath());
const createLogger = require('logging').default;
const logger = createLogger('Icons');
const iconPath = path.resolve(data.paths.source, data.paths.icons);
const svgo = new SVGO();
let config = data.config.svg;
if (!config.hasOwnProperty('sprite')) { config.sprite = 'icons.svg'; } // default sprite name is icons.svg
if (!config.hasOwnProperty('scss')) { config.scss = data.paths.source + data.paths.styles + 'setup'; } // default sprite scss dest is frontend/scss/setup
logger.info('Starting Icons');
let files = fs.readdirSync(iconPath);
let sprite = svgstore();
let icons = [];
let scss = '';
let iconDest = path.resolve(data.paths.dist, data.paths.icons);
/**
*
* @param items An array of items.
* @param fn A function that accepts an item from the array and returns a promise.
* @returns {Promise}
*/
function forEachPromise(items, fn) {
return items.reduce(function (promise, item) {
return promise.then(function () {
return fn(item);
});
}, Promise.resolve());
}
function buildIcon(fileName) {
if (fileName === '.keep') { return false; }
if (fileName === '.DS_Store') { return false; }
const title = path.basename(fileName, '.svg');
let file = fs.readFileSync(path.resolve(iconPath, fileName));
return svgo.optimize(file).then(function(result) {
if (result.error) {
logger.info('Icon error ' + fileName +'.svg : ', result.error);
} else {
icons.push(Object.assign({title}, result.info));
sprite.add('icon--' + path.parse(fileName).name, result.data); // Id will be prefixed with 'icon--' : "icon--fileName"
}
});
}
function storeSprite() {
fs.ensureDirSync(iconDest);
const destination = path.resolve(iconDest, config.sprite);
fs.writeFileSync(destination, sprite.toString());
logger.info('Icons compiled to: ', destination);
}
function makeScssFile() {
fs.ensureDirSync(config.scss);
const destination = path.resolve(config.scss, '_icons.scss');
icons.forEach(icon => {
scss = scss.concat(`.icon--${icon.title}, .icon--${icon.title} svg { width: ${icon.width}px; height: ${icon.height}px }\n`);
});
fs.writeFileSync(destination, scss);
logger.info('Icons SCSS file written at: ', destination);
}
/* run */
forEachPromise(files, buildIcon).then(() => {
storeSprite();
makeScssFile();
logger.info(chalk.green('Finished Icons'));
});