diff --git a/.eslintignore b/.eslintignore
index 2e0ac92741fb37..fd1ac9f8804043 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -12,7 +12,7 @@
/packages/material-ui-codemod/src/*/*.test.js
/packages/material-ui-icons/src
/packages/material-ui-icons/test/fixtures
-/packages/material-ui-icons/tpl
+/packages/material-ui-icons/templateSvgIcon.js
/tmp
build
node_modules
diff --git a/.gitignore b/.gitignore
index 485041be7dcbf0..9df1bb8a651ee6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,6 +12,7 @@
/coverage
/docs/export
/packages/material-ui-codemod/lib
+/packages/material-ui-icons/material-design-icons
/test/regressions/screenshots
/test/selenium-output
/tmp
diff --git a/docs/src/modules/components/AppFrame.js b/docs/src/modules/components/AppFrame.js
index 7857d5da2a45ec..521bc2b12dbb88 100644
--- a/docs/src/modules/components/AppFrame.js
+++ b/docs/src/modules/components/AppFrame.js
@@ -11,12 +11,12 @@ import Toolbar from '@material-ui/core/Toolbar';
import IconButton from '@material-ui/core/IconButton';
import Tooltip from '@material-ui/core/Tooltip';
import MenuIcon from '@material-ui/icons/Menu';
-import LightbulbOutline from '@material-ui/icons/LightbulbOutline';
-import LightbublFull from '@material-ui/docs/svgIcons/LightbublFull';
+import LightbulbOutlineIcon from '@material-ui/docs/svgIcons/LightbulbOutline';
+import LightbulbFullIcon from '@material-ui/docs/svgIcons/LightbulbFull';
import NProgressBar from '@material-ui/docs/NProgressBar';
import FormatTextdirectionLToR from '@material-ui/icons/FormatTextdirectionLToR';
import FormatTextdirectionRToL from '@material-ui/icons/FormatTextdirectionRToL';
-import Github from '@material-ui/docs/svgIcons/GitHub';
+import GithubIcon from '@material-ui/docs/svgIcons/GitHub';
import AppDrawer from 'docs/src/modules/components/AppDrawer';
import AppSearch from 'docs/src/modules/components/AppSearch';
import Notifications from 'docs/src/modules/components/Notifications';
@@ -152,7 +152,7 @@ class AppFrame extends React.Component {
onClick={this.handleTogglePaletteType}
aria-labelledby="appbar-theme"
>
- {uiTheme.paletteType === 'light' ? : }
+ {uiTheme.paletteType === 'light' ? : }
-
+
diff --git a/docs/src/modules/components/Demo.js b/docs/src/modules/components/Demo.js
index 5d5090b365255d..5d152b82dc7113 100644
--- a/docs/src/modules/components/Demo.js
+++ b/docs/src/modules/components/Demo.js
@@ -6,7 +6,7 @@ import copy from 'clipboard-copy';
import { withStyles } from '@material-ui/core/styles';
import IconButton from '@material-ui/core/IconButton';
import Collapse from '@material-ui/core/Collapse';
-import ModeEditIcon from '@material-ui/icons/ModeEdit';
+import EditIcon from '@material-ui/icons/Edit';
import CodeIcon from '@material-ui/icons/Code';
import Menu from '@material-ui/core/Menu';
import MenuItem from '@material-ui/core/MenuItem';
@@ -226,7 +226,7 @@ class Demo extends React.Component {
onClick={this.handleClickCodeSandbox}
aria-labelledby={`demo-codesandbox-${index}`}
>
-
+
)}
diff --git a/docs/src/modules/components/HomeSteps.js b/docs/src/modules/components/HomeSteps.js
index 84521dd5bf7c64..a8de92ca3e03df 100644
--- a/docs/src/modules/components/HomeSteps.js
+++ b/docs/src/modules/components/HomeSteps.js
@@ -6,7 +6,7 @@ import Typography from '@material-ui/core/Typography';
import Grid from '@material-ui/core/Grid';
import Button from '@material-ui/core/Button';
import Divider from '@material-ui/core/Divider';
-import FileDownloadIcon from '@material-ui/icons/FileDownload';
+import FileDownloadIcon from '@material-ui/docs/svgIcons/FileDownload';
import BuildIcon from '@material-ui/icons/Build'; // eslint-disable-line import/no-unresolved
import WhatshotIcon from '@material-ui/icons/Whatshot';
import MarkdownElement from '@material-ui/docs/MarkdownElement';
diff --git a/docs/src/pages/demos/buttons/FloatingActionButtonZoom.js b/docs/src/pages/demos/buttons/FloatingActionButtonZoom.js
index 5457fe8160018c..61c625d1f62ef9 100644
--- a/docs/src/pages/demos/buttons/FloatingActionButtonZoom.js
+++ b/docs/src/pages/demos/buttons/FloatingActionButtonZoom.js
@@ -10,7 +10,7 @@ import Typography from '@material-ui/core/Typography';
import Zoom from '@material-ui/core/Zoom';
import Button from '@material-ui/core/Button';
import AddIcon from '@material-ui/icons/Add';
-import EditIcon from '@material-ui/icons/ModeEdit';
+import EditIcon from '@material-ui/icons/Edit';
import UpIcon from '@material-ui/icons/KeyboardArrowUp';
import green from '@material-ui/core/colors/green';
diff --git a/docs/src/pages/demos/buttons/IconLabelButtons.js b/docs/src/pages/demos/buttons/IconLabelButtons.js
index 00ebb2cb11f891..b6cd34848b16ac 100644
--- a/docs/src/pages/demos/buttons/IconLabelButtons.js
+++ b/docs/src/pages/demos/buttons/IconLabelButtons.js
@@ -3,11 +3,11 @@ import PropTypes from 'prop-types';
import classNames from 'classnames';
import Button from '@material-ui/core/Button';
import { withStyles } from '@material-ui/core/styles';
-import Delete from '@material-ui/icons/Delete';
-import FileUpload from '@material-ui/icons/FileUpload';
-import KeyboardVoice from '@material-ui/icons/KeyboardVoice';
+import DeleteIcon from '@material-ui/icons/Delete';
+import CloudUploadIcon from '@material-ui/icons/CloudUpload';
+import KeyboardVoiceICon from '@material-ui/icons/KeyboardVoice';
import Icon from '@material-ui/core/Icon';
-import Save from '@material-ui/icons/Save';
+import SaveIcon from '@material-ui/icons/Save';
const styles = theme => ({
button: {
@@ -30,7 +30,7 @@ function IconLabelButtons(props) {
diff --git a/docs/src/pages/lab/speed-dial/OpenIconSpeedDial.js b/docs/src/pages/lab/speed-dial/OpenIconSpeedDial.js
index cd42b725909601..bd203fe3a50824 100644
--- a/docs/src/pages/lab/speed-dial/OpenIconSpeedDial.js
+++ b/docs/src/pages/lab/speed-dial/OpenIconSpeedDial.js
@@ -5,12 +5,12 @@ import Button from '@material-ui/core/Button';
import SpeedDial from '@material-ui/lab/SpeedDial';
import SpeedDialIcon from '@material-ui/lab/SpeedDialIcon';
import SpeedDialAction from '@material-ui/lab/SpeedDialAction';
-import ContentCopyIcon from '@material-ui/icons/ContentCopy';
+import FileCopyIcon from '@material-ui/icons/FileCopyOutlined';
import SaveIcon from '@material-ui/icons/Save';
import PrintIcon from '@material-ui/icons/Print';
import ShareIcon from '@material-ui/icons/Share';
import DeleteIcon from '@material-ui/icons/Delete';
-import EditIcon from '@material-ui/icons/ModeEdit';
+import EditIcon from '@material-ui/icons/Edit';
const styles = theme => ({
root: {
@@ -24,7 +24,7 @@ const styles = theme => ({
});
const actions = [
- { icon: , name: 'Copy' },
+ { icon: , name: 'Copy' },
{ icon: , name: 'Save' },
{ icon: , name: 'Print' },
{ icon: , name: 'Share' },
diff --git a/docs/src/pages/lab/speed-dial/SpeedDials.js b/docs/src/pages/lab/speed-dial/SpeedDials.js
index f296b1d530f2cb..66a9bf392de6ad 100644
--- a/docs/src/pages/lab/speed-dial/SpeedDials.js
+++ b/docs/src/pages/lab/speed-dial/SpeedDials.js
@@ -5,7 +5,7 @@ import Button from '@material-ui/core/Button';
import SpeedDial from '@material-ui/lab/SpeedDial';
import SpeedDialIcon from '@material-ui/lab/SpeedDialIcon';
import SpeedDialAction from '@material-ui/lab/SpeedDialAction';
-import ContentCopyIcon from '@material-ui/icons/ContentCopy';
+import FileCopyIcon from '@material-ui/icons/FileCopyOutlined';
import SaveIcon from '@material-ui/icons/Save';
import PrintIcon from '@material-ui/icons/Print';
import ShareIcon from '@material-ui/icons/Share';
@@ -23,7 +23,7 @@ const styles = theme => ({
});
const actions = [
- { icon: , name: 'Copy' },
+ { icon: , name: 'Copy' },
{ icon: , name: 'Save' },
{ icon: , name: 'Print' },
{ icon: , name: 'Share' },
diff --git a/docs/src/pages/style/icons/SvgMaterialIcons.js b/docs/src/pages/style/icons/SvgMaterialIcons.js
index 4948541d93c910..98c399b36a4113 100644
--- a/docs/src/pages/style/icons/SvgMaterialIcons.js
+++ b/docs/src/pages/style/icons/SvgMaterialIcons.js
@@ -1,8 +1,20 @@
import React from 'react';
import PropTypes from 'prop-types';
-import AlarmIcon from '@material-ui/icons/Alarm';
-import AlarmOffIcon from '@material-ui/icons/AlarmOff';
+import Grid from '@material-ui/core/Grid';
+import Typography from '@material-ui/core/Typography';
+import DeleteIcon from '@material-ui/icons/Delete';
+import DeleteOutlinedIcon from '@material-ui/icons/DeleteOutlined';
+import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded';
+import DeleteTwoToneIcon from '@material-ui/icons/DeleteTwoTone';
+import DeleteSharpIcon from '@material-ui/icons/DeleteSharp';
+import DeleteForeverIcon from '@material-ui/icons/DeleteForever';
+import DeleteForeverOutlinedIcon from '@material-ui/icons/DeleteForeverOutlined';
+import DeleteForeverRoundedIcon from '@material-ui/icons/DeleteForeverRounded';
+import DeleteForeverTwoToneIcon from '@material-ui/icons/DeleteForeverTwoTone';
+import DeleteForeverSharpIcon from '@material-ui/icons/DeleteForeverSharp';
import ThreeDRotationIcon from '@material-ui/icons/ThreeDRotation';
+import FourKIcon from '@material-ui/icons/FourK';
+import ThreeSixtyIcon from '@material-ui/icons/ThreeSixty';
import { withStyles } from '@material-ui/core/styles';
const styles = theme => ({
@@ -11,17 +23,58 @@ const styles = theme => ({
},
icon: {
margin: theme.spacing.unit,
+ fontSize: 32,
},
});
function SvgMaterialIcons(props) {
const { classes } = props;
return (
-
+
+
+ Filled
+
+
+
+
+
+
+ Outlined
+
+
+
+
+
+
+ Rounded
+
+
+
+
+
+
+ Two Tone
+
+
+
+
+
+
+ Sharp
+
+
+
+
+
+
+ Edge-cases
+
+
+
+
+
+
+
);
}
diff --git a/docs/src/pages/style/icons/icons.md b/docs/src/pages/style/icons/icons.md
index 4a08e8e110af41..a21792fa8710e2 100644
--- a/docs/src/pages/style/icons/icons.md
+++ b/docs/src/pages/style/icons/icons.md
@@ -33,19 +33,27 @@ Optionally, you can set the icon color using one of the theme color properties:
It's interesting to have the building blocks needed to implement custom icons, but what about presets?
We provide a separate NPM package,
[@material-ui/icons](https://www.npmjs.com/package/@material-ui/icons),
-that includes the 900+ official [Material icons](https://material.io/tools/icons/?style=baseline) converted to `SvgIcon` components.
+that includes the 1,000+ official [Material icons](https://material.io/tools/icons/?style=baseline) converted to `SvgIcon` components.
-
+
You can use [material.io/tools/icons](https://material.io/tools/icons/?style=baseline) to find a specific icon.
When importing an icon, keep in mind that the names of the icons are `PascalCase`, for instance:
-- [`alarm`](https://material.io/tools/icons/?icon=alarm&style=baseline) is exposed as `@material-ui/icons/Alarm`
-- [`alarm off`](https://material.io/tools/icons/?icon=alarm_off&style=baseline) is exposed as `@material-ui/icons/AlarmOff`
-
-There is one exception to this rule:
-- [`3d_rotation`](https://material.io/tools/icons/?icon=3d_rotation&style=baseline) is exposed as `@material-ui/icons/ThreeDRotation`.
+- [`delete`](https://material.io/tools/icons/?icon=delete&style=baseline) is exposed as `@material-ui/icons/Delete`
+- [`delete forever`](https://material.io/tools/icons/?icon=delete_forever&style=baseline) is exposed as `@material-ui/icons/DeleteForever`
+
+For *"themed"* icons, append the theme name to the icon name. For instance with the
+- The Outlined [`delete`](https://material.io/tools/icons/?icon=delete&style=outline) icon is exposed as `@material-ui/icons/BuildOutlined`
+- The Rounded [`delete`](https://material.io/tools/icons/?icon=delete&style=rounded) icon is exposed as `@material-ui/icons/BuildRounded`
+- The Two Tone [`delete`](https://material.io/tools/icons/?icon=delete&style=twotone) icon is exposed as `@material-ui/icons/BuildTwoTone`
+- The Sharp [`delete`](https://material.io/tools/icons/?icon=delete&style=sharp) icon is exposed as `@material-ui/icons/BuildSharp`
+
+There are three exceptions to this rule:
+- [`3d_rotation`](https://material.io/tools/icons/?icon=3d_rotation&style=baseline) is exposed as `@material-ui/icons/ThreeDRotation`
+- [`4k`](https://material.io/tools/icons/?icon=4k&style=baseline) is exposed as `@material-ui/icons/FourK`
+- [`360`](https://material.io/tools/icons/?icon=360&style=baseline) is exposed as `@material-ui/icons/ThreeSixty`
{{"demo": "pages/style/icons/SvgMaterialIcons.js"}}
diff --git a/packages/material-ui-docs/package.json b/packages/material-ui-docs/package.json
index dedc87c9898de3..0c5250ad4b16c0 100644
--- a/packages/material-ui-docs/package.json
+++ b/packages/material-ui-docs/package.json
@@ -31,7 +31,6 @@
},
"peerDependencies": {
"@material-ui/core": "^1.0.0",
- "@material-ui/icons": "^1.0.0",
"react": "^16.3.0",
"react-dom": "^16.3.0"
},
diff --git a/packages/material-ui-docs/src/svgIcons/FileDownload.js b/packages/material-ui-docs/src/svgIcons/FileDownload.js
new file mode 100644
index 00000000000000..bfda83e1d7ce0b
--- /dev/null
+++ b/packages/material-ui-docs/src/svgIcons/FileDownload.js
@@ -0,0 +1,16 @@
+/* eslint-disable max-len */
+
+import React from 'react';
+import SvgIcon from '@material-ui/core/SvgIcon';
+
+function FileDownload(props) {
+ return (
+
+
+
+ );
+}
+
+FileDownload.muiName = 'SvgIcon';
+
+export default FileDownload;
diff --git a/packages/material-ui-docs/src/svgIcons/LightbublFull.js b/packages/material-ui-docs/src/svgIcons/LightbulbFull.js
similarity index 80%
rename from packages/material-ui-docs/src/svgIcons/LightbublFull.js
rename to packages/material-ui-docs/src/svgIcons/LightbulbFull.js
index 695fd6c00aafee..1d1d0aa51814d2 100644
--- a/packages/material-ui-docs/src/svgIcons/LightbublFull.js
+++ b/packages/material-ui-docs/src/svgIcons/LightbulbFull.js
@@ -3,7 +3,7 @@
import React from 'react';
import SvgIcon from '@material-ui/core/SvgIcon';
-function LightbublFull(props) {
+function LightbulbFull(props) {
return (
@@ -11,6 +11,6 @@ function LightbublFull(props) {
);
}
-LightbublFull.muiName = 'SvgIcon';
+LightbulbFull.muiName = 'SvgIcon';
-export default LightbublFull;
+export default LightbulbFull;
diff --git a/packages/material-ui-docs/src/svgIcons/LightbulbOutline.js b/packages/material-ui-docs/src/svgIcons/LightbulbOutline.js
new file mode 100644
index 00000000000000..ff073ff65d4dbd
--- /dev/null
+++ b/packages/material-ui-docs/src/svgIcons/LightbulbOutline.js
@@ -0,0 +1,16 @@
+/* eslint-disable max-len */
+
+import React from 'react';
+import SvgIcon from '@material-ui/core/SvgIcon';
+
+function LightbulbOutline(props) {
+ return (
+
+
+
+ );
+}
+
+LightbulbOutline.muiName = 'SvgIcon';
+
+export default LightbulbOutline;
diff --git a/packages/material-ui-icons/README.md b/packages/material-ui-icons/README.md
index bfac7c02eab8ba..c3488879e79aa9 100644
--- a/packages/material-ui-icons/README.md
+++ b/packages/material-ui-icons/README.md
@@ -1,6 +1,6 @@
# @material-ui/icons
-This package provides the Google [Material icons](https://material.io/icons/) packaged as a set of [React](https://facebook.github.io/react/) components.
+This package provides the Google [Material icons](https://material.io/tools/icons/) packaged as a set of [React](https://facebook.github.io/react/) components.
## Installation
@@ -25,11 +25,15 @@ yarn add @material-ui/core
## Usage
-The import path for each Material icon component includes the icon name in PascalCase. There are two versions provided: filled icon and outline icon. Append `Outline` to the icon name to use the outlined version of the icon (i.e., `@material-ui/icons/InfoOutline`) when available, as not all icons are provided with two versions.
+The import path for each Material icon component includes the icon name in PascalCase.
For example to use the 'access alarm' icon component, import `@material-ui/icons/AccessAlarm`.
+For "themed" icons, append the theme name to the icon name, for example `AccessAlarmOutlined`.
-Note: One exception is '3d rotation', which is named `ThreeDRotation`.
+Note, there are three exceptions:
+- '3d rotation' is named `ThreeDRotation`
+- '4k' is named `FourK`
+- '360' is named `ThreeSixty`
### Examples
diff --git a/packages/material-ui-icons/builder.js b/packages/material-ui-icons/builder.js
index 3cff859c48bf7e..ad5e9502d0377b 100755
--- a/packages/material-ui-icons/builder.js
+++ b/packages/material-ui-icons/builder.js
@@ -7,55 +7,109 @@ import rimraf from 'rimraf';
import Mustache from 'mustache';
import glob from 'glob';
import mkdirp from 'mkdirp';
+import SVGO from 'svgo';
const RENAME_FILTER_DEFAULT = './filters/rename/default';
const RENAME_FILTER_MUI = './filters/rename/material-design-icons';
+const svgo = new SVGO({
+ plugins: [
+ { cleanupAttrs: true },
+ { removeDoctype: true },
+ { removeXMLProcInst: true },
+ { removeComments: true },
+ { removeMetadata: true },
+ { removeTitle: true },
+ { removeDesc: true },
+ { removeUselessDefs: true },
+ { removeXMLNS: true },
+ { removeEditorsNSData: true },
+ { removeEmptyAttrs: true },
+ { removeHiddenElems: true },
+ { removeEmptyText: true },
+ { removeEmptyContainers: true },
+ { removeViewBox: true },
+ { cleanupEnableBackground: true },
+ { minifyStyles: true },
+ { convertStyleToAttrs: true },
+ { convertColors: true },
+ { convertPathData: true },
+ { convertTransform: true },
+ { removeUnknownsAndDefaults: true },
+ { removeNonInheritableGroupAttrs: true },
+ { removeUselessStrokeAndFill: true },
+ { removeUnusedNS: true },
+ { cleanupIDs: true },
+ { cleanupNumericValues: true },
+ { cleanupListOfValues: true },
+ { moveElemsAttrsToGroup: true },
+ { moveGroupAttrsToElems: true },
+ { collapseGroups: true },
+ { removeRasterImages: true },
+ { mergePaths: true },
+ { convertShapeToPath: true },
+ { sortAttrs: true },
+ { removeDimensions: true },
+ { removeAttrs: true },
+ { removeElementsByAttr: true },
+ { removeStyleElement: true },
+ { removeScriptElement: true },
+ ],
+});
+
/**
- * Return Pascal-Cased classname.
+ * Return Pascal-Cased component name.
*
* @param {string} svgPath
* @returns {string} class name
*/
-function pascalCase(destPath) {
+function getComponentName(destPath) {
const splitregex = new RegExp(`[${path.sep}-]+`);
- let parts = destPath.replace('.js', '').split(splitregex);
- parts = parts.map(part => {
- return part.charAt(0).toUpperCase() + part.substring(1);
- });
-
- const className = parts.join('');
+ const parts = destPath
+ .replace('.js', '')
+ .split(splitregex)
+ .map(part => {
+ return part.charAt(0).toUpperCase() + part.substring(1);
+ });
- return className;
+ return parts.join('');
}
-function getJsxString(svgPath, destPath) {
- const className = pascalCase(destPath);
-
- console.log(` ${className}`);
+async function getJsxString(svgPath, destPath, absDestPath) {
+ const componentName = getComponentName(destPath);
+ console.log(` ${componentName}`);
- const data = fs.readFileSync(svgPath, {
- encoding: 'utf8',
- });
- const template = fs.readFileSync(path.join(__dirname, 'tpl/SvgIcon.js'), {
+ const data = fs.readFileSync(svgPath, { encoding: 'utf8' });
+ const template = fs.readFileSync(path.join(__dirname, 'templateSvgIcon.js'), {
encoding: 'utf8',
});
+ const result = await svgo.optimize(data);
// Extract the paths from the svg string
- let paths = data.slice(data.indexOf('>') + 1);
- paths = paths.slice(0, -6);
// Clean xml paths
- paths = paths.replace(/xlink:href="#a"/g, '');
- paths = paths.replace(/xlink:href="#c"/g, '');
- paths = paths.replace(/fill-opacity=/g, 'fillOpacity=');
- paths = paths.replace(/\s?fill=".*?"/g, '');
- paths = paths.replace(/"\/>/g, '" />');
-
- return Mustache.render(template, {
+ const paths = result.data
+ .replace(//g, '')
+ .replace(/<\?xml[^>]*>/g, '')
+ .replace(/