UNPKG

2.87 kBJavaScriptView Raw
1import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
2import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
3import _inherits from 'babel-runtime/helpers/inherits';
4
5var _class, _temp;
6
7import React, { Component, Children } from 'react';
8import { findDOMNode, createPortal } from 'react-dom';
9import PropTypes from 'prop-types';
10import { polyfill } from 'react-lifecycles-compat';
11import { func } from '../util';
12import findNode from './utils/find-node';
13
14var makeChain = func.makeChain;
15
16
17var getContainerNode = function getContainerNode(props) {
18 var targetNode = findNode(props.target);
19 return findNode(props.container, targetNode);
20};
21
22var Gateway = (_temp = _class = function (_Component) {
23 _inherits(Gateway, _Component);
24
25 function Gateway(props) {
26 _classCallCheck(this, Gateway);
27
28 var _this = _possibleConstructorReturn(this, _Component.call(this, props));
29
30 _this.updateContainer = function () {
31 var containerNode = getContainerNode(_this.props);
32
33 if (containerNode !== _this.state.containerNode) {
34 // eslint-disable-next-line
35 _this.setState({
36 containerNode: containerNode
37 });
38 }
39 };
40
41 _this.saveChildRef = function (ref) {
42 _this.child = ref;
43 };
44
45 _this.state = {
46 containerNode: null
47 };
48 return _this;
49 }
50
51 Gateway.prototype.componentDidMount = function componentDidMount() {
52 this.updateContainer();
53 };
54
55 Gateway.prototype.componentDidUpdate = function componentDidUpdate() {
56 this.updateContainer();
57 };
58
59 Gateway.prototype.getChildNode = function getChildNode() {
60 try {
61 return findDOMNode(this.child);
62 } catch (err) {
63 return null;
64 }
65 };
66
67 Gateway.prototype.render = function render() {
68 var containerNode = this.state.containerNode;
69
70
71 if (!containerNode) {
72 return null;
73 }
74
75 var children = this.props.children;
76
77 var child = children ? Children.only(children) : null;
78 if (!child) {
79 return null;
80 }
81
82 if (typeof child.ref === 'string') {
83 throw new Error('Can not set ref by string in Gateway, use function instead.');
84 }
85 child = React.cloneElement(child, {
86 ref: makeChain(this.saveChildRef, child.ref)
87 });
88
89 return createPortal(child, containerNode);
90 };
91
92 return Gateway;
93}(Component), _class.propTypes = {
94 children: PropTypes.node,
95 container: PropTypes.any,
96 target: PropTypes.any
97}, _class.defaultProps = {
98 container: function container() {
99 return document.body;
100 }
101}, _temp);
102Gateway.displayName = 'Gateway';
103
104
105export default polyfill(Gateway);
\No newline at end of file