Skip to content

Commit

Permalink
[icons] Resize svg icons (#12356)
Browse files Browse the repository at this point in the history
* Use URLs provided in data.json to retrieve weirdly sized icons

* Still has to determine correct size

* Linted, but had to use anonymous function to make it happy

* Modify weirdly sized SVGs to fit in a 24x24 viewBox

* let's merge
  • Loading branch information
the-question authored and oliviertassinari committed Aug 6, 2018
1 parent 3059cbd commit b10615b
Show file tree
Hide file tree
Showing 15 changed files with 149 additions and 88 deletions.
125 changes: 69 additions & 56 deletions packages/material-ui-icons/builder.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,9 +119,10 @@ async function worker({ svgPath, options, renameFilter, template }) {
.replace(/<rect id="SVGID_1_" width="24" height="24"\/>/g, '');

const result = await svgo.optimize(input);

// Extract the paths from the svg string
// Clean xml paths
const paths = result.data
let paths = result.data
.replace(/<svg[^>]*>/g, '')
.replace(/<\/svg>/g, '')
.replace(/"\/>/g, '" />')
Expand All @@ -131,6 +132,14 @@ async function worker({ svgPath, options, renameFilter, template }) {
.replace(/clip-rule=/g, 'clipRule=')
.replace(/fill-rule=/g, 'fillRule=');

const size = Number(svgPath.match(/^.*_([0-9]+)px.svg$/)[1]);

if (size !== 24) {
const scale = Math.round((24 / size) * 100) / 100; // Keep a maximum of 2 decimals
paths = paths.replace('clipPath="url(#b)" ', '');
paths = paths.replace(/<path /g, `<path transform="scale(${scale}, ${scale})" `);
}

const fileString = Mustache.render(template, {
paths,
componentName: getComponentName(destPath),
Expand All @@ -141,61 +150,65 @@ async function worker({ svgPath, options, renameFilter, template }) {
}

async function main(options) {
let originalWrite;

options.glob = options.glob || '/**/*.svg';
options.innerPath = options.innerPath || '';
options.renameFilter = options.renameFilter || RENAME_FILTER_DEFAULT;
options.disableLog = options.disableLog || false;

// Disable console.log opt, used for tests
if (options.disableLog) {
originalWrite = process.stdout.write;
process.stdout.write = () => {};
}

rimraf.sync(`${options.outputDir}/*.js`); // Clean old files

let renameFilter = options.renameFilter;
if (typeof renameFilter === 'string') {
/* eslint-disable-next-line global-require, import/no-dynamic-require */
renameFilter = require(renameFilter).default;
}
if (typeof renameFilter !== 'function') {
throw Error('renameFilter must be a function');
}
const exists1 = await fse.exists(options.outputDir);
if (!exists1) {
await fse.mkdir(options.outputDir);
}

const [svgPaths, template] = await Promise.all([
globAsync(path.join(options.svgDir, options.glob)),
fse.readFile(path.join(__dirname, 'templateSvgIcon.js'), {
encoding: 'utf8',
}),
]);

const queue = new Queue(
svgPath => {
return worker({
svgPath,
options,
renameFilter,
template,
});
},
{ concurrency: 4 },
);

queue.push(svgPaths);
await queue.wait({ empty: true });

await generateIndex(options);

if (options.disableLog) {
// bring back stdout
process.stdout.write = originalWrite;
try {
let originalWrite;

options.glob = options.glob || '/**/*.svg';
options.innerPath = options.innerPath || '';
options.renameFilter = options.renameFilter || RENAME_FILTER_DEFAULT;
options.disableLog = options.disableLog || false;

// Disable console.log opt, used for tests
if (options.disableLog) {
originalWrite = process.stdout.write;
process.stdout.write = () => {};
}

rimraf.sync(`${options.outputDir}/*.js`); // Clean old files

let renameFilter = options.renameFilter;
if (typeof renameFilter === 'string') {
/* eslint-disable-next-line global-require, import/no-dynamic-require */
renameFilter = require(renameFilter).default;
}
if (typeof renameFilter !== 'function') {
throw Error('renameFilter must be a function');
}
const exists1 = await fse.exists(options.outputDir);
if (!exists1) {
await fse.mkdir(options.outputDir);
}

const [svgPaths, template] = await Promise.all([
globAsync(path.join(options.svgDir, options.glob)),
fse.readFile(path.join(__dirname, 'templateSvgIcon.js'), {
encoding: 'utf8',
}),
]);

const queue = new Queue(
svgPath => {
return worker({
svgPath,
options,
renameFilter,
template,
});
},
{ concurrency: 8 },
);

queue.push(svgPaths);
await queue.wait({ empty: true });

await generateIndex(options);

if (options.disableLog) {
// bring back stdout
process.stdout.write = originalWrite;
}
} catch (err) {
console.log(err);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/material-ui-icons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"test:unit": "cd ../../ && ./node_modules/.bin/cross-env NODE_ENV=test ./node_modules/.bin/mocha packages/material-ui-icons/{,**/}*.test.js",
"test:watch": "yarn test:unit --watch",
"src:download": "cd ../../ && ./node_modules/.bin/babel-node packages/material-ui-icons/scripts/download.js",
"src:icons": "cd ../../ && node_modules/.bin/babel-node packages/material-ui-icons/builder.js --output-dir packages/material-ui-icons/src --svg-dir packages/material-ui-icons/material-io-tools-icons --glob '/**/*_24px.svg' --renameFilter ./renameFilters/material-design-icons.js",
"src:icons": "cd ../../ && UV_THREADPOOL_SIZE=64 node_modules/.bin/babel-node packages/material-ui-icons/builder.js --output-dir packages/material-ui-icons/src --svg-dir packages/material-ui-icons/material-io-tools-icons --renameFilter ./renameFilters/material-design-icons.js",
"prebuild": "../../node_modules/.bin/rimraf material-design-icons && ../../node_modules/.bin/rimraf build",
"build:es2015": "../../node_modules/.bin/cross-env NODE_ENV=production ../../node_modules/.bin/babel ./src --out-dir ./build",
"build:es2015modules": "../../node_modules/.bin/cross-env NODE_ENV=production BABEL_ENV=modules ../../node_modules/.bin/babel ./src/index.js --out-file ./build/index.es.js",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ function myDestRewriter(svgPathObj: Object) {

fileName = fileName
.slice(3)
.replace('_24px.svg', '.js')
.replace(/_([0-9]+)px\.svg/, '.js')
.replace(/(^.)|(_)(.)/g, (match, p1, p2, p3) => (p1 || p3).toUpperCase());

if (fileName.indexOf('3dRotation') === 0) {
Expand Down
38 changes: 8 additions & 30 deletions packages/material-ui-icons/scripts/download.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,41 +16,19 @@ const themeMap = {
sharp: '_sharp',
};

// Some icons have different sizes.
const sizes = {
cast_for_education: {
baseline: 48,
},
domain: {
baseline: 48,
},
play_circle_filled_white: {
baseline: 48,
},
settings: {
baseline: 20,
},
star_rate: {
baseline: 18,
outline: 18,
round: 18,
twotone: 18,
sharp: 18,
},
weekend: {
baseline: 48,
},
};

function downloadIcon(icon) {
console.log(`downloadIcon ${icon.index}: ${icon.id}`);

return Promise.all(
Object.keys(themeMap).map(async theme => {
const size = sizes[icon.id] && sizes[icon.id][theme] ? sizes[icon.id][theme] : 24;
const response = await fetch(
`https://material.io/tools/icons/static/icons/${theme}-${icon.id}-${size}px.svg`,
);
let endUrl;
if (icon.imageUrls && icon.imageUrls[theme]) {
endUrl = icon.imageUrls[theme];
} else {
endUrl = `${theme}-${icon.id}-24px.svg`;
}
const size = endUrl.match(/^.*-([0-9]+)px.svg$/)[1];
const response = await fetch(`https://material.io/tools/icons/static/icons/${endUrl}`);
if (response.status !== 200) {
throw new Error(`status ${response.status}`);
}
Expand Down
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/CastForEducation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(0.5, 0.5)" d="M42 6H6c-2.2 0-4 1.8-4 4v6h4v-6h36v28H28v4h14c2.2 0 4-1.8 4-4V10c0-2.2-1.8-4-4-4zM2 36v6h6c0-3.32-2.68-6-6-6zm0-8v4c5.52 0 10 4.48 10 10h4c0-7.74-6.26-14-14-14zm0-8v4c9.94 0 18 8.06 18 18h4c0-12.16-9.86-22-22-22zm20 2.18v4L29 30l7-3.82v-4L29 26l-7-3.82zM29 12l-11 6 11 6 11-6-11-6z" /><path transform="scale(0.5, 0.5)" fill="none" d="M0 0h48v48H0z" /></React.Fragment>
, 'CastForEducation');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/Domain.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(0.5, 0.5)" fill="none" d="M0 0h48v48H0z" /><path transform="scale(0.5, 0.5)" d="M24 14V6H4v36h40V14H24zM12 38H8v-4h4v4zm0-8H8v-4h4v4zm0-8H8v-4h4v4zm0-8H8v-4h4v4zm8 24h-4v-4h4v4zm0-8h-4v-4h4v4zm0-8h-4v-4h4v4zm0-8h-4v-4h4v4zm20 24H24v-4h4v-4h-4v-4h4v-4h-4v-4h16v20zm-4-16h-4v4h4v-4zm0 8h-4v4h4v-4z" /></React.Fragment>
, 'Domain');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/PlayCircleFilledWhite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(0.5, 0.5)" fill="none" d="M0 0h48v48H0z" /><path transform="scale(0.5, 0.5)" d="M24 4C12.95 4 4 12.95 4 24s8.95 20 20 20 20-8.95 20-20S35.05 4 24 4zm-4 29V15l12 9-12 9z" /></React.Fragment>
, 'PlayCircleFilledWhite');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/Settings.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/StarRate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(1.33, 1.33)" d="M9 11.3l3.71 2.7-1.42-4.36L15 7h-4.55L9 2.5 7.55 7H3l3.71 2.64L5.29 14z" /><path transform="scale(1.33, 1.33)" fill="none" d="M0 0h18v18H0z" /></React.Fragment>
, 'StarRate');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/StarRateOutlined.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(1.33, 1.33)" fill="none" d="M0 0h18v18H0V0z" /><path transform="scale(1.33, 1.33)" d="M9 11.3l3.71 2.7-1.42-4.36L15 7h-4.55L9 2.5 7.55 7H3l3.71 2.64L5.29 14 9 11.3z" /></React.Fragment>
, 'StarRateOutlined');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/StarRateRounded.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(1.33, 1.33)" fill="none" d="M0 0h18v18H0V0z" /><path transform="scale(1.33, 1.33)" d="M9 11.3l2.46 1.79c.39.29.92-.1.77-.56l-.94-2.89 2.43-1.73c.4-.28.2-.91-.29-.91h-2.98l-.97-3.02c-.15-.46-.8-.46-.95 0L7.55 7H4.57c-.49 0-.69.63-.29.91l2.43 1.73-.94 2.89c-.15.46.38.84.77.56L9 11.3z" /></React.Fragment>
, 'StarRateRounded');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/StarRateSharp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(1.33, 1.33)" fill="none" d="M0 0h18v18H0V0z" /><path transform="scale(1.33, 1.33)" d="M9 11.3l3.71 2.7-1.42-4.36L15 7h-4.55L9 2.5 7.55 7H3l3.71 2.64L5.29 14 9 11.3z" /></React.Fragment>
, 'StarRateSharp');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/StarRateTwoTone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><path transform="scale(1.33, 1.33)" fill="none" d="M0 0h18v18H0V0z" /><path transform="scale(1.33, 1.33)" d="M9 11.3l3.71 2.7-1.42-4.36L15 7h-4.55L9 2.5 7.55 7H3l3.71 2.64L5.29 14 9 11.3z" /></React.Fragment>
, 'StarRateTwoTone');
6 changes: 6 additions & 0 deletions packages/material-ui-icons/src/Weekend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from 'react';
import createSvgIcon from './utils/createSvgIcon';

export default createSvgIcon(
<React.Fragment><defs><path transform="scale(0.5, 0.5)" id="a" d="M0 0h48v48H0z" /></defs><clipPath id="b"><use overflow="visible" xlinkHref="#a" /></clipPath><path transform="scale(0.5, 0.5)" d="M42 20c-2.21 0-4 1.79-4 4v6H10v-6c0-2.21-1.79-4-4-4s-4 1.79-4 4v10c0 2.2 1.8 4 4 4h36c2.2 0 4-1.8 4-4V24c0-2.21-1.79-4-4-4zm-6-10H12c-2.2 0-4 1.8-4 4v4.31c2.32.83 4 3.03 4 5.63V28h24v-4.06c0-2.6 1.68-4.8 4-5.63V14c0-2.2-1.8-4-4-4z" /></React.Fragment>
, 'Weekend');
10 changes: 10 additions & 0 deletions packages/material-ui-icons/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -889,6 +889,7 @@ export { default as CastConnectedOutlined } from './CastConnectedOutlined';
export { default as CastConnectedRounded } from './CastConnectedRounded';
export { default as CastConnectedSharp } from './CastConnectedSharp';
export { default as CastConnectedTwoTone } from './CastConnectedTwoTone';
export { default as CastForEducation } from './CastForEducation';
export { default as CastForEducationOutlined } from './CastForEducationOutlined';
export { default as CastForEducationRounded } from './CastForEducationRounded';
export { default as CastForEducationSharp } from './CastForEducationSharp';
Expand Down Expand Up @@ -1397,6 +1398,7 @@ export { default as DockOutlined } from './DockOutlined';
export { default as DockRounded } from './DockRounded';
export { default as DockSharp } from './DockSharp';
export { default as DockTwoTone } from './DockTwoTone';
export { default as Domain } from './Domain';
export { default as DomainDisabled } from './DomainDisabled';
export { default as DomainDisabledOutlined } from './DomainDisabledOutlined';
export { default as DomainDisabledRounded } from './DomainDisabledRounded';
Expand Down Expand Up @@ -3530,6 +3532,7 @@ export { default as PlayCircleFilledOutlined } from './PlayCircleFilledOutlined'
export { default as PlayCircleFilledRounded } from './PlayCircleFilledRounded';
export { default as PlayCircleFilledSharp } from './PlayCircleFilledSharp';
export { default as PlayCircleFilledTwoTone } from './PlayCircleFilledTwoTone';
export { default as PlayCircleFilledWhite } from './PlayCircleFilledWhite';
export { default as PlayCircleFilledWhiteOutlined } from './PlayCircleFilledWhiteOutlined';
export { default as PlayCircleFilledWhiteRounded } from './PlayCircleFilledWhiteRounded';
export { default as PlayCircleFilledWhiteSharp } from './PlayCircleFilledWhiteSharp';
Expand Down Expand Up @@ -4009,6 +4012,7 @@ export { default as SentimentVerySatisfiedOutlined } from './SentimentVerySatisf
export { default as SentimentVerySatisfiedRounded } from './SentimentVerySatisfiedRounded';
export { default as SentimentVerySatisfiedSharp } from './SentimentVerySatisfiedSharp';
export { default as SentimentVerySatisfiedTwoTone } from './SentimentVerySatisfiedTwoTone';
export { default as Settings } from './Settings';
export { default as SettingsApplications } from './SettingsApplications';
export { default as SettingsApplicationsOutlined } from './SettingsApplicationsOutlined';
export { default as SettingsApplicationsRounded } from './SettingsApplicationsRounded';
Expand Down Expand Up @@ -4380,6 +4384,11 @@ export { default as StarHalfRounded } from './StarHalfRounded';
export { default as StarHalfSharp } from './StarHalfSharp';
export { default as StarHalfTwoTone } from './StarHalfTwoTone';
export { default as StarOutlined } from './StarOutlined';
export { default as StarRate } from './StarRate';
export { default as StarRateOutlined } from './StarRateOutlined';
export { default as StarRateRounded } from './StarRateRounded';
export { default as StarRateSharp } from './StarRateSharp';
export { default as StarRateTwoTone } from './StarRateTwoTone';
export { default as StarRounded } from './StarRounded';
export { default as Stars } from './Stars';
export { default as StarSharp } from './StarSharp';
Expand Down Expand Up @@ -5128,6 +5137,7 @@ export { default as WebOutlined } from './WebOutlined';
export { default as WebRounded } from './WebRounded';
export { default as WebSharp } from './WebSharp';
export { default as WebTwoTone } from './WebTwoTone';
export { default as Weekend } from './Weekend';
export { default as WeekendOutlined } from './WeekendOutlined';
export { default as WeekendRounded } from './WeekendRounded';
export { default as WeekendSharp } from './WeekendSharp';
Expand Down

0 comments on commit b10615b

Please sign in to comment.