devongovett-react-overlays
Version:
Utilities for creating robust overlay components
223 lines (169 loc) • 7.27 kB
JavaScript
'use strict';
exports.__esModule = true;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _elementType = require('prop-types-extra/lib/elementType');
var _elementType2 = _interopRequireDefault(_elementType);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _Portal = require('./Portal');
var _Portal2 = _interopRequireDefault(_Portal);
var _Position = require('./Position');
var _Position2 = _interopRequireDefault(_Position);
var _RootCloseWrapper = require('./RootCloseWrapper');
var _RootCloseWrapper2 = _interopRequireDefault(_RootCloseWrapper);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* Built on top of `<Position/>` and `<Portal/>`, the overlay component is great for custom tooltip overlays.
*/
var Overlay = function (_React$Component) {
_inherits(Overlay, _React$Component);
function Overlay(props, context) {
_classCallCheck(this, Overlay);
var _this = _possibleConstructorReturn(this, _React$Component.call(this, props, context));
_this.handleHidden = function () {
_this.setState({ exited: true });
if (_this.props.onExited) {
var _this$props;
(_this$props = _this.props).onExited.apply(_this$props, arguments);
}
};
_this.state = { exited: !props.show };
_this.onHiddenListener = _this.handleHidden.bind(_this);
return _this;
}
Overlay.prototype.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
if (nextProps.show) {
this.setState({ exited: false });
} else if (!nextProps.transition) {
// Otherwise let handleHidden take care of marking exited.
this.setState({ exited: true });
}
};
Overlay.prototype.render = function render() {
var _props = this.props,
container = _props.container,
containerPadding = _props.containerPadding,
target = _props.target,
placement = _props.placement,
shouldUpdatePosition = _props.shouldUpdatePosition,
rootClose = _props.rootClose,
children = _props.children,
Transition = _props.transition,
props = _objectWithoutProperties(_props, ['container', 'containerPadding', 'target', 'placement', 'shouldUpdatePosition', 'rootClose', 'children', 'transition']);
// Don't un-render the overlay while it's transitioning out.
var mountOverlay = props.show || Transition && !this.state.exited;
if (!mountOverlay) {
// Don't bother showing anything if we don't have to.
return null;
}
var child = children;
// Position is be inner-most because it adds inline styles into the child,
// which the other wrappers don't forward correctly.
child = _react2.default.createElement(
_Position2.default,
{ container: container, containerPadding: containerPadding, target: target, placement: placement, shouldUpdatePosition: shouldUpdatePosition },
child
);
if (Transition) {
var onExit = props.onExit,
onExiting = props.onExiting,
onEnter = props.onEnter,
onEntering = props.onEntering,
onEntered = props.onEntered;
// This animates the child node by injecting props, so it must precede
// anything that adds a wrapping div.
child = _react2.default.createElement(
Transition,
{
'in': props.show,
appear: true,
onExit: onExit,
onExiting: onExiting,
onExited: this.onHiddenListener,
onEnter: onEnter,
onEntering: onEntering,
onEntered: onEntered
},
child
);
}
// This goes after everything else because it adds a wrapping div.
if (rootClose) {
child = _react2.default.createElement(
_RootCloseWrapper2.default,
{ onRootClose: props.onHide },
child
);
}
return _react2.default.createElement(
_Portal2.default,
{ container: container },
child
);
};
return Overlay;
}(_react2.default.Component);
Overlay.propTypes = _extends({}, _Portal2.default.propTypes, _Position2.default.propTypes, {
/**
* Set the visibility of the Overlay
*/
show: _propTypes2.default.bool,
/**
* Specify whether the overlay should trigger `onHide` when the user clicks outside the overlay
*/
rootClose: _propTypes2.default.bool,
/**
* A Callback fired by the Overlay when it wishes to be hidden.
*
* __required__ when `rootClose` is `true`.
*
* @type func
*/
onHide: function onHide(props) {
var propType = _propTypes2.default.func;
if (props.rootClose) {
propType = propType.isRequired;
}
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
return propType.apply(undefined, [props].concat(args));
},
/**
* A `react-transition-group@2.0.0` `<Transition/>` component
* used to animate the overlay as it changes visibility.
*/
transition: _elementType2.default,
/**
* Callback fired before the Overlay transitions in
*/
onEnter: _propTypes2.default.func,
/**
* Callback fired as the Overlay begins to transition in
*/
onEntering: _propTypes2.default.func,
/**
* Callback fired after the Overlay finishes transitioning in
*/
onEntered: _propTypes2.default.func,
/**
* Callback fired right before the Overlay transitions out
*/
onExit: _propTypes2.default.func,
/**
* Callback fired as the Overlay begins to transition out
*/
onExiting: _propTypes2.default.func,
/**
* Callback fired after the Overlay finishes transitioning out
*/
onExited: _propTypes2.default.func
});
exports.default = Overlay;
module.exports = exports['default'];