dc-rmc-trigger
Version:
base abstract trigger component for react mobile
273 lines (242 loc) • 11.4 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: 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 _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 _react2 = _interopRequireDefault(_react);
var _reactDom = require('react-dom');
var _reactDom2 = _interopRequireDefault(_reactDom);
var _contains = require('rc-util/lib/Dom/contains');
var _contains2 = _interopRequireDefault(_contains);
var _addEventListener = require('rc-util/lib/Dom/addEventListener');
var _addEventListener2 = _interopRequireDefault(_addEventListener);
var _Popup = require('./Popup');
var _Popup2 = _interopRequireDefault(_Popup);
var _utils = require('./utils');
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 IS_REACT_16 = !!_react2['default'].createPortal;
function noop() {}
function returnEmptyString() {
return '';
}
function returnDocument() {
return window.document;
}
var Trigger = function (_React$Component) {
_inherits(Trigger, _React$Component);
function Trigger() {
_classCallCheck(this, Trigger);
var _this = _possibleConstructorReturn(this, (Trigger.__proto__ || Object.getPrototypeOf(Trigger)).apply(this, arguments));
_this.onDocumentClick = function (event) {
if (_this.props.mask && !_this.props.maskClosable) {
return;
}
var target = event.target;
var root = (0, _reactDom.findDOMNode)(_this);
var popupNode = _this.getPopupDomNode();
if (!(0, _contains2['default'])(root, target) && !(0, _contains2['default'])(popupNode, target)) {
_this.close();
event.preventDefault();
}
};
_this.getPopupAlign = function () {
var props = _this.props;
var popupPlacement = props.popupPlacement,
popupAlign = props.popupAlign,
builtinPlacements = props.builtinPlacements;
if (popupPlacement && builtinPlacements) {
return (0, _utils.getAlignFromPlacement)(builtinPlacements, popupPlacement, popupAlign);
}
return popupAlign;
};
_this.getRootDomNode = function () {
return (0, _reactDom.findDOMNode)(_this);
};
_this.getPopupClassNameFromAlign = function (align) {
var className = [];
var props = _this.props;
var popupPlacement = props.popupPlacement,
builtinPlacements = props.builtinPlacements,
prefixCls = props.prefixCls;
if (popupPlacement && builtinPlacements) {
className.push((0, _utils.getPopupClassNameFromAlign)(builtinPlacements, prefixCls, align));
}
if (props.getPopupClassNameFromAlign) {
className.push(props.getPopupClassNameFromAlign(align));
}
return className.join(' ');
};
_this.close = function () {
if (_this.props.onClose) {
_this.props.onClose();
}
};
_this.onAnimateLeave = function () {
if (_this.props.destroyPopupOnHide) {
var container = _this._container;
if (container) {
_reactDom2['default'].unmountComponentAtNode(container);
container.parentNode.removeChild(container);
}
}
};
_this.removeContainer = function () {
var container = document.querySelector('#' + _this.props.prefixCls + '-container');
if (container) {
_reactDom2['default'].unmountComponentAtNode(container);
container.parentNode.removeChild(container);
}
};
return _this;
}
_createClass(Trigger, [{
key: 'componentDidMount',
value: function componentDidMount() {
if (this.props.visible) {
this.componentDidUpdate();
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
if (this.props.visible) {
if (!IS_REACT_16) {
this.renderDialog(false);
}
}
this.clearOutsideHandler();
}
}, {
key: 'componentDidUpdate',
value: function componentDidUpdate() {
var _this2 = this;
if (!IS_REACT_16) {
this.renderDialog(this.props.visible);
}
if (this.props.visible) {
// always hide on mobile
if (!this.touchOutsideHandler) {
// add setTimeout for preact
// prevent in here before setTimeout callback
this.touchOutsideHandler = setTimeout(function () {
var currentDocument = _this2.props.getDocument();
_this2.touchOutsideHandler = (0, _addEventListener2['default'])(currentDocument, 'touchend', _this2.onDocumentClick);
});
}
return;
}
this.clearOutsideHandler();
}
}, {
key: 'clearOutsideHandler',
value: function clearOutsideHandler() {
if (this.touchOutsideHandler) {
if (this.touchOutsideHandler.remove) {
this.touchOutsideHandler.remove();
}
this.touchOutsideHandler = null;
}
}
}, {
key: 'getPopupDomNode',
value: function getPopupDomNode() {
// for test
if (this._component && this._component.getPopupDomNode) {
return this._component.getPopupDomNode();
}
return null;
}
}, {
key: 'saveRef',
value: function saveRef(el, visible) {
this.popupRef = el;
this._component = el;
this.props.afterPopupVisibleChange(visible);
}
}, {
key: 'getComponent',
value: function getComponent(visible) {
var _this3 = this;
var props = _extends({}, this.props);
['visible', 'onAnimateLeave'].forEach(function (key) {
if (props.hasOwnProperty(key)) {
delete props[key];
}
});
return _react2['default'].createElement(
_Popup2['default'],
{ key: 'popup', ref: function ref(el) {
return _this3.saveRef(el, visible);
}, prefixCls: props.prefixCls, destroyPopupOnHide: props.destroyPopupOnHide, visible: visible, className: props.popupClassName, align: this.getPopupAlign(), onAlign: props.onPopupAlign, animation: props.popupAnimation, getClassNameFromAlign: this.getPopupClassNameFromAlign, getRootDomNode: this.getRootDomNode, style: props.popupStyle, mask: props.mask, zIndex: props.zIndex, transitionName: props.popupTransitionName, maskAnimation: props.maskAnimation, maskTransitionName: props.maskTransitionName, onAnimateLeave: this.onAnimateLeave },
typeof props.popup === 'function' ? props.popup() : props.popup
);
}
}, {
key: 'getContainer',
value: function getContainer() {
if (!this._container) {
var props = this.props;
var popupContainer = document.createElement('div');
// Make sure default popup container will never cause scrollbar appearing
// https://github.com/react-component/trigger/issues/41
popupContainer.style.position = 'absolute';
popupContainer.style.top = '0';
popupContainer.style.left = '0';
popupContainer.style.width = '100%';
var mountNode = props.getPopupContainer ? props.getPopupContainer((0, _reactDom.findDOMNode)(this)) : props.getDocument().body;
mountNode.appendChild(popupContainer);
this._container = popupContainer;
}
return this._container;
}
}, {
key: 'renderDialog',
value: function renderDialog(visible) {
_reactDom2['default'].unstable_renderSubtreeIntoContainer(this, this.getComponent(visible), this.getContainer());
}
}, {
key: 'render',
value: function render() {
var props = this.props;
var children = props.children;
var child = _react2['default'].Children.only(children);
var newChildProps = {
onClick: this.props.onTargetClick,
key: 'trigger'
};
var trigger = _react2['default'].cloneElement(child, newChildProps);
if (!IS_REACT_16) {
return trigger;
}
var portal = void 0;
// prevent unmounting after it's rendered
if (props.visible || this._component) {
portal = _reactDom2['default'].createPortal(this.getComponent(props.visible), this.getContainer());
}
return [trigger, portal];
}
}]);
return Trigger;
}(_react2['default'].Component);
exports['default'] = Trigger;
Trigger.defaultProps = {
prefixCls: 'rc-trigger-popup',
getPopupClassNameFromAlign: returnEmptyString,
getDocument: returnDocument,
onPopupVisibleChange: noop,
afterPopupVisibleChange: noop,
onPopupAlign: noop,
popupClassName: '',
popupStyle: {},
destroyPopupOnHide: false,
popupAlign: {},
defaultPopupVisible: false,
mask: false,
maskClosable: true
};
module.exports = exports['default'];