455 lines
14 KiB
JavaScript
455 lines
14 KiB
JavaScript
'use strict';
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.styles = undefined;
|
|
|
|
var _extends2 = require('babel-runtime/helpers/extends');
|
|
|
|
var _extends3 = _interopRequireDefault(_extends2);
|
|
|
|
var _defineProperty2 = require('babel-runtime/helpers/defineProperty');
|
|
|
|
var _defineProperty3 = _interopRequireDefault(_defineProperty2);
|
|
|
|
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 _react = require('react');
|
|
|
|
var _react2 = _interopRequireDefault(_react);
|
|
|
|
var _reactDom = require('react-dom');
|
|
|
|
var _classnames = require('classnames');
|
|
|
|
var _classnames2 = _interopRequireDefault(_classnames);
|
|
|
|
var _keycode = require('keycode');
|
|
|
|
var _keycode2 = _interopRequireDefault(_keycode);
|
|
|
|
var _withStyles = require('../styles/withStyles');
|
|
|
|
var _withStyles2 = _interopRequireDefault(_withStyles);
|
|
|
|
var _keyboardFocus = require('../utils/keyboardFocus');
|
|
|
|
var _TouchRipple = require('./TouchRipple');
|
|
|
|
var _TouchRipple2 = _interopRequireDefault(_TouchRipple);
|
|
|
|
var _createRippleHandler = require('./createRippleHandler');
|
|
|
|
var _createRippleHandler2 = _interopRequireDefault(_createRippleHandler);
|
|
|
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
|
|
var babelPluginFlowReactPropTypes_proptype_Node = require('react').babelPluginFlowReactPropTypes_proptype_Node || require('prop-types').any; // weak
|
|
|
|
var babelPluginFlowReactPropTypes_proptype_ElementType = require('react').babelPluginFlowReactPropTypes_proptype_ElementType || require('prop-types').any;
|
|
|
|
var styles = exports.styles = function styles(theme) {
|
|
return {
|
|
root: {
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
position: 'relative',
|
|
// Remove grey highlight
|
|
WebkitTapHighlightColor: theme.palette.common.transparent,
|
|
backgroundColor: 'transparent', // Reset default value
|
|
outline: 'none',
|
|
border: 0,
|
|
borderRadius: 0,
|
|
cursor: 'pointer',
|
|
userSelect: 'none',
|
|
appearance: 'none',
|
|
textDecoration: 'none',
|
|
// So we take precedent over the style of a native <a /> element.
|
|
color: 'inherit',
|
|
'&::-moz-focus-inner': {
|
|
borderStyle: 'none' // Remove Firefox dotted outline.
|
|
}
|
|
},
|
|
disabled: {
|
|
pointerEvents: 'none', // Disable link interactions
|
|
cursor: 'default'
|
|
}
|
|
};
|
|
};
|
|
|
|
var babelPluginFlowReactPropTypes_proptype_Props = {
|
|
/**
|
|
* If `true`, the ripples will be centered.
|
|
* They won't start at the cursor interaction position.
|
|
*/
|
|
centerRipple: require('prop-types').bool,
|
|
|
|
/**
|
|
* The content of the component.
|
|
*/
|
|
children: typeof babelPluginFlowReactPropTypes_proptype_Node === 'function' ? babelPluginFlowReactPropTypes_proptype_Node : require('prop-types').shape(babelPluginFlowReactPropTypes_proptype_Node),
|
|
|
|
/**
|
|
* Useful to extend the style applied to components.
|
|
*/
|
|
classes: require('prop-types').object,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
className: require('prop-types').string,
|
|
|
|
/**
|
|
* The component used for the root node.
|
|
* Either a string to use a DOM element or a component.
|
|
* The default value is a `button`.
|
|
*/
|
|
component: typeof babelPluginFlowReactPropTypes_proptype_ElementType === 'function' ? babelPluginFlowReactPropTypes_proptype_ElementType : require('prop-types').shape(babelPluginFlowReactPropTypes_proptype_ElementType),
|
|
|
|
/**
|
|
* If `true`, the base button will be disabled.
|
|
*/
|
|
disabled: require('prop-types').bool,
|
|
|
|
/**
|
|
* If `true`, the ripple effect will be disabled.
|
|
*/
|
|
disableRipple: require('prop-types').bool,
|
|
|
|
/**
|
|
* If `true`, the base button will have a keyboard focus ripple.
|
|
* `disableRipple` must also be `false`.
|
|
*/
|
|
focusRipple: require('prop-types').bool,
|
|
|
|
/**
|
|
* The CSS class applied while the component is keyboard focused.
|
|
*/
|
|
keyboardFocusedClassName: require('prop-types').string,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onBlur: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onClick: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onFocus: require('prop-types').func,
|
|
|
|
/**
|
|
* Callback fired when the component is focused with a keyboard.
|
|
* We trigger a `onFocus` callback too.
|
|
*/
|
|
onKeyboardFocus: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onKeyDown: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onKeyUp: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onMouseDown: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onMouseLeave: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onMouseUp: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onTouchEnd: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onTouchMove: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onTouchStart: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
role: require('prop-types').string,
|
|
|
|
/**
|
|
* Use that property to pass a ref callback to the root component.
|
|
*/
|
|
rootRef: require('prop-types').func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
tabIndex: require('prop-types').oneOfType([require('prop-types').number, require('prop-types').string]),
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
type: require('prop-types').string.isRequired
|
|
};
|
|
|
|
var ButtonBase = function (_React$Component) {
|
|
(0, _inherits3.default)(ButtonBase, _React$Component);
|
|
|
|
function ButtonBase() {
|
|
var _ref;
|
|
|
|
var _temp, _this, _ret;
|
|
|
|
(0, _classCallCheck3.default)(this, ButtonBase);
|
|
|
|
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 = ButtonBase.__proto__ || (0, _getPrototypeOf2.default)(ButtonBase)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
|
|
keyboardFocused: false
|
|
}, _this.onKeyboardFocusHandler = function (event) {
|
|
_this.keyDown = false;
|
|
_this.setState({ keyboardFocused: true });
|
|
|
|
if (_this.props.onKeyboardFocus) {
|
|
_this.props.onKeyboardFocus(event);
|
|
}
|
|
}, _this.ripple = null, _this.keyDown = false, _this.button = null, _this.keyboardFocusTimeout = null, _this.keyboardFocusCheckTime = 30, _this.keyboardFocusMaxCheckTimes = 5, _this.handleKeyDown = function (event) {
|
|
var _this$props = _this.props,
|
|
component = _this$props.component,
|
|
focusRipple = _this$props.focusRipple,
|
|
onKeyDown = _this$props.onKeyDown,
|
|
onClick = _this$props.onClick;
|
|
|
|
var key = (0, _keycode2.default)(event);
|
|
|
|
// Check if key is already down to avoid repeats being counted as multiple activations
|
|
if (focusRipple && !_this.keyDown && _this.state.keyboardFocused && key === 'space') {
|
|
_this.keyDown = true;
|
|
event.persist();
|
|
_this.ripple.stop(event, function () {
|
|
_this.ripple.start(event);
|
|
});
|
|
}
|
|
|
|
if (onKeyDown) {
|
|
onKeyDown(event);
|
|
}
|
|
|
|
// Keyboard accessibility for non interactive elements
|
|
if (event.target === _this.button && onClick && component && component !== 'a' && component !== 'button' && (key === 'space' || key === 'enter')) {
|
|
event.preventDefault();
|
|
onClick(event);
|
|
}
|
|
}, _this.handleKeyUp = function (event) {
|
|
if (_this.props.focusRipple && (0, _keycode2.default)(event) === 'space' && _this.state.keyboardFocused) {
|
|
_this.keyDown = false;
|
|
event.persist();
|
|
_this.ripple.stop(event, function () {
|
|
return _this.ripple.pulsate(event);
|
|
});
|
|
}
|
|
if (_this.props.onKeyUp) {
|
|
_this.props.onKeyUp(event);
|
|
}
|
|
}, _this.handleMouseDown = (0, _createRippleHandler2.default)(_this, 'MouseDown', 'start', function () {
|
|
clearTimeout(_this.keyboardFocusTimeout);
|
|
(0, _keyboardFocus.focusKeyPressed)(false);
|
|
if (_this.state.keyboardFocused) {
|
|
_this.setState({ keyboardFocused: false });
|
|
}
|
|
}), _this.handleMouseUp = (0, _createRippleHandler2.default)(_this, 'MouseUp', 'stop'), _this.handleMouseLeave = (0, _createRippleHandler2.default)(_this, 'MouseLeave', 'stop', function (event) {
|
|
if (_this.state.keyboardFocused) {
|
|
event.preventDefault();
|
|
}
|
|
}), _this.handleTouchStart = (0, _createRippleHandler2.default)(_this, 'TouchStart', 'start'), _this.handleTouchEnd = (0, _createRippleHandler2.default)(_this, 'TouchEnd', 'stop'), _this.handleTouchMove = (0, _createRippleHandler2.default)(_this, 'TouchEnd', 'stop'), _this.handleBlur = (0, _createRippleHandler2.default)(_this, 'Blur', 'stop', function () {
|
|
clearTimeout(_this.keyboardFocusTimeout);
|
|
(0, _keyboardFocus.focusKeyPressed)(false);
|
|
_this.setState({ keyboardFocused: false });
|
|
}), _this.handleFocus = function (event) {
|
|
if (_this.props.disabled) {
|
|
return;
|
|
}
|
|
|
|
// Fix for https://github.com/facebook/react/issues/7769
|
|
if (!_this.button) {
|
|
_this.button = event.currentTarget;
|
|
}
|
|
|
|
event.persist();
|
|
var keyboardFocusCallback = _this.onKeyboardFocusHandler.bind(_this, event);
|
|
(0, _keyboardFocus.detectKeyboardFocus)(_this, _this.button, keyboardFocusCallback);
|
|
|
|
if (_this.props.onFocus) {
|
|
_this.props.onFocus(event);
|
|
}
|
|
}, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
|
|
}
|
|
|
|
(0, _createClass3.default)(ButtonBase, [{
|
|
key: 'componentDidMount',
|
|
value: function componentDidMount() {
|
|
this.button = (0, _reactDom.findDOMNode)(this);
|
|
(0, _keyboardFocus.listenForFocusKeys)();
|
|
}
|
|
}, {
|
|
key: 'componentWillUpdate',
|
|
value: function componentWillUpdate(nextProps, nextState) {
|
|
if (this.props.focusRipple && nextState.keyboardFocused && !this.state.keyboardFocused && !this.props.disableRipple) {
|
|
this.ripple.pulsate();
|
|
}
|
|
}
|
|
}, {
|
|
key: 'componentWillUnmount',
|
|
value: function componentWillUnmount() {
|
|
this.button = null;
|
|
clearTimeout(this.keyboardFocusTimeout);
|
|
} // Used to help track keyboard activation keyDown
|
|
|
|
}, {
|
|
key: 'renderRipple',
|
|
value: function renderRipple() {
|
|
var _this2 = this;
|
|
|
|
if (!this.props.disableRipple && !this.props.disabled) {
|
|
return _react2.default.createElement(_TouchRipple2.default, {
|
|
innerRef: function innerRef(node) {
|
|
_this2.ripple = node;
|
|
},
|
|
center: this.props.centerRipple
|
|
});
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}, {
|
|
key: 'render',
|
|
value: function render() {
|
|
var _classNames;
|
|
|
|
var _props = this.props,
|
|
centerRipple = _props.centerRipple,
|
|
children = _props.children,
|
|
classes = _props.classes,
|
|
classNameProp = _props.className,
|
|
component = _props.component,
|
|
disabled = _props.disabled,
|
|
disableRipple = _props.disableRipple,
|
|
focusRipple = _props.focusRipple,
|
|
keyboardFocusedClassName = _props.keyboardFocusedClassName,
|
|
onBlur = _props.onBlur,
|
|
onFocus = _props.onFocus,
|
|
onKeyboardFocus = _props.onKeyboardFocus,
|
|
onKeyDown = _props.onKeyDown,
|
|
onKeyUp = _props.onKeyUp,
|
|
onMouseDown = _props.onMouseDown,
|
|
onMouseLeave = _props.onMouseLeave,
|
|
onMouseUp = _props.onMouseUp,
|
|
onTouchEnd = _props.onTouchEnd,
|
|
onTouchMove = _props.onTouchMove,
|
|
onTouchStart = _props.onTouchStart,
|
|
rootRef = _props.rootRef,
|
|
tabIndex = _props.tabIndex,
|
|
type = _props.type,
|
|
other = (0, _objectWithoutProperties3.default)(_props, ['centerRipple', 'children', 'classes', 'className', 'component', 'disabled', 'disableRipple', 'focusRipple', 'keyboardFocusedClassName', 'onBlur', 'onFocus', 'onKeyboardFocus', 'onKeyDown', 'onKeyUp', 'onMouseDown', 'onMouseLeave', 'onMouseUp', 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'rootRef', 'tabIndex', 'type']);
|
|
|
|
|
|
var className = (0, _classnames2.default)(classes.root, (_classNames = {}, (0, _defineProperty3.default)(_classNames, classes.disabled, disabled), (0, _defineProperty3.default)(_classNames, keyboardFocusedClassName || '', this.state.keyboardFocused), _classNames), classNameProp);
|
|
|
|
var buttonProps = {};
|
|
|
|
var ComponentProp = component;
|
|
|
|
if (!ComponentProp) {
|
|
if (other.href) {
|
|
ComponentProp = 'a';
|
|
} else {
|
|
ComponentProp = 'button';
|
|
}
|
|
}
|
|
|
|
if (ComponentProp === 'button') {
|
|
buttonProps.type = type || 'button';
|
|
}
|
|
|
|
if (ComponentProp !== 'a') {
|
|
buttonProps.role = buttonProps.role || 'button';
|
|
buttonProps.disabled = disabled;
|
|
}
|
|
|
|
return _react2.default.createElement(
|
|
ComponentProp,
|
|
(0, _extends3.default)({
|
|
onBlur: this.handleBlur,
|
|
onFocus: this.handleFocus,
|
|
onKeyDown: this.handleKeyDown,
|
|
onKeyUp: this.handleKeyUp,
|
|
onMouseDown: this.handleMouseDown,
|
|
onMouseLeave: this.handleMouseLeave,
|
|
onMouseUp: this.handleMouseUp,
|
|
onTouchEnd: this.handleTouchEnd,
|
|
onTouchMove: this.handleTouchMove,
|
|
onTouchStart: this.handleTouchStart,
|
|
tabIndex: disabled ? -1 : tabIndex,
|
|
className: className
|
|
}, buttonProps, other, {
|
|
ref: rootRef
|
|
}),
|
|
children,
|
|
this.renderRipple()
|
|
);
|
|
}
|
|
}]);
|
|
return ButtonBase;
|
|
}(_react2.default.Component);
|
|
|
|
ButtonBase.defaultProps = {
|
|
centerRipple: false,
|
|
focusRipple: false,
|
|
disableRipple: false,
|
|
tabIndex: 0,
|
|
type: 'button'
|
|
};
|
|
exports.default = (0, _withStyles2.default)(styles, { name: 'MuiButtonBase' })(ButtonBase); |