Removed GopherJS, basic frontend completed, need backend changes for

torrent storage
This commit is contained in:
2017-11-30 18:12:11 -05:00
parent 67fdef16b1
commit e98ad2cc88
69321 changed files with 5498914 additions and 337 deletions

View File

@@ -0,0 +1,24 @@
import * as React from 'react';
import { StandardProps, Replace } from '..';
export interface ButtonBaseProps extends StandardProps<
Replace<React.AnchorHTMLAttributes<HTMLAnchorElement>, React.ButtonHTMLAttributes<HTMLButtonElement>>,
ButtonBaseClassKey
> {
centerRipple?: boolean;
component?: React.ReactType;
disableRipple?: boolean;
focusRipple?: boolean;
keyboardFocusedClassName?: string;
onKeyboardFocus?: React.FocusEventHandler<any>;
rootRef?: React.Ref<any>;
}
export type ButtonBaseClassKey =
| 'root'
| 'disabled'
;
declare const ButtonBase: React.ComponentType<ButtonBaseProps>;
export default ButtonBase;

View File

@@ -0,0 +1,455 @@
'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);

View File

@@ -0,0 +1,394 @@
// @flow weak
import React from 'react';
import type { ElementType, Node } from 'react';
import { findDOMNode } from 'react-dom';
import classNames from 'classnames';
import keycode from 'keycode';
import withStyles from '../styles/withStyles';
import { listenForFocusKeys, detectKeyboardFocus, focusKeyPressed } from '../utils/keyboardFocus';
import TouchRipple from './TouchRipple';
import createRippleHandler from './createRippleHandler';
export const styles = (theme: Object) => ({
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',
},
});
type ProvidedProps = {
classes: Object,
};
export type Props = {
/**
* If `true`, the ripples will be centered.
* They won't start at the cursor interaction position.
*/
centerRipple?: boolean,
/**
* The content of the component.
*/
children?: Node,
/**
* Useful to extend the style applied to components.
*/
classes?: Object,
/**
* @ignore
*/
className?: 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?: ElementType,
/**
* If `true`, the base button will be disabled.
*/
disabled?: boolean,
/**
* If `true`, the ripple effect will be disabled.
*/
disableRipple?: boolean,
/**
* If `true`, the base button will have a keyboard focus ripple.
* `disableRipple` must also be `false`.
*/
focusRipple?: boolean,
/**
* The CSS class applied while the component is keyboard focused.
*/
keyboardFocusedClassName?: string,
/**
* @ignore
*/
onBlur?: Function,
/**
* @ignore
*/
onClick?: Function,
/**
* @ignore
*/
onFocus?: Function,
/**
* Callback fired when the component is focused with a keyboard.
* We trigger a `onFocus` callback too.
*/
onKeyboardFocus?: (event: SyntheticEvent<>) => void,
/**
* @ignore
*/
onKeyDown?: Function,
/**
* @ignore
*/
onKeyUp?: Function,
/**
* @ignore
*/
onMouseDown?: Function,
/**
* @ignore
*/
onMouseLeave?: Function,
/**
* @ignore
*/
onMouseUp?: Function,
/**
* @ignore
*/
onTouchEnd?: Function,
/**
* @ignore
*/
onTouchMove?: Function,
/**
* @ignore
*/
onTouchStart?: Function,
/**
* @ignore
*/
role?: string,
/**
* Use that property to pass a ref callback to the root component.
*/
rootRef?: Function,
/**
* @ignore
*/
tabIndex?: number | string,
/**
* @ignore
*/
type: string,
};
type State = {
keyboardFocused: boolean,
};
class ButtonBase extends React.Component<ProvidedProps & Props, State> {
static defaultProps = {
centerRipple: false,
focusRipple: false,
disableRipple: false,
tabIndex: 0,
type: 'button',
};
state = {
keyboardFocused: false,
};
componentDidMount() {
this.button = findDOMNode(this);
listenForFocusKeys();
}
componentWillUpdate(nextProps, nextState) {
if (
this.props.focusRipple &&
nextState.keyboardFocused &&
!this.state.keyboardFocused &&
!this.props.disableRipple
) {
this.ripple.pulsate();
}
}
componentWillUnmount() {
this.button = null;
clearTimeout(this.keyboardFocusTimeout);
}
onKeyboardFocusHandler = event => {
this.keyDown = false;
this.setState({ keyboardFocused: true });
if (this.props.onKeyboardFocus) {
this.props.onKeyboardFocus(event);
}
};
ripple = null;
keyDown = false; // Used to help track keyboard activation keyDown
button = null;
keyboardFocusTimeout = null;
keyboardFocusCheckTime = 30;
keyboardFocusMaxCheckTimes = 5;
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') {
this.keyDown = true;
event.persist();
this.ripple.stop(event, () => {
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);
}
};
handleKeyUp = event => {
if (this.props.focusRipple && keycode(event) === 'space' && this.state.keyboardFocused) {
this.keyDown = false;
event.persist();
this.ripple.stop(event, () => this.ripple.pulsate(event));
}
if (this.props.onKeyUp) {
this.props.onKeyUp(event);
}
};
handleMouseDown = createRippleHandler(this, 'MouseDown', 'start', () => {
clearTimeout(this.keyboardFocusTimeout);
focusKeyPressed(false);
if (this.state.keyboardFocused) {
this.setState({ keyboardFocused: false });
}
});
handleMouseUp = createRippleHandler(this, 'MouseUp', 'stop');
handleMouseLeave = createRippleHandler(this, 'MouseLeave', 'stop', event => {
if (this.state.keyboardFocused) {
event.preventDefault();
}
});
handleTouchStart = createRippleHandler(this, 'TouchStart', 'start');
handleTouchEnd = createRippleHandler(this, 'TouchEnd', 'stop');
handleTouchMove = createRippleHandler(this, 'TouchEnd', 'stop');
handleBlur = createRippleHandler(this, 'Blur', 'stop', () => {
clearTimeout(this.keyboardFocusTimeout);
focusKeyPressed(false);
this.setState({ keyboardFocused: false });
});
handleFocus = event => {
if (this.props.disabled) {
return;
}
// Fix for https://github.com/facebook/react/issues/7769
if (!this.button) {
this.button = event.currentTarget;
}
event.persist();
const keyboardFocusCallback = this.onKeyboardFocusHandler.bind(this, event);
detectKeyboardFocus(this, this.button, keyboardFocusCallback);
if (this.props.onFocus) {
this.props.onFocus(event);
}
};
renderRipple() {
if (!this.props.disableRipple && !this.props.disabled) {
return (
<TouchRipple
innerRef={node => {
this.ripple = node;
}}
center={this.props.centerRipple}
/>
);
}
return null;
}
render() {
const {
centerRipple,
children,
classes,
className: classNameProp,
component,
disabled,
disableRipple,
focusRipple,
keyboardFocusedClassName,
onBlur,
onFocus,
onKeyboardFocus,
onKeyDown,
onKeyUp,
onMouseDown,
onMouseLeave,
onMouseUp,
onTouchEnd,
onTouchMove,
onTouchStart,
rootRef,
tabIndex,
type,
...other
} = this.props;
const className = classNames(
classes.root,
{
[classes.disabled]: disabled,
[keyboardFocusedClassName || '']: this.state.keyboardFocused,
},
classNameProp,
);
const buttonProps = {};
let 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 (
<ComponentProp
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()}
</ComponentProp>
);
}
}
export default withStyles(styles, { name: 'MuiButtonBase' })(ButtonBase);

