Skip to content

Commit

Permalink
Improve styling of flat buttons
Browse files Browse the repository at this point in the history
  • Loading branch information
troutowicz committed May 15, 2015
1 parent 7898b03 commit 8059858
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 50 deletions.
30 changes: 21 additions & 9 deletions docs/src/app/components/pages/components/buttons.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ButtonPage extends React.Component {
constructor(props) {
super(props);

this.codeFlatButton =
this.codeFlatButton =
'//Flat Buttons\n' +
'<FlatButton label="Default" />\n' +
'<FlatButton label="Primary" primary={true} />\n' +
Expand All @@ -27,7 +27,7 @@ class ButtonPage extends React.Component {
'</div>\n' +
'<FlatButton label="Disabled" disabled={true} />';

this.codeRaisedButton =
this.codeRaisedButton =
'//Raised Buttons\n' +
'<RaisedButton label="Default" />\n' +
'<RaisedButton label="Primary" primary={true} />\n' +
Expand All @@ -44,16 +44,16 @@ class ButtonPage extends React.Component {
'</div>\n' +
'<RaisedButton label="Disabled" disabled={true} />';

this.codeFloatingActionButton =
this.codeFloatingActionButton =
'//Floating Action Buttons\n' +
'<FloatingActionButton iconClassName="muidocs-icon-action-grade" />\n' +
'<FloatingActionButton iconClassName="muidocs-icon-action-grade" mini={true} />\n' +
'<FloatingActionButton iconClassName="muidocs-icon-action-grade" disabled={true} />\n' +
'<FloatingActionButton iconClassName="muidocs-icon-custom-github" linkButton={true} href="https://github.com/callemall/material-ui" mini={true} secondary={true}/>' +
'<FloatingActionButton iconClassName="muidocs-icon-action-grade" mini={true} disabled={true} />\n' +
'<FloatingActionButton iconClassName="muidocs-icon-action-grade" secondary={true} />\n' +
'<FloatingActionButton iconClassName="muidocs-icon-action-grade" mini={true} secondary={true} />';
'<FloatingActionButton iconClassName="muidocs-icon-action-grade" mini={true} secondary={true} />';

this.desc = 'This component generates a button element and all props except for ' +
'the custom props below will be passed down to the button element. Also, ' +
'focus styles will happen on tab but not on click.';
Expand Down Expand Up @@ -100,6 +100,18 @@ class ButtonPage extends React.Component {
type: 'object',
header: 'optional',
desc: 'Override the inline-styles of the button\'s root element.'
},
{
name: 'hoverColor',
type: 'string',
header: 'optional',
desc: 'Override the inline hover color of the button\'s root element.'
},
{
name: 'rippleColor',
type: 'string',
header: 'optional',
desc: 'Override the inline color of the button\'s ripple element.'
}
]
},
Expand Down Expand Up @@ -196,7 +208,7 @@ class ButtonPage extends React.Component {
}

getStyles() {
var styles = {
var styles = {
container: {
textAlign: 'center',
marginBottom: '16px'
Expand All @@ -213,7 +225,7 @@ class ButtonPage extends React.Component {
padding: '0px 16px 0px 8px'
},
exampleIconButtonLabel: {
padding: '0px 8px'
padding: '0px 8px'
},
exampleImageButton: {
whiteSpace: 'pre',
Expand All @@ -238,7 +250,7 @@ class ButtonPage extends React.Component {
left: '0',
width: '100%',
opacity: '0'
},
},
exampleFlatButtonIcon: {
height: '100%',
display: 'inline-block',
Expand Down Expand Up @@ -368,7 +380,7 @@ class ButtonPage extends React.Component {
<div style={styles.container}>
<FloatingActionButton iconClassName="muidocs-icon-action-grade" mini={true} disabled={true} />
</div>
</div>
</div>
</ComponentDoc>
</Tab>
</Tabs>
Expand Down
102 changes: 61 additions & 41 deletions src/flat-button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,17 @@ var FlatButton = React.createClass({

propTypes: {
className: React.PropTypes.string,
disabled: React.PropTypes.bool,
hoverColor: React.PropTypes.string,
label: function(props, propName, componentName){
if (!props.children && !props.label) {
return new Error('Warning: Required prop `label` or `children` was not specified in `'+ componentName + '`.')
}
},
primary: React.PropTypes.bool,
secondary: React.PropTypes.bool,
labelStyle: React.PropTypes.object,
primary: React.PropTypes.bool,
rippleColor: React.PropTypes.string,
secondary: React.PropTypes.bool
},

getDefaultProps: function() {
Expand All @@ -34,6 +37,7 @@ var FlatButton = React.createClass({
getInitialState: function() {
return {
hovered: false,
isKeyboardFocused: false
};
},

Expand All @@ -45,22 +49,38 @@ var FlatButton = React.createClass({
return this.context.muiTheme.component.flatButton;
},

_getColor: function(){
var theme = this.getTheme();
var color = this.props.disabled ? theme.disabledTextColor :
this.props.primary ? theme.primaryTextColor :
this.props.secondary ? theme.secondaryTextColor :
theme.textColor;

return {
default: color,
hover: this.props.hoverColor || ColorManipulator.fade(ColorManipulator.lighten(color, 0.4), 0.15),
ripple: this.props.rippleColor || ColorManipulator.fade(color, 0.8)
};
},

getStyles: function() {
var color = this._getColor();
var styles = {
root: {
color: color.default,
transition: Transitions.easeOut(),
fontSize: Typography.fontStyleButtonFontSize,
letterSpacing: 0,
textTransform: 'uppercase',
fontWeight: Typography.fontWeightMedium,
fontWeight: Typography.fontWeightMedium,
borderRadius: 2,
userSelect: 'none',
position: 'relative',
overflow: 'hidden',
backgroundColor: this.getTheme().color,
lineHeight: this.getThemeButton().height + 'px',
minWidth: this.getThemeButton().minWidth,
padding: 0,
padding: 0,
margin: 0,
//This is need so that ripples do not bleed past border radius.
//See: http://stackoverflow.com/questions/17298739/css-overflow-hidden-not-working-in-chrome-when-parent-has-border-radius-and-chil
Expand All @@ -69,37 +89,34 @@ var FlatButton = React.createClass({
label: {
position: 'relative',
padding: '0px ' + this.context.muiTheme.spacing.desktopGutterLess + 'px',
}
},
rootWhenHovered: {
backgroundColor: color.hover
},
rippleColor: color.ripple
};
return styles;
},

_getColor: function(){
return this.props.disabled ? this.getTheme().disabledTextColor :
this.props.primary ? this.getTheme().primaryTextColor :
this.props.secondary ? this.getTheme().secondaryTextColor :
this.getTheme().textColor;
return styles;
},

render: function() {

var {
children,
hoverColor,
label,
labelStyle,
onBlur,
onMouseOut,
onMouseOver,
primary,
rippleColor,
secondary,
onMouseOver,
onMouseOut,
style,
...other
} = this.props;

var styles = this.getStyles();

styles.root.color = this._getColor();

styles.rootWhenHovered = {
backgroundColor: ColorManipulator.fade(ColorManipulator.lighten(styles.root.color, 0.4), 0.15)
};

var labelElement;
if (label) {
labelElement = (
Expand All @@ -108,21 +125,20 @@ var FlatButton = React.createClass({
</span>
);
};

var rippleColor = ColorManipulator.fade(styles.root.color, 0.8);

return (
<EnhancedButton {...other}
<EnhancedButton
{...other}
ref="enhancedButton"
style={this.mergeAndPrefix(
style={this.mergeStyles(
styles.root,
(this.state.hovered && !this.props.disabled) && styles.rootWhenHovered,
((this.state.hovered || this.state.isKeyboardFocused) && !this.props.disabled) && styles.rootWhenHovered,
this.props.style
)}
onMouseOver={this._handleMouseOver}
onMouseOut={this._handleMouseOut}
focusRippleColor={rippleColor}
touchRippleColor={rippleColor}
onMouseOver={this._handleMouseOver}
onMouseOut={this._handleMouseOut}
focusRippleColor={styles.rippleColor}
touchRippleColor={styles.rippleColor}
onKeyboardFocus={this._handleKeyboardFocus}>
{labelElement}
{this.props.children}
Expand All @@ -131,25 +147,29 @@ var FlatButton = React.createClass({
},

_handleMouseOver: function(e) {
if (!this.refs.enhancedButton.isKeyboardFocused()) this.setState({hovered: true});
if (this.props.onMouseOver) this.props.onMouseOver(e);
this.setState({hovered: true});
if (this.props.onMouseOver) {
this.props.onMouseOver(e);
}
},

_handleMouseOut: function(e) {
if (!this.refs.enhancedButton.isKeyboardFocused()) this.setState({hovered: false});
if (this.props.onMouseOut) this.props.onMouseOut(e);
this.setState({hovered: false});
if (this.props.onMouseOut) {
this.props.onMouseOut(e);
}
},

_handleKeyboardFocus: function(e, keyboardFocused) {
_handleKeyboardFocus: function(e, isKeyboardFocused) {
this.setState({isKeyboardFocused});
},

if (keyboardFocused && !this.props.disabled) {
React.findDOMNode(this).style.backgroundColor = ColorManipulator.fade(ColorManipulator.lighten(this._getColor(), 0.4), 0.15);
} else {
React.findDOMNode(this).style.backgroundColor = 'transparent';
_handleOnBlur: function (e) {
this.setState({hovered: false});
if (this.props.onBlur) {
this.props.onBlur(e);
}
}


});

module.exports = FlatButton;

0 comments on commit 8059858

Please sign in to comment.