rsuite-utils
Version:
340 lines (261 loc) • 11.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _get2 = require('lodash/get');
var _get3 = _interopRequireDefault(_get2);
var _isUndefined2 = require('lodash/isUndefined');
var _isUndefined3 = _interopRequireDefault(_isUndefined2);
var _pick2 = require('lodash/pick');
var _pick3 = _interopRequireDefault(_pick2);
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 _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');
var React = _interopRequireWildcard(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _Overlay = require('./Overlay');
var _Overlay2 = _interopRequireDefault(_Overlay);
var _isNullOrUndefined = require('../utils/isNullOrUndefined');
var _isNullOrUndefined2 = _interopRequireDefault(_isNullOrUndefined);
var _createChainedFunction = require('../utils/createChainedFunction');
var _createChainedFunction2 = _interopRequireDefault(_createChainedFunction);
var _handleMouseOverOut = require('../utils/handleMouseOverOut');
var _handleMouseOverOut2 = _interopRequireDefault(_handleMouseOverOut);
var _isOneOf = require('../utils/isOneOf');
var _isOneOf2 = _interopRequireDefault(_isOneOf);
var _Portal = require('./Portal');
var _Portal2 = _interopRequireDefault(_Portal);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
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; }
var unsupportedCreatePortal = !_reactDom2.default.createPortal;
var OverlayTrigger = function (_React$Component) {
_inherits(OverlayTrigger, _React$Component);
function OverlayTrigger(props) {
_classCallCheck(this, OverlayTrigger);
var _this = _possibleConstructorReturn(this, (OverlayTrigger.__proto__ || Object.getPrototypeOf(OverlayTrigger)).call(this, props));
_this.getOverlayTarget = function () {
return (0, _reactDom.findDOMNode)(_this);
};
_this.speaker = null;
_this.handleMouseOver = null;
_this.handleMouseOut = null;
_this.hoverShowDelay = null;
_this.hoverHideDelay = null;
_this.target = null;
_this.mountNode = null;
_this.enterSpeaker = false;
_this.enterTrigger = false;
_this.handleSpeakerMouseEnter = function () {
_this.enterSpeaker = true;
};
_this.handleSpeakerMouseLeave = function () {
var trigger = _this.props.trigger;
_this.enterSpeaker = false;
if (!(0, _isOneOf2.default)('click', trigger) && !(0, _isOneOf2.default)('active', trigger)) {
_this.handleHide();
}
};
_this.hide = function () {
_this.setState({ isOverlayShown: false });
};
_this.show = function () {
_this.setState({ isOverlayShown: true });
};
_this.handleHide = function () {
if (!_this.enterSpeaker && !_this.enterTrigger) {
_this.hide();
}
};
_this.handleToggle = function () {
if (_this.state.isOverlayShown) {
_this.handleHide();
} else {
_this.show();
}
};
_this.handleDelayedShow = function () {
var _this$props = _this.props,
delayShow = _this$props.delayShow,
delay = _this$props.delay;
_this.enterTrigger = true;
if (!(0, _isNullOrUndefined2.default)(_this.hoverHideDelay)) {
clearTimeout(_this.hoverHideDelay);
_this.hoverHideDelay = null;
_this.show();
return;
}
if (_this.state.isOverlayShown) {
return;
}
var nextDelay = !(0, _isNullOrUndefined2.default)(delayShow) ? delayShow : delay;
if (!nextDelay) {
_this.show();
return;
}
_this.hoverShowDelay = setTimeout(function () {
_this.hoverShowDelay = null;
_this.show();
}, nextDelay);
};
_this.handleDelayedHide = function () {
var _this$props2 = _this.props,
delayHide = _this$props2.delayHide,
delay = _this$props2.delay;
_this.enterTrigger = false;
if (!(0, _isNullOrUndefined2.default)(_this.hoverShowDelay)) {
clearTimeout(_this.hoverShowDelay);
_this.hoverShowDelay = null;
return;
}
if (!_this.state.isOverlayShown || !(0, _isNullOrUndefined2.default)(_this.hoverHideDelay)) {
return;
}
var nextDelay = !(0, _isNullOrUndefined2.default)(delayHide) ? delayHide : delay;
if (!nextDelay) {
_this.handleHide();
return;
}
_this.hoverHideDelay = setTimeout(function () {
var isOnSpeaker = _this.state.isOnSpeaker;
if (isOnSpeaker) {
return;
}
clearTimeout(_this.hoverHideDelay);
_this.hoverHideDelay = null;
_this.handleHide();
}, nextDelay);
};
_this.handleMouseOver = function (e) {
return (0, _handleMouseOverOut2.default)(_this.handleDelayedShow, e);
};
_this.handleMouseOut = function (e) {
return (0, _handleMouseOverOut2.default)(_this.handleDelayedHide, e);
};
_this.state = {
isOverlayShown: props.defaultOpen
};
return _this;
}
_createClass(OverlayTrigger, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (unsupportedCreatePortal) {
this.mountNode = document.createElement('div');
this.renderOverlay();
}
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
if (unsupportedCreatePortal && this.mountNode) {
this.renderOverlay();
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
clearTimeout(this.hoverShowDelay);
clearTimeout(this.hoverHideDelay);
if (unsupportedCreatePortal) {
_reactDom2.default.unmountComponentAtNode(this.mountNode);
this.mountNode = null;
}
}
}, {
key: 'getOverlay',
// eslint-disable-line react/no-find-dom-node
value: function getOverlay() {
var _props = this.props,
open = _props.open,
speaker = _props.speaker,
trigger = _props.trigger,
onHide = _props.onHide;
var isOverlayShown = this.state.isOverlayShown;
var overlayProps = _extends({}, (0, _pick3.default)(this.props, _Overlay2.default.handledProps), {
show: (0, _isUndefined3.default)(open) ? isOverlayShown : open,
target: this.getOverlayTarget
});
if ((0, _isOneOf2.default)('click', trigger)) {
overlayProps.onHide = (0, _createChainedFunction2.default)(this.hide, onHide);
} else if ((0, _isOneOf2.default)('active', trigger)) {
overlayProps.onHide = (0, _createChainedFunction2.default)(this.hide, onHide);
}
var speakerProps = {
onMouseEnter: this.handleSpeakerMouseEnter,
onMouseLeave: this.handleSpeakerMouseLeave,
placement: overlayProps.placement
};
return React.createElement(
_Overlay2.default,
overlayProps,
React.cloneElement(speaker, speakerProps)
);
}
}, {
key: 'renderOverlay',
value: function renderOverlay() {
if (this.speaker) {
_reactDom2.default.unstable_renderSubtreeIntoContainer(this, this.speaker, this.mountNode);
}
}
}, {
key: 'render',
value: function render() {
var _props2 = this.props,
children = _props2.children,
speaker = _props2.speaker,
onClick = _props2.onClick,
trigger = _props2.trigger,
onMouseOver = _props2.onMouseOver,
onMouseOut = _props2.onMouseOut,
onFocus = _props2.onFocus,
onBlur = _props2.onBlur,
disabled = _props2.disabled;
var triggerComponent = React.Children.only(children);
var triggerProps = triggerComponent.props;
var props = {
key: 'triggerComponent',
'aria-describedby': (0, _get3.default)(speaker, ['props', 'id'])
};
props.onClick = (0, _createChainedFunction2.default)(triggerProps.onClick, onClick);
if (!disabled) {
if ((0, _isOneOf2.default)('click', trigger)) {
props.onClick = (0, _createChainedFunction2.default)(this.handleToggle, props.onClick);
}
if ((0, _isOneOf2.default)('active', trigger)) {
props.onClick = (0, _createChainedFunction2.default)(this.show, props.onClick);
}
if ((0, _isOneOf2.default)('hover', trigger)) {
props.onMouseOver = (0, _createChainedFunction2.default)(this.handleMouseOver, onMouseOver, triggerProps.onMouseOver);
props.onMouseOut = (0, _createChainedFunction2.default)(this.handleMouseOut, onMouseOut, triggerProps.onMouseOut);
}
if ((0, _isOneOf2.default)('focus', trigger)) {
props.onFocus = (0, _createChainedFunction2.default)(this.handleDelayedShow, onFocus, triggerProps.onFocus);
props.onBlur = (0, _createChainedFunction2.default)(this.handleDelayedHide, onBlur, triggerProps.onBlur);
}
}
if (unsupportedCreatePortal) {
this.speaker = this.getOverlay();
return React.cloneElement(triggerComponent, props);
}
return [React.cloneElement(triggerComponent, props), React.createElement(
_Portal2.default,
{ key: 'portal' },
this.getOverlay()
)];
}
}]);
return OverlayTrigger;
}(React.Component);
OverlayTrigger.defaultProps = {
trigger: ['hover', 'focus'],
delayHide: 200,
placement: 'bottomStart',
rootClose: true
};
OverlayTrigger.handledProps = ['animation', 'children', 'container', 'containerPadding', 'defaultOpen', 'delay', 'delayHide', 'delayShow', 'disabled', 'onBlur', 'onClick', 'onEnter', 'onEntered', 'onEntering', 'onExit', 'onExited', 'onExiting', 'onFocus', 'onHide', 'onMouseOut', 'onMouseOver', 'open', 'placement', 'preventOverflow', 'rootClose', 'show', 'speaker', 'target', 'transition', 'trigger'];
exports.default = OverlayTrigger;