View File

@@ -0,0 +1,167 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _Transition = require('react-transition-group/Transition');
var _Transition2 = _interopRequireDefault(_Transition);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var babelPluginFlowReactPropTypes_proptype_Props = {
/**
* Useful to extend the style applied to components.
*/
classes: require('prop-types').object,
/**
* @ignore
*/
className: require('prop-types').string,
/**
* If `true`, the ripple pulsates, typically indicating the keyboard focus state of an element.
*/
pulsate: require('prop-types').bool,
/**
* Diameter of the ripple.
*/
rippleSize: require('prop-types').number.isRequired,
/**
* Horizontal position of the ripple center.
*/
rippleX: require('prop-types').number.isRequired,
/**
* Vertical position of the ripple center.
*/
rippleY: require('prop-types').number.isRequired
}; // weak
/**
* @ignore - internal component.
*/
var Ripple = function (_React$Component) {
(0, _inherits3.default)(Ripple, _React$Component);
function Ripple() {
var _ref;
var _temp, _this, _ret;
(0, _classCallCheck3.default)(this, Ripple);
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 = Ripple.__proto__ || (0, _getPrototypeOf2.default)(Ripple)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
rippleVisible: false,
rippleLeaving: false
}, _this.getRippleStyles = function (props) {
var rippleSize = props.rippleSize,
rippleX = props.rippleX,
rippleY = props.rippleY;
return {
width: rippleSize,
height: rippleSize,
top: -(rippleSize / 2) + rippleY,
left: -(rippleSize / 2) + rippleX
};
}, _this.handleEnter = function () {
_this.setState({
rippleVisible: true
});
}, _this.handleExit = function () {
_this.setState({
rippleLeaving: true
});
}, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
}
(0, _createClass3.default)(Ripple, [{
key: 'render',
value: function render() {
var _classNames, _classNames2;
var _props = this.props,
classes = _props.classes,
classNameProp = _props.className,
pulsate = _props.pulsate,
rippleX = _props.rippleX,
rippleY = _props.rippleY,
rippleSize = _props.rippleSize,
other = (0, _objectWithoutProperties3.default)(_props, ['classes', 'className', 'pulsate', 'rippleX', 'rippleY', 'rippleSize']);
var _state = this.state,
rippleVisible = _state.rippleVisible,
rippleLeaving = _state.rippleLeaving;
var className = (0, _classnames2.default)(classes.wrapper, (_classNames = {}, (0, _defineProperty3.default)(_classNames, classes.wrapperLeaving, rippleLeaving), (0, _defineProperty3.default)(_classNames, classes.wrapperPulsating, pulsate), _classNames), classNameProp);
var rippleClassName = (0, _classnames2.default)(classes.ripple, (_classNames2 = {}, (0, _defineProperty3.default)(_classNames2, classes.rippleVisible, rippleVisible), (0, _defineProperty3.default)(_classNames2, classes.rippleFast, pulsate), _classNames2));
return _react2.default.createElement(
_Transition2.default,
(0, _extends3.default)({ onEnter: this.handleEnter, onExit: this.handleExit }, other),
_react2.default.createElement(
'span',
{ className: className },
_react2.default.createElement('span', { className: rippleClassName, style: this.getRippleStyles(this.props) })
)
);
}
}]);
return Ripple;
}(_react2.default.Component);
Ripple.defaultProps = {
pulsate: false
};
exports.default = Ripple;

