Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save shawnsandy/3a4eb3ee53f0957d6a81 to your computer and use it in GitHub Desktop.

Select an option

Save shawnsandy/3a4eb3ee53f0957d6a81 to your computer and use it in GitHub Desktop.
Material Design Button in ReactJS with Encapsulated Styles
<div id="container"></div>
/**
* Material Design Button with Encapsulated Styling
* By: Ken Wheeler (http://kenwheeler.github.io)
* Based on slides/theory by Vjeux, and with a little help from him as well :)
* Slides from the original presentation available at: https://speakerdeck.com/vjeux/react-css-in-js
*/
// Define Material Button Class
var MaterialButton = React.createClass({
// Set initial state
getInitialState: function(){
return { style: 'default' };
},
// Handle click event
onClick: function(){
// Fire click event if supplies via props
this.props.onClick && this.props.onClick();
// Make ripple transition relative to click position
_.extend(styles.rippleActive, {
transformOrigin: event.offsetX + "px " + event.offsetY + "px"
});
// Set active state
this.setState({style: 'active'});
// In 100ms, set out state
setTimeout(function(){
this.setState({style: 'out'});
// In another 100ms, return to default state
setTimeout(function(){
this.setState({style: 'default'});
}.bind(this), 200);
}.bind(this), 200);
},
// Handle mouse down
onMouseDown: function() {
// Set pressed state
this.setState({style: 'pressed'});
},
// Render component
render: function() {
// Set state to this.state.style
var state = this.state.style;
// Set button style based off of state to style in styles object
var buttonStyle = _.extend({},
styles.button,
state === 'pressed' && styles.pressed
);
// Set ripple style based off of state to style in styles object
var rippleStyle = _.extend({},
styles.ripple,
state === 'active' && styles.rippleActive,
state === 'out' && styles.rippleOut
);
// Return component
return (
<button style={buttonStyle}
onMouseDown={this.onMouseDown}
onTouchStart={this.onMouseDown}
onClick={this.onClick}
type="button">
+
<span style={rippleStyle}></span>
</button>
);
}
});
// Define styles object to be applied conditionally via state changes
var styles = {
button: {
position: 'relative',
border: 'none',
outline: 'none',
color: 'white',
borderRadius: 56,
boxShadow: '0 3px 10px rgba(0, 0, 0, 0.23)',
backgroundColor: '#d23f31',
fontSize: 18,
height: 56,
width: 56,
WebkitTapHighlightColor: 'rgba(0,0,0,0)',
transition: '200ms all ease',
userSelect: 'none',
WebkitUserSelect: 'none',
WebkitTransition: '200ms all ease'
},
pressed: {
backgroundColor: '#ab3125',
boxShadow: '0 8px 17px 0 rgba(0, 0, 0, 0.1)'
},
ripple: {
position: 'absolute',
top: 0,
left: 0,
height: '100%',
width: '100%',
borderRadius: '100%',
display: 'block',
background: 'rgba(255,255,255,0.2)',
transform: 'scale(0)',
webkitTransform: 'scale(0)'
},
rippleActive: {
transform: 'scale(1)',
webkitTransform: 'scale(1)',
transition: '200ms all ease',
webkitTransition: '200ms all ease'
},
rippleOut: {
opacity: 0,
}
};
// Render component
React.render(<MaterialButton />, document.getElementById('container'));
#container {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment