From 5a4e55b64a8d8552bebc132297d4f684cd9dafce Mon Sep 17 00:00:00 2001 From: Neil Gabbadon Date: Wed, 17 Feb 2016 01:41:01 -0500 Subject: [PATCH] Remove click-awayable mixin --- src/ClickAwayListener.jsx | 48 ++++++++++++++++++++++++++++++++++++ src/menus/menu.jsx | 11 +++------ src/mixins/click-awayable.js | 43 -------------------------------- src/mixins/index.js | 3 --- src/snackbar.jsx | 20 +++++++++------ src/table/table-body.jsx | 15 +++++------ 6 files changed, 72 insertions(+), 68 deletions(-) create mode 100644 src/ClickAwayListener.jsx delete mode 100644 src/mixins/click-awayable.js diff --git a/src/ClickAwayListener.jsx b/src/ClickAwayListener.jsx new file mode 100644 index 00000000000000..f8a92054e02043 --- /dev/null +++ b/src/ClickAwayListener.jsx @@ -0,0 +1,48 @@ +/*eslint-disable */ +import React from 'react'; +import ReactDOM from 'react-dom'; +import EventListener from 'react-event-listener'; + +const isDescendant = (el, target) => { + if (target !== null) { + return el === target || isDescendant(el, target.parentNode) + } + return false; +}; + +export default class ClickAwayListener extends React.Component { + + static defaultProps = { + type: 'div', + }; + + handleRelease = (event) => { + if (event.defaultPrevented) { + return; + } + + const el = ReactDOM.findDOMNode(this); + if (document.documentElement.contains(event.target) && !isDescendant(el, event.target)) { + this.props.onClickAway(event); + } + }; + + render() { + const { + children, + onClickAway, + type, + ...other, + } = this.props; + + const listener = onClickAway && ( + + ); + + return React.createElement(type, other, listener, children); + } +} diff --git a/src/menus/menu.jsx b/src/menus/menu.jsx index 528bbfaaed09fc..03b0a3b20508d0 100644 --- a/src/menus/menu.jsx +++ b/src/menus/menu.jsx @@ -1,7 +1,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import update from 'react-addons-update'; -import ClickAwayable from '../mixins/click-awayable'; +import ClickAwayListener from '../ClickAwayListener'; import autoPrefix from '../styles/auto-prefix'; import Transitions from '../styles/transitions'; import KeyCode from '../utils/key-code'; @@ -132,10 +132,6 @@ const Menu = React.createClass({ muiTheme: React.PropTypes.object, }, - mixins: [ - ClickAwayable, - ], - getDefaultProps() { return { autoWidth: true, @@ -564,7 +560,8 @@ const Menu = React.createClass({ }); return ( -
@@ -581,7 +578,7 @@ const Menu = React.createClass({ {newChildren} -
+ ); }, diff --git a/src/mixins/click-awayable.js b/src/mixins/click-awayable.js deleted file mode 100644 index 5f2350029a8414..00000000000000 --- a/src/mixins/click-awayable.js +++ /dev/null @@ -1,43 +0,0 @@ -import ReactDOM from 'react-dom'; -import Events from '../utils/events'; -import Dom from '../utils/dom'; - -export default { - - //When the component mounts, listen to click events and check if we need to - //Call the componentClickAway function. - componentDidMount() { - if (!this.manuallyBindClickAway) this._bindClickAway(); - }, - - componentWillUnmount() { - this._unbindClickAway(); - }, - - _checkClickAway(event) { - if (this.isMounted()) { - const el = ReactDOM.findDOMNode(this); - - // Check if the target is inside the current component - if (event.target !== el && - !Dom.isDescendant(el, event.target) && - document.documentElement.contains(event.target)) { - if (this.componentClickAway) this.componentClickAway(event); - } - } - }, - - _bindClickAway() { - // On touch-enabled devices, both events fire, and the handler is called twice, - // but it's fine since all operations for which the mixin is used - // are idempotent. - Events.on(document, 'mouseup', this._checkClickAway); - Events.on(document, 'touchend', this._checkClickAway); - }, - - _unbindClickAway() { - Events.off(document, 'mouseup', this._checkClickAway); - Events.off(document, 'touchend', this._checkClickAway); - }, - -}; diff --git a/src/mixins/index.js b/src/mixins/index.js index 272b08160ca445..21ba89e0b4b987 100644 --- a/src/mixins/index.js +++ b/src/mixins/index.js @@ -1,13 +1,10 @@ -import ClickAwayable from './click-awayable'; import StylePropable from './style-propable'; import StyleResizable from './style-resizable'; -export {ClickAwayable}; export {StylePropable}; export {StyleResizable}; export default { - ClickAwayable, StylePropable, StyleResizable, }; diff --git a/src/snackbar.jsx b/src/snackbar.jsx index 09a0b3626bddee..b3c36a4633c4ce 100644 --- a/src/snackbar.jsx +++ b/src/snackbar.jsx @@ -1,6 +1,6 @@ import React from 'react'; import Transitions from './styles/transitions'; -import ClickAwayable from './mixins/click-awayable'; +import ClickAwayListener from './ClickAwayListener'; import FlatButton from './flat-button'; import getMuiTheme from './styles/getMuiTheme'; import StyleResizable from './mixins/style-resizable'; @@ -138,7 +138,6 @@ const Snackbar = React.createClass({ mixins: [ StyleResizable, - ClickAwayable, ], getInitialState() { @@ -162,7 +161,7 @@ const Snackbar = React.createClass({ //Only Bind clickaway after transition finishes this.timerTransitionId = setTimeout(() => { - this._bindClickAway(); + this.timerTransitionId = 0; }, 400); } }, @@ -204,11 +203,10 @@ const Snackbar = React.createClass({ //Only Bind clickaway after transition finishes this.timerTransitionId = setTimeout(() => { - this._bindClickAway(); + this.timerTransitionId = 0; }, 400); } else { clearTimeout(this.timerAutoHideId); - this._unbindClickAway(); } } }, @@ -217,7 +215,6 @@ const Snackbar = React.createClass({ clearTimeout(this.timerAutoHideId); clearTimeout(this.timerTransitionId); clearTimeout(this.timerOneAtTheTimeId); - this._unbindClickAway(); }, manuallyBindClickAway: true, @@ -227,6 +224,8 @@ const Snackbar = React.createClass({ timerOneAtTheTimeId: undefined, componentClickAway() { + if (!this.timerTransitionId) return; + if (this.props.open !== null && this.props.onRequestClose) { this.props.onRequestClose('clickaway'); } else { @@ -263,6 +262,7 @@ const Snackbar = React.createClass({ muiTheme: { prepareStyles, }, + open, } = this.state; const styles = getStyles(this.props, this.state); @@ -276,14 +276,18 @@ const Snackbar = React.createClass({ ); return ( -
+
{message} {actionButton}
-
+ ); }, diff --git a/src/table/table-body.jsx b/src/table/table-body.jsx index 3d9e75653ed64d..4245d0d1884114 100644 --- a/src/table/table-body.jsx +++ b/src/table/table-body.jsx @@ -1,7 +1,7 @@ import React from 'react'; import Checkbox from '../checkbox'; import TableRowColumn from './table-row-column'; -import ClickAwayable from '../mixins/click-awayable'; +import ClickAwayListener from '../ClickAwayListener'; import getMuiTheme from '../styles/getMuiTheme'; const TableBody = React.createClass({ @@ -121,10 +121,6 @@ const TableBody = React.createClass({ muiTheme: React.PropTypes.object, }, - mixins: [ - ClickAwayable, - ], - getDefaultProps() { return { allRowsSelected: false, @@ -419,9 +415,14 @@ const TableBody = React.createClass({ const rows = this._createRows(); return ( - + {rows} - + ); },