Skip to content

Commit

Permalink
Add the Material Design Light icons. Update Material Design Icons.
Browse files Browse the repository at this point in the history
  • Loading branch information
leMaik committed Jun 22, 2019
1 parent b97b9be commit 16fc2a0
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 30 deletions.
24 changes: 11 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Material Design Icons for Material-UI
[![npm](https://img.shields.io/npm/v/mdi-material-ui/legacy.svg)](https://www.npmjs.com/package/mdi-material-ui)
[![Material Design Icons version](https://img.shields.io/badge/mdi-v3.6.95-blue.svg)](https://github.com/Templarian/MaterialDesign-SVG/)
[![Material Design Icons version](https://img.shields.io/badge/mdi-v3.7.95-blue.svg)](https://github.com/Templarian/MaterialDesign)
[![Material Design Icons version](https://img.shields.io/badge/mdi--light-v0.2.63-blue.svg)](https://github.com/Templarian/MaterialDesignLight)

This module provides [Material-UI][material-ui] `<SvgIcon />` components for all
[Material Design Icons][md-icons]. This is pretty handy if you use React and Material-UI
Expand All @@ -22,14 +23,19 @@ npm install mdi-material-ui@legacy --save
Every icon is exported with its original name in PascalCase. So `coffee` becomes `Coffee`,
`cloud-print-outline` is exported as `CloudPrintOutline` and so on.

The Material Design _Light_ icons are included in the `/light` subdirectory.

### With tree-shaking
If your environment supports tree-shaking and you are sure that it works fine in your setup, you can simply import the icons as follows:

```js
import { Coffee, Food } from 'mdi-material-ui'
import { Camera, Settings } from 'mdi-material-ui/light'

<Coffee />
<Food />
<Camera />
<Settings />
```

### Without tree-shaking
Expand All @@ -38,21 +44,13 @@ If your environment doesn't support tree-shaking, you should only import the ico
```js
import Coffee from 'mdi-material-ui/Coffee'
import Food from 'mdi-material-ui/Food'
import Camera from 'mdi-material-ui/light/Camera'
import Settings from 'mdi-material-ui/light/Settings'

<Coffee />
<Food />
```

If you think that this is far too verbose (I agree!), consider using [babel-plugin-direct-import](https://github.com/umidbekkarimov/babel-plugin-direct-import). Install it and adjust your `.babelrc` by adding the following snippet to the plugins section:

```js
{
// ...
plugins: [
// ...
["direct-import", ["mdi-material-ui"]]
]
}
<Camera />
<Settings />
```

## License
Expand Down
52 changes: 41 additions & 11 deletions generate-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,15 @@ const pick = require('lodash.pick')
svgPath: path
}))

const lightIcons = Object.entries(require('@mdi/light-js'))
.filter(([name]) => name.indexOf('mdil') === 0)
.map(([name, path]) => ({
name: pascalCase(name.substr(4)), // remove mdil prefix
svgPath: path
}))

fse.removeSync(path.join(__dirname, 'package'))
fse.mkdirpSync(path.join(__dirname, 'package'))
fse.mkdirpSync(path.join(__dirname, 'package', 'light'))

for (const { name, svgPath } of icons) {
const code = `import createIcon from './util/createIcon'
Expand All @@ -32,18 +39,39 @@ const pick = require('lodash.pick')
`)
}

// es2015 module syntax
const allExports = icons.map(({ name }) => `export { default as ${name} } from './${name}'`).join('\n')
fse.writeFileSync(path.join(__dirname, 'package', 'index.es.js'), allExports)
for (const { name, svgPath } of lightIcons) {
const code = `import createIcon from '../util/createIcon'
export default createIcon('${svgPath}')
`

// commonjs module syntax
fse.writeFileSync(path.join(__dirname, 'package', 'light', `${name}.js`), babel.transform(code, {
presets: ['es2015', 'react', 'stage-0'],
compact: process.env.NODE_ENV === 'production'
}).code)

// typescript definition
fse.writeFileSync(path.join(__dirname, 'package', 'light', `${name}.d.ts`), `export { default } from '@material-ui/core/SvgIcon'
`)
}

// typescript index definition (looks exactly the same)
fse.writeFileSync(path.join(__dirname, 'package', 'index.d.ts'), allExports)
const generateIndexFiles = (destination, icons) => {
// es2015 module syntax
const allExports = icons.map(({ name }) => `export { default as ${name} } from './${name}'`).join('\n')
fse.writeFileSync(path.join(destination, 'index.es.js'), allExports)

// typescript index definition (looks exactly the same)
fse.writeFileSync(path.join(destination, 'index.d.ts'), allExports)

// commonjs module
fse.writeFileSync(path.join(destination, 'index.js'), babel.transform(allExports, {
plugins: ['transform-es2015-modules-commonjs'],
compact: process.env.NODE_ENV === 'production'
}).code)
}

// commonjs module
fse.writeFileSync(path.join(__dirname, 'package', 'index.js'), babel.transform(allExports, {
plugins: ['transform-es2015-modules-commonjs'],
compact: process.env.NODE_ENV === 'production'
}).code)
generateIndexFiles(path.join(__dirname, 'package'), icons)
generateIndexFiles(path.join(__dirname, 'package', 'light'), lightIcons)

// createIcon function
fse.mkdirSync(path.join(__dirname, 'package', 'util'))
Expand All @@ -57,8 +85,10 @@ const pick = require('lodash.pick')

// update readme
const mdiVersion = require(path.join(require.resolve('@mdi/js'), '..', '..', 'package.json')).version
const mdiLightVersion = require(path.join(require.resolve('@mdi/light-js'), '..', '..', 'package.json')).version
let readme = await fse.readFile(path.join(__dirname, 'README.md'), 'utf-8')
readme = readme.replace(/img\.shields\.io\/badge\/mdi-v(.+?)-blue\.svg/g, `img.shields.io/badge/mdi-v${mdiVersion}-blue.svg`)
readme = readme.replace(/img\.shields\.io\/badge\/mdi--light-v(.+?)-blue\.svg/g, `img.shields.io/badge/mdi--light-v${mdiLightVersion}-blue.svg`)
await fse.writeFile(path.join(__dirname, 'README.md'), readme, 'utf-8')

// copy other files
Expand Down
12 changes: 9 additions & 3 deletions package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@
},
"homepage": "https://github.com/TeamWertarbyte/mdi-material-ui#readme",
"devDependencies": {
"@mdi/js": "^3.6.95",
"@mdi/js": "^3.7.95",
"@mdi/light-js": "^0.2.63",
"@storybook/react": "^3.4.11",
"ava": "^0.25.0",
"babel-core": "^6.8.0",
Expand Down
18 changes: 17 additions & 1 deletion stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import lightBaseTheme from 'material-ui/styles/baseThemes/lightBaseTheme'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import getMuiTheme from 'material-ui/styles/getMuiTheme'
const icons = require('../package/index')
const lightIcons = require('../package/light/index')

function themed (children) {
return (
Expand All @@ -15,7 +16,7 @@ function themed (children) {
)
}

const iconStories = storiesOf('Icons', module)
const iconStories = storiesOf('Material Design Icons', module)
iconStories.add(`all icons (${Object.keys(icons).length.toLocaleString()})`, () => themed(
<div>
{Object.keys(icons).map((icon) => {
Expand All @@ -29,3 +30,18 @@ Object.keys(icons).sort().forEach((icon) => {
const Icon = icons[icon]
iconStories.add(icon, () => themed(<Icon />))
})

const lightIconStories = storiesOf('Material Design Icons Light', module)
lightIconStories.add(`all icons (${Object.keys(lightIcons).length.toLocaleString()})`, () => themed(
<div>
{Object.keys(lightIcons).map((icon) => {
const Icon = lightIcons[icon]
return <Icon key={icon} />
})}
</div>
))

Object.keys(lightIcons).sort().forEach((icon) => {
const Icon = lightIcons[icon]
lightIconStories.add(icon, () => themed(<Icon />))
})
23 changes: 23 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import renderer from 'react-test-renderer'
import fs from 'fs'
import { MuiThemeProvider } from 'material-ui/styles';
const commonjsIcons = require('./package/index')
const commonjsIconsLight = require('./package/light/index')

test('the npm package', (t) => {
// should set sideEffects to false to allow webpack to optimize re-exports
Expand All @@ -22,6 +23,7 @@ for (const iconName of Object.keys(commonjsIcons)) {
t.is(commonjsIcons[iconName].muiName, 'SvgIcon')
})
}

test('ES module index file', (t) => {
const esmReExports = fs.readFileSync('./package/index.es.js', 'utf-8')
.split('\n')
Expand All @@ -34,3 +36,24 @@ test('ES module index file', (t) => {
t.truthy(commonjsIcons[match[1]])
}
})

for (const iconName of Object.keys(commonjsIconsLight)) {
test(`light icons > ${iconName}`, (t) => {
const renderedIcon = renderer.create(React.createElement(commonjsIconsLight[iconName])).toJSON()
t.is(renderedIcon.type, 'svg')
t.is(commonjsIconsLight[iconName].muiName, 'SvgIcon')
})
}

test('mdi-light ES module index file', (t) => {
const esmReExports = fs.readFileSync('./package/light/index.es.js', 'utf-8')
.split('\n')
.filter((line) => line.length > 0)
t.is(esmReExports.length, Object.keys(commonjsIconsLight).length)

for (const line of esmReExports) {
const match = line.match(/^export \{ default as (.+?) \} from '\.\/(.+?)'$/)
t.is(match[1], match[2])
t.truthy(commonjsIconsLight[match[1]])
}
})
2 changes: 1 addition & 1 deletion update.sh
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
#!/bin/sh
npm i --save-dev @mdi/js@latest
npm i --save-dev @mdi/js@latest @mdi/light-js@latest
./generate-module.js

0 comments on commit 16fc2a0

Please sign in to comment.