From 86b0af132724e859d579f7ef065f9266b85886f4 Mon Sep 17 00:00:00 2001 From: Sithum Nissanka Date: Mon, 17 Sep 2018 15:41:18 +0200 Subject: [PATCH 1/3] fix(pencil): Latest fixes and features --- README.md | 14 +++--- demo/.alm/sessionsV2.json | 17 +++++++ demo/package.json | 2 +- demo/src/App.css | 35 +++++++++++++++ demo/src/App.js | 94 ++++++++++++++++++++++++--------------- package.json | 4 +- src/__tests__/index.js | 81 ++++++++++++++++++--------------- src/index.css | 21 ++++++++- src/index.js | 65 ++++++++++++++++++++++----- 9 files changed, 242 insertions(+), 91 deletions(-) create mode 100644 demo/.alm/sessionsV2.json diff --git a/README.md b/README.md index d369ee0..f207fff 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ # material-icons-react -[![Build Status](https://semaphoreci.com/api/v1/logtrace/material-icons-react/branches/remove-mocha-from-deps/shields_badge.svg)](https://semaphoreci.com/logtrace/material-icons-react) +[![Build Status](https://semaphoreci.com/api/v1/logtrace/material-icons-react/branches/master/shields_badge.svg)](https://semaphoreci.com/logtrace/material-icons-react) -## NOTE: Version 1.0.1 release +## NOTE: Version 1.0.3 release -* Spelling mistakes corrected -* Proptypes added -* Unwanted dependencies for production is removed from `dependencies` +* Demo app added +* Fix for [#1](https://github.com/logtrace/material-icons-react/issues/1) +* Fix for [#11](https://github.com/logtrace/material-icons-react/issues/11) +* Fix for [#12](https://github.com/logtrace/material-icons-react/issues/12) +* Fix for [#13](https://github.com/logtrace/material-icons-react/issues/13) +* Passing in `className` prop will replace the default icon styles, defaultColor and inactive styles. Own styles for these should be provided if className prop is defined. ## Introduction @@ -57,6 +60,7 @@ import MaterialIcon, {colorPalette} from 'material-icons-react'; ``` + ## Icon size matrix | Alias | Size | |-------|-----:| diff --git a/demo/.alm/sessionsV2.json b/demo/.alm/sessionsV2.json new file mode 100644 index 0000000..692b35b --- /dev/null +++ b/demo/.alm/sessionsV2.json @@ -0,0 +1,17 @@ +{ + "sessions": [ + { + "id": "6d48b963-c09f-418a-9c33-45977096d663", + "tabLayout": { + "type": "stack", + "width": 100, + "height": 100, + "tabs": [], + "subItems": [], + "activeItemIndex": 0 + }, + "lastUsed": 1532597970240, + "selectedTabId": null + } + ] +} diff --git a/demo/package.json b/demo/package.json index e77ecaf..bac0caa 100644 --- a/demo/package.json +++ b/demo/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { - "material-icons-react": "1.0.1", + "material-icons-react": "file:///mnt/c/Users/snissanka/Documents/workspaces/MyProjects/material-icons-react", "react": "^16.4.1", "react-dom": "^16.4.1", "react-scripts": "1.1.4" diff --git a/demo/src/App.css b/demo/src/App.css index 63c7846..f43022b 100644 --- a/demo/src/App.css +++ b/demo/src/App.css @@ -33,3 +33,38 @@ from { transform: rotate(0deg); } to { transform: rotate(360deg); } } + +.lds-ripple { + display: inline-block; + position: relative; + width: 64px; + height: 64px; +} +.lds-ripple div { + position: absolute; + border: 4px solid #921515; + opacity: 1; + border-radius: 50%; + animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; +} +.lds-ripple div:nth-child(2) { + animation-delay: -0.5s; +} + +@keyframes lds-ripple { + 0% { + top: 28px; + left: 28px; + width: 0; + height: 0; + opacity: 1; + } + 100% { + top: -1px; + left: -1px; + width: 58px; + height: 58px; + opacity: 0; + } +} + diff --git a/demo/src/App.js b/demo/src/App.js index 0d71392..70e46c6 100644 --- a/demo/src/App.js +++ b/demo/src/App.js @@ -4,7 +4,19 @@ import './App.css'; import MaterialIcon, {colorPalette} from 'material-icons-react'; class App extends Component { + + constructor(props) { + super(props) + + this.state = { + inactive: false + } + } + render() { + + let loader =
+ return (
@@ -13,42 +25,52 @@ class App extends Component {
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Default
Default
Large
Custom size(100)
Inverted
Inactive
Color from pallete(amber._200)
Color from pallete(amber.A700)
Custom color(#7bb92f)
Default
Default
Large
Custom size(100)
Inverted
Inactive
Color from pallete(amber._200)
Color from pallete(amber.A700)
Custom color(#7bb92f)
Preloader
Additional props
diff --git a/package.json b/package.json index 356b96d..f3b5d5f 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,9 @@ "react-component", "react", "material-icons", - "google" + "material design", + "google", + "material-ui" ], "options": { "mocha": "--require ignore-styles --require scripts/mocha_runner src/**/__tests__/**/*.js" diff --git a/src/__tests__/index.js b/src/__tests__/index.js index 81bc3b8..605b371 100644 --- a/src/__tests__/index.js +++ b/src/__tests__/index.js @@ -6,68 +6,79 @@ import sinon from 'sinon'; import MaterialIcon from '../index'; -const loadIconAndValidateBasic = (props) => { - const wrapper = shallow(); - expect(wrapper.find('.material-icons')).to.have.length(1); +const loadIcon = (props) => { + const wrapper = mount(); + return wrapper; } -const loadAndValidateWithIcon = (props) => { - const wrapper = loadIconAndValidateBasic(props); - expect(wrapper.find('.material-icons').text()).to.equal('face'); - return wrapper; -} +describe('MaterialIcon renders', () => { + it('with an `i`', () => { + const wrapper = loadIcon({icon: 'face'}) + + expect(wrapper.find('i')).to.be.not.null + }); -describe('MaterialIcon renders without any props', () => { - it('to have an `i`', () => { - loadIconAndValidateBasic(); + it('with the icon prop', () => { + const wrapper = loadIcon({icon: 'face'}) + + expect(wrapper.props().icon).to.equal('face'); }); -}); -describe('MaterialIcon renders with icon prop', () => { - it('to have an `i` with class md-24 by default', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face' }); - expect(wrapper.find('.material-icons').hasClass('md-24')).to.equal(true); + it('with class md-24 by default', async () => { + const wrapper = loadIcon({ icon: 'face' }); + + expect(wrapper.find('i').hasClass('md-24')).to.equal(true); }); - it('to have an `i` with size prop overridden to medium', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face', size: 'medium' }); - expect(wrapper.find('.material-icons').hasClass('md-36')).to.equal(true); + it('with size prop overridden to medium', async () => { + const wrapper = loadIcon({ icon: 'face', size: 'medium' }); + + expect(wrapper.find('i').hasClass('md-36')).to.equal(true); }); -}); -describe('MaterialIcon renders', () => { - it('to have an `i` with dark color by default', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face' }); + it('with dark color by default', () => { + const wrapper = loadIcon({ icon: 'face' }); expect(wrapper.find('.material-icons').hasClass('md-dark')).to.equal(true); }); - it('to have an `i` with light color when inverted', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face', invert: true }); + it('with light color when inverted', () => { + const wrapper = loadIcon({ icon: 'face', invert: true }); expect(wrapper.find('.material-icons').hasClass('md-light')).to.equal(true); }); -}); -describe('MaterialIcon renders', () => { - it('to have an `i` with active state by default', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face' }); + it('with active state by default', () => { + const wrapper = loadIcon({ icon: 'face' }); expect(wrapper.find('.material-icons').hasClass('md-inactive')).to.equal(false); }); - it('to have an `i` with `md-inactive` when inactive', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face', inactive: true }); + it('with `md-inactive` when inactive', () => { + const wrapper = loadIcon({ icon: 'face', inactive: true }); expect(wrapper.find('.material-icons').hasClass('md-inactive')).to.equal(true); }); - it('to have an `i` with active state by default when inverted', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face', invert: true }); + it('with active state by default when inverted', () => { + const wrapper = loadIcon({ icon: 'face', invert: true }); expect(wrapper.find('.material-icons').hasClass('md-light')).to.equal(true); expect(wrapper.find('.material-icons').hasClass('md-inactive')).to.equal(false); }); - it('to have an `i` with `md-inactive` and `md-light` when inactive and inverted', () => { - const wrapper = loadAndValidateWithIcon({ icon: 'face', invert: true, inactive: true }); + it('with `md-inactive` and `md-light` when inactive and inverted', () => { + const wrapper = loadIcon({ icon: 'face', invert: true, inactive: true }); expect(wrapper.find('.material-icons').hasClass('md-light')).to.equal(true); expect(wrapper.find('.material-icons').hasClass('md-inactive')).to.equal(true); }); + + it('with default classes overriden when className prop provided', () => { + const wrapper = loadIcon({ icon: 'face', className: 'test-class-name' }); + + expect(wrapper.find('i').hasClass('test-class-name')).to.equal(true); + }); + + it('with custom props available', () => { + const wrapper = loadIcon({ icon: 'face', testProp: 'custom-prop'}); + + expect(wrapper.props().testProp).to.be.not.null + expect(wrapper.props().testProp).to.equal('custom-prop') + }); }); \ No newline at end of file diff --git a/src/index.css b/src/index.css index b07b260..d7430d1 100644 --- a/src/index.css +++ b/src/index.css @@ -1,4 +1,16 @@ -@import url('https://fonts.googleapis.com/css?family=Material+Icons'); +/*@import url('https://fonts.googleapis.com/css?family=Material+Icons');*/ + +@font-face { + font-family: 'Material Icons'; + font-style: normal; + font-weight: 400; + src: url(https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/fonts/Material-Design-Iconic-Font.eot); /* For IE6-8 */ + src: local('Material Icons'), + local('MaterialIcons-Regular'), + url(https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/fonts/Material-Design-Iconic-Font.woff2) format('woff2'), + url(https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/fonts/Material-Design-Iconic-Font.woff) format('woff'), + url(https://cdnjs.cloudflare.com/ajax/libs/material-design-iconic-font/2.2.0/fonts/Material-Design-Iconic-Font.ttf) format('truetype'); +} .material-icons { font-family: 'Material Icons'; @@ -38,4 +50,9 @@ /* Rules for using icons as white on a dark background. */ .material-icons.md-light { color: rgba(255, 255, 255, 1); } -.material-icons.md-light.md-inactive { color: rgba(255, 255, 255, 0.3); } \ No newline at end of file +.material-icons.md-light.md-inactive { color: rgba(255, 255, 255, 0.3); } + +/* Toggle icon display +.material-icons.show { display: block } +.material-icons.show { display: none } +*/ \ No newline at end of file diff --git a/src/index.js b/src/index.js index 710b965..dd1be0c 100644 --- a/src/index.js +++ b/src/index.js @@ -1,19 +1,62 @@ -import React from 'react'; +import React, { Component } from 'react'; import PropTypes from 'prop-types'; +import WebFont from 'webfontloader'; import './index.css'; import { sizes, light, dark, mdInactive } from './config/mappings'; -const MaterialIcon = ({ icon, size, invert, inactive, color, style }) => { - const sizeMapped = sizes[size] || parseInt(size) || sizes['small']; - const defaultColor = (invert && 'invert') ? light : dark; - const inactiveColor = (inactive && 'inactive') ? mdInactive : ''; - const propStyle = style || {}; - const styleOverride = Object.assign(propStyle, {color: color ? color : '', fontSize: sizeMapped}); - - return ( - {icon} - ) +class MaterialIcon extends Component { + constructor(props) { + super(props); + + const {preloader} = this.props; + + this.state = { + element: preloader + } + + this.onFontActive = this.onFontActive.bind(this); + this.processProps = this.processProps.bind(this); + + WebFont.load({ + google: { + families: ['Material+Icons'] + }, + timeout:5000, + fontactive: this.onFontActive + }) + } + + componentDidMount() { + + } + + onFontActive(fontFamily, fvd) { + const {size, invert, inactive, style, className, icon, color, ...other} = this.processProps(); + + this.setState({element: {icon}}) + } + + processProps() { + const {size, invert, inactive, style, className, color, icon, ...other} = this.props; + + const sizeMapped = sizes[size] || parseInt(size) || sizes['small']; + const defaultColor = (invert && 'invert') ? light : dark; + const inactiveColor = (inactive && 'inactive') ? mdInactive : ''; + const propStyle = style || {}; + const styleOverride = Object.assign(propStyle, {color: color ? color : '', fontSize: sizeMapped}); + const clsName = className || `material-icons ${sizeMapped} ${defaultColor} ${inactiveColor}`; + + return { + icon, sizeMapped, defaultColor, inactiveColor, propStyle, styleOverride, clsName, ...other + } + } + + render() { + const {sizeMapped, defaultColor, inactiveColor, propStyle, styleOverride, clsName, ...other} = this.processProps(); + + return (this.state.element || ) + } } MaterialIcon.propTypes = { From 8ad61c42bdd5eb762b848f646e7aea8f73b92861 Mon Sep 17 00:00:00 2001 From: Sithum Nissanka Date: Mon, 17 Sep 2018 19:51:56 +0200 Subject: [PATCH 2/3] fix(pencil): Readme update --- README.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/README.md b/README.md index f207fff..c36bbc6 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,39 @@ import MaterialIcon, {colorPalette} from 'material-icons-react'; ``` +## Showing a preloader until the icon is rendered(For slow connections) +1. CSS + +``` +.lds-ripple { + display: inline-block; + position: relative; + width: 64px; + height: 64px; +} +.lds-ripple div { + position: absolute; + border: 4px solid #921515; + opacity: 1; + border-radius: 50%; + animation: lds-ripple 1s cubic-bezier(0, 0.2, 0.8, 1) infinite; +} +.lds-ripple div:nth-child(2) { + animation-delay: -0.5s; +} +``` + +2. Preloader element + +``` +let loader =
+``` + +3. Icon + +``` + +``` ## Icon size matrix | Alias | Size | From ed399a70e71d33b7cb7f78259143630dcde76d26 Mon Sep 17 00:00:00 2001 From: Sithum Nissanka Date: Mon, 17 Sep 2018 20:04:22 +0200 Subject: [PATCH 3/3] fix(pencil): Missing dependency --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index f3b5d5f..823db72 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "dependencies": { "prop-types": "^15.6.1", "react": "^15.0.0", - "react-dom": "^15.0.0" + "react-dom": "^15.0.0", + "webfontloader": "^1.6.28" } }