From 81ed4ee001c4bfab880028cc1561ed130e8fc330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Maneiro?= Date: Mon, 5 Mar 2018 16:39:49 +0100 Subject: [PATCH 01/36] Write to build/ every JSX component separately --- grunt-tasks/svg-to-react.js | 12 ++ .../index-footer-individual-component.jsx | 4 + .../index-header-individual-component.jsx | 150 ++++++++++++++++++ 3 files changed, 166 insertions(+) create mode 100644 sources/react/index-footer-individual-component.jsx create mode 100644 sources/react/index-header-individual-component.jsx diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index 70d5b847..92746b49 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -32,6 +32,18 @@ module.exports = function( grunt ) { name = name.replace( 'gridicons-', '' ); componentExample += ' \n'; + // Prepare and write to disk every individual component separately + var individualComponent = + grunt.file.read( + 'sources/react/index-header-individual-component.jsx', + ) + + ' svg = ' + + fileContent + + ';\n' + + grunt.file.read( + 'sources/react/index-footer-individual-component.jsx', + ); + grunt.file.write(files.dest + name + '.jsx', individualComponent); } ); diff --git a/sources/react/index-footer-individual-component.jsx b/sources/react/index-footer-individual-component.jsx new file mode 100644 index 00000000..960512db --- /dev/null +++ b/sources/react/index-footer-individual-component.jsx @@ -0,0 +1,4 @@ + + return ( svg ); + } +} diff --git a/sources/react/index-header-individual-component.jsx b/sources/react/index-header-individual-component.jsx new file mode 100644 index 00000000..a4e59ffe --- /dev/null +++ b/sources/react/index-header-individual-component.jsx @@ -0,0 +1,150 @@ +/** @ssr-ready **/ + +/* !!! +IF YOU ARE EDITING gridicon/index.jsx +THEN YOU ARE EDITING A FILE THAT GETS OUTPUT FROM THE GRIDICONS REPO! +DO NOT EDIT THAT FILE! EDIT index-header.jsx and index-footer.jsx instead +OR if you're looking to change now SVGs get output, you'll need to edit strings in the Gruntfile :) +!!! */ + +/** + * External dependencies + */ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; + +export default class Gridicon extends PureComponent { + + static defaultProps = { + size: 24 + }; + + static propTypes = { + icon: PropTypes.string.isRequired, + size: PropTypes.number, + onClick: PropTypes.func, + className: PropTypes.string + }; + + needsOffset( icon, size ) { + const iconNeedsOffset = [ + 'gridicons-add-outline', + 'gridicons-add', + 'gridicons-align-image-center', + 'gridicons-align-image-left', + 'gridicons-align-image-none', + 'gridicons-align-image-right', + 'gridicons-attachment', + 'gridicons-bold', + 'gridicons-bookmark-outline', + 'gridicons-bookmark', + 'gridicons-calendar', + 'gridicons-cart', + 'gridicons-create', + 'gridicons-custom-post-type', + 'gridicons-external', + 'gridicons-folder', + 'gridicons-heading', + 'gridicons-help-outline', + 'gridicons-help', + 'gridicons-history', + 'gridicons-info-outline', + 'gridicons-info', + 'gridicons-italic', + 'gridicons-layout-blocks', + 'gridicons-link-break', + 'gridicons-link', + 'gridicons-list-checkmark', + 'gridicons-list-ordered', + 'gridicons-list-unordered', + 'gridicons-menus', + 'gridicons-minus', + 'gridicons-my-sites', + 'gridicons-notice-outline', + 'gridicons-notice', + 'gridicons-plus-small', + 'gridicons-plus', + 'gridicons-popout', + 'gridicons-posts', + 'gridicons-scheduled', + 'gridicons-share-ios', + 'gridicons-star-outline', + 'gridicons-star', + 'gridicons-stats', + 'gridicons-status', + 'gridicons-thumbs-up', + 'gridicons-textcolor', + 'gridicons-time', + 'gridicons-trophy', + 'gridicons-user-circle', + 'gridicons-reader-follow', + 'gridicons-reader-following' + ]; + + if ( iconNeedsOffset.indexOf( icon ) >= 0 ) { + return ( size % 18 === 0 ); + } + return false; + } + + needsOffsetX( icon, size ) { + const iconNeedsOffsetX = [ + 'gridicons-arrow-down', + 'gridicons-arrow-up', + 'gridicons-comment', + 'gridicons-clear-formatting', + 'gridicons-flag', + 'gridicons-menu', + 'gridicons-reader', + 'gridicons-strikethrough' + ]; + + if ( iconNeedsOffsetX.indexOf( icon ) >= 0 ) { + return ( size % 18 === 0 ); + } + return false; + } + + needsOffsetY( icon, size ) { + const iconNeedsOffsetY = [ + 'gridicons-align-center', + 'gridicons-align-justify', + 'gridicons-align-left', + 'gridicons-align-right', + 'gridicons-arrow-left', + 'gridicons-arrow-right', + 'gridicons-house', + 'gridicons-indent-left', + 'gridicons-indent-right', + 'gridicons-minus-small', + 'gridicons-print', + 'gridicons-sign-out', + 'gridicons-stats-alt', + 'gridicons-trash', + 'gridicons-underline', + 'gridicons-video-camera' + ]; + + if ( iconNeedsOffsetY.indexOf( icon ) >= 0 ) { + return ( size % 18 === 0 ); + } + return false; + } + + render() { + const { size, onClick, icon: iconProp, className, ...otherProps } = this.props; + const icon = 'gridicons-' + iconProp; + const needsOffset = this.needsOffset( icon, size ); + const needsOffsetX = this.needsOffsetX( icon, size ); + const needsOffsetY = this.needsOffsetY( icon, size ); + + let svg; + + const iconClass = [ + 'gridicon', + icon, + className, + needsOffset ? 'needs-offset' : false, + needsOffsetX ? 'needs-offset-x' : false, + needsOffsetY ? 'needs-offset-y' : false, + ].filter( Boolean ).join( ' ' ); From d27ab4e62e34fa76f2aabebf141282d3a7fc471e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Maneiro?= Date: Tue, 6 Mar 2018 09:22:09 +0100 Subject: [PATCH 02/36] Teach babel to process every JSX in build --- Gruntfile.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 2c352428..1cf13882 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -98,10 +98,14 @@ module.exports = function( grunt ) { ] }, dist: { - files: { - "build/index.js": "build/index.jsx", - "build/example.js": "build/example.jsx" - } + files: [{ + expand: true, + cwd: 'build/', + src: [ '**/*.jsx' ], + dest: 'build/', + ext: '.js', + filter: 'isFile' + }] } }, From 6946b708ce1a39b1a64134c6e796153ba57c2016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Maneiro?= Date: Tue, 6 Mar 2018 09:46:54 +0100 Subject: [PATCH 03/36] Allow individual icons to be imported by gridicons/icon To make this possible: import GridiconExternal from 'gridicons/external'; we need to publish the individual icons in the root of our npm package. This also changes how do we tell npm which files to include from whitelisting (using the files prop in package.json) to blacklisting (using the .npmignore file). The reason for that is that I've tried to whitelist every individual icon by setting the files prop to "*.js" and then blacklist only the Gruntfile.js within .npmignore. It seems that in case of conflict the files prop takes precedence over .npmignore, so the Gruntfile.js was still included. --- .npmignore | 12 ++++++++++++ package.json | 6 +----- 2 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 .npmignore diff --git a/.npmignore b/.npmignore new file mode 100644 index 00000000..404aa123 --- /dev/null +++ b/.npmignore @@ -0,0 +1,12 @@ +.github/ +.idea/ +build/ +docs/ +grunt-tasks/ +pdf/ +php/ +sources/ +svg-min/ +svg-min-react/ +svg-sprite/ +Gruntfile.js diff --git a/package.json b/package.json index 302daa0d..ac21f6e4 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "main": "build/index.js", "scripts": { "build": "grunt --verbose", - "prepublish": "npm run build" + "prepublish": "npm run build && cp build/*.js ." }, "peerDependencies": { "react": "^15.3.0 || ^16.0.0 " @@ -14,10 +14,6 @@ "url": "https://github.com/Automattic/gridicons" }, "license": "GPL-2.0+", - "files": [ - "build/index.js", - "build/example.js" - ], "dependencies": { "prop-types": "^15.5.7" }, From e7b114c029e6d1fc889478aec9a015bb21b410fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Maneiro?= Date: Tue, 6 Mar 2018 11:07:50 +0100 Subject: [PATCH 04/36] Rename build/ to react-icons/ Note that this is necessary to prevent the build/ folder to be included in the npm package. For some reason, although the build/ folder was blacklisted in the .npmignore, it was not excluded from the package. https://docs.npmjs.com/misc/developers#keeping-files-out-of-your-package The docs don't mention the build/ folder as one of the always included directories, though. --- .gitignore | 2 +- .npmignore | 2 +- Gruntfile.js | 6 +++--- package.json | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 202af42e..4d500e10 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,5 @@ node_modules/ /npm-debug.log .idea/ svg-min-react/ -build/ +react-icons/ .DS_Store diff --git a/.npmignore b/.npmignore index 404aa123..abc29743 100644 --- a/.npmignore +++ b/.npmignore @@ -1,11 +1,11 @@ .github/ .idea/ -build/ docs/ grunt-tasks/ pdf/ php/ sources/ +react-icons/ svg-min/ svg-min-react/ svg-sprite/ diff --git a/Gruntfile.js b/Gruntfile.js index 1cf13882..cb1af1c5 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -100,9 +100,9 @@ module.exports = function( grunt ) { dist: { files: [{ expand: true, - cwd: 'build/', + cwd: 'react-icons/', src: [ '**/*.jsx' ], - dest: 'build/', + dest: 'react-icons/', ext: '.js', filter: 'isFile' }] @@ -147,7 +147,7 @@ module.exports = function( grunt ) { cwd: 'svg-min-react/', src: [ '**/*.svg' ], filter: 'isFile', - dest: 'build/' + dest: 'react-icons/' }] } }, diff --git a/package.json b/package.json index ac21f6e4..727794f4 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "main": "build/index.js", "scripts": { "build": "grunt --verbose", - "prepublish": "npm run build && cp build/*.js ." + "prepublish": "npm run build && cp react-icons/*.js ." }, "peerDependencies": { "react": "^15.3.0 || ^16.0.0 " From 5fbbef9dbc7c92fa7f5f27e99c275f4cbf4eaea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Maneiro?= Date: Tue, 6 Mar 2018 12:43:45 +0100 Subject: [PATCH 05/36] Add the gridicon-iconname class to every component --- grunt-tasks/svg-to-react.js | 5 ++--- .../index-footer-individual-component.jsx | 11 ++++++++++ .../index-header-individual-component.jsx | 20 +++---------------- 3 files changed, 16 insertions(+), 20 deletions(-) diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index 92746b49..04900c2f 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -37,9 +37,8 @@ module.exports = function( grunt ) { grunt.file.read( 'sources/react/index-header-individual-component.jsx', ) + - ' svg = ' + - fileContent + - ';\n' + + ' const icon = \'gridicons-' + name + '\';\n' + + ' const svg = ' + fileContent + ';\n' + grunt.file.read( 'sources/react/index-footer-individual-component.jsx', ); diff --git a/sources/react/index-footer-individual-component.jsx b/sources/react/index-footer-individual-component.jsx index 960512db..d17553be 100644 --- a/sources/react/index-footer-individual-component.jsx +++ b/sources/react/index-footer-individual-component.jsx @@ -1,3 +1,14 @@ + const needsOffset = this.needsOffset( icon, size ); + const needsOffsetX = this.needsOffsetX( icon, size ); + const needsOffsetY = this.needsOffsetY( icon, size ); + const iconClass = [ + 'gridicon', + icon, + className, + needsOffset ? 'needs-offset' : false, + needsOffsetX ? 'needs-offset-x' : false, + needsOffsetY ? 'needs-offset-y' : false, + ].filter( Boolean ).join( ' ' ); return ( svg ); } diff --git a/sources/react/index-header-individual-component.jsx b/sources/react/index-header-individual-component.jsx index a4e59ffe..1d903e40 100644 --- a/sources/react/index-header-individual-component.jsx +++ b/sources/react/index-header-individual-component.jsx @@ -20,7 +20,6 @@ export default class Gridicon extends PureComponent { }; static propTypes = { - icon: PropTypes.string.isRequired, size: PropTypes.number, onClick: PropTypes.func, className: PropTypes.string @@ -132,19 +131,6 @@ export default class Gridicon extends PureComponent { } render() { - const { size, onClick, icon: iconProp, className, ...otherProps } = this.props; - const icon = 'gridicons-' + iconProp; - const needsOffset = this.needsOffset( icon, size ); - const needsOffsetX = this.needsOffsetX( icon, size ); - const needsOffsetY = this.needsOffsetY( icon, size ); - - let svg; - - const iconClass = [ - 'gridicon', - icon, - className, - needsOffset ? 'needs-offset' : false, - needsOffsetX ? 'needs-offset-x' : false, - needsOffsetY ? 'needs-offset-y' : false, - ].filter( Boolean ).join( ' ' ); + // We don't want the icon prop in to otherProps, as we'll pass those to the svg component. + // That's why we destructure it from the props but not use it. + const { size, onClick, icon: iconProp, className, ...otherProps } = this.props; From a82adb328e5bf6179865603cdaccf7bc1edc1211 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Maneiro?= Date: Tue, 6 Mar 2018 12:50:49 +0100 Subject: [PATCH 06/36] Shrink icons by using a function instead of React.PureComponent By using a function instead of React.PureComponent the transpiled icon is 1,5K smaller. Most individual components are between 4K and 5K, so this change means a ~30% size reduction. --- grunt-tasks/svg-to-react.js | 4 +-- .../index-footer-individual-component.jsx | 25 +++++++------ .../index-header-individual-component.jsx | 35 ++++++++----------- 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index 04900c2f..4569181c 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -37,8 +37,8 @@ module.exports = function( grunt ) { grunt.file.read( 'sources/react/index-header-individual-component.jsx', ) + - ' const icon = \'gridicons-' + name + '\';\n' + - ' const svg = ' + fileContent + ';\n' + + ' const icon = \'gridicons-' + name + '\';\n' + + ' const svg = ' + fileContent + ';\n' + grunt.file.read( 'sources/react/index-footer-individual-component.jsx', ); diff --git a/sources/react/index-footer-individual-component.jsx b/sources/react/index-footer-individual-component.jsx index d17553be..35b34eed 100644 --- a/sources/react/index-footer-individual-component.jsx +++ b/sources/react/index-footer-individual-component.jsx @@ -1,15 +1,14 @@ - const needsOffset = this.needsOffset( icon, size ); - const needsOffsetX = this.needsOffsetX( icon, size ); - const needsOffsetY = this.needsOffsetY( icon, size ); - const iconClass = [ - 'gridicon', - icon, - className, - needsOffset ? 'needs-offset' : false, - needsOffsetX ? 'needs-offset-x' : false, - needsOffsetY ? 'needs-offset-y' : false, - ].filter( Boolean ).join( ' ' ); + const needsOffset = calculateNeedsOffset( icon, size ); + const needsOffsetX = calculateNeedsOffsetX( icon, size ); + const needsOffsetY = calculateNeedsOffsetY( icon, size ); + const iconClass = [ + 'gridicon', + icon, + className, + needsOffset ? 'needs-offset' : false, + needsOffsetX ? 'needs-offset-x' : false, + needsOffsetY ? 'needs-offset-y' : false, + ].filter( Boolean ).join( ' ' ); - return ( svg ); - } + return ( svg ); } diff --git a/sources/react/index-header-individual-component.jsx b/sources/react/index-header-individual-component.jsx index 1d903e40..25387a1f 100644 --- a/sources/react/index-header-individual-component.jsx +++ b/sources/react/index-header-individual-component.jsx @@ -10,22 +10,20 @@ OR if you're looking to change now SVGs get output, you'll need to edit strings /** * External dependencies */ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; +import React from 'react'; -export default class Gridicon extends PureComponent { +// We don't want the icon prop in to otherProps, +// as we'll pass those to the svg component. +// That's why we destructure it from the props but not use it. +export default function({ + size = 24, + onClick, + icon: iconProp, + className, + ...otherProps +}){ - static defaultProps = { - size: 24 - }; - - static propTypes = { - size: PropTypes.number, - onClick: PropTypes.func, - className: PropTypes.string - }; - - needsOffset( icon, size ) { + const calculateNeedsOffset = ( icon, size ) => { const iconNeedsOffset = [ 'gridicons-add-outline', 'gridicons-add', @@ -86,7 +84,7 @@ export default class Gridicon extends PureComponent { return false; } - needsOffsetX( icon, size ) { + const calculateNeedsOffsetX = ( icon, size ) => { const iconNeedsOffsetX = [ 'gridicons-arrow-down', 'gridicons-arrow-up', @@ -104,7 +102,7 @@ export default class Gridicon extends PureComponent { return false; } - needsOffsetY( icon, size ) { + const calculateNeedsOffsetY = ( icon, size ) => { const iconNeedsOffsetY = [ 'gridicons-align-center', 'gridicons-align-justify', @@ -129,8 +127,3 @@ export default class Gridicon extends PureComponent { } return false; } - - render() { - // We don't want the icon prop in to otherProps, as we'll pass those to the svg component. - // That's why we destructure it from the props but not use it. - const { size, onClick, icon: iconProp, className, ...otherProps } = this.props; From b32bf60e3e0fbdb1c1b4affd1d3a1762da9eb858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Maneiro?= Date: Tue, 6 Mar 2018 13:35:16 +0100 Subject: [PATCH 07/36] Add classes to SVG --- grunt-tasks/svg-to-react.js | 26 ++++++++++++------- .../index-footer-individual-component.jsx | 14 ---------- 2 files changed, 17 insertions(+), 23 deletions(-) delete mode 100644 sources/react/index-footer-individual-component.jsx diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index 4569181c..4f4b3b78 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -34,15 +34,23 @@ module.exports = function( grunt ) { // Prepare and write to disk every individual component separately var individualComponent = - grunt.file.read( - 'sources/react/index-header-individual-component.jsx', - ) + - ' const icon = \'gridicons-' + name + '\';\n' + - ' const svg = ' + fileContent + ';\n' + - grunt.file.read( - 'sources/react/index-footer-individual-component.jsx', - ); - grunt.file.write(files.dest + name + '.jsx', individualComponent); + grunt.file.read( 'sources/react/index-header-individual-component.jsx' ) + + `const icon = 'gridicons-${ name }'; +const needsOffset = calculateNeedsOffset( icon, size ); +const needsOffsetX = calculateNeedsOffsetX( icon, size ); +const needsOffsetY = calculateNeedsOffsetY( icon, size ); +const iconClass = [ + 'gridicon', + icon, + className, + needsOffset ? 'needs-offset' : false, + needsOffsetX ? 'needs-offset-x' : false, + needsOffsetY ? 'needs-offset-y' : false, +].filter( Boolean ).join( ' ' ); + +return (${ fileContent }); +}`; + grunt.file.write( files.dest + name + '.jsx', individualComponent ); } ); diff --git a/sources/react/index-footer-individual-component.jsx b/sources/react/index-footer-individual-component.jsx deleted file mode 100644 index 35b34eed..00000000 --- a/sources/react/index-footer-individual-component.jsx +++ /dev/null @@ -1,14 +0,0 @@ - const needsOffset = calculateNeedsOffset( icon, size ); - const needsOffsetX = calculateNeedsOffsetX( icon, size ); - const needsOffsetY = calculateNeedsOffsetY( icon, size ); - const iconClass = [ - 'gridicon', - icon, - className, - needsOffset ? 'needs-offset' : false, - needsOffsetX ? 'needs-offset-x' : false, - needsOffsetY ? 'needs-offset-y' : false, - ].filter( Boolean ).join( ' ' ); - - return ( svg ); -} From a9010c937f93b56596c99721b2a78f5fefa967db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 11:04:51 +0100 Subject: [PATCH 08/36] Use cjs and esm folders to publish the icons The idea is that we want to prepare Gridicons to be able to distribute both CommonJS and ECMAScript Modules. Initially, the idea was to use the directory root to publish the CJS modules so others could: import external from 'gridicons/external'; The main disadvantage of that approach is that, in the future, when ECMAScript modules become more common that namespaced will be taken by the CommonJS modules and we won't be able to change that if we want to be backwards-compatible. So, instead, the approach we're taking is being agnostic about what module system the library user wants to use by default. So, either: import external from 'gridicons/cjs/external'; import external from 'gridicons/esm/external'; will work. --- .npmignore | 12 ------------ Gruntfile.js | 6 +++--- package.json | 7 +++++-- 3 files changed, 8 insertions(+), 17 deletions(-) delete mode 100644 .npmignore diff --git a/.npmignore b/.npmignore deleted file mode 100644 index abc29743..00000000 --- a/.npmignore +++ /dev/null @@ -1,12 +0,0 @@ -.github/ -.idea/ -docs/ -grunt-tasks/ -pdf/ -php/ -sources/ -react-icons/ -svg-min/ -svg-min-react/ -svg-sprite/ -Gruntfile.js diff --git a/Gruntfile.js b/Gruntfile.js index cb1af1c5..3fc6ff37 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -100,9 +100,9 @@ module.exports = function( grunt ) { dist: { files: [{ expand: true, - cwd: 'react-icons/', + cwd: 'esm/', src: [ '**/*.jsx' ], - dest: 'react-icons/', + dest: 'cjs/', ext: '.js', filter: 'isFile' }] @@ -147,7 +147,7 @@ module.exports = function( grunt ) { cwd: 'svg-min-react/', src: [ '**/*.svg' ], filter: 'isFile', - dest: 'react-icons/' + dest: 'esm/' }] } }, diff --git a/package.json b/package.json index 727794f4..9c6f5154 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,13 @@ { "name": "gridicons", "version": "2.1.3", - "main": "build/index.js", + "main": "cjs/index.js", + "files": [ + "cjs" + ], "scripts": { "build": "grunt --verbose", - "prepublish": "npm run build && cp react-icons/*.js ." + "prepublish": "npm run build" }, "peerDependencies": { "react": "^15.3.0 || ^16.0.0 " From 2c0e26437c4387ba9a15f545c43a9a4fe36c68d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 12:19:59 +0100 Subject: [PATCH 09/36] Convert to templates By creating the files dynamically form a template literal, we're able to centralize the declaration of icons that need offset. --- grunt-tasks/svg-to-react.js | 153 ++++++++++++----- sources/react/example-footer.jsx | 4 - sources/react/index-footer.jsx | 5 - .../index-header-individual-component.jsx | 129 --------------- sources/react/index-header.jsx | 155 ------------------ sources/react/template-all-icons.js | 88 ++++++++++ ...header.jsx => template-devdocs-example.js} | 10 ++ sources/react/template-individual-icon.js | 48 ++++++ 8 files changed, 257 insertions(+), 335 deletions(-) delete mode 100644 sources/react/example-footer.jsx delete mode 100644 sources/react/index-footer.jsx delete mode 100644 sources/react/index-header-individual-component.jsx delete mode 100644 sources/react/index-header.jsx create mode 100644 sources/react/template-all-icons.js rename sources/react/{example-header.jsx => template-devdocs-example.js} (78%) create mode 100644 sources/react/template-individual-icon.js diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index 4f4b3b78..a1c56454 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -3,19 +3,101 @@ module.exports = function( grunt ) { grunt.registerMultiTask( 'svg-to-react', 'Output a react component for SVGs', function() { - var component = ''; - var componentExample = ''; - var filesDest; + let components = ''; + let componentsExample = ''; + let filesDest; + const prepareIndividualIcon = require( '../sources/react/template-individual-icon' ); + const prepareAllIcons = require( '../sources/react/template-all-icons' ); + const prepareDevDocsExample = require( '../sources/react/template-devdocs-example' ); + const iconsThatNeedOffset = [ + 'gridicons-add-outline', + 'gridicons-add', + 'gridicons-align-image-center', + 'gridicons-align-image-left', + 'gridicons-align-image-none', + 'gridicons-align-image-right', + 'gridicons-attachment', + 'gridicons-bold', + 'gridicons-bookmark-outline', + 'gridicons-bookmark', + 'gridicons-calendar', + 'gridicons-cart', + 'gridicons-create', + 'gridicons-custom-post-type', + 'gridicons-external', + 'gridicons-folder', + 'gridicons-heading', + 'gridicons-help-outline', + 'gridicons-help', + 'gridicons-history', + 'gridicons-info-outline', + 'gridicons-info', + 'gridicons-italic', + 'gridicons-layout-blocks', + 'gridicons-link-break', + 'gridicons-link', + 'gridicons-list-checkmark', + 'gridicons-list-ordered', + 'gridicons-list-unordered', + 'gridicons-menus', + 'gridicons-minus', + 'gridicons-my-sites', + 'gridicons-notice-outline', + 'gridicons-notice', + 'gridicons-plus-small', + 'gridicons-plus', + 'gridicons-popout', + 'gridicons-posts', + 'gridicons-scheduled', + 'gridicons-share-ios', + 'gridicons-star-outline', + 'gridicons-star', + 'gridicons-stats', + 'gridicons-status', + 'gridicons-thumbs-up', + 'gridicons-textcolor', + 'gridicons-time', + 'gridicons-trophy', + 'gridicons-user-circle', + 'gridicons-reader-follow', + 'gridicons-reader-following' + ]; + const iconsThatNeedOffsetY = [ + 'gridicons-align-center', + 'gridicons-align-justify', + 'gridicons-align-left', + 'gridicons-align-right', + 'gridicons-arrow-left', + 'gridicons-arrow-right', + 'gridicons-house', + 'gridicons-indent-left', + 'gridicons-indent-right', + 'gridicons-minus-small', + 'gridicons-print', + 'gridicons-sign-out', + 'gridicons-stats-alt', + 'gridicons-trash', + 'gridicons-underline', + 'gridicons-video-camera' + ]; + const iconsThatNeedOffsetX = [ + 'gridicons-arrow-down', + 'gridicons-arrow-up', + 'gridicons-comment', + 'gridicons-clear-formatting', + 'gridicons-flag', + 'gridicons-menu', + 'gridicons-reader', + 'gridicons-strikethrough' + ]; - // Create a switch() case for each svg file this.files.forEach( function( files ) { files.src.forEach( function( svgFile ) { - // Clean up the filename to use for the react components - var name = svgFile.split( '.' ); - name = name[0]; + // Name to be used by the react components + let name = svgFile.split( '.' )[ 0 ]; // Grab the relevant bits from the file contents - var fileContent = grunt.file.read( files.cwd + svgFile ); + let fileContent = grunt.file.read( files.cwd + svgFile ); // Add className, height, and width to the svg element fileContent = fileContent.slice( 0, 4 ) + @@ -23,51 +105,38 @@ module.exports = function( grunt ) { fileContent.slice( 4, -6 ) + fileContent.slice( -6 ); - // Output the case for each icon - component += " case '" + name + "':\n" + + // Holds the switch's cases for every icon + components += " case '" + name + "':\n" + " svg = " + fileContent + ";\n" + " break;\n";; - // Example Document + // Holds the Example Document name = name.replace( 'gridicons-', '' ); - componentExample += ' \n'; + componentsExample += ' \n'; - // Prepare and write to disk every individual component separately - var individualComponent = - grunt.file.read( 'sources/react/index-header-individual-component.jsx' ) + - `const icon = 'gridicons-${ name }'; -const needsOffset = calculateNeedsOffset( icon, size ); -const needsOffsetX = calculateNeedsOffsetX( icon, size ); -const needsOffsetY = calculateNeedsOffsetY( icon, size ); -const iconClass = [ - 'gridicon', - icon, - className, - needsOffset ? 'needs-offset' : false, - needsOffsetX ? 'needs-offset-x' : false, - needsOffsetY ? 'needs-offset-y' : false, -].filter( Boolean ).join( ' ' ); - -return (${ fileContent }); -}`; - grunt.file.write( files.dest + name + '.jsx', individualComponent ); + // Prepare and write to disk every individual icon separately + grunt.file.write( files.dest + name + '.jsx', prepareIndividualIcon( { + name, + component: fileContent, + iconsThatNeedOffset, + iconsThatNeedOffsetX, + iconsThatNeedOffsetY, + } ) ); } ); filesDest = files.dest; } ); - // React Component Wrapping - component = grunt.file.read( 'sources/react/index-header.jsx' ) + component; - component += grunt.file.read( 'sources/react/index-footer.jsx' ); - - // Design Docs Wrapping - componentExample = grunt.file.read( 'sources/react/example-header.jsx' ) + componentExample; - componentExample += grunt.file.read( 'sources/react/example-footer.jsx' ); - + // Prepare and write to disk the Design Docs Example component + grunt.file.write( filesDest + 'example.jsx', prepareDevDocsExample( componentsExample ) ); - // Write the React component to gridicon/index.jsx - grunt.file.write( filesDest + 'index.jsx', component ); - grunt.file.write( filesDest + 'example.jsx', componentExample ); + // Prepare and write to disk the Gridicon React component + grunt.file.write( filesDest + 'index.jsx', prepareAllIcons( { + components, + iconsThatNeedOffset, + iconsThatNeedOffsetX, + iconsThatNeedOffsetY, + } ) ); } ); }; diff --git a/sources/react/example-footer.jsx b/sources/react/example-footer.jsx deleted file mode 100644 index d9ffa026..00000000 --- a/sources/react/example-footer.jsx +++ /dev/null @@ -1,4 +0,0 @@ - - ); - } -} diff --git a/sources/react/index-footer.jsx b/sources/react/index-footer.jsx deleted file mode 100644 index 2bd5cb66..00000000 --- a/sources/react/index-footer.jsx +++ /dev/null @@ -1,5 +0,0 @@ - } - - return ( svg ); - } -} diff --git a/sources/react/index-header-individual-component.jsx b/sources/react/index-header-individual-component.jsx deleted file mode 100644 index 25387a1f..00000000 --- a/sources/react/index-header-individual-component.jsx +++ /dev/null @@ -1,129 +0,0 @@ -/** @ssr-ready **/ - -/* !!! -IF YOU ARE EDITING gridicon/index.jsx -THEN YOU ARE EDITING A FILE THAT GETS OUTPUT FROM THE GRIDICONS REPO! -DO NOT EDIT THAT FILE! EDIT index-header.jsx and index-footer.jsx instead -OR if you're looking to change now SVGs get output, you'll need to edit strings in the Gruntfile :) -!!! */ - -/** - * External dependencies - */ -import React from 'react'; - -// We don't want the icon prop in to otherProps, -// as we'll pass those to the svg component. -// That's why we destructure it from the props but not use it. -export default function({ - size = 24, - onClick, - icon: iconProp, - className, - ...otherProps -}){ - - const calculateNeedsOffset = ( icon, size ) => { - const iconNeedsOffset = [ - 'gridicons-add-outline', - 'gridicons-add', - 'gridicons-align-image-center', - 'gridicons-align-image-left', - 'gridicons-align-image-none', - 'gridicons-align-image-right', - 'gridicons-attachment', - 'gridicons-bold', - 'gridicons-bookmark-outline', - 'gridicons-bookmark', - 'gridicons-calendar', - 'gridicons-cart', - 'gridicons-create', - 'gridicons-custom-post-type', - 'gridicons-external', - 'gridicons-folder', - 'gridicons-heading', - 'gridicons-help-outline', - 'gridicons-help', - 'gridicons-history', - 'gridicons-info-outline', - 'gridicons-info', - 'gridicons-italic', - 'gridicons-layout-blocks', - 'gridicons-link-break', - 'gridicons-link', - 'gridicons-list-checkmark', - 'gridicons-list-ordered', - 'gridicons-list-unordered', - 'gridicons-menus', - 'gridicons-minus', - 'gridicons-my-sites', - 'gridicons-notice-outline', - 'gridicons-notice', - 'gridicons-plus-small', - 'gridicons-plus', - 'gridicons-popout', - 'gridicons-posts', - 'gridicons-scheduled', - 'gridicons-share-ios', - 'gridicons-star-outline', - 'gridicons-star', - 'gridicons-stats', - 'gridicons-status', - 'gridicons-thumbs-up', - 'gridicons-textcolor', - 'gridicons-time', - 'gridicons-trophy', - 'gridicons-user-circle', - 'gridicons-reader-follow', - 'gridicons-reader-following' - ]; - - if ( iconNeedsOffset.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } - - const calculateNeedsOffsetX = ( icon, size ) => { - const iconNeedsOffsetX = [ - 'gridicons-arrow-down', - 'gridicons-arrow-up', - 'gridicons-comment', - 'gridicons-clear-formatting', - 'gridicons-flag', - 'gridicons-menu', - 'gridicons-reader', - 'gridicons-strikethrough' - ]; - - if ( iconNeedsOffsetX.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } - - const calculateNeedsOffsetY = ( icon, size ) => { - const iconNeedsOffsetY = [ - 'gridicons-align-center', - 'gridicons-align-justify', - 'gridicons-align-left', - 'gridicons-align-right', - 'gridicons-arrow-left', - 'gridicons-arrow-right', - 'gridicons-house', - 'gridicons-indent-left', - 'gridicons-indent-right', - 'gridicons-minus-small', - 'gridicons-print', - 'gridicons-sign-out', - 'gridicons-stats-alt', - 'gridicons-trash', - 'gridicons-underline', - 'gridicons-video-camera' - ]; - - if ( iconNeedsOffsetY.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } diff --git a/sources/react/index-header.jsx b/sources/react/index-header.jsx deleted file mode 100644 index ad91e72e..00000000 --- a/sources/react/index-header.jsx +++ /dev/null @@ -1,155 +0,0 @@ -/** @ssr-ready **/ - -/* !!! -IF YOU ARE EDITING gridicon/index.jsx -THEN YOU ARE EDITING A FILE THAT GETS OUTPUT FROM THE GRIDICONS REPO! -DO NOT EDIT THAT FILE! EDIT index-header.jsx and index-footer.jsx instead -OR if you're looking to change now SVGs get output, you'll need to edit strings in the Gruntfile :) -!!! */ - -/** - * External dependencies - */ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; - -export default class Gridicon extends PureComponent { - - static defaultProps = { - size: 24 - }; - - static propTypes = { - icon: PropTypes.string.isRequired, - size: PropTypes.number, - onClick: PropTypes.func, - className: PropTypes.string - }; - - needsOffset( icon, size ) { - const iconNeedsOffset = [ - 'gridicons-add-outline', - 'gridicons-add', - 'gridicons-align-image-center', - 'gridicons-align-image-left', - 'gridicons-align-image-none', - 'gridicons-align-image-right', - 'gridicons-attachment', - 'gridicons-bold', - 'gridicons-bookmark-outline', - 'gridicons-bookmark', - 'gridicons-calendar', - 'gridicons-cart', - 'gridicons-create', - 'gridicons-custom-post-type', - 'gridicons-external', - 'gridicons-folder', - 'gridicons-heading', - 'gridicons-help-outline', - 'gridicons-help', - 'gridicons-history', - 'gridicons-info-outline', - 'gridicons-info', - 'gridicons-italic', - 'gridicons-layout-blocks', - 'gridicons-link-break', - 'gridicons-link', - 'gridicons-list-checkmark', - 'gridicons-list-ordered', - 'gridicons-list-unordered', - 'gridicons-menus', - 'gridicons-minus', - 'gridicons-my-sites', - 'gridicons-notice-outline', - 'gridicons-notice', - 'gridicons-plus-small', - 'gridicons-plus', - 'gridicons-popout', - 'gridicons-posts', - 'gridicons-scheduled', - 'gridicons-share-ios', - 'gridicons-star-outline', - 'gridicons-star', - 'gridicons-stats', - 'gridicons-status', - 'gridicons-thumbs-up', - 'gridicons-textcolor', - 'gridicons-time', - 'gridicons-trophy', - 'gridicons-user-circle', - 'gridicons-reader-follow', - 'gridicons-reader-following' - ]; - - if ( iconNeedsOffset.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } - - needsOffsetX( icon, size ) { - const iconNeedsOffsetX = [ - 'gridicons-arrow-down', - 'gridicons-arrow-up', - 'gridicons-comment', - 'gridicons-clear-formatting', - 'gridicons-flag', - 'gridicons-menu', - 'gridicons-reader', - 'gridicons-strikethrough' - ]; - - if ( iconNeedsOffsetX.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } - - needsOffsetY( icon, size ) { - const iconNeedsOffsetY = [ - 'gridicons-align-center', - 'gridicons-align-justify', - 'gridicons-align-left', - 'gridicons-align-right', - 'gridicons-arrow-left', - 'gridicons-arrow-right', - 'gridicons-house', - 'gridicons-indent-left', - 'gridicons-indent-right', - 'gridicons-minus-small', - 'gridicons-print', - 'gridicons-sign-out', - 'gridicons-stats-alt', - 'gridicons-trash', - 'gridicons-underline', - 'gridicons-video-camera' - ]; - - if ( iconNeedsOffsetY.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } - - render() { - const { size, onClick, icon: iconProp, className, ...otherProps } = this.props; - const icon = 'gridicons-' + iconProp; - const needsOffset = this.needsOffset( icon, size ); - const needsOffsetX = this.needsOffsetX( icon, size ); - const needsOffsetY = this.needsOffsetY( icon, size ); - - let svg; - - const iconClass = [ - 'gridicon', - icon, - className, - needsOffset ? 'needs-offset' : false, - needsOffsetX ? 'needs-offset-x' : false, - needsOffsetY ? 'needs-offset-y' : false, - ].filter( Boolean ).join( ' ' ); - - switch ( icon ) { - default: - svg = ; - break; diff --git a/sources/react/template-all-icons.js b/sources/react/template-all-icons.js new file mode 100644 index 00000000..2a2689d5 --- /dev/null +++ b/sources/react/template-all-icons.js @@ -0,0 +1,88 @@ +const toString = array => array.reduce( ( acc, item ) => ( acc = acc + "'" + item + "', " ), '' ); + +const prepareAllIcons = ( { + components, + iconsThatNeedOffset, + iconsThatNeedOffsetX, + iconsThatNeedOffsetY, +} ) => ` +/** @ssr-ready **/ + +/** + * External dependencies + */ +import React, { PureComponent } from 'react'; +import PropTypes from 'prop-types'; + +export default class Gridicon extends PureComponent { + + static defaultProps = { + size: 24 + }; + + static propTypes = { + icon: PropTypes.string.isRequired, + size: PropTypes.number, + onClick: PropTypes.func, + className: PropTypes.string + }; + + needsOffset( icon, size ) { + const iconNeedsOffset = [ ${ toString( iconsThatNeedOffset ) } ]; + + if ( iconNeedsOffset.indexOf( icon ) >= 0 ) { + return ( size % 18 === 0 ); + } + return false; + } + + needsOffsetX( icon, size ) { + const iconNeedsOffsetX = [ ${ toString( iconsThatNeedOffsetX ) } ]; + + if ( iconNeedsOffsetX.indexOf( icon ) >= 0 ) { + return ( size % 18 === 0 ); + } + return false; + } + + needsOffsetY( icon, size ) { + const iconNeedsOffsetY = [ ${ toString( iconsThatNeedOffsetY ) } ]; + + if ( iconNeedsOffsetY.indexOf( icon ) >= 0 ) { + return ( size % 18 === 0 ); + } + return false; + } + + render() { + const { size, onClick, icon: iconProp, className, ...otherProps } = this.props; + const icon = 'gridicons-' + iconProp; + const needsOffset = this.needsOffset( icon, size ); + const needsOffsetX = this.needsOffsetX( icon, size ); + const needsOffsetY = this.needsOffsetY( icon, size ); + + let svg; + const iconClass = [ + 'gridicon', + icon, + className, + needsOffset ? 'needs-offset' : false, + needsOffsetX ? 'needs-offset-x' : false, + needsOffsetY ? 'needs-offset-y' : false, + ].filter( Boolean ).join( ' ' ); + + switch ( icon ) { + default: + svg = ; + break; + + ${ components } + + } + + return ( svg ); + } +} +`; + +module.exports = prepareAllIcons; diff --git a/sources/react/example-header.jsx b/sources/react/template-devdocs-example.js similarity index 78% rename from sources/react/example-header.jsx rename to sources/react/template-devdocs-example.js index d976fb37..8582bc8c 100644 --- a/sources/react/example-header.jsx +++ b/sources/react/template-devdocs-example.js @@ -1,4 +1,6 @@ +const prepareDevDocsExample = components => ` /* eslint-disable no-alert */ + /** * External dependencies */ @@ -20,3 +22,11 @@ export default class Gridicons extends PureComponent { render() { return (
+ ${ components } +
+ ); + } +} +`; + +module.exports = prepareDevDocsExample; diff --git a/sources/react/template-individual-icon.js b/sources/react/template-individual-icon.js new file mode 100644 index 00000000..b59c1818 --- /dev/null +++ b/sources/react/template-individual-icon.js @@ -0,0 +1,48 @@ +/** @format */ + +const needsOffset = ( name, icons ) => icons.indexOf( 'gridicons-' + name ) >= 0; + +const prepareIndividualIcon = ( { + name, + component, + iconsThatNeedOffset, + iconsThatNeedOffsetX, + iconsThatNeedOffsetY, +} ) => ` +/* @ssr-ready */ + +/** + * External dependencies + */ +import React from 'react'; + +// We don't want the icon prop in to otherProps, as we'll pass those to the svg component. +// That's why we destructure it from the props but not use it. +export default function( { size = 24, onClick, icon, className, ...otherProps } ) { + const isModulo18 = size => size % 18 === 0; + const iconClass = [ + 'gridicon', + 'gridicons-${ name }', + className, + ${ + needsOffset( name, iconsThatNeedOffset ) + ? "isModulo18( size ) ? 'needs-offset' : false" + : false + } , + ${ + needsOffset( name, iconsThatNeedOffsetX ) + ? "isModulo18( size ) ? 'needs-offset-x' : false" + : false + }, + ${ + needsOffset( name, iconsThatNeedOffsetY ) + ? "isModulo18( size ) ? 'needs-offset-y' : false" + : false + }, + ].filter( Boolean ).join( ' ' ); + + return ( ${ component } ); +} +`; + +module.exports = prepareIndividualIcon; From 134456595e8702aaaf8d8f02560602d25d1342e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 18:34:17 +0100 Subject: [PATCH 10/36] Save some bytes of cjs/index.js --- sources/react/template-all-icons.js | 87 +++++++++-------------------- 1 file changed, 27 insertions(+), 60 deletions(-) diff --git a/sources/react/template-all-icons.js b/sources/react/template-all-icons.js index 2a2689d5..34062508 100644 --- a/sources/react/template-all-icons.js +++ b/sources/react/template-all-icons.js @@ -11,77 +11,44 @@ const prepareAllIcons = ( { /** * External dependencies */ -import React, { PureComponent } from 'react'; -import PropTypes from 'prop-types'; +import React from 'react'; -export default class Gridicon extends PureComponent { +export default function( { icon: iconProp, className, onClick, size = 24, ...otherProps } ) { - static defaultProps = { - size: 24 - }; + const iconsThatNeedOffset = [ ${ toString( iconsThatNeedOffset ) } ]; - static propTypes = { - icon: PropTypes.string.isRequired, - size: PropTypes.number, - onClick: PropTypes.func, - className: PropTypes.string - }; + const iconsThatNeedOffsetX = [ ${ toString( iconsThatNeedOffsetX ) } ]; - needsOffset( icon, size ) { - const iconNeedsOffset = [ ${ toString( iconsThatNeedOffset ) } ]; + const iconsThatNeedOffsetY = [ ${ toString( iconsThatNeedOffsetY ) } ]; - if ( iconNeedsOffset.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } - - needsOffsetX( icon, size ) { - const iconNeedsOffsetX = [ ${ toString( iconsThatNeedOffsetX ) } ]; + const doesItNeedOffset = ( name, icons ) => icons.indexOf( name ) >= 0; + const isModulo18 = size => size % 18 === 0; - if ( iconNeedsOffsetX.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } + const icon = 'gridicons-' + iconProp; + const needsOffset = doesItNeedOffset( icon, iconsThatNeedOffset ) && isModulo18( size ); + const needsOffsetX = doesItNeedOffset( icon, iconsThatNeedOffsetX ) && isModulo18( size ); + const needsOffsetY = doesItNeedOffset( icon, iconsThatNeedOffsetY ) && isModulo18( size ); - needsOffsetY( icon, size ) { - const iconNeedsOffsetY = [ ${ toString( iconsThatNeedOffsetY ) } ]; - - if ( iconNeedsOffsetY.indexOf( icon ) >= 0 ) { - return ( size % 18 === 0 ); - } - return false; - } + let svg; + const iconClass = [ + 'gridicon', + icon, + className, + needsOffset ? 'needs-offset' : false, + needsOffsetX ? 'needs-offset-x' : false, + needsOffsetY ? 'needs-offset-y' : false, + ].filter( Boolean ).join( ' ' ); - render() { - const { size, onClick, icon: iconProp, className, ...otherProps } = this.props; - const icon = 'gridicons-' + iconProp; - const needsOffset = this.needsOffset( icon, size ); - const needsOffsetX = this.needsOffsetX( icon, size ); - const needsOffsetY = this.needsOffsetY( icon, size ); + switch ( icon ) { + default: + svg = ; + break; - let svg; - const iconClass = [ - 'gridicon', - icon, - className, - needsOffset ? 'needs-offset' : false, - needsOffsetX ? 'needs-offset-x' : false, - needsOffsetY ? 'needs-offset-y' : false, - ].filter( Boolean ).join( ' ' ); + ${ components } - switch ( icon ) { - default: - svg = ; - break; - - ${ components } - - } - - return ( svg ); } + + return ( svg ); } `; From 15357c6e9f5f9ae9a99fd6a57f01c48729d0de20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 18:45:25 +0100 Subject: [PATCH 11/36] Save some bytes in example --- sources/react/template-devdocs-example.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/sources/react/template-devdocs-example.js b/sources/react/template-devdocs-example.js index 8582bc8c..3c1c5f4e 100644 --- a/sources/react/template-devdocs-example.js +++ b/sources/react/template-devdocs-example.js @@ -4,28 +4,26 @@ const prepareDevDocsExample = components => ` /** * External dependencies */ -import React, { PureComponent } from 'react'; +import React from 'react'; /** * Internal dependencies */ import Gridicon from './index.js'; -export default class Gridicons extends PureComponent { - static displayName = 'Gridicons'; // Don't remove, needed for Calypso devdocs! +export default function() { + const displayName = 'Gridicons'; // Don't remove, needed for Calypso devdocs! - handleClick = ( icon ) => { + const handleClick = icon => { const toCopy = ''; window.prompt( 'Copy component code:', toCopy ); - }; - - render() { - return ( -
- ${ components } -
- ); } + + return ( +
+ ${ components } +
+ ); } `; From df051c3db073b944e35297d095ebabc7e1ab5b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 18:49:32 +0100 Subject: [PATCH 12/36] Use js extension for ESModules The example file imports './index.js', so we need that extension to be used by both the CommonJS and ES modules. --- Gruntfile.js | 2 +- grunt-tasks/svg-to-react.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 3fc6ff37..e16acc32 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -101,7 +101,7 @@ module.exports = function( grunt ) { files: [{ expand: true, cwd: 'esm/', - src: [ '**/*.jsx' ], + src: [ '**/*.js' ], dest: 'cjs/', ext: '.js', filter: 'isFile' diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index a1c56454..c60707c3 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -115,7 +115,7 @@ module.exports = function( grunt ) { componentsExample += ' \n'; // Prepare and write to disk every individual icon separately - grunt.file.write( files.dest + name + '.jsx', prepareIndividualIcon( { + grunt.file.write( files.dest + name + '.js', prepareIndividualIcon( { name, component: fileContent, iconsThatNeedOffset, @@ -129,10 +129,10 @@ module.exports = function( grunt ) { } ); // Prepare and write to disk the Design Docs Example component - grunt.file.write( filesDest + 'example.jsx', prepareDevDocsExample( componentsExample ) ); + grunt.file.write( filesDest + 'example.js', prepareDevDocsExample( componentsExample ) ); // Prepare and write to disk the Gridicon React component - grunt.file.write( filesDest + 'index.jsx', prepareAllIcons( { + grunt.file.write( filesDest + 'index.js', prepareAllIcons( { components, iconsThatNeedOffset, iconsThatNeedOffsetX, From b4ad13847ac99d257e0fe0b166d6b1cdd8030ded Mon Sep 17 00:00:00 2001 From: Bernie Reiter Date: Thu, 8 Mar 2018 19:14:41 +0100 Subject: [PATCH 13/36] Publish both CommonJS and ESModules Props to @ockham for the push of publishing both. --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 9c6f5154..e55952f0 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "2.1.3", "main": "cjs/index.js", "files": [ - "cjs" + "cjs/", + "esm/" ], "scripts": { "build": "grunt --verbose", From 482b14296622e2d62621d989d9ea908421bcab35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 19:15:37 +0100 Subject: [PATCH 14/36] Fix .gitignore --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 4d500e10..5bffa1e1 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ node_modules/ /npm-debug.log .idea/ svg-min-react/ -react-icons/ +cjs/ +esm/ .DS_Store From b4ca4330348d81351f6572772d36294fe9328c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 19:18:49 +0100 Subject: [PATCH 15/36] Fix package.json indentation --- package.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e55952f0..969b3814 100644 --- a/package.json +++ b/package.json @@ -2,10 +2,10 @@ "name": "gridicons", "version": "2.1.3", "main": "cjs/index.js", - "files": [ - "cjs/", - "esm/" - ], + "files": [ + "cjs/", + "esm/" + ], "scripts": { "build": "grunt --verbose", "prepublish": "npm run build" @@ -19,7 +19,7 @@ }, "license": "GPL-2.0+", "dependencies": { - "prop-types": "^15.5.7" + "prop-types": "^15.5.7" }, "devDependencies": { "babel-plugin-add-module-exports": "^0.2.1", From eb60b9c6f1d06a12b833ae7b2bb7ef3ba8ab5c7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 19:27:44 +0100 Subject: [PATCH 16/36] Declare where is the main untranspiled file --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 969b3814..7250b7d7 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "gridicons", "version": "2.1.3", "main": "cjs/index.js", + "esnext": "esm/index.js", "files": [ "cjs/", "esm/" From dbb5a2c0554af3a4709d1a77e215fc88e73bc870 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 19:51:17 +0100 Subject: [PATCH 17/36] Update docs --- README.md | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 59f07280..8adbec15 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ The [Calypso](https://github.com/Automattic/wp-calypso/) / [WordPress.com](https://wordpress.com) official icon set. -## Using the Gridicon Component in your project: +## Using the Gridicon Component in your project Note that this component requires [react](https://www.npmjs.com/package/react) to be installed in your project. If you don't want to use React, you can simply include the raw `.svg` files from the [`svg-min`](https://github.com/Automattic/gridicons/tree/master/svg-min) folder. @@ -16,6 +16,8 @@ npm install gridicons --save #### Usage +You can either import the whole iconset and decide at run-time which icon to use: + ``` import Gridicon from 'gridicons'; //... @@ -24,9 +26,21 @@ render() { } ``` +Or import icons individually: + +``` +import GridiconAddImage from 'gridicons/cjs/add-image'; +//... +render() { + return ; +} +``` + +We also support importing the untranspiled ECMASCript modules by using `gridicons/esm` instead of `gridicons/cjs`. + #### Props -* `icon`: String - the icon name. +* `icon`: String - the icon name. This is ignored when importing icons individually. * `size`: Number - (default: 24) set the size of the icon. * `onClick`: Function - (optional) if you need a click callback. @@ -34,7 +48,7 @@ render() { * The icon set is made to be used exactly at these pixel sizes: 12, 18, 24, 36, 48, 54, 72. * `gridicon-my-sites` as it's a small-size version of the WordPress logo, shouldn't be used larger than 36px. If you need to use the WordPress logo in larger sizes, see the [Social Logos project](https://github.com/Automattic/social-logos). - +* Individual icons are between 1K and 2K. If you use only a few, the recommended way of using the Gridicon library is to import them individually. At the moment, the main file containing the whole iconset sits at 92K. ## Icon Set Style Guidelines @@ -81,19 +95,19 @@ Note that the icons in this set are tied to be used in [Calypso](https://github. This icon set uses a few automation scripts to ease the generation of new icons in a reliable way. In short, we require `node` and `grunt`. For detailed instructions check [the installation page](https://github.com/Automattic/gridicons/wiki/Installation). -Once you checkout the repo run `npm install` in the `gridicons` folder. -To generate all the fonts, svgs and so on you run `npm run build` +Once you checkout the repo run `npm install` in the `gridicons` folder. +To generate all the fonts, svgs and so on you run `npm run build` ## Publishing to npm Note: to proceed with this you need to have write authorization to npm. -1. Create a new PR with updated `CHANGELOG.md` and updated version in `package.json` (i.e. `1.2.3-alpha.1`), see an example [here](https://github.com/Automattic/gridicons/pull/275). -2. In the "CHANGELOG.md" make sure to check all the previous commits since the previous versioned release. +1. Create a new PR with updated `CHANGELOG.md` and updated version in `package.json` (i.e. `1.2.3-alpha.1`), see an example [here](https://github.com/Automattic/gridicons/pull/275). +2. In the "CHANGELOG.md" make sure to check all the previous commits since the previous versioned release. 3. Pre-publish that PR branch on npm with `npm publish --tag next` ([more info](https://docs.npmjs.com/cli/dist-tag)). Running the `npm publish --tag next` command will send the data that you have localy to npm. Having the alpha version in the `package.json` file will create a newly tagged version npm package. Use `npm view gridicons` to look at the list of current tags. You do not need to commit changes to github in order to publish to npm, but it is recommended so folks testing know what's available. -4. Create a new update PR in a repository that makes use of Gridicons and run `npm install gridicons@next --save` (which will update `packages.json`). If you're creating the PR in [Calypso](https://github.com/Automattic/wp-calypso) and you get warnings, it might need to regenerate the shrinkwrap, in which case run `npm run update-deps`. See an example [here](https://github.com/Automattic/wp-calypso/pull/17601). +4. Create a new update PR in a repository that makes use of Gridicons and run `npm install gridicons@next --save` (which will update `packages.json`). If you're creating the PR in [Calypso](https://github.com/Automattic/wp-calypso) and you get warnings, it might need to regenerate the shrinkwrap, in which case run `npm run update-deps`. See an example [here](https://github.com/Automattic/wp-calypso/pull/17601). 5. Test if the new icons show up, and there are no regressions in the previous icons. Take a look at the `http://calypso.localhost:3000/devdocs/design/gridicons` for example. -6. If changes look good, remove the alpha postfix in the version (i.e. `1.2.3-alpha.1` to `1.2.3`) on both repositories PRs. +6. If changes look good, remove the alpha postfix in the version (i.e. `1.2.3-alpha.1` to `1.2.3`) on both repositories PRs. 7. Merge the Gridicons PR. 8. Tag the release on GitHub: `git tag -a v1.2.3 -m "Release v1.2.3"` (and push `git push origin v1.2.3`). 9. Check if it shows up in the [Releases list](https://github.com/Automattic/gridicons/releases). @@ -106,11 +120,11 @@ Gridicons is licensed under [GNU General Public License v2 (or later)](./LICENSE ## More notes on publishing to npm You need to have a npm user account. [Create one here](https://www.npmjs.com/signup). -Once you have created it, set up the account on you machine via +Once you have created it, set up the account on you machine via $ `npm adduser` -Setup the 2fa with npm -$ `npm profile enable-2fa` +Setup the 2fa with npm +$ `npm profile enable-2fa` -Now everytime before you can publish +Now everytime before you can publish You will be asked for a your [2FA code (OPT)](https://en.wikipedia.org/wiki/One-time_password) From 64fb4ba37e590df4642b41ba01f61d8cf5751e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 8 Mar 2018 19:53:53 +0100 Subject: [PATCH 18/36] Update docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8adbec15..ef6398b5 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ Note that the icons in this set are tied to be used in [Calypso](https://github. 1. Switch to the branch (i.e. Pull Request) with the new icon. 2. Review the SVG source of the new icons to make sure they are clean and readable. 3. Check pixel sharpness: open in Illustrator (with "Pixel Preview") or Sketch (with "Show Pixels"), adjust if needed. -4. Run `grunt` command from terminal. It will generate `svg-min`, React (`build`), `svg-sprite`, `pdf`, `php`, and `docs`. +4. Run `grunt` command from terminal. It will generate `svg-min`, React (`esm` and `cjs`), `svg-sprite`, `pdf`, `php`, and `docs`. 5. Commit 6. Merge & delete branch From 42fae14be1b2bc2c05d2354844f072495fe10a4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 10:20:11 +0100 Subject: [PATCH 19/36] Bump to v3.0.0-alpha and update CHANGELOG --- CHANGELOG.md | 7 +++++++ package.json | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e79648a..b87d182a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ _The versioning refers to the React component build._ +#### v3.0.0 (2018-03-09) +* React: allow importing individual icons, both in CommonJS and ECMAScript module formats. +* React: substitute React.PureComponent for a JavaScript function, to minimize the bundle size of transpiled CommonJS files as much as possible. +* Package: added a `esnext` key in the package.json so API consumers can use it for importing the main ESM file. +* Build: use template literals to create the React components and centralize the _icon needs offset_ logic in the svg-to-react Grunt task. +* Build: deleted the `build/` directory in favor of separate `cjs/` and `esm/` folders that contain CommonJS and ECMAScript modules respectively. + #### v2.1.3 (2018-02-22) * Icon added: "Shutter" diff --git a/package.json b/package.json index 7250b7d7..1edd5026 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridicons", - "version": "2.1.3", + "version": "3.0.0-alpha", "main": "cjs/index.js", "esnext": "esm/index.js", "files": [ From 84d9357a876e08d277cfe042f09f05df5e3f8ae6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 12:27:51 +0100 Subject: [PATCH 20/36] Fix Calypso DevDocs example component --- grunt-tasks/svg-to-react.js | 2 +- sources/react/template-devdocs-example.js | 22 ++++++++++++---------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index c60707c3..8a9ed335 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -108,7 +108,7 @@ module.exports = function( grunt ) { // Holds the switch's cases for every icon components += " case '" + name + "':\n" + " svg = " + fileContent + ";\n" + - " break;\n";; + " break;\n"; // Holds the Example Document name = name.replace( 'gridicons-', '' ); diff --git a/sources/react/template-devdocs-example.js b/sources/react/template-devdocs-example.js index 3c1c5f4e..ec2c6b8b 100644 --- a/sources/react/template-devdocs-example.js +++ b/sources/react/template-devdocs-example.js @@ -4,26 +4,28 @@ const prepareDevDocsExample = components => ` /** * External dependencies */ -import React from 'react'; +import React, { PureComponent } from 'react'; /** * Internal dependencies */ import Gridicon from './index.js'; -export default function() { - const displayName = 'Gridicons'; // Don't remove, needed for Calypso devdocs! +export default class Gridicons extends PureComponent { + static displayName = 'Gridicons'; // Don't remove, needed for Calypso devdocs! - const handleClick = icon => { + handleClick = ( icon ) => { const toCopy = ''; window.prompt( 'Copy component code:', toCopy ); - } + }; - return ( -
- ${ components } -
- ); + render() { + return ( +
+ ${components} +
+ ); + } } `; From 568cbdea99daa3989496ebf6438900fa5ab42600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 12:29:55 +0100 Subject: [PATCH 21/36] Bump to v3.0.1-alpha --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1edd5026..049ed738 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridicons", - "version": "3.0.0-alpha", + "version": "3.0.1-alpha", "main": "cjs/index.js", "esnext": "esm/index.js", "files": [ From d5963b94fc874d34473ef28a3abc58c2742c1540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 14:43:09 +0100 Subject: [PATCH 22/36] Remove ssr-pragma --- CHANGELOG.md | 1 + sources/react/template-all-icons.js | 2 -- sources/react/template-individual-icon.js | 2 -- 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b87d182a..da817cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ _The versioning refers to the React component build._ #### v3.0.0 (2018-03-09) +* React: remove obsolete @ssr-ready pragma from components. * React: allow importing individual icons, both in CommonJS and ECMAScript module formats. * React: substitute React.PureComponent for a JavaScript function, to minimize the bundle size of transpiled CommonJS files as much as possible. * Package: added a `esnext` key in the package.json so API consumers can use it for importing the main ESM file. diff --git a/sources/react/template-all-icons.js b/sources/react/template-all-icons.js index 34062508..ccaa7783 100644 --- a/sources/react/template-all-icons.js +++ b/sources/react/template-all-icons.js @@ -6,8 +6,6 @@ const prepareAllIcons = ( { iconsThatNeedOffsetX, iconsThatNeedOffsetY, } ) => ` -/** @ssr-ready **/ - /** * External dependencies */ diff --git a/sources/react/template-individual-icon.js b/sources/react/template-individual-icon.js index b59c1818..6f6c1149 100644 --- a/sources/react/template-individual-icon.js +++ b/sources/react/template-individual-icon.js @@ -9,8 +9,6 @@ const prepareIndividualIcon = ( { iconsThatNeedOffsetX, iconsThatNeedOffsetY, } ) => ` -/* @ssr-ready */ - /** * External dependencies */ From d2d1478777ba30cbb1d7008af6418a3d7cec9f13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 14:52:25 +0100 Subject: [PATCH 23/36] Remove extension in import --- sources/react/template-devdocs-example.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sources/react/template-devdocs-example.js b/sources/react/template-devdocs-example.js index ec2c6b8b..96b2573e 100644 --- a/sources/react/template-devdocs-example.js +++ b/sources/react/template-devdocs-example.js @@ -9,7 +9,7 @@ import React, { PureComponent } from 'react'; /** * Internal dependencies */ -import Gridicon from './index.js'; +import Gridicon from './index'; export default class Gridicons extends PureComponent { static displayName = 'Gridicons'; // Don't remove, needed for Calypso devdocs! From bed88b493df6c968a7bda21d129e12dc0af6bfef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 14:57:10 +0100 Subject: [PATCH 24/36] Move icon offset arrays to external file --- grunt-tasks/svg-to-react.js | 86 ++-------------------------------- sources/react/icons-offset.js | 87 +++++++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+), 81 deletions(-) create mode 100644 sources/react/icons-offset.js diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index 8a9ed335..6db6105c 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -9,87 +9,11 @@ module.exports = function( grunt ) { const prepareIndividualIcon = require( '../sources/react/template-individual-icon' ); const prepareAllIcons = require( '../sources/react/template-all-icons' ); const prepareDevDocsExample = require( '../sources/react/template-devdocs-example' ); - const iconsThatNeedOffset = [ - 'gridicons-add-outline', - 'gridicons-add', - 'gridicons-align-image-center', - 'gridicons-align-image-left', - 'gridicons-align-image-none', - 'gridicons-align-image-right', - 'gridicons-attachment', - 'gridicons-bold', - 'gridicons-bookmark-outline', - 'gridicons-bookmark', - 'gridicons-calendar', - 'gridicons-cart', - 'gridicons-create', - 'gridicons-custom-post-type', - 'gridicons-external', - 'gridicons-folder', - 'gridicons-heading', - 'gridicons-help-outline', - 'gridicons-help', - 'gridicons-history', - 'gridicons-info-outline', - 'gridicons-info', - 'gridicons-italic', - 'gridicons-layout-blocks', - 'gridicons-link-break', - 'gridicons-link', - 'gridicons-list-checkmark', - 'gridicons-list-ordered', - 'gridicons-list-unordered', - 'gridicons-menus', - 'gridicons-minus', - 'gridicons-my-sites', - 'gridicons-notice-outline', - 'gridicons-notice', - 'gridicons-plus-small', - 'gridicons-plus', - 'gridicons-popout', - 'gridicons-posts', - 'gridicons-scheduled', - 'gridicons-share-ios', - 'gridicons-star-outline', - 'gridicons-star', - 'gridicons-stats', - 'gridicons-status', - 'gridicons-thumbs-up', - 'gridicons-textcolor', - 'gridicons-time', - 'gridicons-trophy', - 'gridicons-user-circle', - 'gridicons-reader-follow', - 'gridicons-reader-following' - ]; - const iconsThatNeedOffsetY = [ - 'gridicons-align-center', - 'gridicons-align-justify', - 'gridicons-align-left', - 'gridicons-align-right', - 'gridicons-arrow-left', - 'gridicons-arrow-right', - 'gridicons-house', - 'gridicons-indent-left', - 'gridicons-indent-right', - 'gridicons-minus-small', - 'gridicons-print', - 'gridicons-sign-out', - 'gridicons-stats-alt', - 'gridicons-trash', - 'gridicons-underline', - 'gridicons-video-camera' - ]; - const iconsThatNeedOffsetX = [ - 'gridicons-arrow-down', - 'gridicons-arrow-up', - 'gridicons-comment', - 'gridicons-clear-formatting', - 'gridicons-flag', - 'gridicons-menu', - 'gridicons-reader', - 'gridicons-strikethrough' - ]; + const { + iconsThatNeedOffset, + iconsThatNeedOffsetX, + iconsThatNeedOffsetY + } = require( '../sources/react/icons-offset' ); this.files.forEach( function( files ) { files.src.forEach( function( svgFile ) { diff --git a/sources/react/icons-offset.js b/sources/react/icons-offset.js new file mode 100644 index 00000000..00a9182f --- /dev/null +++ b/sources/react/icons-offset.js @@ -0,0 +1,87 @@ +const iconsThatNeedOffset = [ + 'gridicons-add-outline', + 'gridicons-add', + 'gridicons-align-image-center', + 'gridicons-align-image-left', + 'gridicons-align-image-none', + 'gridicons-align-image-right', + 'gridicons-attachment', + 'gridicons-bold', + 'gridicons-bookmark-outline', + 'gridicons-bookmark', + 'gridicons-calendar', + 'gridicons-cart', + 'gridicons-create', + 'gridicons-custom-post-type', + 'gridicons-external', + 'gridicons-folder', + 'gridicons-heading', + 'gridicons-help-outline', + 'gridicons-help', + 'gridicons-history', + 'gridicons-info-outline', + 'gridicons-info', + 'gridicons-italic', + 'gridicons-layout-blocks', + 'gridicons-link-break', + 'gridicons-link', + 'gridicons-list-checkmark', + 'gridicons-list-ordered', + 'gridicons-list-unordered', + 'gridicons-menus', + 'gridicons-minus', + 'gridicons-my-sites', + 'gridicons-notice-outline', + 'gridicons-notice', + 'gridicons-plus-small', + 'gridicons-plus', + 'gridicons-popout', + 'gridicons-posts', + 'gridicons-scheduled', + 'gridicons-share-ios', + 'gridicons-star-outline', + 'gridicons-star', + 'gridicons-stats', + 'gridicons-status', + 'gridicons-thumbs-up', + 'gridicons-textcolor', + 'gridicons-time', + 'gridicons-trophy', + 'gridicons-user-circle', + 'gridicons-reader-follow', + 'gridicons-reader-following' +]; +const iconsThatNeedOffsetY = [ + 'gridicons-align-center', + 'gridicons-align-justify', + 'gridicons-align-left', + 'gridicons-align-right', + 'gridicons-arrow-left', + 'gridicons-arrow-right', + 'gridicons-house', + 'gridicons-indent-left', + 'gridicons-indent-right', + 'gridicons-minus-small', + 'gridicons-print', + 'gridicons-sign-out', + 'gridicons-stats-alt', + 'gridicons-trash', + 'gridicons-underline', + 'gridicons-video-camera' +]; +const iconsThatNeedOffsetX = [ + 'gridicons-arrow-down', + 'gridicons-arrow-up', + 'gridicons-comment', + 'gridicons-clear-formatting', + 'gridicons-flag', + 'gridicons-menu', + 'gridicons-reader', + 'gridicons-strikethrough' +]; + +module.exports = { + iconsThatNeedOffset, + iconsThatNeedOffsetX, + iconsThatNeedOffsetY, +}; From fbd44f906c091efc06cd669992fcb250b9639ef1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 16:47:08 +0100 Subject: [PATCH 25/36] Bump to v3.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 049ed738..0dc3972c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridicons", - "version": "3.0.1-alpha", + "version": "3.0.2-alpha", "main": "cjs/index.js", "esnext": "esm/index.js", "files": [ From 7001b5d18c2ff15b84061681464043b489760833 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 16:47:32 +0100 Subject: [PATCH 26/36] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da817cca..775bb89f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ _The versioning refers to the React component build._ -#### v3.0.0 (2018-03-09) +#### v3.0.2 (2018-03-09) * React: remove obsolete @ssr-ready pragma from components. * React: allow importing individual icons, both in CommonJS and ECMAScript module formats. * React: substitute React.PureComponent for a JavaScript function, to minimize the bundle size of transpiled CommonJS files as much as possible. From 31ccaf0c436496df7d13e3515ab54ed25bdb7988 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 9 Mar 2018 17:13:00 +0100 Subject: [PATCH 27/36] Bump to v3.0.0-alpha.1 In previous commits, I bumped to 3.0.1-alpha and 3.0.2-alpha instead of 3.0.0-alpha.1 and 3.0.0-alpha.2. I'm sorry! Taking advantage of the npm unpublish feature I've reverted those wrong alpha publications so I hope that, when you read this, they're available to you. --- CHANGELOG.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 775bb89f..da817cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ _The versioning refers to the React component build._ -#### v3.0.2 (2018-03-09) +#### v3.0.0 (2018-03-09) * React: remove obsolete @ssr-ready pragma from components. * React: allow importing individual icons, both in CommonJS and ECMAScript module formats. * React: substitute React.PureComponent for a JavaScript function, to minimize the bundle size of transpiled CommonJS files as much as possible. diff --git a/package.json b/package.json index 0dc3972c..8e2ece9f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridicons", - "version": "3.0.2-alpha", + "version": "3.0.0-alpha.1", "main": "cjs/index.js", "esnext": "esm/index.js", "files": [ From 27ca79f84ea0eca465d3bae0c214163048e12759 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Tue, 13 Mar 2018 11:31:47 +0100 Subject: [PATCH 28/36] Remove esnext key --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 8e2ece9f..fa54b56e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "name": "gridicons", "version": "3.0.0-alpha.1", "main": "cjs/index.js", - "esnext": "esm/index.js", "files": [ "cjs/", "esm/" From c0d1361f747cc9e43c988f7e4d45bfc6f9e79458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Tue, 13 Mar 2018 13:20:01 +0100 Subject: [PATCH 29/36] Use a unique dist/ folder instead of esm/ and cjs/ --- Gruntfile.js | 8 ++++---- grunt-tasks/svg-to-react.js | 6 +++--- package.json | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index e16acc32..aac4724e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -100,9 +100,9 @@ module.exports = function( grunt ) { dist: { files: [{ expand: true, - cwd: 'esm/', - src: [ '**/*.js' ], - dest: 'cjs/', + cwd: 'dist/', + src: [ '**/*.jsx' ], + dest: 'dist/', ext: '.js', filter: 'isFile' }] @@ -147,7 +147,7 @@ module.exports = function( grunt ) { cwd: 'svg-min-react/', src: [ '**/*.svg' ], filter: 'isFile', - dest: 'esm/' + dest: 'dist/' }] } }, diff --git a/grunt-tasks/svg-to-react.js b/grunt-tasks/svg-to-react.js index 6db6105c..ba29adf2 100644 --- a/grunt-tasks/svg-to-react.js +++ b/grunt-tasks/svg-to-react.js @@ -39,7 +39,7 @@ module.exports = function( grunt ) { componentsExample += ' \n'; // Prepare and write to disk every individual icon separately - grunt.file.write( files.dest + name + '.js', prepareIndividualIcon( { + grunt.file.write( files.dest + name + '.jsx', prepareIndividualIcon( { name, component: fileContent, iconsThatNeedOffset, @@ -53,10 +53,10 @@ module.exports = function( grunt ) { } ); // Prepare and write to disk the Design Docs Example component - grunt.file.write( filesDest + 'example.js', prepareDevDocsExample( componentsExample ) ); + grunt.file.write( filesDest + 'example.jsx', prepareDevDocsExample( componentsExample ) ); // Prepare and write to disk the Gridicon React component - grunt.file.write( filesDest + 'index.js', prepareAllIcons( { + grunt.file.write( filesDest + 'index.jsx', prepareAllIcons( { components, iconsThatNeedOffset, iconsThatNeedOffsetX, diff --git a/package.json b/package.json index fa54b56e..e3c8691c 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,9 @@ { "name": "gridicons", "version": "3.0.0-alpha.1", - "main": "cjs/index.js", + "main": "dist/index.js", "files": [ - "cjs/", - "esm/" + "dist/" ], "scripts": { "build": "grunt --verbose", From a5bed975c7aaca7596473fb82ee1df12a7f6d512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Tue, 13 Mar 2018 13:20:48 +0100 Subject: [PATCH 30/36] Only export CommonJS modules --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e3c8691c..8441f2cc 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "3.0.0-alpha.1", "main": "dist/index.js", "files": [ - "dist/" + "dist/*js" ], "scripts": { "build": "grunt --verbose", From 63376243cf03efa50043119e8f5d1f273c502908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Tue, 13 Mar 2018 15:17:52 +0100 Subject: [PATCH 31/36] Update README --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index ef6398b5..9c784ed1 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,14 @@ render() { Or import icons individually: ``` -import GridiconAddImage from 'gridicons/cjs/add-image'; +import GridiconAddImage from 'gridicons/dist/add-image'; //... render() { return ; } ``` -We also support importing the untranspiled ECMASCript modules by using `gridicons/esm` instead of `gridicons/cjs`. +If you use only a few icons, the recommended way of using the Gridicon library is to import them individually. At the moment of writing this, individual icons are between 1K and 2K, and the file containing the whole iconset sits at 92K. #### Props @@ -48,7 +48,6 @@ We also support importing the untranspiled ECMASCript modules by using `gridicon * The icon set is made to be used exactly at these pixel sizes: 12, 18, 24, 36, 48, 54, 72. * `gridicon-my-sites` as it's a small-size version of the WordPress logo, shouldn't be used larger than 36px. If you need to use the WordPress logo in larger sizes, see the [Social Logos project](https://github.com/Automattic/social-logos). -* Individual icons are between 1K and 2K. If you use only a few, the recommended way of using the Gridicon library is to import them individually. At the moment, the main file containing the whole iconset sits at 92K. ## Icon Set Style Guidelines @@ -86,7 +85,7 @@ Note that the icons in this set are tied to be used in [Calypso](https://github. 1. Switch to the branch (i.e. Pull Request) with the new icon. 2. Review the SVG source of the new icons to make sure they are clean and readable. 3. Check pixel sharpness: open in Illustrator (with "Pixel Preview") or Sketch (with "Show Pixels"), adjust if needed. -4. Run `grunt` command from terminal. It will generate `svg-min`, React (`esm` and `cjs`), `svg-sprite`, `pdf`, `php`, and `docs`. +4. Run `grunt` command from terminal. It will generate `svg-min`, `dist`, `svg-sprite`, `pdf`, `php`, and `docs`. 5. Commit 6. Merge & delete branch From 37f871a9ef2ade943de8592c118d1cbb1713f59f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Wed, 14 Mar 2018 10:08:24 +0100 Subject: [PATCH 32/36] Update ignored folders --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 5bffa1e1..78c7e445 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,5 @@ node_modules/ /npm-debug.log .idea/ svg-min-react/ -cjs/ -esm/ +dist/ .DS_Store From 65ce3d9a98c2b3b4bd0f09b3f0060eb1a6b49cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Wed, 14 Mar 2018 10:08:35 +0100 Subject: [PATCH 33/36] Update CHANGELOG with new proposal --- CHANGELOG.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da817cca..7ddd1424 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,11 @@ _The versioning refers to the React component build._ -#### v3.0.0 (2018-03-09) +#### v3.0.0 (2018-03-14) * React: remove obsolete @ssr-ready pragma from components. -* React: allow importing individual icons, both in CommonJS and ECMAScript module formats. +* React: allow importing individual icons in CommonJS module formats. * React: substitute React.PureComponent for a JavaScript function, to minimize the bundle size of transpiled CommonJS files as much as possible. -* Package: added a `esnext` key in the package.json so API consumers can use it for importing the main ESM file. * Build: use template literals to create the React components and centralize the _icon needs offset_ logic in the svg-to-react Grunt task. -* Build: deleted the `build/` directory in favor of separate `cjs/` and `esm/` folders that contain CommonJS and ECMAScript modules respectively. +* Build: renamed `build/` to `dist/`, which is now part of the gridicons npm package. #### v2.1.3 (2018-02-22) * Icon added: "Shutter" From 0262b6bdccbd177c4cd340b357e5720d60641d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Wed, 14 Mar 2018 10:10:17 +0100 Subject: [PATCH 34/36] Bump to 3.0.0-alpha.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 8441f2cc..de6ce949 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridicons", - "version": "3.0.0-alpha.1", + "version": "3.0.0-alpha.2", "main": "dist/index.js", "files": [ "dist/*js" From b884c3158ce0bae8f5153c170e96db5cf6e63e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Wed, 14 Mar 2018 12:39:04 +0100 Subject: [PATCH 35/36] Use intermediate build/ dir for JSX files --- .gitignore | 1 + Gruntfile.js | 4 ++-- README.md | 2 +- package.json | 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 78c7e445..2d92a50b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,6 @@ node_modules/ /npm-debug.log .idea/ svg-min-react/ +build/ dist/ .DS_Store diff --git a/Gruntfile.js b/Gruntfile.js index aac4724e..4534bae7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -100,7 +100,7 @@ module.exports = function( grunt ) { dist: { files: [{ expand: true, - cwd: 'dist/', + cwd: 'build/', src: [ '**/*.jsx' ], dest: 'dist/', ext: '.js', @@ -147,7 +147,7 @@ module.exports = function( grunt ) { cwd: 'svg-min-react/', src: [ '**/*.svg' ], filter: 'isFile', - dest: 'dist/' + dest: 'build/' }] } }, diff --git a/README.md b/README.md index 9c784ed1..5b077adb 100644 --- a/README.md +++ b/README.md @@ -85,7 +85,7 @@ Note that the icons in this set are tied to be used in [Calypso](https://github. 1. Switch to the branch (i.e. Pull Request) with the new icon. 2. Review the SVG source of the new icons to make sure they are clean and readable. 3. Check pixel sharpness: open in Illustrator (with "Pixel Preview") or Sketch (with "Show Pixels"), adjust if needed. -4. Run `grunt` command from terminal. It will generate `svg-min`, `dist`, `svg-sprite`, `pdf`, `php`, and `docs`. +4. Run `grunt` command from terminal. It will generate `svg-min`, `build`, `dist`, `svg-sprite`, `pdf`, `php`, and `docs`. 5. Commit 6. Merge & delete branch diff --git a/package.json b/package.json index de6ce949..07c57a6a 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "3.0.0-alpha.2", "main": "dist/index.js", "files": [ - "dist/*js" + "dist/" ], "scripts": { "build": "grunt --verbose", From da5f24e98196a4139a9c65d2d38c939dbd6cc889 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Wed, 14 Mar 2018 12:40:32 +0100 Subject: [PATCH 36/36] Bump version to 3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07c57a6a..588e52cc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gridicons", - "version": "3.0.0-alpha.2", + "version": "3.0.0", "main": "dist/index.js", "files": [ "dist/"