View File

@@ -0,0 +1,112 @@
// @flow weak
import React from 'react';
import classNames from 'classnames';
import Transition from 'react-transition-group/Transition';
type ProvidedProps = {
classes: Object,
};
export type Props = {
/**
* Useful to extend the style applied to components.
*/
classes?: Object,
/**
* @ignore
*/
className?: string,
/**
* If `true`, the ripple pulsates, typically indicating the keyboard focus state of an element.
*/
pulsate?: boolean,
/**
* Diameter of the ripple.
*/
rippleSize: number,
/**
* Horizontal position of the ripple center.
*/
rippleX: number,
/**
* Vertical position of the ripple center.
*/
rippleY: number,
};
type State = { rippleVisible: boolean, rippleLeaving: boolean };
/**
* @ignore - internal component.
*/
class Ripple extends React.Component<ProvidedProps & Props, State> {
static defaultProps = {
pulsate: false,
};
state = {
rippleVisible: false,
rippleLeaving: false,
};
getRippleStyles = props => {
const { rippleSize, rippleX, rippleY } = props;
return {
width: rippleSize,
height: rippleSize,
top: -(rippleSize / 2) + rippleY,
left: -(rippleSize / 2) + rippleX,
};
};
handleEnter = () => {
this.setState({
rippleVisible: true,
});
};
handleExit = () => {
this.setState({
rippleLeaving: true,
});
};
render() {
const {
classes,
className: classNameProp,
pulsate,
rippleX,
rippleY,
rippleSize,
...other
} = this.props;
const { rippleVisible, rippleLeaving } = this.state;
const className = classNames(
classes.wrapper,
{
[classes.wrapperLeaving]: rippleLeaving,
[classes.wrapperPulsating]: pulsate,
},
classNameProp,
);
const rippleClassName = classNames(classes.ripple, {
[classes.rippleVisible]: rippleVisible,
[classes.rippleFast]: pulsate,
});
return (
<Transition onEnter={this.handleEnter} onExit={this.handleExit} {...other}>
<span className={className}>
<span className={rippleClassName} style={this.getRippleStyles(this.props)} />
</span>
</Transition>
);
}
}
export default Ripple;

