choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
617 lines (538 loc) • 20.8 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
import _objectSpread from "@babel/runtime/helpers/objectSpread2";
function _createSuper(Derived) {
function isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Date.prototype.toString.call(Reflect.construct(Date, [], function () {}));
return true;
} catch (e) {
return false;
}
}
return function () {
var Super = _getPrototypeOf(Derived),
result;
if (isNativeReflectConstruct()) {
var NewTarget = _getPrototypeOf(this).constructor;
result = Reflect.construct(Super, arguments, NewTarget);
} else {
result = Super.apply(this, arguments);
}
return _possibleConstructorReturn(this, result);
};
}
import { __decorate } from "tslib";
import React, { Children, Component, isValidElement } from 'react';
import PropTypes from 'prop-types';
import { findDOMNode } from 'react-dom';
import classNames from 'classnames';
import raf from 'raf';
import { action as mobxAction, observable, runInAction } from 'mobx';
import { observer, PropTypes as MobxPropTypes } from 'mobx-react';
import noop from 'lodash/noop';
import Popup from './Popup';
import autobind from '../_util/autobind';
import TaskRunner from '../_util/TaskRunner';
import EventManager from '../_util/EventManager';
import { Action, HideAction, ShowAction } from './enum';
import TriggerChild from './TriggerChild';
function isPointsEq(a1, a2) {
return a1[0] === a2[0] && a1[1] === a2[1];
}
function _getPopupClassNameFromAlign(builtinPlacements, prefixCls, align) {
var points = align.points;
var found = Object.keys(builtinPlacements).find(function (placement) {
return {}.hasOwnProperty.call(builtinPlacements, placement) && isPointsEq(builtinPlacements[placement].points, points);
});
return found ? "".concat(prefixCls, "-popup-placement-").concat(found) : '';
}
function getAlignFromPlacement(builtinPlacements, placementStr, align) {
var baseAlign = builtinPlacements[placementStr] || {};
return _objectSpread({}, baseAlign, {}, align);
}
function contains(root, n) {
var node = n;
if (root) {
while (node) {
if (node === root || root.contains && root.contains(node)) {
return true;
}
node = node.parentNode;
}
}
return false;
}
var Trigger =
/*#__PURE__*/
function (_Component) {
_inherits(Trigger, _Component);
var _super = _createSuper(Trigger);
function Trigger(props, context) {
var _this;
_classCallCheck(this, Trigger);
_this = _super.call(this, props, context); // 兼容ie11
// 在ie11上当pop的内容存在滚动条的时候 点击滚动条会导致当前组件失去焦点
// 给组件设置的 preventDefault 不会起到作用
// 根据 handlePopupMouseDown handlePopupMouseUp 设置一个标识符来判断当前点击的是否是弹出框
// 不应该使用 state 将isClickScrollbar放到state里面会导致渲染导致在chrome下无法点击滚动条进行拖动
_this.isClickScrollbar = {
value: false
};
_this.popupTask = new TaskRunner();
_this.documentEvent = new EventManager(typeof window !== 'undefined' && document);
_this.focusTime = 0;
_this.preClickTime = 0;
_this.animateFrameId = 0;
_this.saveRef = function (node) {
return _this.popup = node;
};
runInAction(function () {
_this.popupHidden = 'popupHidden' in props ? props.popupHidden : props.defaultPopupHidden;
});
return _this;
}
_createClass(Trigger, [{
key: "render",
value: function render() {
var _this2 = this;
var children = this.props.children;
var popup = this.getPopup();
var newChildren = Children.map(children, function (child) {
if (isValidElement(child)) {
var newChildProps = {};
if (popup) {
if (_this2.isContextMenuToShow()) {
newChildProps.onContextMenu = _this2.handleEvent;
}
if (_this2.isClickToHide() || _this2.isClickToShow()) {
newChildProps.onClick = _this2.handleEvent;
newChildProps.onMouseDown = _this2.handleEvent;
}
if (_this2.isMouseEnterToShow()) {
newChildProps.onMouseEnter = _this2.handleEvent;
}
if (_this2.isMouseLeaveToHide()) {
newChildProps.onMouseLeave = _this2.handleEvent;
}
if (_this2.isFocusToShow() || _this2.isBlurToHide()) {
newChildProps.onFocus = _this2.handleEvent;
newChildProps.onBlur = _this2.handleEvent;
}
newChildProps.isClickScrollbar = _this2.isClickScrollbar;
newChildProps.popupHidden = _this2.popupHidden;
}
return React.createElement(TriggerChild, _extends({}, newChildProps), child);
}
return child;
});
return [newChildren, popup];
}
}, {
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(nextProps) {
var popupHidden = nextProps.popupHidden;
if (popupHidden !== this.popupHidden && popupHidden !== undefined) {
this.popupHidden = popupHidden;
}
}
}, {
key: "componentDidMount",
value: function componentDidMount() {
this.mounted = true;
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate() {
var popupHidden = this.popupHidden;
this.documentEvent.clear();
if (!popupHidden) {
this.documentEvent.addEventListener('scroll', this.handleDocumentScroll, true);
if ((this.isClickToHide() || this.isContextMenuToShow()) && !this.isBlurToHide()) {
this.documentEvent.addEventListener('mousedown', this.handleDocumentMouseDown);
}
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
this.popupTask.cancel();
this.documentEvent.clear();
}
}, {
key: "handleEvent",
value: function handleEvent(eventName, child, e) {
var handle = this.props["on".concat(eventName)];
var childHandle = child.props["on".concat(eventName)];
if (childHandle) {
childHandle(e);
}
if (!e.isDefaultPrevented()) {
if (handle) {
handle(e);
}
if (!e.isDefaultPrevented()) {
this["handle".concat(eventName)].call(this, e);
}
}
}
}, {
key: "handleContextMenu",
value: function handleContextMenu(e) {
e.preventDefault();
this.setPopupHidden(false);
}
}, {
key: "handleFocus",
value: function handleFocus() {
if (this.isFocusToShow()) {
var focusDelay = this.props.focusDelay;
this.focusTime = Date.now();
this.delaySetPopupHidden(false, focusDelay);
}
}
}, {
key: "handleBlur",
value: function handleBlur() {
if (this.isBlurToHide()) {
var blurDelay = this.props.blurDelay;
this.delaySetPopupHidden(true, blurDelay);
}
}
}, {
key: "handleDocumentMouseDown",
value: function handleDocumentMouseDown(e) {
if (this.popup) {
var target = e.target;
if (!contains(findDOMNode(this), target) && !contains(findDOMNode(this.popup), target)) {
this.setPopupHidden(true);
}
}
}
}, {
key: "handleDocumentScroll",
value: function handleDocumentScroll(_ref) {
var target = _ref.target;
if (this.popup && target !== document && !contains(findDOMNode(this.popup), target)) {
if (this.animateFrameId) {
raf.cancel(this.animateFrameId);
}
this.animateFrameId = raf(this.forcePopupAlign);
}
}
}, {
key: "handleMouseDown",
value: function handleMouseDown() {
this.preClickTime = Date.now();
}
}, {
key: "handleClick",
value: function handleClick(e) {
var popupHidden = this.popupHidden;
if (this.focusTime) {
if (Math.abs(this.preClickTime - this.focusTime) < 20) {
return;
}
this.focusTime = 0;
}
this.preClickTime = 0;
if (this.isClickToHide() && !popupHidden || popupHidden && this.isClickToShow()) {
e.preventDefault();
this.setPopupHidden(!popupHidden);
}
}
}, {
key: "handleMouseEnter",
value: function handleMouseEnter() {
var mouseEnterDelay = this.props.mouseEnterDelay;
this.delaySetPopupHidden(false, mouseEnterDelay);
}
}, {
key: "handleMouseLeave",
value: function handleMouseLeave() {
var mouseLeaveDelay = this.props.mouseLeaveDelay;
this.delaySetPopupHidden(true, mouseLeaveDelay);
}
}, {
key: "handlePopupMouseEnter",
value: function handlePopupMouseEnter() {
this.popupTask.cancel();
}
}, {
key: "handlePopupMouseLeave",
value: function handlePopupMouseLeave() {
var mouseLeaveDelay = this.props.mouseLeaveDelay;
this.delaySetPopupHidden(true, mouseLeaveDelay);
}
}, {
key: "getPopup",
value: function getPopup() {
var _this$props = this.props,
prefixCls = _this$props.prefixCls,
popupCls = _this$props.popupCls,
popupStyle = _this$props.popupStyle,
popupClassName = _this$props.popupClassName,
onPopupAnimateAppear = _this$props.onPopupAnimateAppear,
onPopupAnimateEnter = _this$props.onPopupAnimateEnter,
onPopupAnimateLeave = _this$props.onPopupAnimateLeave,
onPopupAnimateEnd = _this$props.onPopupAnimateEnd,
onPopupAlign = _this$props.onPopupAlign,
popupContent = _this$props.popupContent,
getPopupStyleFromAlign = _this$props.getPopupStyleFromAlign,
_this$props$getRootDo = _this$props.getRootDomNode,
getRootDomNode = _this$props$getRootDo === void 0 ? this.getRootDomNode : _this$props$getRootDo,
transitionName = _this$props.transitionName,
getPopupContainer = _this$props.getPopupContainer,
_this$props$onMouseDo = _this$props.onMouseDown,
onMouseDown = _this$props$onMouseDo === void 0 ? this.handlePopupMouseDown : _this$props$onMouseDo;
if (this.mounted || !getPopupContainer) {
if (popupContent) {
var visible = !this.popupHidden;
var mouseProps = {};
if (this.isMouseEnterToShow()) {
mouseProps.onMouseEnter = this.handlePopupMouseEnter;
}
if (this.isMouseLeaveToHide()) {
mouseProps.onMouseLeave = this.handlePopupMouseLeave;
}
return React.createElement(Popup, _extends({
key: "popup",
ref: this.saveRef,
transitionName: transitionName,
className: classNames("".concat(prefixCls, "-popup"), popupCls, popupClassName),
style: popupStyle,
hidden: !visible,
align: this.getPopupAlign(),
onAlign: onPopupAlign,
onMouseDown: onMouseDown,
onMouseUp: this.handlePopupMouseUp,
getRootDomNode: getRootDomNode,
onAnimateAppear: onPopupAnimateAppear,
onAnimateEnter: onPopupAnimateEnter,
onAnimateLeave: onPopupAnimateLeave,
onAnimateEnd: onPopupAnimateEnd,
getStyleFromAlign: getPopupStyleFromAlign,
getClassNameFromAlign: this.getPopupClassNameFromAlign,
getPopupContainer: getPopupContainer
}, mouseProps), popupContent);
}
}
}
}, {
key: "getPopupAlign",
value: function getPopupAlign() {
var _this$props2 = this.props,
popupPlacement = _this$props2.popupPlacement,
popupAlign = _this$props2.popupAlign,
builtinPlacements = _this$props2.builtinPlacements;
if (popupPlacement && builtinPlacements) {
return getAlignFromPlacement(builtinPlacements, popupPlacement, popupAlign);
}
return popupAlign;
}
}, {
key: "handlePopupMouseDown",
value: function handlePopupMouseDown(e) {
this.isClickScrollbar.value = true;
e.preventDefault();
}
}, {
key: "handlePopupMouseUp",
value: function handlePopupMouseUp() {
this.isClickScrollbar.value = false;
}
}, {
key: "getRootDomNode",
value: function getRootDomNode() {
return findDOMNode(this);
}
}, {
key: "getPopupClassNameFromAlign",
value: function getPopupClassNameFromAlign(align) {
var className = [];
var _this$props3 = this.props,
popupPlacement = _this$props3.popupPlacement,
builtinPlacements = _this$props3.builtinPlacements,
prefixCls = _this$props3.prefixCls,
getCls = _this$props3.getPopupClassNameFromAlign;
if (popupPlacement && builtinPlacements) {
className.push(_getPopupClassNameFromAlign(builtinPlacements, prefixCls, align));
}
if (getCls) {
var cls = getCls(align);
if (cls) {
className.push(cls);
}
}
return className.join(' ');
}
}, {
key: "forcePopupAlign",
value: function forcePopupAlign() {
if (!this.popupHidden && this.popup) {
this.popup.forceAlign();
}
}
}, {
key: "setPopupHidden",
value: function setPopupHidden(hidden) {
this.popupTask.cancel();
if (this.popupHidden !== hidden) {
var _this$props4 = this.props,
popupHidden = _this$props4.popupHidden,
_this$props4$onPopupH = _this$props4.onPopupHiddenChange,
onPopupHiddenChange = _this$props4$onPopupH === void 0 ? noop : _this$props4$onPopupH;
if (popupHidden === undefined) {
this.popupHidden = hidden;
}
onPopupHiddenChange(hidden);
}
}
}, {
key: "delaySetPopupHidden",
value: function delaySetPopupHidden(popupHidden, delay) {
var _this3 = this;
this.popupTask.cancel();
if (delay) {
this.popupTask.delay(delay, function () {
_this3.setPopupHidden(popupHidden);
});
} else {
this.setPopupHidden(popupHidden);
}
}
}, {
key: "isClickToShow",
value: function isClickToShow() {
var _this$props5 = this.props,
_this$props5$action = _this$props5.action,
action = _this$props5$action === void 0 ? [] : _this$props5$action,
_this$props5$showActi = _this$props5.showAction,
showAction = _this$props5$showActi === void 0 ? [] : _this$props5$showActi;
return action.indexOf(Action.click) !== -1 || showAction.indexOf(ShowAction.click) !== -1;
}
}, {
key: "isContextMenuToShow",
value: function isContextMenuToShow() {
var _this$props6 = this.props,
_this$props6$action = _this$props6.action,
action = _this$props6$action === void 0 ? [] : _this$props6$action,
_this$props6$showActi = _this$props6.showAction,
showAction = _this$props6$showActi === void 0 ? [] : _this$props6$showActi;
return action.indexOf(Action.contextMenu) !== -1 || showAction.indexOf(ShowAction.contextMenu) !== -1;
}
}, {
key: "isClickToHide",
value: function isClickToHide() {
var _this$props7 = this.props,
_this$props7$action = _this$props7.action,
action = _this$props7$action === void 0 ? [] : _this$props7$action,
_this$props7$hideActi = _this$props7.hideAction,
hideAction = _this$props7$hideActi === void 0 ? [] : _this$props7$hideActi;
return action.indexOf(Action.click) !== -1 || hideAction.indexOf(HideAction.click) !== -1;
}
}, {
key: "isMouseEnterToShow",
value: function isMouseEnterToShow() {
var _this$props8 = this.props,
_this$props8$action = _this$props8.action,
action = _this$props8$action === void 0 ? [] : _this$props8$action,
_this$props8$showActi = _this$props8.showAction,
showAction = _this$props8$showActi === void 0 ? [] : _this$props8$showActi;
return action.indexOf(Action.hover) !== -1 || showAction.indexOf(ShowAction.mouseEnter) !== -1;
}
}, {
key: "isMouseLeaveToHide",
value: function isMouseLeaveToHide() {
var _this$props9 = this.props,
_this$props9$action = _this$props9.action,
action = _this$props9$action === void 0 ? [] : _this$props9$action,
_this$props9$hideActi = _this$props9.hideAction,
hideAction = _this$props9$hideActi === void 0 ? [] : _this$props9$hideActi;
return action.indexOf(Action.hover) !== -1 || hideAction.indexOf(HideAction.mouseLeave) !== -1;
}
}, {
key: "isFocusToShow",
value: function isFocusToShow() {
var _this$props10 = this.props,
_this$props10$action = _this$props10.action,
action = _this$props10$action === void 0 ? [] : _this$props10$action,
_this$props10$showAct = _this$props10.showAction,
showAction = _this$props10$showAct === void 0 ? [] : _this$props10$showAct;
return action.indexOf(Action.focus) !== -1 || showAction.indexOf(ShowAction.focus) !== -1;
}
}, {
key: "isBlurToHide",
value: function isBlurToHide() {
var _this$props11 = this.props,
_this$props11$action = _this$props11.action,
action = _this$props11$action === void 0 ? [] : _this$props11$action,
_this$props11$hideAct = _this$props11.hideAction,
hideAction = _this$props11$hideAct === void 0 ? [] : _this$props11$hideAct;
return action.indexOf(Action.focus) !== -1 || hideAction.indexOf(HideAction.blur) !== -1;
}
}]);
return Trigger;
}(Component);
Trigger.displayName = 'Trigger';
Trigger.propTypes = {
action: MobxPropTypes.arrayOrObservableArrayOf(PropTypes.oneOf([Action.hover, Action.contextMenu, Action.focus, Action.click])),
showAction: MobxPropTypes.arrayOrObservableArrayOf(PropTypes.oneOf([ShowAction.mouseEnter, ShowAction.contextMenu, ShowAction.focus, ShowAction.click])),
hideAction: MobxPropTypes.arrayOrObservableArrayOf(PropTypes.oneOf([HideAction.blur, HideAction.mouseLeave, HideAction.click])),
popupContent: PropTypes.node,
popupCls: PropTypes.string,
popupStyle: PropTypes.object,
popupHidden: PropTypes.bool,
popupPlacement: PropTypes.string,
popupAlign: PropTypes.object,
builtinPlacements: PropTypes.any,
onPopupAnimateAppear: PropTypes.func,
onPopupAnimateEnter: PropTypes.func,
onPopupAnimateLeave: PropTypes.func,
onPopupAnimateEnd: PropTypes.func,
onPopupAlign: PropTypes.func,
onPopupHiddenChange: PropTypes.func,
getPopupStyleFromAlign: PropTypes.func,
getPopupContainer: PropTypes.func,
focusDelay: PropTypes.number,
blurDelay: PropTypes.number,
mouseEnterDelay: PropTypes.number,
mouseLeaveDelay: PropTypes.number,
transitionName: PropTypes.string,
defaultPopupHidden: PropTypes.bool,
popupClassName: PropTypes.string,
onMouseDown: PropTypes.func
};
Trigger.defaultProps = {
focusDelay: 150,
blurDelay: 0,
mouseEnterDelay: 100,
mouseLeaveDelay: 100,
transitionName: 'slide-up',
defaultPopupHidden: true
};
__decorate([observable], Trigger.prototype, "popupHidden", void 0);
__decorate([observable], Trigger.prototype, "mounted", void 0);
__decorate([mobxAction], Trigger.prototype, "componentWillReceiveProps", null);
__decorate([mobxAction], Trigger.prototype, "componentDidMount", null);
__decorate([autobind], Trigger.prototype, "handleEvent", null);
__decorate([autobind], Trigger.prototype, "handleDocumentMouseDown", null);
__decorate([autobind], Trigger.prototype, "handleDocumentScroll", null);
__decorate([autobind], Trigger.prototype, "handlePopupMouseEnter", null);
__decorate([autobind], Trigger.prototype, "handlePopupMouseLeave", null);
__decorate([autobind], Trigger.prototype, "handlePopupMouseDown", null);
__decorate([autobind], Trigger.prototype, "handlePopupMouseUp", null);
__decorate([autobind], Trigger.prototype, "getRootDomNode", null);
__decorate([autobind], Trigger.prototype, "getPopupClassNameFromAlign", null);
__decorate([autobind], Trigger.prototype, "forcePopupAlign", null);
__decorate([mobxAction], Trigger.prototype, "setPopupHidden", null);
Trigger = __decorate([observer], Trigger);
export default Trigger;
//# sourceMappingURL=Trigger.js.map