Completely updated React, fixed #11, (hopefully)

This commit is contained in:
2018-03-04 19:11:49 -05:00
parent 6e0afd6e2a
commit 34e5f5139a
13674 changed files with 333464 additions and 473223 deletions

View File

@@ -1,34 +1,35 @@
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
// weak
import _extends from 'babel-runtime/helpers/extends';
import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
import React from 'react';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
import classNames from 'classnames';
import keycode from 'keycode';
import ownerWindow from 'dom-helpers/ownerWindow';
import withStyles from '../styles/withStyles';
import { listenForFocusKeys, detectKeyboardFocus, focusKeyPressed } from '../utils/keyboardFocus';
import TouchRipple from './TouchRipple';
import createRippleHandler from './createRippleHandler';
export const styles = theme => ({
export const styles = {
root: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
position: 'relative',
// Remove grey highlight
WebkitTapHighlightColor: theme.palette.common.transparent,
WebkitTapHighlightColor: 'transparent',
backgroundColor: 'transparent', // Reset default value
outline: 'none',
border: 0,
margin: 0, // Remove the margin in Safari
borderRadius: 0,
padding: 0, // Remove the padding in Firefox
cursor: 'pointer',
userSelect: 'none',
appearance: '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',
@@ -40,8 +41,13 @@ export const styles = theme => ({
pointerEvents: 'none', // Disable link interactions
cursor: 'default'
}
});
};
/**
* `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.
*/
class ButtonBase extends React.Component {
constructor(...args) {
var _temp;
@@ -55,12 +61,14 @@ class ButtonBase extends React.Component {
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 = event => {
}, this.onRippleRef = node => {
this.ripple = node;
}, this.ripple = null, this.keyDown = false, this.button = null, this.keyboardFocusTimeout = null, this.keyboardFocusCheckTime = 50, this.keyboardFocusMaxCheckTimes = 5, this.handleKeyDown = event => {
const { component, focusRipple, onKeyDown, onClick } = this.props;
const key = keycode(event);
// Check if key is already down to avoid repeats being counted as multiple activations
if (focusRipple && !this.keyDown && this.state.keyboardFocused && key === 'space') {
if (focusRipple && !this.keyDown && this.state.keyboardFocused && this.ripple && key === 'space') {
this.keyDown = true;
event.persist();
this.ripple.stop(event, () => {
@@ -73,12 +81,14 @@ class ButtonBase extends React.Component {
}
// Keyboard accessibility for non interactive elements
if (event.target === this.button && onClick && component && component !== 'a' && component !== 'button' && (key === 'space' || key === 'enter')) {
if (event.target === event.currentTarget && component && component !== 'button' && (key === 'space' || key === 'enter')) {
event.preventDefault();
onClick(event);
if (onClick) {
onClick(event);
}
}
}, this.handleKeyUp = event => {
if (this.props.focusRipple && keycode(event) === 'space' && this.state.keyboardFocused) {
if (this.props.focusRipple && keycode(event) === 'space' && this.ripple && this.state.keyboardFocused) {
this.keyDown = false;
event.persist();
this.ripple.stop(event, () => this.ripple.pulsate(event));
@@ -111,8 +121,9 @@ class ButtonBase extends React.Component {
}
event.persist();
const keyboardFocusCallback = this.onKeyboardFocusHandler.bind(this, event);
detectKeyboardFocus(this, this.button, keyboardFocusCallback);
detectKeyboardFocus(this, this.button, () => {
this.onKeyboardFocusHandler(event);
});
if (this.props.onFocus) {
this.props.onFocus(event);
@@ -122,7 +133,17 @@ class ButtonBase extends React.Component {
componentDidMount() {
this.button = findDOMNode(this);
listenForFocusKeys();
listenForFocusKeys(ownerWindow(this.button));
}
componentWillReceiveProps(nextProps) {
// 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 (!this.props.disabled && nextProps.disabled && this.state.keyboardFocused) {
this.setState({
keyboardFocused: false
});
}
}
componentWillUpdate(nextProps, nextState) {
@@ -137,22 +158,10 @@ class ButtonBase extends React.Component {
} // Used to help track keyboard activation keyDown
renderRipple() {
if (!this.props.disableRipple && !this.props.disabled) {
return React.createElement(TouchRipple, {
innerRef: node => {
this.ripple = node;
},
center: this.props.centerRipple
});
}
return null;
}
render() {
const _props = this.props,
{
buttonRef,
centerRipple,
children,
classes,
@@ -173,11 +182,10 @@ class ButtonBase extends React.Component {
onTouchEnd,
onTouchMove,
onTouchStart,
rootRef,
tabIndex,
type
} = _props,
other = _objectWithoutProperties(_props, ['centerRipple', 'children', 'classes', 'className', 'component', 'disabled', 'disableRipple', 'focusRipple', 'keyboardFocusedClassName', 'onBlur', 'onFocus', 'onKeyboardFocus', 'onKeyDown', 'onKeyUp', 'onMouseDown', 'onMouseLeave', 'onMouseUp', 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'rootRef', 'tabIndex', 'type']);
other = _objectWithoutProperties(_props, ['buttonRef', 'centerRipple', 'children', 'classes', 'className', 'component', 'disabled', 'disableRipple', 'focusRipple', 'keyboardFocusedClassName', 'onBlur', 'onFocus', 'onKeyboardFocus', 'onKeyDown', 'onKeyUp', 'onMouseDown', 'onMouseLeave', 'onMouseUp', 'onTouchEnd', 'onTouchMove', 'onTouchStart', 'tabIndex', 'type']);
const className = classNames(classes.root, {
[classes.disabled]: disabled,
@@ -198,11 +206,9 @@ class ButtonBase extends React.Component {
if (ComponentProp === 'button') {
buttonProps.type = type || 'button';
}
if (ComponentProp !== 'a') {
buttonProps.role = buttonProps.role || 'button';
buttonProps.disabled = disabled;
} else {
buttonProps.role = 'button';
}
return React.createElement(
@@ -218,22 +224,130 @@ class ButtonBase extends React.Component {
onTouchEnd: this.handleTouchEnd,
onTouchMove: this.handleTouchMove,
onTouchStart: this.handleTouchStart,
tabIndex: disabled ? -1 : tabIndex,
className: className
}, buttonProps, other, {
ref: rootRef
}),
tabIndex: disabled ? '-1' : tabIndex,
className: className,
ref: buttonRef
}, buttonProps, other),
children,
this.renderRipple()
!disableRipple && !disabled ? React.createElement(TouchRipple, { innerRef: this.onRippleRef, center: centerRipple }) : null
);
}
}
ButtonBase.propTypes = process.env.NODE_ENV !== "production" ? {
/**
* Use that property to pass a ref callback to the native button component.
*/
buttonRef: PropTypes.func,
/**
* If `true`, the ripples will be centered.
* They won't start at the cursor interaction position.
*/
centerRipple: PropTypes.bool,
/**
* The content of the component.
*/
children: PropTypes.node,
/**
* Useful to extend the style applied to components.
*/
classes: PropTypes.object.isRequired,
/**
* @ignore
*/
className: PropTypes.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.oneOfType([PropTypes.string, PropTypes.func]),
/**
* If `true`, the base button will be disabled.
*/
disabled: PropTypes.bool,
/**
* If `true`, the ripple effect will be disabled.
*/
disableRipple: PropTypes.bool,
/**
* If `true`, the base button will have a keyboard focus ripple.
* `disableRipple` must also be `false`.
*/
focusRipple: PropTypes.bool,
/**
* The CSS class applied while the component is keyboard focused.
*/
keyboardFocusedClassName: PropTypes.string,
/**
* @ignore
*/
onBlur: PropTypes.func,
/**
* @ignore
*/
onClick: PropTypes.func,
/**
* @ignore
*/
onFocus: PropTypes.func,
/**
* Callback fired when the component is focused with a keyboard.
* We trigger a `onFocus` callback too.
*/
onKeyboardFocus: PropTypes.func,
/**
* @ignore
*/
onKeyDown: PropTypes.func,
/**
* @ignore
*/
onKeyUp: PropTypes.func,
/**
* @ignore
*/
onMouseDown: PropTypes.func,
/**
* @ignore
*/
onMouseLeave: PropTypes.func,
/**
* @ignore
*/
onMouseUp: PropTypes.func,
/**
* @ignore
*/
onTouchEnd: PropTypes.func,
/**
* @ignore
*/
onTouchMove: PropTypes.func,
/**
* @ignore
*/
onTouchStart: PropTypes.func,
/**
* @ignore
*/
role: PropTypes.string,
/**
* @ignore
*/
tabIndex: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
/**
* @ignore
*/
type: PropTypes.string
} : {};
ButtonBase.defaultProps = {
centerRipple: false,
focusRipple: false,
disableRipple: false,
tabIndex: 0,
focusRipple: false,
tabIndex: '0',
type: 'button'
};
export default withStyles(styles, { name: 'MuiButtonBase' })(ButtonBase);