material-ui
Version:
React Components that Implement Google's Material Design.
489 lines (432 loc) • 16.2 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _simpleAssign = require('simple-assign');
var _simpleAssign2 = _interopRequireDefault(_simpleAssign);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _transitions = require('../styles/transitions');
var _transitions2 = _interopRequireDefault(_transitions);
var _colorManipulator = require('../utils/colorManipulator');
var _EnhancedButton = require('../internal/EnhancedButton');
var _EnhancedButton2 = _interopRequireDefault(_EnhancedButton);
var _Paper = require('../Paper');
var _Paper2 = _interopRequireDefault(_Paper);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function validateLabel(props, propName, componentName) {
if (process.env.NODE_ENV !== 'production') {
if (!props.children && props.label !== 0 && !props.label && !props.icon) {
return new Error('Required prop label or children or icon was not specified in ' + componentName + '.');
}
}
}
function getStyles(props, context, state) {
var _context$muiTheme = context.muiTheme,
baseTheme = _context$muiTheme.baseTheme,
button = _context$muiTheme.button,
raisedButton = _context$muiTheme.raisedButton,
borderRadius = _context$muiTheme.borderRadius;
var disabled = props.disabled,
disabledBackgroundColor = props.disabledBackgroundColor,
disabledLabelColor = props.disabledLabelColor,
fullWidth = props.fullWidth,
icon = props.icon,
label = props.label,
labelPosition = props.labelPosition,
primary = props.primary,
secondary = props.secondary,
style = props.style;
var amount = primary || secondary ? 0.4 : 0.08;
var backgroundColor = raisedButton.color;
var labelColor = raisedButton.textColor;
if (disabled) {
backgroundColor = disabledBackgroundColor || raisedButton.disabledColor;
labelColor = disabledLabelColor || raisedButton.disabledTextColor;
} else if (primary) {
backgroundColor = raisedButton.primaryColor;
labelColor = raisedButton.primaryTextColor;
} else if (secondary) {
backgroundColor = raisedButton.secondaryColor;
labelColor = raisedButton.secondaryTextColor;
} else {
if (props.backgroundColor) {
backgroundColor = props.backgroundColor;
}
if (props.labelColor) {
labelColor = props.labelColor;
}
}
var buttonHeight = style && style.height || button.height;
return {
root: {
display: 'inline-block',
transition: _transitions2.default.easeOut(),
minWidth: fullWidth ? '100%' : button.minWidth
},
button: {
height: buttonHeight,
lineHeight: buttonHeight + 'px',
width: '100%',
padding: 0,
borderRadius: borderRadius,
transition: _transitions2.default.easeOut(),
backgroundColor: backgroundColor,
// That's the default value for a button but not a link
textAlign: 'center'
},
label: {
position: 'relative',
opacity: 1,
fontSize: raisedButton.fontSize,
letterSpacing: 0,
textTransform: raisedButton.textTransform || button.textTransform || 'uppercase',
fontWeight: raisedButton.fontWeight,
margin: 0,
userSelect: 'none',
paddingLeft: icon && labelPosition !== 'before' ? 8 : baseTheme.spacing.desktopGutterLess,
paddingRight: icon && labelPosition === 'before' ? 8 : baseTheme.spacing.desktopGutterLess,
color: labelColor
},
icon: {
verticalAlign: 'middle',
marginLeft: label && labelPosition !== 'before' ? 12 : 0,
marginRight: label && labelPosition === 'before' ? 12 : 0
},
overlay: {
height: buttonHeight,
borderRadius: borderRadius,
backgroundColor: (state.keyboardFocused || state.hovered) && !disabled && (0, _colorManipulator.fade)(labelColor, amount),
transition: _transitions2.default.easeOut(),
top: 0
},
ripple: {
color: labelColor,
opacity: !(primary || secondary) ? 0.1 : 0.16
}
};
}
var RaisedButton = function (_Component) {
(0, _inherits3.default)(RaisedButton, _Component);
function RaisedButton() {
var _ref;
var _temp, _this, _ret;
(0, _classCallCheck3.default)(this, RaisedButton);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = (0, _possibleConstructorReturn3.default)(this, (_ref = RaisedButton.__proto__ || (0, _getPrototypeOf2.default)(RaisedButton)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
hovered: false,
keyboardFocused: false,
touched: false,
initialZDepth: 0,
zDepth: 0
}, _this.handleMouseDown = function (event) {
// only listen to left clicks
if (event.button === 0) {
_this.setState({
zDepth: _this.state.initialZDepth + 1
});
}
if (_this.props.onMouseDown) {
_this.props.onMouseDown(event);
}
}, _this.handleMouseUp = function (event) {
_this.setState({
zDepth: _this.state.initialZDepth
});
if (_this.props.onMouseUp) {
_this.props.onMouseUp(event);
}
}, _this.handleMouseLeave = function (event) {
if (!_this.state.keyboardFocused) {
_this.setState({
zDepth: _this.state.initialZDepth,
hovered: false
});
}
if (_this.props.onMouseLeave) {
_this.props.onMouseLeave(event);
}
}, _this.handleMouseEnter = function (event) {
if (!_this.state.keyboardFocused && !_this.state.touched) {
_this.setState({
hovered: true
});
}
if (_this.props.onMouseEnter) {
_this.props.onMouseEnter(event);
}
}, _this.handleTouchStart = function (event) {
_this.setState({
touched: true,
zDepth: _this.state.initialZDepth + 1
});
if (_this.props.onTouchStart) {
_this.props.onTouchStart(event);
}
}, _this.handleTouchEnd = function (event) {
_this.setState({
touched: true,
zDepth: _this.state.initialZDepth
});
if (_this.props.onTouchEnd) {
_this.props.onTouchEnd(event);
}
}, _this.handleKeyboardFocus = function (event, keyboardFocused) {
var zDepth = keyboardFocused && !_this.props.disabled ? _this.state.initialZDepth + 1 : _this.state.initialZDepth;
_this.setState({
zDepth: zDepth,
keyboardFocused: keyboardFocused
});
}, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
}
(0, _createClass3.default)(RaisedButton, [{
key: 'componentWillMount',
value: function componentWillMount() {
var zDepth = this.props.disabled ? 0 : 1;
this.setState({
zDepth: zDepth,
initialZDepth: zDepth
});
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var zDepth = nextProps.disabled ? 0 : 1;
var nextState = {
zDepth: zDepth,
initialZDepth: zDepth
};
if (nextProps.disabled) {
nextState.hovered = false;
}
this.setState(nextState);
}
}, {
key: 'render',
value: function render() {
var _props = this.props,
backgroundColor = _props.backgroundColor,
buttonStyle = _props.buttonStyle,
children = _props.children,
className = _props.className,
disabled = _props.disabled,
disabledBackgroundColor = _props.disabledBackgroundColor,
disabledLabelColor = _props.disabledLabelColor,
fullWidth = _props.fullWidth,
icon = _props.icon,
label = _props.label,
labelColor = _props.labelColor,
labelPosition = _props.labelPosition,
labelStyle = _props.labelStyle,
overlayStyle = _props.overlayStyle,
primary = _props.primary,
rippleStyle = _props.rippleStyle,
secondary = _props.secondary,
style = _props.style,
other = (0, _objectWithoutProperties3.default)(_props, ['backgroundColor', 'buttonStyle', 'children', 'className', 'disabled', 'disabledBackgroundColor', 'disabledLabelColor', 'fullWidth', 'icon', 'label', 'labelColor', 'labelPosition', 'labelStyle', 'overlayStyle', 'primary', 'rippleStyle', 'secondary', 'style']);
var prepareStyles = this.context.muiTheme.prepareStyles;
var styles = getStyles(this.props, this.context, this.state);
var mergedRippleStyles = (0, _simpleAssign2.default)({}, styles.ripple, rippleStyle);
var buttonEventHandlers = disabled ? {} : {
onMouseDown: this.handleMouseDown,
onMouseUp: this.handleMouseUp,
onMouseLeave: this.handleMouseLeave,
onMouseEnter: this.handleMouseEnter,
onTouchStart: this.handleTouchStart,
onTouchEnd: this.handleTouchEnd,
onKeyboardFocus: this.handleKeyboardFocus
};
var labelElement = label && _react2.default.createElement(
'span',
{ style: prepareStyles((0, _simpleAssign2.default)(styles.label, labelStyle)), key: 'labelElement' },
label
);
var iconCloned = icon && (0, _react.cloneElement)(icon, {
color: icon.props.color || styles.label.color,
style: (0, _simpleAssign2.default)(styles.icon, icon.props.style),
key: 'iconCloned'
});
var overlayBackgroundProxy = {
backgroundColor: overlayStyle && styles.overlay.backgroundColor && overlayStyle.backgroundColor || styles.overlay.backgroundColor
};
// Place label before or after children.
var enhancedButtonChildren = labelPosition === 'before' ? [labelElement, iconCloned, children] : [children, iconCloned, labelElement];
return _react2.default.createElement(
_Paper2.default,
{
className: className,
style: (0, _simpleAssign2.default)(styles.root, style),
zDepth: this.state.zDepth
},
_react2.default.createElement(
_EnhancedButton2.default,
(0, _extends3.default)({}, other, buttonEventHandlers, {
ref: 'container',
disabled: disabled,
style: (0, _simpleAssign2.default)(styles.button, buttonStyle),
focusRippleColor: mergedRippleStyles.color,
touchRippleColor: mergedRippleStyles.color,
focusRippleOpacity: mergedRippleStyles.opacity,
touchRippleOpacity: mergedRippleStyles.opacity
}),
_react2.default.createElement(
'div',
{
ref: 'overlay',
style: prepareStyles((0, _simpleAssign2.default)(styles.overlay, overlayStyle, overlayBackgroundProxy))
},
enhancedButtonChildren
)
)
);
}
}]);
return RaisedButton;
}(_react.Component);
RaisedButton.muiName = 'RaisedButton';
RaisedButton.defaultProps = {
disabled: false,
labelPosition: 'after',
fullWidth: false,
primary: false,
secondary: false
};
RaisedButton.contextTypes = {
muiTheme: _propTypes2.default.object.isRequired
};
RaisedButton.propTypes = process.env.NODE_ENV !== "production" ? {
/**
* Override the default background color for the button,
* but not the default disabled background color
* (use `disabledBackgroundColor` for this).
*/
backgroundColor: _propTypes2.default.string,
/**
* Override the inline-styles of the button element.
*/
buttonStyle: _propTypes2.default.object,
/**
* The content of the button.
* If a label is provided via the `label` prop, the text within the label
* will be displayed in addition to the content provided here.
*/
children: _propTypes2.default.node,
/**
* The CSS class name of the root element.
*/
className: _propTypes2.default.string,
/**
* The element to use as the container for the RaisedButton. Either a string to
* use a DOM element or a ReactElement. This is useful for wrapping the
* RaisedButton in a custom Link component. If a ReactElement is given, ensure
* that it passes all of its given props through to the underlying DOM
* element and renders its children prop for proper integration.
*/
containerElement: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.element]),
/**
* If true, the element's ripple effect will be disabled.
*/
disableTouchRipple: _propTypes2.default.bool,
/**
* If true, the button will be disabled.
*/
disabled: _propTypes2.default.bool,
/**
* Override the default background color for the button
* when it is disabled.
*/
disabledBackgroundColor: _propTypes2.default.string,
/**
* The color of the button's label when the button is disabled.
*/
disabledLabelColor: _propTypes2.default.string,
/**
* If true, the button will take up the full width of its container.
*/
fullWidth: _propTypes2.default.bool,
/**
* The URL to link to when the button is clicked.
*/
href: _propTypes2.default.string,
/**
* An icon to be displayed within the button.
*/
icon: _propTypes2.default.node,
/**
* The label to be displayed within the button.
* If content is provided via the `children` prop, that content will be
* displayed in addition to the label provided here.
*/
label: validateLabel,
/**
* The color of the button's label.
*/
labelColor: _propTypes2.default.string,
/**
* The position of the button's label relative to the button's `children`.
*/
labelPosition: _propTypes2.default.oneOf(['before', 'after']),
/**
* Override the inline-styles of the button's label element.
*/
labelStyle: _propTypes2.default.object,
/**
* Callback function fired when the button is clicked.
*
* @param {object} event Click event targeting the button.
*/
onClick: _propTypes2.default.func,
/** @ignore */
onMouseDown: _propTypes2.default.func,
/** @ignore */
onMouseEnter: _propTypes2.default.func,
/** @ignore */
onMouseLeave: _propTypes2.default.func,
/** @ignore */
onMouseUp: _propTypes2.default.func,
/** @ignore */
onTouchEnd: _propTypes2.default.func,
/** @ignore */
onTouchStart: _propTypes2.default.func,
/**
* Override the inline style of the button overlay.
*/
overlayStyle: _propTypes2.default.object,
/**
* If true, the button will use the theme's primary color.
*/
primary: _propTypes2.default.bool,
/**
* Override the inline style of the ripple element.
*/
rippleStyle: _propTypes2.default.object,
/**
* If true, the button will use the theme's secondary color.
* If both `secondary` and `primary` are true, the button will use
* the theme's primary color.
*/
secondary: _propTypes2.default.bool,
/**
* Override the inline-styles of the root element.
*/
style: _propTypes2.default.object
} : {};
exports.default = RaisedButton;