material-ui
Version:
React Components that Implement Google's Material Design.
179 lines (141 loc) • 5.29 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
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 _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _reactDom = require('react-dom');
var _dom = require('../utils/dom');
var _dom2 = _interopRequireDefault(_dom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// heavily inspired by https://github.com/Khan/react-components/blob/master/js/layered-component-mixin.jsx
var RenderToLayer = function (_Component) {
(0, _inherits3.default)(RenderToLayer, _Component);
function RenderToLayer() {
var _ref;
var _temp, _this, _ret;
(0, _classCallCheck3.default)(this, RenderToLayer);
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 = RenderToLayer.__proto__ || (0, _getPrototypeOf2.default)(RenderToLayer)).call.apply(_ref, [this].concat(args))), _this), _this.onClickAway = function (event) {
if (event.defaultPrevented) {
return;
}
if (!_this.props.componentClickAway) {
return;
}
if (!_this.props.open) {
return;
}
var el = _this.layer;
if (event.target !== el && event.target === window || document.documentElement.contains(event.target) && !_dom2.default.isDescendant(el, event.target)) {
_this.props.componentClickAway(event);
}
}, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
}
(0, _createClass3.default)(RenderToLayer, [{
key: 'componentDidMount',
value: function componentDidMount() {
this.renderLayer();
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
this.renderLayer();
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.unrenderLayer();
}
}, {
key: 'getLayer',
value: function getLayer() {
return this.layer;
}
}, {
key: 'unrenderLayer',
value: function unrenderLayer() {
if (!this.layer) {
return;
}
if (this.props.useLayerForClickAway) {
this.layer.style.position = 'relative';
this.layer.removeEventListener('click', this.onClickAway);
} else {
window.removeEventListener('click', this.onClickAway);
}
(0, _reactDom.unmountComponentAtNode)(this.layer);
document.body.removeChild(this.layer);
this.layer = null;
}
/**
* By calling this method in componentDidMount() and
* componentDidUpdate(), you're effectively creating a "wormhole" that
* funnels React's hierarchical updates through to a DOM node on an
* entirely different part of the page.
*/
}, {
key: 'renderLayer',
value: function renderLayer() {
var _this2 = this;
var _props = this.props,
open = _props.open,
render = _props.render;
if (open) {
if (!this.layer) {
this.layer = document.createElement('div');
document.body.appendChild(this.layer);
if (this.props.useLayerForClickAway) {
this.layer.addEventListener('click', this.onClickAway);
this.layer.style.position = 'fixed';
this.layer.style.top = 0;
this.layer.style.bottom = 0;
this.layer.style.left = 0;
this.layer.style.right = 0;
this.layer.style.zIndex = this.context.muiTheme.zIndex.layer;
} else {
setTimeout(function () {
window.addEventListener('click', _this2.onClickAway);
}, 0);
}
}
var layerElement = render();
this.layerElement = (0, _reactDom.unstable_renderSubtreeIntoContainer)(this, layerElement, this.layer);
} else {
this.unrenderLayer();
}
}
}, {
key: 'render',
value: function render() {
return null;
}
}]);
return RenderToLayer;
}(_react.Component);
RenderToLayer.defaultProps = {
useLayerForClickAway: true
};
RenderToLayer.contextTypes = {
muiTheme: _propTypes2.default.object.isRequired
};
RenderToLayer.propTypes = process.env.NODE_ENV !== "production" ? {
componentClickAway: _propTypes2.default.func,
open: _propTypes2.default.bool.isRequired,
render: _propTypes2.default.func.isRequired,
useLayerForClickAway: _propTypes2.default.bool
} : {};
exports.default = RenderToLayer;