View File

@@ -0,0 +1,363 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.styles = exports.DELAY_RIPPLE = undefined;
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _objectWithoutProperties2 = require('babel-runtime/helpers/objectWithoutProperties');
var _objectWithoutProperties3 = _interopRequireDefault(_objectWithoutProperties2);
var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
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 _reactDom2 = _interopRequireDefault(_reactDom);
var _TransitionGroup = require('react-transition-group/TransitionGroup');
var _TransitionGroup2 = _interopRequireDefault(_TransitionGroup);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _withStyles = require('../styles/withStyles');
var _withStyles2 = _interopRequireDefault(_withStyles);
var _Ripple = require('./Ripple');
var _Ripple2 = _interopRequireDefault(_Ripple);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// weak
var DURATION = 550;
var DELAY_RIPPLE = exports.DELAY_RIPPLE = 80;
var styles = exports.styles = function styles(theme) {
return {
root: {
display: 'block',
position: 'absolute',
overflow: 'hidden',
borderRadius: 'inherit',
width: '100%',
height: '100%',
left: 0,
top: 0,
pointerEvents: 'none',
zIndex: 0
},
wrapper: {
opacity: 1
},
wrapperLeaving: {
opacity: 0,
animation: 'mui-ripple-exit ' + DURATION + 'ms ' + theme.transitions.easing.easeInOut
},
wrapperPulsating: {
position: 'absolute',
left: 0,
top: 0,
display: 'block',
width: '100%',
height: '100%',
animation: 'mui-ripple-pulsate 1500ms ' + theme.transitions.easing.easeInOut + ' 200ms infinite',
rippleVisible: {
opacity: 0.2
}
},
'@keyframes mui-ripple-enter': {
'0%': {
transform: 'scale(0)'
},
'100%': {
transform: 'scale(1)'
}
},
'@keyframes mui-ripple-exit': {
'0%': {
opacity: 1
},
'100%': {
opacity: 0
}
},
'@keyframes mui-ripple-pulsate': {
'0%': {
transform: 'scale(1)'
},
'50%': {
transform: 'scale(0.9)'
},
'100%': {
transform: 'scale(1)'
}
},
ripple: {
width: 50,
height: 50,
left: 0,
top: 0,
opacity: 0,
position: 'absolute',
borderRadius: '50%',
background: 'currentColor'
},
rippleVisible: {
opacity: 0.3,
transform: 'scale(1)',
animation: 'mui-ripple-enter ' + DURATION + 'ms ' + theme.transitions.easing.easeInOut
},
rippleFast: {
animationDuration: '200ms'
}
};
};
var babelPluginFlowReactPropTypes_proptype_Props = {
/**
* If `true`, the ripple starts at the center of the component
* rather than at the point of interaction.
*/
center: require('prop-types').bool,
/**
* Useful to extend the style applied to components.
*/
classes: require('prop-types').object,
/**
* @ignore
*/
className: require('prop-types').string
};
/**
* @ignore - internal component.
*/
var TouchRipple = function (_React$Component) {
(0, _inherits3.default)(TouchRipple, _React$Component);
function TouchRipple() {
var _ref;
var _temp, _this, _ret;
(0, _classCallCheck3.default)(this, TouchRipple);
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 = TouchRipple.__proto__ || (0, _getPrototypeOf2.default)(TouchRipple)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
nextKey: 0,
ripples: []
}, _this.ignoringMouseDown = false, _this.startTimer = null, _this.startTimerCommit = null, _this.pulsate = function () {
_this.start({}, { pulsate: true });
}, _this.start = function () {
var event = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var cb = arguments[2];
var _options$pulsate = options.pulsate,
pulsate = _options$pulsate === undefined ? false : _options$pulsate,
_options$center = options.center,
center = _options$center === undefined ? _this.props.center || options.pulsate : _options$center,
_options$fakeElement = options.fakeElement,
fakeElement = _options$fakeElement === undefined ? false : _options$fakeElement;
if (event.type === 'mousedown' && _this.ignoringMouseDown) {
_this.ignoringMouseDown = false;
return;
}
if (event.type === 'touchstart') {
_this.ignoringMouseDown = true;
}
var element = fakeElement ? null : _reactDom2.default.findDOMNode(_this);
var rect = element ? // $FlowFixMe
element.getBoundingClientRect() : {
width: 0,
height: 0,
left: 0,
top: 0
};
// Get the size of the ripple
var rippleX = void 0;
var rippleY = void 0;
var rippleSize = void 0;
if (center || event.clientX === 0 && event.clientY === 0 || !event.clientX && !event.touches) {
rippleX = Math.round(rect.width / 2);
rippleY = Math.round(rect.height / 2);
} else {
var clientX = event.clientX ? event.clientX : event.touches[0].clientX;
var clientY = event.clientY ? event.clientY : event.touches[0].clientY;
rippleX = Math.round(clientX - rect.left);
rippleY = Math.round(clientY - rect.top);
}
if (center) {
rippleSize = Math.sqrt((2 * Math.pow(rect.width, 2) + Math.pow(rect.height, 2)) / 3);
// For some reason the animation is broken on Mobile Chrome if the size if even.
if (rippleSize % 2 === 0) {
rippleSize += 1;
}
} else {
var sizeX = Math.max(
// $FlowFixMe
Math.abs((element ? element.clientWidth : 0) - rippleX), rippleX) * 2 + 2;
var sizeY = Math.max(
// $FlowFixMe
Math.abs((element ? element.clientHeight : 0) - rippleY), rippleY) * 2 + 2;
rippleSize = Math.sqrt(Math.pow(sizeX, 2) + Math.pow(sizeY, 2));
}
// Touche devices
if (event.touches) {
// Prepare the ripple effect.
_this.startTimerCommit = function () {
_this.startCommit({ pulsate: pulsate, rippleX: rippleX, rippleY: rippleY, rippleSize: rippleSize, cb: cb });
};
// Deplay the execution of the ripple effect.
_this.startTimer = setTimeout(function () {
_this.startTimerCommit();
_this.startTimerCommit = null;
}, DELAY_RIPPLE); // We have to make a tradeoff with this value.
} else {
_this.startCommit({ pulsate: pulsate, rippleX: rippleX, rippleY: rippleY, rippleSize: rippleSize, cb: cb });
}
}, _this.startCommit = function (params) {
var pulsate = params.pulsate,
rippleX = params.rippleX,
rippleY = params.rippleY,
rippleSize = params.rippleSize,
cb = params.cb;
var ripples = _this.state.ripples;
// Add a ripple to the ripples array
ripples = [].concat((0, _toConsumableArray3.default)(ripples), [_react2.default.createElement(_Ripple2.default, {
key: _this.state.nextKey,
classes: _this.props.classes,
timeout: {
exit: DURATION,
enter: DURATION
},
pulsate: pulsate,
rippleX: rippleX,
rippleY: rippleY,
rippleSize: rippleSize
})]);
_this.setState({
nextKey: _this.state.nextKey + 1,
ripples: ripples
}, cb);
}, _this.stop = function (event, cb) {
clearTimeout(_this.startTimer);
var ripples = _this.state.ripples;
// The touch interaction occures to quickly.
// We still want to show ripple effect.
if (event.type === 'touchend' && _this.startTimerCommit) {
event.persist();
_this.startTimerCommit();
_this.startTimerCommit = null;
_this.startTimer = setTimeout(function () {
_this.stop(event, cb);
}, 0);
return;
}
_this.startTimerCommit = null;
if (ripples && ripples.length) {
_this.setState({
ripples: ripples.slice(1)
}, cb);
}
}, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
}
(0, _createClass3.default)(TouchRipple, [{
key: 'componentWillUnmount',
value: function componentWillUnmount() {
clearTimeout(this.startTimer);
}
// Used to filter out mouse emulated events on mobile.
// We use a timer in order to only show the ripples for touch "click" like events.
// We don't want to display the ripple for touch scroll events.
// This is the hook called once the previous timeout is ready.
}, {
key: 'render',
value: function render() {
var _props = this.props,
center = _props.center,
classes = _props.classes,
className = _props.className,
other = (0, _objectWithoutProperties3.default)(_props, ['center', 'classes', 'className']);
return _react2.default.createElement(
_TransitionGroup2.default,
(0, _extends3.default)({
component: 'span',
enter: true,
exit: true,
className: (0, _classnames2.default)(classes.root, className)
}, other),
this.state.ripples
);
}
}]);
return TouchRipple;
}(_react2.default.Component);
TouchRipple.defaultProps = {
center: false
};
exports.default = (0, _withStyles2.default)(styles, { flip: false, name: 'MuiTouchRipple' })(TouchRipple);

