1 | import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
|
2 | import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
|
3 | import _inherits from 'babel-runtime/helpers/inherits';
|
4 |
|
5 | var _class, _temp;
|
6 |
|
7 | import React, { Component, Children } from 'react';
|
8 | import { findDOMNode, createPortal } from 'react-dom';
|
9 | import PropTypes from 'prop-types';
|
10 | import { polyfill } from 'react-lifecycles-compat';
|
11 | import { func } from '../util';
|
12 | import findNode from './utils/find-node';
|
13 |
|
14 | var makeChain = func.makeChain;
|
15 |
|
16 |
|
17 | var getContainerNode = function getContainerNode(props) {
|
18 | var targetNode = findNode(props.target);
|
19 | return findNode(props.container, targetNode);
|
20 | };
|
21 |
|
22 | var 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 |
|
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);
|
102 | Gateway.displayName = 'Gateway';
|
103 |
|
104 |
|
105 | export default polyfill(Gateway); |
\ | No newline at end of file |