Move Ripple main to Decorator approach

old
Javi Velasco 2015-12-07 02:34:12 +01:00
parent 947c22d752
commit 1139fa6a62
9 changed files with 122 additions and 206 deletions

View File

@ -1,7 +1,7 @@
import React from 'react';
import ClassNames from 'classnames';
import FontIcon from '../font_icon';
import RippleDecorator from '../ripple/RippleDecorator';
import Ripple from '../ripple';
import style from './style';
class Button extends React.Component {
@ -66,4 +66,4 @@ class Button extends React.Component {
}
}
export default RippleDecorator({centered: false})(Button);
export default Ripple({centered: false})(Button);

View File

@ -1,7 +1,7 @@
import React from 'react';
import ClassNames from 'classnames';
import FontIcon from '../font_icon';
import RippleDecorator from '../ripple/RippleDecorator';
import Ripple from '../ripple';
import style from './style';
class IconButton extends React.Component {
@ -50,4 +50,4 @@ class IconButton extends React.Component {
}
}
export default RippleDecorator({centered: true})(IconButton);
export default Ripple({centered: true})(IconButton);

View File

@ -1,6 +1,6 @@
import React from 'react';
import ClassNames from 'classnames';
import RippleDecorator from '../ripple/RippleDecorator';
import Ripple from '../ripple';
import style from './style';
const Check = ({checked, children, onMouseDown}) => {
@ -11,7 +11,7 @@ const Check = ({checked, children, onMouseDown}) => {
return <div data-role='checkbox' onMouseDown={onMouseDown} className={className}>{children}</div>;
};
export default RippleDecorator({
export default Ripple({
className: style.ripple,
spread: 2.6,
centered: true

View File

@ -2,7 +2,7 @@ import React from 'react';
import ClassNames from 'classnames';
import FontIcon from '../font_icon';
import ListItemContent from './ListItemContent';
import RippleDecorator from '../ripple/RippleDecorator';
import Ripple from '../ripple';
import style from './style';
class ListItem extends React.Component {
@ -60,7 +60,7 @@ class ListItem extends React.Component {
}
}
export default RippleDecorator({
export default Ripple({
className: style.ripple,
centered: false
})(ListItem);

View File

@ -1,7 +1,7 @@
import React from 'react';
import FontIcon from '../font_icon';
import ClassNames from 'classnames';
import RippleDecorator from '../ripple/RippleDecorator';
import Ripple from '../ripple';
import style from './style.menu_item';
class MenuItem extends React.Component {
@ -46,6 +46,6 @@ class MenuItem extends React.Component {
}
}
export default RippleDecorator({
export default Ripple({
className: style.ripple
})(MenuItem);

View File

@ -1,5 +1,5 @@
import React from 'react';
import RippleDecorator from '../ripple/RippleDecorator';
import Ripple from '../ripple';
import style from './style';
const Radio = ({checked, children, onMouseDown}) => {
@ -7,7 +7,7 @@ const Radio = ({checked, children, onMouseDown}) => {
return <div data-role='radio' onMouseDown={onMouseDown} className={className}>{children}</div>;
};
export default RippleDecorator({
export default Ripple({
className: style.ripple,
spread: 2.6,
centered: true

View File

@ -1,84 +1,122 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ClassNames from 'classnames';
import prefixer from '../utils/prefixer';
import style from './style';
import prefixer from '../utils/prefixer';
class Ripple extends React.Component {
static propTypes = {
centered: React.PropTypes.bool,
className: React.PropTypes.string,
loading: React.PropTypes.bool,
spread: React.PropTypes.number
};
const defaults = {
centered: false,
className: '',
spread: 2
};
static defaultProps = {
centered: false,
className: '',
loading: false,
spread: 2
};
const Ripple = (options = {}) => {
const {
centered: defaultCentered,
className: defaultClassName,
spread: defaultSpread
} = {...defaults, ...options};
state = {
active: false,
left: null,
restarting: false,
top: null,
width: null
};
return ComposedComponent => {
return class RippledComponent extends React.Component {
static propTypes = {
children: React.PropTypes.any,
disabled: React.PropTypes.bool,
ripple: React.PropTypes.bool,
rippleCentered: React.PropTypes.bool,
rippleClassName: React.PropTypes.string,
rippleSpread: React.PropTypes.number
};
handleEnd = () => {
document.removeEventListener(this.touch ? 'touchend' : 'mouseup', this.handleEnd);
this.setState({active: false});
};
static defaultProps = {
disabled: false,
ripple: true,
rippleCentered: defaultCentered,
rippleClassName: defaultClassName,
rippleSpread: defaultSpread
};
start = ({pageX, pageY}, touch = false) => {
if (!this._isTouchRippleReceivingMouseEvent(touch)) {
this.touch = touch;
document.addEventListener(this.touch ? 'touchend' : 'mouseup', this.handleEnd);
const {top, left, width} = this._getDescriptor(pageX, pageY);
this.setState({active: false, restarting: true, top, left, width}, () => {
this.refs.ripple.offsetWidth; //eslint-disable-line no-unused-expressions
this.setState({active: true, restarting: false});
});
}
};
state = {
active: false,
left: null,
restarting: false,
top: null,
width: null
};
_isTouchRippleReceivingMouseEvent (touch) {
return this.touch && !touch;
}
handleEnd = () => {
document.removeEventListener(this.touch ? 'touchend' : 'mouseup', this.handleEnd);
this.setState({active: false});
};
_getDescriptor (pageX, pageY) {
const {left, top, height, width} = ReactDOM.findDOMNode(this).getBoundingClientRect();
return {
left: this.props.centered ? 0 : pageX - left - width / 2 - window.scrollX,
top: this.props.centered ? 0 : pageY - top - height / 2 - window.scrollY,
width: width * this.props.spread
start = ({pageX, pageY}, touch = false) => {
if (!this._isTouchRippleReceivingMouseEvent(touch)) {
this.touch = touch;
document.addEventListener(this.touch ? 'touchend' : 'mouseup', this.handleEnd);
const {top, left, width} = this._getDescriptor(pageX, pageY);
this.setState({active: false, restarting: true, top, left, width}, () => {
this.refs.ripple.offsetWidth; //eslint-disable-line no-unused-expressions
this.setState({active: true, restarting: false});
});
}
};
_isTouchRippleReceivingMouseEvent (touch) {
return this.touch && !touch;
}
_getDescriptor (pageX, pageY) {
const {left, top, height, width} = ReactDOM.findDOMNode(this).getBoundingClientRect();
const {rippleCentered: centered, rippleSpread: spread} = this.props;
return {
left: centered ? 0 : pageX - left - width / 2 - window.scrollX,
top: centered ? 0 : pageY - top - height / 2 - window.scrollY,
width: width * spread
};
}
handleMouseDown = (event) => {
if (!this.props.disabled) this.start(event);
if (this.props.onMouseDown) this.props.onMouseDown(event);
};
render () {
if (!this.props.ripple) {
return <ComposedComponent {...this.props} />;
} else {
const {
children,
ripple,
rippleClassName: className,
rippleCentered: centered,
rippleSpread: spread,
...other
} = this.props;
const rippleClassName = ClassNames(style.normal, {
[style.active]: this.state.active,
[style.restarting]: this.state.restarting
}, className);
const { left, top, width } = this.state;
const scale = this.state.restarting ? 0 : 1;
const rippleStyle = prefixer({
transform: `translate3d(${-width / 2 + left}px, ${-width / 2 + top}px, 0) scale(${scale})`
}, {width, height: width});
return (
<ComposedComponent {...other} onMouseDown={this.handleMouseDown}>
{children ? children : null}
<span data-react-toolbox='ripple' className={style.wrapper}>
<span ref='ripple' role='ripple' className={rippleClassName} style={rippleStyle} />
</span>
</ComposedComponent>
);
}
}
};
}
render () {
const { left, top, width } = this.state;
const scale = this.state.restarting ? 0 : 1;
let rippleStyle = {width, height: width};
if (!this.props.loading) {
rippleStyle = prefixer({
transform: `translate3d(${-width / 2 + left}px, ${-width / 2 + top}px, 0) scale(${scale})`
}, rippleStyle);
}
const className = ClassNames(style[this.props.loading ? 'loading' : 'normal'], {
[style.active]: this.state.active,
[style.restarting]: this.state.restarting
}, this.props.className);
return (
<span data-react-toolbox='ripple' className={style.wrapper}>
<span ref='ripple' role='ripple' className={className} style={rippleStyle} />
</span>
);
}
}
};
};
export default Ripple;

View File

@ -1,122 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ClassNames from 'classnames';
import style from './style';
import prefixer from '../utils/prefixer';
const defaults = {
centered: false,
className: '',
spread: 2
};
const Ripple = (options = {}) => {
const {
centered: defaultCentered,
className: defaultClassName,
spread: defaultSpread
} = {...defaults, ...options};
return ComposedComponent => {
return class RippledComponent extends React.Component {
static propTypes = {
children: React.PropTypes.any,
disabled: React.PropTypes.bool,
ripple: React.PropTypes.bool,
rippleCentered: React.PropTypes.bool,
rippleClassName: React.PropTypes.string,
rippleSpread: React.PropTypes.number
};
static defaultProps = {
disabled: false,
ripple: true,
rippleCentered: defaultCentered,
rippleClassName: defaultClassName,
rippleSpread: defaultSpread
};
state = {
active: false,
left: null,
restarting: false,
top: null,
width: null
};
handleEnd = () => {
document.removeEventListener(this.touch ? 'touchend' : 'mouseup', this.handleEnd);
this.setState({active: false});
};
start = ({pageX, pageY}, touch = false) => {
if (!this._isTouchRippleReceivingMouseEvent(touch)) {
this.touch = touch;
document.addEventListener(this.touch ? 'touchend' : 'mouseup', this.handleEnd);
const {top, left, width} = this._getDescriptor(pageX, pageY);
this.setState({active: false, restarting: true, top, left, width}, () => {
this.refs.ripple.offsetWidth; //eslint-disable-line no-unused-expressions
this.setState({active: true, restarting: false});
});
}
};
_isTouchRippleReceivingMouseEvent (touch) {
return this.touch && !touch;
}
_getDescriptor (pageX, pageY) {
const {left, top, height, width} = ReactDOM.findDOMNode(this).getBoundingClientRect();
const {rippleCentered: centered, rippleSpread: spread} = this.props;
return {
left: centered ? 0 : pageX - left - width / 2 - window.scrollX,
top: centered ? 0 : pageY - top - height / 2 - window.scrollY,
width: width * spread
};
}
handleMouseDown = (event) => {
if (!this.props.disabled) this.start(event);
if (this.props.onMouseDown) this.props.onMouseDown(event);
};
render () {
if (!this.props.ripple) {
return <ComposedComponent {...this.props} />;
} else {
const {
children,
ripple,
rippleClassName: className,
rippleCentered: centered,
rippleSpread: spread,
...other
} = this.props;
const rippleClassName = ClassNames(style.normal, {
[style.active]: this.state.active,
[style.restarting]: this.state.restarting
}, className);
const { left, top, width } = this.state;
const scale = this.state.restarting ? 0 : 1;
const rippleStyle = prefixer({
transform: `translate3d(${-width / 2 + left}px, ${-width / 2 + top}px, 0) scale(${scale})`
}, {width, height: width});
return (
<ComposedComponent {...other} onMouseDown={this.handleMouseDown}>
{children ? children : null}
<span data-react-toolbox='ripple' className={style.wrapper}>
<span ref='ripple' role='ripple' className={rippleClassName} style={rippleStyle} />
</span>
</ComposedComponent>
);
}
}
};
};
};
export default Ripple;

View File

@ -1,12 +1,12 @@
import React from 'react';
import RippleDecorator from '../ripple/RippleDecorator';
import Ripple from '../ripple';
import style from './style';
const Check = ({children, onMouseDown}) => (
<span role='thumb' className={style.thumb} onMouseDown={onMouseDown}>{children}</span>
);
export default RippleDecorator({
export default Ripple({
className: style.ripple,
spread: 2.6,
centered: true