-
Notifications
You must be signed in to change notification settings - Fork 227
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(icon-button): create component (#154)
- Loading branch information
Matt Goo
authored
Sep 21, 2018
1 parent
cb477f5
commit c7b4cf6
Showing
14 changed files
with
440 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
index.js | ||
IconToggle.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import React, {Component} from 'react'; | ||
import classnames from 'classnames'; | ||
import PropTypes from 'prop-types'; | ||
|
||
export default class IconToggle extends Component { | ||
render() { | ||
const {isOn, className, children} = this.props; | ||
const classes = classnames( | ||
'mdc-icon-button__icon', | ||
{'mdc-icon-button__icon--on': isOn}, | ||
className, | ||
); | ||
return ( | ||
<div className={classes}> | ||
{children} | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
IconToggle.propTypes = { | ||
children: PropTypes.node, | ||
className: PropTypes.string, | ||
isOn: PropTypes.bool, | ||
}; | ||
|
||
IconToggle.defaultProps = { | ||
children: '', | ||
className: '', | ||
isOn: false, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
# React Icon Button | ||
|
||
A React version of an [MDC Icon Button](https://github.com/material-components/material-components-web/tree/master/packages/mdc-icon-button). | ||
|
||
## Installation | ||
|
||
``` | ||
npm install @material/react-icon-button | ||
``` | ||
|
||
## Usage | ||
|
||
```js | ||
import React from 'react'; | ||
import IconButton from '@material/react-icon-button'; | ||
import MaterialIcon from '@material/react-material-icon'; | ||
|
||
class MyApp extends React.Component { | ||
render() { | ||
return ( | ||
<IconButton> | ||
<MaterialIcon icon='favorite' /> | ||
</IconButton> | ||
); | ||
} | ||
} | ||
``` | ||
|
||
You can use any other icon here such as Font Awesome, which is documented more in detail [here](https://github.com/material-components/material-components-web/tree/master/packages/mdc-icon-button#icon-button-toggle-with-font-awesome). If you're using [Google Font's Material Icons](https://material.io/tools/icons/?style=baseline), we recommend using our [Material Icon Component](../material-icon) as shown in the example above. | ||
|
||
## Variants | ||
|
||
### Icon Button Toggle | ||
|
||
If you need to use this component as an Icon Button Toggle, please read [this documentation](https://github.com/material-components/material-components-web/blob/master/packages/mdc-icon-button/README.md#icon-button-toggle). The following is an example using the `<IconToggle />` component as children of `<IconButton>`. One component with the `isOn` prop, and one without. | ||
|
||
```js | ||
import React from 'react'; | ||
import IconButton, {IconToggle} from '@material/react-icon-button'; | ||
import MaterialIcon from '@material/react-material-icon'; | ||
|
||
class MyApp extends React.Component { | ||
render() { | ||
return ( | ||
<IconButton> | ||
<IconToggle isOn> | ||
<MaterialIcon icon='favorite' /> | ||
</IconToggle> | ||
<IconToggle> | ||
<MaterialIcon icon='favorite_border' /> | ||
</IconToggle> | ||
</IconButton> | ||
); | ||
} | ||
} | ||
``` | ||
|
||
## Props | ||
|
||
Prop Name | Type | Description | ||
--- | --- | --- | ||
children | Element | Icon element or text to be displayed within root element. | ||
className | String | Classes to be applied to the root element. | ||
disabled | Boolean | Disables button if true. | ||
isLink | Boolean | Changes root element to an anchor tag (default button). | ||
onClick | Function | Click event handler. Event is passed as an argument | ||
|
||
## Sass Mixins | ||
|
||
Sass mixins may be available to customize various aspects of the Components. Please refer to the | ||
MDC Web repository for more information on what mixins are available, and how to use them. | ||
|
||
[Advanced Sass Mixins](https://github.com/material-components/material-components-web/blob/master/packages/mdc-icon-button/README.md#sass-mixins) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
import React, {Component} from 'react'; | ||
import classnames from 'classnames'; | ||
import PropTypes from 'prop-types'; | ||
import withRipple from '@material/react-ripple'; | ||
import {MDCIconButtonToggleFoundation} from '@material/icon-button/dist/mdc.iconButton'; | ||
import IconToggle from './IconToggle'; | ||
|
||
const {strings} = MDCIconButtonToggleFoundation; | ||
|
||
class IconButtonBase extends Component { | ||
|
||
constructor(props) { | ||
super(props); | ||
this.state = { | ||
classList: new Set(), | ||
[strings.ARIA_PRESSED]: props[strings.ARIA_PRESSED], | ||
}; | ||
} | ||
|
||
componentDidMount() { | ||
this.foundation_ = new MDCIconButtonToggleFoundation(this.adapter); | ||
this.foundation_.init(); | ||
} | ||
|
||
get classes() { | ||
const {classList} = this.state; | ||
const {className} = this.props; | ||
return classnames('mdc-icon-button', Array.from(classList), className); | ||
} | ||
|
||
get adapter() { | ||
return { | ||
addClass: (className) => | ||
this.setState({classList: this.state.classList.add(className)}), | ||
removeClass: (className) => { | ||
const classList = new Set(this.state.classList); | ||
classList.delete(className); | ||
this.setState({classList}); | ||
}, | ||
hasClass: (className) => this.classes.split(' ').includes(className), | ||
setAttr: (attr, value) => this.setState({[attr]: value}), | ||
}; | ||
} | ||
|
||
handleClick_ = (e) => { | ||
this.props.onClick(e); | ||
this.foundation_.handleClick(); | ||
} | ||
|
||
render() { | ||
const { | ||
children, | ||
initRipple, | ||
isLink, | ||
/* eslint-disable no-unused-vars */ | ||
className, | ||
onClick, | ||
unbounded, | ||
[strings.ARIA_PRESSED]: ariaPressed, | ||
/* eslint-enable no-unused-vars */ | ||
...otherProps | ||
} = this.props; | ||
|
||
const props = { | ||
className: this.classes, | ||
ref: initRipple, | ||
[strings.ARIA_PRESSED]: this.state[strings.ARIA_PRESSED], | ||
onClick: this.handleClick_, | ||
...otherProps, | ||
}; | ||
|
||
if (isLink) { | ||
return ( | ||
<a {...props}> | ||
{children} | ||
</a> | ||
); | ||
} | ||
|
||
return ( | ||
<button {...props}> | ||
{children} | ||
</button> | ||
); | ||
} | ||
} | ||
|
||
IconButtonBase.propTypes = { | ||
children: PropTypes.node, | ||
className: PropTypes.string, | ||
initRipple: PropTypes.func, | ||
isLink: PropTypes.bool, | ||
onClick: PropTypes.func, | ||
unbounded: PropTypes.bool, | ||
}; | ||
|
||
IconButtonBase.defaultProps = { | ||
children: '', | ||
className: '', | ||
initRipple: () => {}, | ||
isLink: false, | ||
onClick: () => {}, | ||
unbounded: true, | ||
}; | ||
|
||
export default withRipple(IconButtonBase); | ||
export {IconToggle, IconButtonBase}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
@import "@material/icon-button/mdc-icon-button"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
{ | ||
"name": "@material/react-icon-button", | ||
"version": "0.0.0", | ||
"description": "Material Components React Icon Button", | ||
"license": "Apache-2.0", | ||
"keywords": [ | ||
"mdc web react", | ||
"material components react", | ||
"material design", | ||
"material icon button", | ||
"materialiconbutton" | ||
], | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/material-components/material-components-web-react.git" | ||
}, | ||
"dependencies": { | ||
"@material/icon-button": "^0.39.0", | ||
"@material/react-ripple": "^0.4.2", | ||
"classnames": "^2.2.5", | ||
"prop-types": "^15.6.1", | ||
"react": "^16.3.2" | ||
}, | ||
"publishConfig": { | ||
"access": "public" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import React from 'react'; | ||
import MaterialIcon from '../../../packages/material-icon/index'; | ||
import '../../../packages/icon-button/index.scss'; | ||
import './index.scss'; | ||
|
||
import IconButton, {IconToggle} from '../../../packages/icon-button/index'; | ||
|
||
class IconButtonTest extends React.Component { | ||
render() { | ||
return ( | ||
<div> | ||
<IconButton> | ||
<MaterialIcon icon='favorite' /> | ||
</IconButton> | ||
|
||
<span className='demo-custom-color'> | ||
<IconButton> | ||
<MaterialIcon icon='favorite' /> | ||
</IconButton> | ||
</span> | ||
|
||
<IconButton isLink> | ||
<MaterialIcon icon='favorite' /> | ||
</IconButton> | ||
|
||
<IconButton disabled> | ||
<MaterialIcon icon='favorite' /> | ||
</IconButton> | ||
|
||
<IconButton> | ||
<IconToggle> | ||
<MaterialIcon icon='favorite_border' /> | ||
</IconToggle> | ||
<IconToggle isOn> | ||
<MaterialIcon icon='favorite' /> | ||
</IconToggle> | ||
</IconButton> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
export default IconButtonTest; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
@import "../../../packages/icon-button/index.scss"; | ||
|
||
.demo-custom-color .mdc-icon-button { | ||
@include mdc-icon-button-ink-color(primary); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import React from 'react'; | ||
import {assert} from 'chai'; | ||
import {shallow} from 'enzyme'; | ||
import {IconToggle} from '../../../packages/icon-button/index'; | ||
|
||
suite('IconButtonIconToggle'); | ||
|
||
test('classNames adds classes', () => { | ||
const wrapper = shallow(<IconToggle className='test-class-name' />); | ||
assert.isTrue(wrapper.hasClass('test-class-name')); | ||
}); | ||
|
||
test('has icon button icon class', () => { | ||
const wrapper = shallow(<IconToggle className='test-class-name' />); | ||
assert.isTrue(wrapper.hasClass('mdc-icon-button__icon')); | ||
}); | ||
|
||
test('has icon button on icon class if props.isOn is true', () => { | ||
const wrapper = shallow(<IconToggle isOn className='test-class-name' />); | ||
assert.isTrue(wrapper.hasClass('mdc-icon-button__icon--on')); | ||
}); | ||
|
||
test('renders icon', () => { | ||
const wrapper = shallow(<IconToggle> | ||
<i className='test-icon' /> | ||
</IconToggle>); | ||
assert.equal(wrapper.children().first().type(), 'i'); | ||
}); | ||
|
||
test('renders svg', () => { | ||
const wrapper = shallow(<IconToggle> | ||
<svg className='test-svg' /> | ||
</IconToggle>); | ||
assert.equal(wrapper.children().first().type(), 'svg'); | ||
}); | ||
|
||
test('renders img', () => { | ||
const wrapper = shallow(<IconToggle> | ||
<img className='test-img' /> | ||
</IconToggle>); | ||
assert.equal(wrapper.children().first().type(), 'img'); | ||
}); |
Oops, something went wrong.