UNPKG

5.29 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
8
9var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
10
11var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
12
13var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
14
15var _createClass2 = require('babel-runtime/helpers/createClass');
16
17var _createClass3 = _interopRequireDefault(_createClass2);
18
19var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
20
21var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
22
23var _inherits2 = require('babel-runtime/helpers/inherits');
24
25var _inherits3 = _interopRequireDefault(_inherits2);
26
27var _react = require('react');
28
29var _propTypes = require('prop-types');
30
31var _propTypes2 = _interopRequireDefault(_propTypes);
32
33var _reactDom = require('react-dom');
34
35var _dom = require('../utils/dom');
36
37var _dom2 = _interopRequireDefault(_dom);
38
39function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
40
41// heavily inspired by https://github.com/Khan/react-components/blob/master/js/layered-component-mixin.jsx
42var RenderToLayer = function (_Component) {
43 (0, _inherits3.default)(RenderToLayer, _Component);
44
45 function RenderToLayer() {
46 var _ref;
47
48 var _temp, _this, _ret;
49
50 (0, _classCallCheck3.default)(this, RenderToLayer);
51
52 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
53 args[_key] = arguments[_key];
54 }
55
56 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) {
57 if (event.defaultPrevented) {
58 return;
59 }
60
61 if (!_this.props.componentClickAway) {
62 return;
63 }
64
65 if (!_this.props.open) {
66 return;
67 }
68
69 var el = _this.layer;
70 if (event.target !== el && event.target === window || document.documentElement.contains(event.target) && !_dom2.default.isDescendant(el, event.target)) {
71 _this.props.componentClickAway(event);
72 }
73 }, _temp), (0, _possibleConstructorReturn3.default)(_this, _ret);
74 }
75
76 (0, _createClass3.default)(RenderToLayer, [{
77 key: 'componentDidMount',
78 value: function componentDidMount() {
79 this.renderLayer();
80 }
81 }, {
82 key: 'componentDidUpdate',
83 value: function componentDidUpdate() {
84 this.renderLayer();
85 }
86 }, {
87 key: 'componentWillUnmount',
88 value: function componentWillUnmount() {
89 this.unrenderLayer();
90 }
91 }, {
92 key: 'getLayer',
93 value: function getLayer() {
94 return this.layer;
95 }
96 }, {
97 key: 'unrenderLayer',
98 value: function unrenderLayer() {
99 if (!this.layer) {
100 return;
101 }
102
103 if (this.props.useLayerForClickAway) {
104 this.layer.style.position = 'relative';
105 this.layer.removeEventListener('click', this.onClickAway);
106 } else {
107 window.removeEventListener('click', this.onClickAway);
108 }
109
110 (0, _reactDom.unmountComponentAtNode)(this.layer);
111 document.body.removeChild(this.layer);
112 this.layer = null;
113 }
114
115 /**
116 * By calling this method in componentDidMount() and
117 * componentDidUpdate(), you're effectively creating a "wormhole" that
118 * funnels React's hierarchical updates through to a DOM node on an
119 * entirely different part of the page.
120 */
121
122 }, {
123 key: 'renderLayer',
124 value: function renderLayer() {
125 var _this2 = this;
126
127 var _props = this.props,
128 open = _props.open,
129 render = _props.render;
130
131
132 if (open) {
133 if (!this.layer) {
134 this.layer = document.createElement('div');
135 document.body.appendChild(this.layer);
136
137 if (this.props.useLayerForClickAway) {
138 this.layer.addEventListener('click', this.onClickAway);
139 this.layer.style.position = 'fixed';
140 this.layer.style.top = 0;
141 this.layer.style.bottom = 0;
142 this.layer.style.left = 0;
143 this.layer.style.right = 0;
144 this.layer.style.zIndex = this.context.muiTheme.zIndex.layer;
145 } else {
146 setTimeout(function () {
147 window.addEventListener('click', _this2.onClickAway);
148 }, 0);
149 }
150 }
151
152 var layerElement = render();
153 this.layerElement = (0, _reactDom.unstable_renderSubtreeIntoContainer)(this, layerElement, this.layer);
154 } else {
155 this.unrenderLayer();
156 }
157 }
158 }, {
159 key: 'render',
160 value: function render() {
161 return null;
162 }
163 }]);
164 return RenderToLayer;
165}(_react.Component);
166
167RenderToLayer.defaultProps = {
168 useLayerForClickAway: true
169};
170RenderToLayer.contextTypes = {
171 muiTheme: _propTypes2.default.object.isRequired
172};
173RenderToLayer.propTypes = process.env.NODE_ENV !== "production" ? {
174 componentClickAway: _propTypes2.default.func,
175 open: _propTypes2.default.bool.isRequired,
176 render: _propTypes2.default.func.isRequired,
177 useLayerForClickAway: _propTypes2.default.bool
178} : {};
179exports.default = RenderToLayer;
\No newline at end of file