'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _componentOrElement = require('react-prop-types/lib/componentOrElement');
var _componentOrElement2 = _interopRequireDefault(_componentOrElement);
var _ownerDocument = require('./utils/ownerDocument');
var _ownerDocument2 = _interopRequireDefault(_ownerDocument);
var _getContainer = require('./utils/getContainer');
var _getContainer2 = _interopRequireDefault(_getContainer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The `` component renders its children into a new "subtree" outside of current component hierarchy.
* You can think of it as a declarative `appendChild()`, or jQuery's `$.fn.appendTo()`.
* The children of `` component will be appended to the `container` specified.
*/
var Portal = _react2.default.createClass({
displayName: 'Portal',
propTypes: {
/**
* A Node, Component instance, or function that returns either. The `container` will have the Portal children
* appended to it.
*/
container: _react2.default.PropTypes.oneOfType([_componentOrElement2.default, _react2.default.PropTypes.func])
},
componentDidMount: function componentDidMount() {
this._renderOverlay();
},
componentDidUpdate: function componentDidUpdate() {
this._renderOverlay();
},
componentWillReceiveProps: function componentWillReceiveProps(nextProps) {
if (this._overlayTarget && nextProps.container !== this.props.container) {
this._portalContainerNode.removeChild(this._overlayTarget);
this._portalContainerNode = (0, _getContainer2.default)(nextProps.container, (0, _ownerDocument2.default)(this).body);
this._portalContainerNode.appendChild(this._overlayTarget);
}
},
componentWillUnmount: function componentWillUnmount() {
this._unrenderOverlay();
this._unmountOverlayTarget();
},
_mountOverlayTarget: function _mountOverlayTarget() {
if (!this._overlayTarget) {
this._overlayTarget = document.createElement('div');
this._portalContainerNode = (0, _getContainer2.default)(this.props.container, (0, _ownerDocument2.default)(this).body);
this._portalContainerNode.appendChild(this._overlayTarget);
}
},
_unmountOverlayTarget: function _unmountOverlayTarget() {
if (this._overlayTarget) {
this._portalContainerNode.removeChild(this._overlayTarget);
this._overlayTarget = null;
}
this._portalContainerNode = null;
},
_renderOverlay: function _renderOverlay() {
var overlay = !this.props.children ? null : _react2.default.Children.only(this.props.children);
// Save reference for future access.
if (overlay !== null) {
this._mountOverlayTarget();
this._overlayInstance = _reactDom2.default.unstable_renderSubtreeIntoContainer(this, overlay, this._overlayTarget);
} else {
// Unrender if the component is null for transitions to null
this._unrenderOverlay();
this._unmountOverlayTarget();
}
},
_unrenderOverlay: function _unrenderOverlay() {
if (this._overlayTarget) {
_reactDom2.default.unmountComponentAtNode(this._overlayTarget);
this._overlayInstance = null;
}
},
render: function render() {
return null;
},
getMountNode: function getMountNode() {
return this._overlayTarget;
},
getOverlayDOMNode: function getOverlayDOMNode() {
if (!this.isMounted()) {
throw new Error('getOverlayDOMNode(): A component must be mounted to have a DOM node.');
}
if (this._overlayInstance) {
return _reactDom2.default.findDOMNode(this._overlayInstance);
}
return null;
}
});
exports.default = Portal;
module.exports = exports['default'];