View File

@@ -0,0 +1,307 @@
// @flow weak
import React from 'react';
import ReactDOM from 'react-dom';
import TransitionGroup from 'react-transition-group/TransitionGroup';
import classNames from 'classnames';
import withStyles from '../styles/withStyles';
import Ripple from './Ripple';
const DURATION = 550;
export const DELAY_RIPPLE = 80;
export const styles = (theme: Object) => ({
root: {
display: 'block',
position: 'absolute',
overflow: 'hidden',
borderRadius: 'inherit',
width: '100%',
height: '100%',
left: 0,
top: 0,
pointerEvents: 'none',
zIndex: 0,
},
wrapper: {
opacity: 1,
},
wrapperLeaving: {
opacity: 0,
animation: `mui-ripple-exit ${DURATION}ms ${theme.transitions.easing.easeInOut}`,
},
wrapperPulsating: {
position: 'absolute',
left: 0,
top: 0,
display: 'block',
width: '100%',
height: '100%',
animation: `mui-ripple-pulsate 1500ms ${theme.transitions.easing.easeInOut} 200ms infinite`,
rippleVisible: {
opacity: 0.2,
},
},
'@keyframes mui-ripple-enter': {
'0%': {
transform: 'scale(0)',
},
'100%': {
transform: 'scale(1)',
},
},
'@keyframes mui-ripple-exit': {
'0%': {
opacity: 1,
},
'100%': {
opacity: 0,
},
},
'@keyframes mui-ripple-pulsate': {
'0%': {
transform: 'scale(1)',
},
'50%': {
transform: 'scale(0.9)',
},
'100%': {
transform: 'scale(1)',
},
},
ripple: {
width: 50,
height: 50,
left: 0,
top: 0,
opacity: 0,
position: 'absolute',
borderRadius: '50%',
background: 'currentColor',
},
rippleVisible: {
opacity: 0.3,
transform: 'scale(1)',
animation: `mui-ripple-enter ${DURATION}ms ${theme.transitions.easing.easeInOut}`,
},
rippleFast: {
animationDuration: '200ms',
},
});
type ProvidedProps = {
classes: Object,
};
export type Props = {
/**
* If `true`, the ripple starts at the center of the component
* rather than at the point of interaction.
*/
center?: boolean,
/**
* Useful to extend the style applied to components.
*/
classes?: Object,
/**
* @ignore
*/
className?: string,
};
type State = { nextKey: number, ripples: Array<*> };
/**
* @ignore - internal component.
*/
class TouchRipple extends React.Component<ProvidedProps & Props, State> {
static defaultProps = {
center: false,
};
state = {
nextKey: 0,
ripples: [],
};
componentWillUnmount() {
clearTimeout(this.startTimer);
}
// Used to filter out mouse emulated events on mobile.
ignoringMouseDown = false;
// We use a timer in order to only show the ripples for touch "click" like events.
// We don't want to display the ripple for touch scroll events.
startTimer = null;
// This is the hook called once the previous timeout is ready.
startTimerCommit = null;
pulsate = () => {
this.start({}, { pulsate: true });
};
start = (event = {}, options = {}, cb) => {
const {
pulsate = false,
center = this.props.center || options.pulsate,
fakeElement = false, // For test purposes
} = options;
if (event.type === 'mousedown' && this.ignoringMouseDown) {
this.ignoringMouseDown = false;
return;
}
if (event.type === 'touchstart') {
this.ignoringMouseDown = true;
}
const element = fakeElement ? null : ReactDOM.findDOMNode(this);
const rect = element
? // $FlowFixMe
element.getBoundingClientRect()
: {
width: 0,
height: 0,
left: 0,
top: 0,
};
// Get the size of the ripple
let rippleX;
let rippleY;
let rippleSize;
if (
center ||
(event.clientX === 0 && event.clientY === 0) ||
(!event.clientX && !event.touches)
) {
rippleX = Math.round(rect.width / 2);
rippleY = Math.round(rect.height / 2);
} else {
const clientX = event.clientX ? event.clientX : event.touches[0].clientX;
const clientY = event.clientY ? event.clientY : event.touches[0].clientY;
rippleX = Math.round(clientX - rect.left);
rippleY = Math.round(clientY - rect.top);
}
if (center) {
rippleSize = Math.sqrt((2 * Math.pow(rect.width, 2) + Math.pow(rect.height, 2)) / 3);
// For some reason the animation is broken on Mobile Chrome if the size if even.
if (rippleSize % 2 === 0) {
rippleSize += 1;
}
} else {
const sizeX =
Math.max(
// $FlowFixMe
Math.abs((element ? element.clientWidth : 0) - rippleX),
rippleX,
) *
2 +
2;
const sizeY =
Math.max(
// $FlowFixMe
Math.abs((element ? element.clientHeight : 0) - rippleY),
rippleY,
) *
2 +
2;
rippleSize = Math.sqrt(Math.pow(sizeX, 2) + Math.pow(sizeY, 2));
}
// Touche devices
if (event.touches) {
// Prepare the ripple effect.
this.startTimerCommit = () => {
this.startCommit({ pulsate, rippleX, rippleY, rippleSize, cb });
};
// Deplay the execution of the ripple effect.
this.startTimer = setTimeout(() => {
this.startTimerCommit();
this.startTimerCommit = null;
}, DELAY_RIPPLE); // We have to make a tradeoff with this value.
} else {
this.startCommit({ pulsate, rippleX, rippleY, rippleSize, cb });
}
};
startCommit = params => {
const { pulsate, rippleX, rippleY, rippleSize, cb } = params;
let ripples = this.state.ripples;
// Add a ripple to the ripples array
ripples = [
...ripples,
<Ripple
key={this.state.nextKey}
classes={this.props.classes}
timeout={{
exit: DURATION,
enter: DURATION,
}}
pulsate={pulsate}
rippleX={rippleX}
rippleY={rippleY}
rippleSize={rippleSize}
/>,
];
this.setState(
{
nextKey: this.state.nextKey + 1,
ripples,
},
cb,
);
};
stop = (event, cb) => {
clearTimeout(this.startTimer);
const { ripples } = this.state;
// The touch interaction occures to quickly.
// We still want to show ripple effect.
if (event.type === 'touchend' && this.startTimerCommit) {
event.persist();
this.startTimerCommit();
this.startTimerCommit = null;
this.startTimer = setTimeout(() => {
this.stop(event, cb);
}, 0);
return;
}
this.startTimerCommit = null;
if (ripples && ripples.length) {
this.setState(
{
ripples: ripples.slice(1),
},
cb,
);
}
};
render() {
const { center, classes, className, ...other } = this.props;
return (
<TransitionGroup
component="span"
enter
exit
className={classNames(classes.root, className)}
{...other}
>
{this.state.ripples}
</TransitionGroup>
);
}
}
export default withStyles(styles, { flip: false, name: 'MuiTouchRipple' })(TouchRipple);

