From 3476e36204e2b99b65f105efd0c403df6e8d5bae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Thu, 2 May 2019 16:40:54 +0100 Subject: [PATCH 1/9] Reimplement gridicons using SVG external content. --- assets/stylesheets/_vendor.scss | 6 +- client/blocks/inline-help/style.scss | 2 +- .../components/async-gridicons/fallback.jsx | 23 ------ client/components/async-gridicons/index.jsx | 65 --------------- client/components/gridicon/index.jsx | 56 +++++++++++++ .../my-sites/plugins/plugin-action/style.scss | 2 +- .../plugin-automated-transfer/style.scss | 6 +- npm-shrinkwrap.json | 80 ++++++++++++------- package.json | 2 +- webpack.config.js | 2 +- 10 files changed, 116 insertions(+), 128 deletions(-) delete mode 100644 client/components/async-gridicons/fallback.jsx delete mode 100644 client/components/async-gridicons/index.jsx create mode 100644 client/components/gridicon/index.jsx diff --git a/assets/stylesheets/_vendor.scss b/assets/stylesheets/_vendor.scss index 44276c9e566bbd..bd8bf83a5da623 100644 --- a/assets/stylesheets/_vendor.scss +++ b/assets/stylesheets/_vendor.scss @@ -5,15 +5,15 @@ .gridicon { fill: currentColor; - &.needs-offset g { + &.needs-offset use { transform: translate( 1px, 1px ); /* translates to .5px because it's in a child element */ } - &.needs-offset-x g { + &.needs-offset-x use { transform: translate( 1px, 0 ); /* only nudges horizontally */ } - &.needs-offset-y g { + &.needs-offset-y use { transform: translate( 0, 1px ); /* only nudges vertically */ } } diff --git a/client/blocks/inline-help/style.scss b/client/blocks/inline-help/style.scss index 5e471dc7e39993..38e754666b2ed6 100644 --- a/client/blocks/inline-help/style.scss +++ b/client/blocks/inline-help/style.scss @@ -74,7 +74,7 @@ height: 36px; width: 36px; - g { + use { transform: none; } } diff --git a/client/components/async-gridicons/fallback.jsx b/client/components/async-gridicons/fallback.jsx deleted file mode 100644 index 935e1845eb3aa8..00000000000000 --- a/client/components/async-gridicons/fallback.jsx +++ /dev/null @@ -1,23 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import React from 'react'; - -/** - * Internal dependencies - */ - -export default function FallbackIcon() { - /* eslint-disable wpcalypso/jsx-classname-namespace */ - return ( - - ); -} diff --git a/client/components/async-gridicons/index.jsx b/client/components/async-gridicons/index.jsx deleted file mode 100644 index 1331189d64e4e1..00000000000000 --- a/client/components/async-gridicons/index.jsx +++ /dev/null @@ -1,65 +0,0 @@ -/** @format */ - -/** - * External dependencies - */ -import React, { Component } from 'react'; - -/** - * Internal dependencies - */ -import FallbackIcon from './fallback'; - -const loadedIcons = new Map(); - -function loadIcon( icon ) { - return import( - /* webpackChunkName: "gridicons", webpackInclude: /\.js$/, webpackExclude: /dist\/(index\.js|example\.js)$/, webpackMode: "lazy-once" */ - `gridicons/dist/${ icon }` - ).then( - g => { - loadedIcons.set( icon, g.default ); - return g.default; - }, - err => { - loadedIcons.set( icon, false ); - console.warn( `Error loading icon '${ icon }':`, err.message ); // eslint-disable-line no-console - } - ); -} - -class AsyncGridicon extends Component { - constructor( props ) { - super( props ); - } - checkAndLoad() { - if ( this.props.icon && ! loadedIcons.has( this.props.icon ) ) { - loadIcon( this.props.icon ).then( () => this.update() ); - } - } - - componentDidMount() { - this.checkAndLoad(); - } - componentDidUpdate() { - this.checkAndLoad(); - } - - update = () => this.forceUpdate(); - - componentWillUnmount() { - this.update = () => {}; - } - - render() { - const { icon = '', ...rest } = this.props; - if ( loadedIcons.get( icon ) ) { - const Icon = loadedIcons.get( icon ); - return ; - } - - return ; - } -} - -export default AsyncGridicon; diff --git a/client/components/gridicon/index.jsx b/client/components/gridicon/index.jsx new file mode 100644 index 00000000000000..a85b316c28ff9d --- /dev/null +++ b/client/components/gridicon/index.jsx @@ -0,0 +1,56 @@ +/** + * External dependencies + */ +import React from 'react'; +import PropTypes from 'prop-types'; +import classnames from 'classnames'; +import { + iconsThatNeedOffset, + iconsThatNeedOffsetX, + iconsThatNeedOffsetY, +} from 'gridicons/dist/util/icons-offset'; +import spritePath from 'gridicons/svg-sprite/gridicons.svg'; + +function needsOffset( name, icons ) { + return icons.indexOf( name ) >= 0; +} + +function Gridicon( props ) { + const { size = 24, icon, onClick, className, ...otherProps } = props; + const isModulo18 = size % 18 === 0; + + // Using a missing icon doesn't produce any errors, just a blank icon, which is the exact intended behaviour. + // This means we don't need to perform any checks on the icon name. + const iconName = `gridicons-${ icon }`; + const offsetClasses = isModulo18 + ? [ + needsOffset( iconName, iconsThatNeedOffset ) ? 'needs-offset' : false, + needsOffset( iconName, iconsThatNeedOffsetX ) ? 'needs-offset-x' : false, + needsOffset( iconName, iconsThatNeedOffsetY ) ? 'needs-offset-y' : false, + ] + : []; + const iconClass = classnames( 'gridicon', iconName, className, ...offsetClasses ); + + return ( + + + + ); +} + +Gridicon.propTypes = { + icon: PropTypes.string.isRequired, + size: PropTypes.number, + onClick: PropTypes.func, + className: PropTypes.string, +}; + +export default React.memo( Gridicon ); diff --git a/client/my-sites/plugins/plugin-action/style.scss b/client/my-sites/plugins/plugin-action/style.scss index 7a91ebdfd8664e..a12c07b27d841b 100644 --- a/client/my-sites/plugins/plugin-action/style.scss +++ b/client/my-sites/plugins/plugin-action/style.scss @@ -75,7 +75,7 @@ display: block; } - .gridicons-info-outline g { + .gridicons-info-outline use { // revert the translate(1px,1px) done by needs-offset transform: none; } diff --git a/client/my-sites/plugins/plugin-automated-transfer/style.scss b/client/my-sites/plugins/plugin-automated-transfer/style.scss index 10079c75e150ff..57be652e53f46f 100644 --- a/client/my-sites/plugins/plugin-automated-transfer/style.scss +++ b/client/my-sites/plugins/plugin-automated-transfer/style.scss @@ -1,10 +1,10 @@ .plugin-automated-transfer__notice { - .gridicons-sync g { + .gridicons-sync use { animation: spinning-sync-icon linear 2s infinite; transform-origin: center; } - .gridicons-checkmark g, - .gridicons-notice g { + .gridicons-checkmark use, + .gridicons-notice use { transform: rotate( 0deg ); } } diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 21ca08509e12e3..926dcb12c5a38b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -41,7 +41,7 @@ "css-loader": "2.1.1", "duplicate-package-checker-webpack-plugin": "3.0.0", "file-loader": "3.0.1", - "mini-css-extract-plugin-with-rtl": "github:Automattic/mini-css-extract-plugin-with-rtl#af1300db7027af8caa9a3015f54a34aec545cc54", + "mini-css-extract-plugin-with-rtl": "github:Automattic/mini-css-extract-plugin-with-rtl", "node-sass": "4.11.0", "postcss-custom-properties": "8.0.9", "postcss-loader": "3.0.0", @@ -57,7 +57,7 @@ "dependencies": { "@babel/core": { "version": "7.4.0", - "bundled": true, + "resolved": "", "dev": true, "requires": { "@babel/code-frame": "^7.0.0", @@ -78,7 +78,7 @@ }, "@babel/plugin-transform-runtime": { "version": "7.4.0", - "bundled": true, + "resolved": "", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -89,7 +89,7 @@ }, "@babel/preset-env": { "version": "7.4.2", - "bundled": true, + "resolved": "", "dev": true, "requires": { "@babel/helper-module-imports": "^7.0.0", @@ -141,7 +141,7 @@ }, "autoprefixer": { "version": "9.4.4", - "bundled": true, + "resolved": "", "dev": true, "requires": { "browserslist": "^4.3.7", @@ -154,12 +154,14 @@ }, "camelcase": { "version": "5.3.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "cross-spawn": { "version": "6.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", "dev": true, "requires": { "nice-try": "^1.0.4", @@ -171,7 +173,7 @@ }, "debug": { "version": "4.1.1", - "bundled": true, + "resolved": "", "dev": true, "requires": { "ms": "^2.1.1" @@ -179,7 +181,8 @@ }, "execa": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", "dev": true, "requires": { "cross-spawn": "^6.0.0", @@ -193,7 +196,8 @@ }, "find-up": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", "dev": true, "requires": { "locate-path": "^3.0.0" @@ -201,7 +205,8 @@ }, "findup-sync": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", + "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", "dev": true, "requires": { "detect-file": "^1.0.0", @@ -212,7 +217,8 @@ }, "get-stream": { "version": "4.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { "pump": "^3.0.0" @@ -220,7 +226,8 @@ }, "import-local": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", "dev": true, "requires": { "pkg-dir": "^3.0.0", @@ -229,12 +236,14 @@ }, "invert-kv": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", "dev": true }, "is-glob": { "version": "3.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { "is-extglob": "^2.1.0" @@ -242,7 +251,8 @@ }, "lcid": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", "dev": true, "requires": { "invert-kv": "^2.0.0" @@ -250,7 +260,8 @@ }, "locate-path": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { "p-locate": "^3.0.0", @@ -259,7 +270,8 @@ }, "mem": { "version": "4.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", "dev": true, "requires": { "map-age-cleaner": "^0.1.1", @@ -269,12 +281,14 @@ }, "mimic-fn": { "version": "2.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, "os-locale": { "version": "3.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", "dev": true, "requires": { "execa": "^1.0.0", @@ -284,7 +298,8 @@ }, "p-limit": { "version": "2.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -292,7 +307,8 @@ }, "p-locate": { "version": "3.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", "dev": true, "requires": { "p-limit": "^2.0.0" @@ -300,12 +316,13 @@ }, "p-try": { "version": "2.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, "source-map": { "version": "0.5.7", - "bundled": true, + "resolved": "", "dev": true }, "webpack": { @@ -342,7 +359,8 @@ }, "webpack-cli": { "version": "3.3.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.0.tgz", + "integrity": "sha512-t1M7G4z5FhHKJ92WRKwZ1rtvi7rHc0NZoZRbSkol0YKl4HvcC8+DsmGDmK7MmZxHSAetHagiOsjOB6MmzC2TUw==", "dev": true, "requires": { "chalk": "^2.4.1", @@ -360,7 +378,8 @@ }, "yargs": { "version": "12.0.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", "dev": true, "requires": { "cliui": "^4.0.0", @@ -379,7 +398,8 @@ }, "yargs-parser": { "version": "11.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -10357,9 +10377,9 @@ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, "gridicons": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/gridicons/-/gridicons-3.2.0.tgz", - "integrity": "sha512-82bdTGEV12d9Ig5gTYw0uR2gf/Q/PNytAfLQdmBdZyj/iqCTw2jOipLq/GpG+VgiRQEXjc5TujBj7Jg/R2aP6Q==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/gridicons/-/gridicons-3.3.1.tgz", + "integrity": "sha512-eQsmujjLptLtyhGuu31US3mXkcptYHkgEE/s277HWv+j6c3Z2gYyjoHcBKwSFbQwxbfhToRd5uzYimR2ExWJdQ==", "requires": { "prop-types": "^15.5.7" } diff --git a/package.json b/package.json index a1e71dd840b002..48ff76ad28c28e 100644 --- a/package.json +++ b/package.json @@ -110,7 +110,7 @@ "get-video-id": "3.1.1", "gfm-code-blocks": "1.0.0", "globby": "9.2.0", - "gridicons": "3.2.0", + "gridicons": "3.3.1", "gzip-size": "5.1.0", "hash.js": "1.1.7", "he": "1.2.0", diff --git a/webpack.config.js b/webpack.config.js index 00d02d9f128399..e1fd4384e96a7d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -251,7 +251,7 @@ const webpackConfig = { 'react-virtualized': 'react-virtualized/dist/es', debug: path.resolve( __dirname, 'node_modules/debug' ), store: 'store/dist/store.modern', - gridicons$: path.resolve( __dirname, 'client/components/async-gridicons' ), + gridicons$: path.resolve( __dirname, 'client/components/gridicon' ), }, getAliasesForExtensions( { extensionsDirectory: path.join( __dirname, 'client', 'extensions' ), From 5d892f3633e1e58865e9455343fac904797b9611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Fri, 3 May 2019 13:14:23 +0100 Subject: [PATCH 2/9] Replace external Gridicon example w/ internal one. --- client/components/gridicon/docs/example.jsx | 233 ++++++++++++++++++++ client/devdocs/design/index.jsx | 4 +- webpack.config.js | 1 - 3 files changed, 235 insertions(+), 3 deletions(-) create mode 100644 client/components/gridicon/docs/example.jsx diff --git a/client/components/gridicon/docs/example.jsx b/client/components/gridicon/docs/example.jsx new file mode 100644 index 00000000000000..641def0611099f --- /dev/null +++ b/client/components/gridicon/docs/example.jsx @@ -0,0 +1,233 @@ +/** + * External dependencies + */ + +import React from 'react'; + +/** + * Internal dependencies + */ +import Gridicon from '../index'; + +const icons = [ + 'add-image', + 'add-outline', + 'add', + 'align-center', + 'align-image-center', + 'align-image-left', + 'align-image-none', + 'align-image-right', + 'align-justify', + 'align-left', + 'align-right', + 'arrow-down', + 'arrow-left', + 'arrow-right', + 'arrow-up', + 'aside', + 'attachment', + 'audio', + 'bell', + 'block', + 'bold', + 'book', + 'bookmark-outline', + 'bookmark', + 'briefcase', + 'bug', + 'calendar', + 'camera', + 'caption', + 'cart', + 'chat', + 'checkmark-circle', + 'checkmark', + 'chevron-down', + 'chevron-left', + 'chevron-right', + 'chevron-up', + 'clear-formatting', + 'clipboard', + 'cloud-download', + 'cloud-outline', + 'cloud-upload', + 'cloud', + 'code', + 'cog', + 'comment', + 'computer', + 'coupon', + 'create', + 'credit-card', + 'crop', + 'cross-circle', + 'cross-small', + 'cross', + 'custom-post-type', + 'customize', + 'domains', + 'dropdown', + 'ellipsis-circle', + 'ellipsis', + 'external', + 'filter', + 'flag', + 'flip-horizontal', + 'flip-vertical', + 'folder-multiple', + 'folder', + 'fullscreen-exit', + 'fullscreen', + 'gift', + 'globe', + 'grid', + 'heading-h1', + 'heading-h2', + 'heading-h3', + 'heading-h4', + 'heading-h5', + 'heading-h6', + 'heading', + 'heart-outline', + 'heart', + 'help-outline', + 'help', + 'history', + 'house', + 'image-multiple', + 'image-remove', + 'image', + 'indent-left', + 'indent-right', + 'info-outline', + 'info', + 'ink', + 'institution', + 'italic', + 'layout-blocks', + 'layout', + 'line-graph', + 'link-break', + 'link', + 'list-checkmark', + 'list-ordered-rtl', + 'list-ordered', + 'list-unordered', + 'location', + 'lock', + 'mail', + 'mention', + 'menu', + 'menus', + 'microphone', + 'minus-small', + 'minus', + 'money', + 'multiple-users', + 'my-sites-horizon', + 'my-sites', + 'nametag', + 'next-page', + 'not-visible', + 'notice-outline', + 'notice', + 'offline', + 'pages', + 'pause', + 'pencil', + 'phone', + 'pin', + 'plans', + 'play', + 'plugins', + 'plus-small', + 'plus', + 'popout', + 'posts', + 'print', + 'product-downloadable', + 'product-external', + 'product-virtual', + 'product', + 'quote', + 'read-more', + 'reader-follow-conversation', + 'reader-follow', + 'reader-following-conversation', + 'reader-following', + 'reader', + 'reblog', + 'redo', + 'refresh', + 'refund', + 'reply', + 'resize', + 'rotate', + 'scheduled', + 'search', + 'share-computer', + 'share-ios', + 'share', + 'shipping', + 'shutter', + 'sign-out', + 'site', + 'spam', + 'speaker', + 'special-character', + 'star-outline', + 'star', + 'stats', + 'stats-alt', + 'stats-down', + 'stats-down-alt', + 'stats-up', + 'stats-up-alt', + 'status', + 'strikethrough', + 'sync', + 'tablet', + 'tag', + 'text-color', + 'themes', + 'thumbs-up', + 'time', + 'trash', + 'trophy', + 'types', + 'underline', + 'undo', + 'user-add', + 'user-circle', + 'user', + 'video-camera', + 'video-remove', + 'video', + 'visible', + 'zoom-in', + 'zoom-out', +]; + +export default function GridiconExample() { + function handleClick( icon ) { + const toCopy = ``; + window.prompt( 'Copy component code:', toCopy ); + } + + return ( + // eslint-disable-next-line wpcalypso/jsx-classname-namespace +
+

+ Social Logo +

+
+ { icons.map( icon => ( + handleClick( icon ) } /> + ) ) } +
+
+ ); +} + +GridiconExample.displayName = 'Gridicon'; diff --git a/client/devdocs/design/index.jsx b/client/devdocs/design/index.jsx index 8b8e3a53bf7714..c1a72b099a145c 100644 --- a/client/devdocs/design/index.jsx +++ b/client/devdocs/design/index.jsx @@ -10,7 +10,6 @@ import { bindActionCreators } from 'redux'; import { connect } from 'react-redux'; import { slugToCamelCase } from 'devdocs/docs-example/util'; import { trim } from 'lodash'; -import Gridicons from 'gridicons/example'; /** * Internal dependencies @@ -68,6 +67,7 @@ import Gauge from 'components/gauge/docs/example'; import GlobalNotices from 'components/global-notices/docs/example'; import Gravatar from 'components/gravatar/docs/example'; import GravatarCaterpillar from 'components/gravatar-caterpillar/docs/example'; +import Gridicon from 'components/gridicon/docs/example'; import HeaderButton from 'components/header-button/docs/example'; import Headers from 'components/header-cake/docs/example'; import ImagePreloader from 'components/image-preloader/docs/example'; @@ -226,7 +226,7 @@ class DesignAssets extends React.Component { - + diff --git a/webpack.config.js b/webpack.config.js index e1fd4384e96a7d..173dfdc1150f3b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -247,7 +247,6 @@ const webpackConfig = { modules: [ path.join( __dirname, 'client' ), 'node_modules' ], alias: Object.assign( { - 'gridicons/example': 'gridicons/dist/example', 'react-virtualized': 'react-virtualized/dist/es', debug: path.resolve( __dirname, 'node_modules/debug' ), store: 'store/dist/store.modern', From 934410e73e11c8d062ffb3bb1dcd91f9cb4ec321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Fri, 3 May 2019 13:23:15 +0100 Subject: [PATCH 3/9] Update `icons.md` with new gridicons info. --- docs/icons.md | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/docs/icons.md b/docs/icons.md index 43f5e61c1fe31d..f64ef0ec66029a 100644 --- a/docs/icons.md +++ b/docs/icons.md @@ -10,28 +10,23 @@ This document will cover how to use icons in Calypso, as well as how to create i Gridicons are born with a 24px base grid. Strokes are 2px thick and icons are solid. If an icon is hollow, it generally means the "inactive" version of that icon. For example an outline bookmark icon becomes solid once clicked. +Calypso has a specific Gridicon component that should be used instead of the one included in the `gridicons` package, since it offers better loading performance. +Any usage of `gridicons` gets rewritten to `components/gridicon`. +You should not use `gridicons/dist/...`, as that will load a legacy gridicon and cause duplication in the bundles. + ### Usage Import the iconset and decide at run-time which icon to use: ``` -import Gridicon from 'gridicons'; +import Gridicon from 'components/gridicon'; +// or `import Gridicon from 'gridicons'`; //... render() { return ; } ``` -If your project is using a small number of icons, the recommendation is to import them individually. By doing so, your JavaScript bundle will be smaller because only the icons you actually use will be added to your bundle. - -``` -import GridiconExternal from 'gridicons/dist/external'; -//... -render() { - -} -``` - **Props** - `icon`: String - the icon name. This is ignored when importing icons individually. @@ -56,7 +51,7 @@ Some icons at 18 and 36px size needs an extra feature in order to look crisp. Th What this basically does is nudge the pixels up and to the left by half a pixel. In the case of 36px icons (1.5 * 24) what it means is that icons can be **perfectly crisp**. In the case of 18px icons, it means icons will be **crisper**, though not perfect. Just trust me on the math. -The tricky part is that not all icons need this `offset-adjust` hack, only some icons do. We are currently working out how to best roll this feature out. +The tricky part is that not all icons need this `offset-adjust` hack, only some icons do. A list of icons that need adjustment is kept in the `gridicons` package and used by the Gridicon component at run-time, to determine which icons to adjust and when to do so. ### Do's and Don'ts From ec9b022801bcba0e9a0d684bf5c103640d6cfc35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Fri, 3 May 2019 13:39:05 +0100 Subject: [PATCH 4/9] Replace usage of 'gridicons/dist/...' --- client/components/happiness-support/index.jsx | 4 +- .../tinymce/plugins/advanced/plugin.jsx | 5 +- .../tinymce/plugins/contact-form/plugin.jsx | 4 +- .../plugins/insert-menu/menu-items.jsx | 22 +++--- .../tinymce/plugins/insert-menu/plugin.jsx | 7 +- .../tinymce/plugins/media/advanced/index.jsx | 5 +- .../tinymce/plugins/media/plugin.jsx | 12 +-- .../tinymce/plugins/wplink/dialog.jsx | 73 +++++++++---------- .../checkout/cart/cart-summary-bar.jsx | 4 +- 9 files changed, 69 insertions(+), 67 deletions(-) diff --git a/client/components/happiness-support/index.jsx b/client/components/happiness-support/index.jsx index e0db08e4ff7e8f..c77a9471e92669 100644 --- a/client/components/happiness-support/index.jsx +++ b/client/components/happiness-support/index.jsx @@ -14,7 +14,7 @@ import { localize } from 'i18n-calypso'; * Internal dependencies */ import Button from 'components/button'; -import GridiconExternal from 'gridicons/dist/external'; +import Gridicon from 'components/gridicon'; import isHappychatAvailable from 'state/happychat/selectors/is-happychat-available'; import { CALYPSO_CONTACT, @@ -149,7 +149,7 @@ export class HappinessSupport extends Component { rel="noopener noreferrer" className="happiness-support__support-button" > - + { this.props.translate( 'Support documentation' ) } ); diff --git a/client/components/tinymce/plugins/advanced/plugin.jsx b/client/components/tinymce/plugins/advanced/plugin.jsx index 63e3fb2cc06dfc..38cebeb0f377b7 100644 --- a/client/components/tinymce/plugins/advanced/plugin.jsx +++ b/client/components/tinymce/plugins/advanced/plugin.jsx @@ -8,7 +8,6 @@ import React from 'react'; import ReactDomServer from 'react-dom/server'; import tinymce from 'tinymce/tinymce'; import { translate } from 'i18n-calypso'; -import GridiconEllipsis from 'gridicons/dist/ellipsis'; /** * Internal dependencies @@ -16,6 +15,7 @@ import GridiconEllipsis from 'gridicons/dist/ellipsis'; import { isWithinBreakpoint } from 'lib/viewport'; import { savePreference, fetchPreferences } from 'state/preferences/actions'; import { getPreference, isFetchingPreferences } from 'state/preferences/selectors'; +import Gridicon from 'components/gridicon'; function advanced( editor ) { const store = editor.getParam( 'redux_store' ); @@ -72,9 +72,10 @@ function advanced( editor ) { this.innerHtml( ReactDomServer.renderToStaticMarkup( + // eslint-disable-next-line jsx-a11y/no-interactive-element-to-noninteractive-role ) diff --git a/client/components/tinymce/plugins/contact-form/plugin.jsx b/client/components/tinymce/plugins/contact-form/plugin.jsx index 9f4aca1ea67cc7..e5a575571e9de6 100644 --- a/client/components/tinymce/plugins/contact-form/plugin.jsx +++ b/client/components/tinymce/plugins/contact-form/plugin.jsx @@ -9,7 +9,6 @@ import i18n from 'i18n-calypso'; import React, { createElement } from 'react'; import { unmountComponentAtNode } from 'react-dom'; import { renderToStaticMarkup } from 'react-dom/server'; -import GridiconMention from 'gridicons/dist/mention'; /** * Internal Dependencies @@ -25,6 +24,7 @@ import { } from 'state/ui/editor/contact-form/actions'; import { serialize, deserialize } from './shortcode-utils'; import { renderWithReduxStore } from 'lib/react-helpers'; +import Gridicon from 'components/gridicon'; function wpcomContactForm( editor ) { let node; @@ -102,7 +102,7 @@ function wpcomContactForm( editor ) { renderToStaticMarkup( // eslint-disable-next-line jsx-a11y/no-interactive-element-to-noninteractive-role ) ); diff --git a/client/components/tinymce/plugins/insert-menu/menu-items.jsx b/client/components/tinymce/plugins/insert-menu/menu-items.jsx index bfc54d0ad72f87..af8865a565fd62 100644 --- a/client/components/tinymce/plugins/insert-menu/menu-items.jsx +++ b/client/components/tinymce/plugins/insert-menu/menu-items.jsx @@ -6,16 +6,12 @@ import React from 'react'; import i18n from 'i18n-calypso'; -import GridiconImage from 'gridicons/dist/image'; -import GridiconShutter from 'gridicons/dist/shutter'; -import GridiconMoney from 'gridicons/dist/money'; -import GridiconImageMultiple from 'gridicons/dist/image-multiple'; -import GridiconMention from 'gridicons/dist/mention'; /** * Internal dependencies */ import config from 'config'; +import Gridicon from 'components/gridicon'; /* eslint-disable wpcalypso/jsx-classname-namespace */ export const GridiconButton = ( { icon, label, e2e } ) => ( @@ -32,7 +28,11 @@ export const menuItems = [ { name: 'insert_media_item', item: ( - } label={ i18n.translate( 'Media' ) } e2e="media" /> + } + label={ i18n.translate( 'Media' ) } + e2e="media" + /> ), cmd: 'wpcomAddMedia', }, @@ -44,7 +44,7 @@ if ( config.isEnabled( 'external-media' ) ) { name: 'insert_from_google', item: ( } + icon={ } label={ i18n.translate( 'Google Photos library' ) } e2e="google-media" /> @@ -57,7 +57,7 @@ if ( config.isEnabled( 'external-media' ) ) { name: 'insert_from_pexels', item: ( } + icon={ } label={ i18n.translate( 'Free photo library' ) } e2e="stock-media-pexels" /> @@ -71,7 +71,7 @@ menuItems.push( { name: 'insert_contact_form', item: ( } + icon={ } label={ i18n.translate( 'Contact form' ) } e2e="contact-form" /> @@ -83,7 +83,7 @@ menuItems.push( { name: 'insert_payment_button', item: ( } + icon={ } label={ i18n.translate( 'Payment button' ) } e2e="payment-button" /> @@ -96,7 +96,7 @@ if ( config.isEnabled( 'memberships' ) ) { name: 'insert_memberships_button', item: ( } + icon={ } label={ i18n.translate( 'Recurring Payment' ) } e2e="memberships" /> diff --git a/client/components/tinymce/plugins/insert-menu/plugin.jsx b/client/components/tinymce/plugins/insert-menu/plugin.jsx index ed1660526052ee..d8cc10d99c5e6f 100644 --- a/client/components/tinymce/plugins/insert-menu/plugin.jsx +++ b/client/components/tinymce/plugins/insert-menu/plugin.jsx @@ -6,12 +6,12 @@ import React from 'react'; import tinymce from 'tinymce/tinymce'; import { renderToString } from 'react-dom/server'; import i18n from 'i18n-calypso'; -import GridiconAddOutline from 'gridicons/dist/add-outline'; /** * Internal dependencies */ import { menuItems, GridiconButton } from './menu-items'; +import Gridicon from 'components/gridicon'; function initialize( editor ) { menuItems.forEach( item => @@ -33,7 +33,10 @@ function initialize( editor ) { const [ insertContentElm ] = this.$el[ 0 ].children; insertContentElm.innerHTML = renderToString( - } label={ i18n.translate( 'Add' ) } /> + } + label={ i18n.translate( 'Add' ) } + /> ); }, } ); diff --git a/client/components/tinymce/plugins/media/advanced/index.jsx b/client/components/tinymce/plugins/media/advanced/index.jsx index 600559e281b644..e5c1e0a6285e99 100644 --- a/client/components/tinymce/plugins/media/advanced/index.jsx +++ b/client/components/tinymce/plugins/media/advanced/index.jsx @@ -6,7 +6,6 @@ import React from 'react'; import ReactDom from 'react-dom'; import ReactDomServer from 'react-dom/server'; import i18n from 'i18n-calypso'; -import GridiconPencil from 'gridicons/dist/pencil'; /** * Internal dependencies @@ -15,6 +14,7 @@ import { deserialize } from 'lib/media-serialization'; import config from 'config'; import EditorMediaAdvanced from 'post-editor/editor-media-advanced'; import { renderWithReduxStore } from 'lib/react-helpers'; +import Gridicon from 'components/gridicon'; export default function( editor ) { const store = editor.getParam( 'redux_store' ); @@ -70,8 +70,9 @@ export default function( editor ) { onPostRender() { this.innerHtml( ReactDomServer.renderToStaticMarkup( + // eslint-disable-next-line jsx-a11y/no-interactive-element-to-noninteractive-role ) ); diff --git a/client/components/tinymce/plugins/media/plugin.jsx b/client/components/tinymce/plugins/media/plugin.jsx index 5e27357874edc2..e7a58c13e2d007 100644 --- a/client/components/tinymce/plugins/media/plugin.jsx +++ b/client/components/tinymce/plugins/media/plugin.jsx @@ -10,7 +10,6 @@ import { assign, debounce, find, findLast, pick, values } from 'lodash'; import i18n from 'i18n-calypso'; import { parse, stringify } from 'lib/shortcode'; import closest from 'component-closest'; -import GridiconImageMultiple from 'gridicons/dist/image-multiple'; /** * Internal dependencies @@ -33,6 +32,7 @@ import { unblockSave } from 'state/ui/editor/save-blockers/actions'; import { getEditorRawContent, isEditorSaveBlocked } from 'state/ui/editor/selectors'; import { ModalViews } from 'state/ui/media-modal/constants'; import { renderWithReduxStore } from 'lib/react-helpers'; +import Gridicon from 'components/gridicon'; /** * Module variables @@ -52,9 +52,8 @@ function mediaButton( editor ) { const { dispatch, getState } = store; - let nodes = {}, - resizeEditor, - updateMedia; // eslint-disable-line + let nodes = {}; + let updateMedia; // eslint-disable-line const getSelectedSiteFromState = () => getSelectedSite( getState() ); @@ -453,9 +452,10 @@ function mediaButton( editor ) { onPostRender: function() { this.innerHtml( ReactDomServer.renderToStaticMarkup( + // eslint-disable-next-line jsx-a11y/no-interactive-element-to-noninteractive-role ) @@ -753,7 +753,7 @@ function mediaButton( editor ) { ); } ); - resizeEditor = debounce( + const resizeEditor = debounce( function() { // eslint-disable-line editor.execCommand( 'wpcomAutoResize', null, null, { skip_focus: true } ); diff --git a/client/components/tinymce/plugins/wplink/dialog.jsx b/client/components/tinymce/plugins/wplink/dialog.jsx index 4883f62f99a7df..c3182e7c8140f1 100644 --- a/client/components/tinymce/plugins/wplink/dialog.jsx +++ b/client/components/tinymce/plugins/wplink/dialog.jsx @@ -1,4 +1,3 @@ -/** @format */ /** * External dependencies */ @@ -8,7 +7,6 @@ import React from 'react'; import tinymce from 'tinymce/tinymce'; import { connect } from 'react-redux'; import { find } from 'lodash'; -import GridiconLinkBreak from 'gridicons/dist/link-break'; /** * Internal dependencies @@ -27,13 +25,14 @@ import { getSelectedSite } from 'state/ui/selectors'; import { getSitePosts } from 'state/posts/selectors'; import { decodeEntities } from 'lib/formatting'; import { recordEditorEvent, recordEditorStat } from 'state/posts/stats'; +import Gridicon from 'components/gridicon'; /** * Module variables */ -let REGEXP_EMAIL = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i, - REGEXP_URL = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i, - REGEXP_STANDALONE_URL = /^(?:[a-z]+:|#|\?|\.|\/)/; +const REGEXP_EMAIL = /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i; +const REGEXP_URL = /^(https?|ftp):\/\/[A-Z0-9.-]+\.[A-Z]{2,4}[^ "]*$/i; +const REGEXP_STANDALONE_URL = /^(?:[a-z]+:|#|\?|\.|\/)/; class LinkDialog extends React.Component { static propTypes = { @@ -57,7 +56,7 @@ class LinkDialog extends React.Component { } getLink = () => { - const editor = this.props.editor; + const { editor } = this.props; return editor.dom.getParent( editor.selection.getNode(), 'a' ); }; @@ -77,10 +76,7 @@ class LinkDialog extends React.Component { }; updateEditor = () => { - let editor = this.props.editor, - attrs, - link, - linkText; + const { editor } = this.props; editor.focus(); @@ -93,9 +89,9 @@ class LinkDialog extends React.Component { return; } - link = this.getLink(); - linkText = this.state.linkText; - attrs = { + const link = this.getLink(); + let { linkText } = this.state; + const attrs = { href: this.getCorrectedUrl(), target: this.state.newWindow ? '_blank' : '', }; @@ -121,10 +117,9 @@ class LinkDialog extends React.Component { }; hasSelectedText = linkNode => { - let editor = this.props.editor, - html = editor.selection.getContent(), - nodes, - i; + const { editor } = this.props; + const html = editor.selection.getContent(); + let nodes; // Partial html and not a fully selected anchor element if ( @@ -141,7 +136,7 @@ class LinkDialog extends React.Component { return false; } - for ( i = nodes.length - 1; i >= 0; i-- ) { + for ( let i = nodes.length - 1; i >= 0; i-- ) { if ( nodes[ i ].nodeType !== 3 ) { return false; } @@ -152,10 +147,9 @@ class LinkDialog extends React.Component { }; getInferredUrl = () => { - let selectedText = this.props.editor.selection.getContent(), - selectedNode, - parsedImage, - knownImage; + const selectedText = this.props.editor.selection.getContent(); + let parsedImage; + let knownImage; if ( REGEXP_EMAIL.test( selectedText ) ) { return 'mailto:' + selectedText; @@ -163,7 +157,7 @@ class LinkDialog extends React.Component { return selectedText.replace( /&|�?38;/gi, '&' ); } - selectedNode = this.props.editor.selection.getNode(); + const selectedNode = this.props.editor.selection.getNode(); if ( selectedNode && 'IMG' === selectedNode.nodeName ) { parsedImage = deserialize( selectedNode ); if ( this.props.site && parsedImage.media.ID ) { @@ -179,18 +173,18 @@ class LinkDialog extends React.Component { }; getState = () => { - let editor = this.props.editor, - selectedNode = editor.selection.getNode(), - linkNode = editor.dom.getParent( selectedNode, 'a[href]' ), - onlyText = this.hasSelectedText( linkNode ), - nextState = { - isNew: true, - newWindow: false, - showLinkText: true, - linkText: '', - url: '', - isUserDefinedLinkText: false, - }; + const { editor } = this.props; + const selectedNode = editor.selection.getNode(); + const linkNode = editor.dom.getParent( selectedNode, 'a[href]' ); + const onlyText = this.hasSelectedText( linkNode ); + const nextState = { + isNew: true, + newWindow: false, + showLinkText: true, + linkText: '', + url: '', + isUserDefinedLinkText: false, + }; if ( linkNode ) { nextState.linkText = linkNode.innerText || linkNode.textContent; @@ -244,7 +238,7 @@ class LinkDialog extends React.Component { }; getButtons = () => { - let buttonText, buttons; + let buttonText; if ( this.state.isNew ) { buttonText = this.props.translate( 'Add Link' ); @@ -252,7 +246,7 @@ class LinkDialog extends React.Component { buttonText = this.props.translate( 'Save' ); } - buttons = [ + const buttons = [ { buttonText } , @@ -264,7 +258,7 @@ class LinkDialog extends React.Component { if ( this.state.url && ! this.state.isNew ) { buttons.push( ); @@ -305,6 +299,7 @@ class LinkDialog extends React.Component { state = this.getState(); + /* eslint-disable jsx-a11y/no-autofocus */ render() { return ( { this.props.translate( 'URL' ) } ); } + /* eslint-enable jsx-a11y/no-autofocus */ } export default connect( diff --git a/client/my-sites/checkout/cart/cart-summary-bar.jsx b/client/my-sites/checkout/cart/cart-summary-bar.jsx index cf48562f69bb2e..48e7a3a6f00b59 100644 --- a/client/my-sites/checkout/cart/cart-summary-bar.jsx +++ b/client/my-sites/checkout/cart/cart-summary-bar.jsx @@ -11,7 +11,7 @@ import { localize } from 'i18n-calypso'; * Internal dependencies */ import SectionHeader from 'components/section-header'; -import GridiconCart from 'gridicons/dist/cart'; +import Gridicon from 'components/gridicon'; class CartSummaryBar extends React.Component { render() { @@ -28,7 +28,7 @@ class CartSummaryBar extends React.Component { return (
- +
); From 21625f813a54863ee8f5c86756f96e9e9304c9f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Mon, 6 May 2019 09:41:26 +0100 Subject: [PATCH 5/9] Enable SVG file-loader transform in gridicons. --- test/client/jest.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/client/jest.config.js b/test/client/jest.config.js index 068992f0da3b9f..0d8fe1c506d5f6 100644 --- a/test/client/jest.config.js +++ b/test/client/jest.config.js @@ -13,7 +13,7 @@ module.exports = { roots: [ '/client/' ], testEnvironment: 'node', transformIgnorePatterns: [ - 'node_modules[\\/\\\\](?!flag-icon-css|redux-form|simple-html-tokenizer|draft-js|social-logos)', + 'node_modules[\\/\\\\](?!flag-icon-css|redux-form|simple-html-tokenizer|draft-js|social-logos|gridicons)', ], testMatch: [ '/client/**/test/*.js?(x)', '!**/.eslintrc.*' ], testURL: 'https://example.com', From 508d4eb0496e9a5dc343873a2832d35e3fc2b68d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Mon, 6 May 2019 14:05:01 +0100 Subject: [PATCH 6/9] Change icon adjustment CSS to use :first-child. This ensures that alignment works both in polyfilled and non-polyfilled setups. --- assets/stylesheets/_vendor.scss | 6 +++--- client/blocks/inline-help/style.scss | 2 +- client/my-sites/plugins/plugin-action/style.scss | 2 +- .../my-sites/plugins/plugin-automated-transfer/style.scss | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/stylesheets/_vendor.scss b/assets/stylesheets/_vendor.scss index bd8bf83a5da623..d1d38b10ebffa1 100644 --- a/assets/stylesheets/_vendor.scss +++ b/assets/stylesheets/_vendor.scss @@ -5,15 +5,15 @@ .gridicon { fill: currentColor; - &.needs-offset use { + &.needs-offset :first-child { transform: translate( 1px, 1px ); /* translates to .5px because it's in a child element */ } - &.needs-offset-x use { + &.needs-offset-x :first-child { transform: translate( 1px, 0 ); /* only nudges horizontally */ } - &.needs-offset-y use { + &.needs-offset-y :first-child { transform: translate( 0, 1px ); /* only nudges vertically */ } } diff --git a/client/blocks/inline-help/style.scss b/client/blocks/inline-help/style.scss index 38e754666b2ed6..32342c10e51bde 100644 --- a/client/blocks/inline-help/style.scss +++ b/client/blocks/inline-help/style.scss @@ -74,7 +74,7 @@ height: 36px; width: 36px; - use { + :first-child { transform: none; } } diff --git a/client/my-sites/plugins/plugin-action/style.scss b/client/my-sites/plugins/plugin-action/style.scss index a12c07b27d841b..5051bca8040518 100644 --- a/client/my-sites/plugins/plugin-action/style.scss +++ b/client/my-sites/plugins/plugin-action/style.scss @@ -75,7 +75,7 @@ display: block; } - .gridicons-info-outline use { + .gridicons-info-outline :first-child { // revert the translate(1px,1px) done by needs-offset transform: none; } diff --git a/client/my-sites/plugins/plugin-automated-transfer/style.scss b/client/my-sites/plugins/plugin-automated-transfer/style.scss index 57be652e53f46f..230ace9edf9095 100644 --- a/client/my-sites/plugins/plugin-automated-transfer/style.scss +++ b/client/my-sites/plugins/plugin-automated-transfer/style.scss @@ -1,10 +1,10 @@ .plugin-automated-transfer__notice { - .gridicons-sync use { + .gridicons-sync :first-child { animation: spinning-sync-icon linear 2s infinite; transform-origin: center; } - .gridicons-checkmark use, - .gridicons-notice use { + .gridicons-checkmark :first-child, + .gridicons-notice :first-child { transform: rotate( 0deg ); } } From 01a01038ca024345c74ecca92be9289ad3d1d753 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Mon, 6 May 2019 14:28:43 +0100 Subject: [PATCH 7/9] Remove role=presentation from button. --- client/components/tinymce/plugins/media/advanced/index.jsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/components/tinymce/plugins/media/advanced/index.jsx b/client/components/tinymce/plugins/media/advanced/index.jsx index e5c1e0a6285e99..1da316621766b1 100644 --- a/client/components/tinymce/plugins/media/advanced/index.jsx +++ b/client/components/tinymce/plugins/media/advanced/index.jsx @@ -70,8 +70,7 @@ export default function( editor ) { onPostRender() { this.innerHtml( ReactDomServer.renderToStaticMarkup( - // eslint-disable-next-line jsx-a11y/no-interactive-element-to-noninteractive-role - ) From 804f39ba5cd9e2049cffc1510fe92dc0300eac4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Mon, 6 May 2019 15:51:55 +0100 Subject: [PATCH 8/9] Fix scoping bug in updated CSS rules. --- assets/stylesheets/_vendor.scss | 6 +++--- client/blocks/inline-help/style.scss | 2 +- client/my-sites/plugins/plugin-action/style.scss | 2 +- .../my-sites/plugins/plugin-automated-transfer/style.scss | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/assets/stylesheets/_vendor.scss b/assets/stylesheets/_vendor.scss index d1d38b10ebffa1..28678f936f385e 100644 --- a/assets/stylesheets/_vendor.scss +++ b/assets/stylesheets/_vendor.scss @@ -5,15 +5,15 @@ .gridicon { fill: currentColor; - &.needs-offset :first-child { + &.needs-offset > :first-child { transform: translate( 1px, 1px ); /* translates to .5px because it's in a child element */ } - &.needs-offset-x :first-child { + &.needs-offset-x > :first-child { transform: translate( 1px, 0 ); /* only nudges horizontally */ } - &.needs-offset-y :first-child { + &.needs-offset-y > :first-child { transform: translate( 0, 1px ); /* only nudges vertically */ } } diff --git a/client/blocks/inline-help/style.scss b/client/blocks/inline-help/style.scss index 32342c10e51bde..4468a0e9cdd090 100644 --- a/client/blocks/inline-help/style.scss +++ b/client/blocks/inline-help/style.scss @@ -74,7 +74,7 @@ height: 36px; width: 36px; - :first-child { + > :first-child { transform: none; } } diff --git a/client/my-sites/plugins/plugin-action/style.scss b/client/my-sites/plugins/plugin-action/style.scss index 5051bca8040518..5d633d26a3b1a2 100644 --- a/client/my-sites/plugins/plugin-action/style.scss +++ b/client/my-sites/plugins/plugin-action/style.scss @@ -75,7 +75,7 @@ display: block; } - .gridicons-info-outline :first-child { + .gridicons-info-outline > :first-child { // revert the translate(1px,1px) done by needs-offset transform: none; } diff --git a/client/my-sites/plugins/plugin-automated-transfer/style.scss b/client/my-sites/plugins/plugin-automated-transfer/style.scss index 230ace9edf9095..1842ccdb66a6dc 100644 --- a/client/my-sites/plugins/plugin-automated-transfer/style.scss +++ b/client/my-sites/plugins/plugin-automated-transfer/style.scss @@ -1,10 +1,10 @@ .plugin-automated-transfer__notice { - .gridicons-sync :first-child { + .gridicons-sync > :first-child { animation: spinning-sync-icon linear 2s infinite; transform-origin: center; } - .gridicons-checkmark :first-child, - .gridicons-notice :first-child { + .gridicons-checkmark > :first-child, + .gridicons-notice > :first-child { transform: rotate( 0deg ); } } From e2e1b63becc091b57087ff01c118a679c0d9949d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Gomes?= Date: Mon, 6 May 2019 15:59:49 +0100 Subject: [PATCH 9/9] Make CSS rules more explicit --- assets/stylesheets/_vendor.scss | 9 ++++++--- client/blocks/inline-help/style.scss | 3 ++- client/my-sites/plugins/plugin-action/style.scss | 3 ++- .../plugins/plugin-automated-transfer/style.scss | 7 ++++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/assets/stylesheets/_vendor.scss b/assets/stylesheets/_vendor.scss index 28678f936f385e..b2b0a3a722ed1e 100644 --- a/assets/stylesheets/_vendor.scss +++ b/assets/stylesheets/_vendor.scss @@ -5,15 +5,18 @@ .gridicon { fill: currentColor; - &.needs-offset > :first-child { + &.needs-offset > use:first-child, + &.needs-offset > g:first-child { transform: translate( 1px, 1px ); /* translates to .5px because it's in a child element */ } - &.needs-offset-x > :first-child { + &.needs-offset-x > use:first-child, + &.needs-offset-x > g:first-child { transform: translate( 1px, 0 ); /* only nudges horizontally */ } - &.needs-offset-y > :first-child { + &.needs-offset-y > use:first-child, + &.needs-offset-y > g:first-child { transform: translate( 0, 1px ); /* only nudges vertically */ } } diff --git a/client/blocks/inline-help/style.scss b/client/blocks/inline-help/style.scss index 4468a0e9cdd090..29ebeb2a752be8 100644 --- a/client/blocks/inline-help/style.scss +++ b/client/blocks/inline-help/style.scss @@ -74,7 +74,8 @@ height: 36px; width: 36px; - > :first-child { + > use:first-child, + > g:first-child { transform: none; } } diff --git a/client/my-sites/plugins/plugin-action/style.scss b/client/my-sites/plugins/plugin-action/style.scss index 5d633d26a3b1a2..80ba8a1fe28028 100644 --- a/client/my-sites/plugins/plugin-action/style.scss +++ b/client/my-sites/plugins/plugin-action/style.scss @@ -75,7 +75,8 @@ display: block; } - .gridicons-info-outline > :first-child { + .gridicons-info-outline > use:first-child, + .gridicons-info-outline > g:first-child { // revert the translate(1px,1px) done by needs-offset transform: none; } diff --git a/client/my-sites/plugins/plugin-automated-transfer/style.scss b/client/my-sites/plugins/plugin-automated-transfer/style.scss index 1842ccdb66a6dc..4f3a30fd8a5c50 100644 --- a/client/my-sites/plugins/plugin-automated-transfer/style.scss +++ b/client/my-sites/plugins/plugin-automated-transfer/style.scss @@ -1,10 +1,11 @@ .plugin-automated-transfer__notice { - .gridicons-sync > :first-child { + .gridicons-sync > use:first-child, + .gridicons-sync > g:first-child { animation: spinning-sync-icon linear 2s infinite; transform-origin: center; } - .gridicons-checkmark > :first-child, - .gridicons-notice > :first-child { + .gridicons-checkmark > use:first-child, + .gridicons-notice > g:first-child { transform: rotate( 0deg ); } }