forked from Gitlink/forgeplus-react
596 lines
19 KiB
JavaScript
596 lines
19 KiB
JavaScript
"use strict";
|
|
|
|
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = exports.styles = void 0;
|
|
|
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
|
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
|
|
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
|
|
|
|
var _getPrototypeOf = _interopRequireDefault(require("@babel/runtime/core-js/object/get-prototype-of"));
|
|
|
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
|
|
|
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
|
|
|
|
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn"));
|
|
|
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
|
|
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
|
|
|
|
var _react = _interopRequireDefault(require("react"));
|
|
|
|
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
|
var _reactDom = _interopRequireDefault(require("react-dom"));
|
|
|
|
var _classnames = _interopRequireDefault(require("classnames"));
|
|
|
|
var _keycode = _interopRequireDefault(require("keycode"));
|
|
|
|
var _reactLifecyclesCompat = require("react-lifecycles-compat");
|
|
|
|
var _ownerWindow = _interopRequireDefault(require("../utils/ownerWindow"));
|
|
|
|
var _withStyles = _interopRequireDefault(require("../styles/withStyles"));
|
|
|
|
var _focusVisible = require("../utils/focusVisible");
|
|
|
|
var _TouchRipple = _interopRequireDefault(require("./TouchRipple"));
|
|
|
|
var _createRippleHandler = _interopRequireDefault(require("./createRippleHandler"));
|
|
|
|
var styles = {
|
|
root: {
|
|
display: 'inline-flex',
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
position: 'relative',
|
|
// Remove grey highlight
|
|
WebkitTapHighlightColor: 'transparent',
|
|
backgroundColor: 'transparent',
|
|
// Reset default value
|
|
// We disable the focus ring for mouse, touch and keyboard users.
|
|
outline: 'none',
|
|
border: 0,
|
|
margin: 0,
|
|
// Remove the margin in Safari
|
|
borderRadius: 0,
|
|
padding: 0,
|
|
// Remove the padding in Firefox
|
|
cursor: 'pointer',
|
|
userSelect: 'none',
|
|
verticalAlign: 'middle',
|
|
'-moz-appearance': 'none',
|
|
// Reset
|
|
'-webkit-appearance': 'none',
|
|
// Reset
|
|
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'
|
|
}
|
|
},
|
|
disabled: {},
|
|
focusVisible: {}
|
|
};
|
|
/**
|
|
* `ButtonBase` contains as few styles as possible.
|
|
* It aims to be a simple building block for creating a button.
|
|
* It contains a load of style reset and some focus/ripple logic.
|
|
*/
|
|
|
|
exports.styles = styles;
|
|
|
|
var ButtonBase =
|
|
/*#__PURE__*/
|
|
function (_React$Component) {
|
|
(0, _inherits2.default)(ButtonBase, _React$Component);
|
|
|
|
function ButtonBase() {
|
|
var _ref;
|
|
|
|
var _temp, _this;
|
|
|
|
(0, _classCallCheck2.default)(this, ButtonBase);
|
|
|
|
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
args[_key] = arguments[_key];
|
|
}
|
|
|
|
return (0, _possibleConstructorReturn2.default)(_this, (_temp = _this = (0, _possibleConstructorReturn2.default)(this, (_ref = ButtonBase.__proto__ || (0, _getPrototypeOf.default)(ButtonBase)).call.apply(_ref, [this].concat(args))), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "state", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: {}
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "onFocusVisibleHandler", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: function value(event) {
|
|
_this.keyDown = false;
|
|
|
|
_this.setState({
|
|
focusVisible: true
|
|
});
|
|
|
|
if (_this.props.onFocusVisible) {
|
|
_this.props.onFocusVisible(event);
|
|
}
|
|
}
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "onRippleRef", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: function value(node) {
|
|
_this.ripple = node;
|
|
}
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "ripple", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: null
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "keyDown", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: false
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "button", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: null
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "focusVisibleTimeout", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: null
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "focusVisibleCheckTime", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: 50
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "focusVisibleMaxCheckTimes", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: 5
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleKeyDown", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: function value(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, _keycode.default)(event); // Check if key is already down to avoid repeats being counted as multiple activations
|
|
|
|
if (focusRipple && !_this.keyDown && _this.state.focusVisible && _this.ripple && 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 === event.currentTarget && component && component !== 'button' && (key === 'space' || key === 'enter')) {
|
|
event.preventDefault();
|
|
|
|
if (onClick) {
|
|
onClick(event);
|
|
}
|
|
}
|
|
}
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleKeyUp", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: function value(event) {
|
|
if (_this.props.focusRipple && (0, _keycode.default)(event) === 'space' && _this.ripple && _this.state.focusVisible) {
|
|
_this.keyDown = false;
|
|
event.persist();
|
|
|
|
_this.ripple.stop(event, function () {
|
|
return _this.ripple.pulsate(event);
|
|
});
|
|
}
|
|
|
|
if (_this.props.onKeyUp) {
|
|
_this.props.onKeyUp(event);
|
|
}
|
|
}
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleMouseDown", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'MouseDown', 'start', function () {
|
|
clearTimeout(_this.focusVisibleTimeout);
|
|
|
|
if (_this.state.focusVisible) {
|
|
_this.setState({
|
|
focusVisible: false
|
|
});
|
|
}
|
|
})
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleMouseUp", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'MouseUp', 'stop')
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleMouseLeave", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'MouseLeave', 'stop', function (event) {
|
|
if (_this.state.focusVisible) {
|
|
event.preventDefault();
|
|
}
|
|
})
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleTouchStart", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'TouchStart', 'start')
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleTouchEnd", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'TouchEnd', 'stop')
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleTouchMove", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'TouchMove', 'stop')
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleBlur", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: (0, _createRippleHandler.default)((0, _assertThisInitialized2.default)(_this), 'Blur', 'stop', function () {
|
|
clearTimeout(_this.focusVisibleTimeout);
|
|
|
|
if (_this.state.focusVisible) {
|
|
_this.setState({
|
|
focusVisible: false
|
|
});
|
|
}
|
|
})
|
|
}), Object.defineProperty((0, _assertThisInitialized2.default)(_this), "handleFocus", {
|
|
configurable: true,
|
|
enumerable: true,
|
|
writable: true,
|
|
value: function value(event) {
|
|
if (_this.props.disabled) {
|
|
return;
|
|
} // Fix for https://github.com/facebook/react/issues/7769
|
|
|
|
|
|
if (!_this.button) {
|
|
_this.button = event.currentTarget;
|
|
}
|
|
|
|
event.persist();
|
|
(0, _focusVisible.detectFocusVisible)((0, _assertThisInitialized2.default)(_this), _this.button, function () {
|
|
_this.onFocusVisibleHandler(event);
|
|
});
|
|
|
|
if (_this.props.onFocus) {
|
|
_this.props.onFocus(event);
|
|
}
|
|
}
|
|
}), _temp));
|
|
}
|
|
|
|
(0, _createClass2.default)(ButtonBase, [{
|
|
key: "componentDidMount",
|
|
value: function componentDidMount() {
|
|
var _this2 = this;
|
|
|
|
this.button = _reactDom.default.findDOMNode(this);
|
|
(0, _focusVisible.listenForFocusKeys)((0, _ownerWindow.default)(this.button));
|
|
|
|
if (this.props.action) {
|
|
this.props.action({
|
|
focusVisible: function focusVisible() {
|
|
_this2.setState({
|
|
focusVisible: true
|
|
});
|
|
|
|
_this2.button.focus();
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}, {
|
|
key: "componentDidUpdate",
|
|
value: function componentDidUpdate(prevProps, prevState) {
|
|
if (this.props.focusRipple && !this.props.disableRipple && !prevState.focusVisible && this.state.focusVisible) {
|
|
this.ripple.pulsate();
|
|
}
|
|
}
|
|
}, {
|
|
key: "componentWillUnmount",
|
|
value: function componentWillUnmount() {
|
|
this.button = null;
|
|
clearTimeout(this.focusVisibleTimeout);
|
|
}
|
|
}, {
|
|
key: "render",
|
|
value: function render() {
|
|
var _classNames;
|
|
|
|
var _props = this.props,
|
|
action = _props.action,
|
|
buttonRef = _props.buttonRef,
|
|
centerRipple = _props.centerRipple,
|
|
children = _props.children,
|
|
classes = _props.classes,
|
|
classNameProp = _props.className,
|
|
component = _props.component,
|
|
disabled = _props.disabled,
|
|
disableRipple = _props.disableRipple,
|
|
focusRipple = _props.focusRipple,
|
|
focusVisibleClassName = _props.focusVisibleClassName,
|
|
onBlur = _props.onBlur,
|
|
onFocus = _props.onFocus,
|
|
onFocusVisible = _props.onFocusVisible,
|
|
onKeyDown = _props.onKeyDown,
|
|
onKeyUp = _props.onKeyUp,
|
|
onMouseDown = _props.onMouseDown,
|
|
onMouseLeave = _props.onMouseLeave,
|
|
onMouseUp = _props.onMouseUp,
|
|
onTouchEnd = _props.onTouchEnd,
|
|
onTouchMove = _props.onTouchMove,
|
|
onTouchStart = _props.onTouchStart,
|
|
tabIndex = _props.tabIndex,
|
|
TouchRippleProps = _props.TouchRippleProps,
|
|
type = _props.type,
|
|
other = (0, _objectWithoutProperties2.default)(_props, ["action", "buttonRef", "centerRipple", "children", "classes", "className", "component", "disabled", "disableRipple", "focusRipple", "focusVisibleClassName", "onBlur", "onFocus", "onFocusVisible", "onKeyDown", "onKeyUp", "onMouseDown", "onMouseLeave", "onMouseUp", "onTouchEnd", "onTouchMove", "onTouchStart", "tabIndex", "TouchRippleProps", "type"]);
|
|
var className = (0, _classnames.default)(classes.root, (_classNames = {}, (0, _defineProperty2.default)(_classNames, classes.disabled, disabled), (0, _defineProperty2.default)(_classNames, classes.focusVisible, this.state.focusVisible), (0, _defineProperty2.default)(_classNames, focusVisibleClassName, this.state.focusVisible), _classNames), classNameProp);
|
|
var buttonProps = {};
|
|
var ComponentProp = component;
|
|
|
|
if (!ComponentProp) {
|
|
if (other.href) {
|
|
ComponentProp = 'a';
|
|
} else {
|
|
ComponentProp = 'button';
|
|
}
|
|
}
|
|
|
|
if (ComponentProp === 'button') {
|
|
buttonProps.type = type || 'button';
|
|
buttonProps.disabled = disabled;
|
|
} else {
|
|
buttonProps.role = 'button';
|
|
}
|
|
|
|
return _react.default.createElement(ComponentProp, (0, _extends2.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,
|
|
ref: buttonRef
|
|
}, buttonProps, other), children, !disableRipple && !disabled ? _react.default.createElement(_TouchRipple.default, (0, _extends2.default)({
|
|
innerRef: this.onRippleRef,
|
|
center: centerRipple
|
|
}, TouchRippleProps)) : null);
|
|
}
|
|
}], [{
|
|
key: "getDerivedStateFromProps",
|
|
value: function getDerivedStateFromProps(nextProps, prevState) {
|
|
if (typeof prevState.focusVisible === 'undefined') {
|
|
return {
|
|
focusVisible: false,
|
|
lastDisabled: nextProps.disabled
|
|
};
|
|
} // The blur won't fire when the disabled state is set on a focused input.
|
|
// We need to book keep the focused state manually.
|
|
|
|
|
|
if (!prevState.prevState && nextProps.disabled && prevState.focusVisible) {
|
|
return {
|
|
focusVisible: false,
|
|
lastDisabled: nextProps.disabled
|
|
};
|
|
}
|
|
|
|
return {
|
|
lastDisabled: nextProps.disabled
|
|
};
|
|
}
|
|
}]);
|
|
return ButtonBase;
|
|
}(_react.default.Component);
|
|
|
|
ButtonBase.propTypes = process.env.NODE_ENV !== "production" ? {
|
|
/**
|
|
* Callback fired when the component mounts.
|
|
* This is useful when you want to trigger an action programmatically.
|
|
* It currently only supports `focusVisible()` action.
|
|
*
|
|
* @param {object} actions This object contains all possible actions
|
|
* that can be triggered programmatically.
|
|
*/
|
|
action: _propTypes.default.func,
|
|
|
|
/**
|
|
* Use that property to pass a ref callback to the native button component.
|
|
*/
|
|
buttonRef: _propTypes.default.func,
|
|
|
|
/**
|
|
* If `true`, the ripples will be centered.
|
|
* They won't start at the cursor interaction position.
|
|
*/
|
|
centerRipple: _propTypes.default.bool,
|
|
|
|
/**
|
|
* The content of the component.
|
|
*/
|
|
children: _propTypes.default.node,
|
|
|
|
/**
|
|
* Useful to extend the style applied to components.
|
|
*/
|
|
classes: _propTypes.default.object.isRequired,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
className: _propTypes.default.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: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func]),
|
|
|
|
/**
|
|
* If `true`, the base button will be disabled.
|
|
*/
|
|
disabled: _propTypes.default.bool,
|
|
|
|
/**
|
|
* If `true`, the ripple effect will be disabled.
|
|
*/
|
|
disableRipple: _propTypes.default.bool,
|
|
|
|
/**
|
|
* If `true`, the base button will have a keyboard focus ripple.
|
|
* `disableRipple` must also be `false`.
|
|
*/
|
|
focusRipple: _propTypes.default.bool,
|
|
|
|
/**
|
|
* This property can help a person know which element has the keyboard focus.
|
|
* The class name will be applied when the element gain the focus throught a keyboard interaction.
|
|
* It's a polyfill for the [CSS :focus-visible feature](https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo).
|
|
* The rational for using this feature [is explain here](https://github.com/WICG/focus-visible/blob/master/explainer.md).
|
|
*/
|
|
focusVisibleClassName: _propTypes.default.string,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onBlur: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onClick: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onFocus: _propTypes.default.func,
|
|
|
|
/**
|
|
* Callback fired when the component is focused with a keyboard.
|
|
* We trigger a `onFocus` callback too.
|
|
*/
|
|
onFocusVisible: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onKeyDown: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onKeyUp: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onMouseDown: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onMouseLeave: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onMouseUp: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onTouchEnd: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onTouchMove: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
onTouchStart: _propTypes.default.func,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
role: _propTypes.default.string,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
tabIndex: _propTypes.default.oneOfType([_propTypes.default.number, _propTypes.default.string]),
|
|
|
|
/**
|
|
* Properties applied to the `TouchRipple` element.
|
|
*/
|
|
TouchRippleProps: _propTypes.default.object,
|
|
|
|
/**
|
|
* @ignore
|
|
*/
|
|
type: _propTypes.default.string
|
|
} : {};
|
|
ButtonBase.defaultProps = {
|
|
centerRipple: false,
|
|
disableRipple: false,
|
|
focusRipple: false,
|
|
tabIndex: '0',
|
|
type: 'button'
|
|
};
|
|
|
|
var _default = (0, _withStyles.default)(styles, {
|
|
name: 'MuiButtonBase'
|
|
})((0, _reactLifecyclesCompat.polyfill)(ButtonBase));
|
|
|
|
exports.default = _default; |