View File

@@ -0,0 +1,28 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
function createRippleHandler(instance, eventName, action, cb) {
return function handleEvent(event) {
if (cb) {
cb.call(instance, event);
}
if (event.defaultPrevented) {
return false;
}
if (instance.ripple) {
instance.ripple[action](event);
}
if (instance.props && typeof instance.props['on' + eventName] === 'function') {
instance.props['on' + eventName](event);
}
return true;
};
}
exports.default = createRippleHandler;

View File

@@ -0,0 +1,25 @@
// @flow
function createRippleHandler(instance: Object, eventName: string, action: string, cb: ?Function) {
return function handleEvent(event: SyntheticUIEvent<>) {
if (cb) {
cb.call(instance, event);
}
if (event.defaultPrevented) {
return false;
}
if (instance.ripple) {
instance.ripple[action](event);
}
if (instance.props && typeof instance.props[`on${eventName}`] === 'function') {
instance.props[`on${eventName}`](event);
}
return true;
};
}
export default createRippleHandler;

View File

@@ -0,0 +1,2 @@
export { default } from './ButtonBase';
export * from './ButtonBase';

View File

@@ -0,0 +1,16 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _ButtonBase = require('./ButtonBase');
Object.defineProperty(exports, 'default', {
enumerable: true,
get: function get() {
return _interopRequireDefault(_ButtonBase).default;
}
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

View File

@@ -0,0 +1,3 @@
// @flow
export { default } from './ButtonBase';