UNPKG

3.17 kBJavaScriptView Raw
1/*
2
3Icons
4=====
5
6Icons are combined into one SVG as symbols.
7This also generates a SCSS file detailing the dimensions of each icon with a corresponding CSS class name.
8The compiled symbols SVG is ajax'd into the document in the head.js.
9
10Read more about our suggested accessibility approaches [here](https://code.area17.com/a17/fe-boilerplate/wikis/svg-sprite).
11
12*/
13
14const SVGO = require('svgo');
15const svgstore = require('svgstore');
16const path = require('path');
17const fs = require('fs-extra');
18const utils = require('../utils');
19const chalk = require('chalk');
20const data = utils.getManifest();
21const createLogger = require('logging').default;
22const logger = createLogger('Icons');
23
24const iconPath = path.resolve(data.paths.source, data.paths.icons);
25const svgo = new SVGO({plugins:[{removeViewBox:false}]});
26
27let config = data.config.svg;
28if (!config.hasOwnProperty('sprite')) { config.sprite = 'icons.svg'; } // default sprite name is icons.svg
29if (!config.hasOwnProperty('scss')) { config.scss = data.paths.source + data.paths.styles; }
30
31logger.info('Starting Icons', config.scss);
32
33let files = fs.readdirSync(iconPath);
34let sprite = svgstore();
35let icons = [];
36let scss = '';
37let iconDest = path.resolve(data.paths.source + 'images/'); // copy the icon in the image folder
38
39/**
40 *
41 * @param items An array of items.
42 * @param fn A function that accepts an item from the array and returns a promise.
43 * @returns {Promise}
44 */
45function forEachPromise(items, fn) {
46 return items.reduce(function (promise, item) {
47 return promise.then(function () {
48 return fn(item);
49 });
50 }, Promise.resolve());
51}
52
53function buildIcon(fileName) {
54 if (fileName === '.keep') { return false; }
55 if (fileName === '.DS_Store') { return false; }
56 const title = path.basename(fileName, '.svg');
57
58 let file = fs.readFileSync(path.resolve(iconPath, fileName));
59 return svgo.optimize(file).then(function(result) {
60 if (result.error) {
61 logger.info('Icon error ' + fileName +'.svg : ', result.error);
62 } else {
63 icons.push(Object.assign({title}, result.info));
64 sprite.add('icon--' + path.parse(fileName).name, result.data); // Id will be prefixed with 'icon--' : "icon--fileName"
65 }
66 });
67}
68
69function storeSprite() {
70 fs.ensureDirSync(iconDest);
71 const destination = path.resolve(iconDest, config.sprite);
72 fs.writeFileSync(destination, sprite.toString());
73 logger.info('Icons compiled to: ', destination);
74}
75
76function makeScssFile() {
77 fs.ensureDirSync(config.scss);
78 scss = "$icon-sizes: ();\n";
79 const destination = path.resolve(config.scss, "_icons.scss");
80 icons.forEach(icon => {
81 scss = scss.concat(
82 `.icon--${icon.title}, .icon--${icon.title} svg { width: ${icon.width}px; height: ${icon.height}px }\n`
83 );
84 scss = scss.concat(
85 `$icon-sizes: map-merge($icon-sizes, ( ${icon.title}: ( width: ${icon.width}px, height: ${icon.height}px ) ) );\n`
86 );
87 });
88 fs.writeFileSync(destination, scss);
89 logger.info("Icons SCSS file written at: ", destination);
90}
91
92/* run */
93forEachPromise(files, buildIcon).then(() => {
94 storeSprite();
95 makeScssFile();
96 logger.info(chalk.green('Finished Icons'));
97});