UNPKG

choerodon-ui

Version:

An enterprise-class UI design language and React-based implementation

617 lines (538 loc) 20.8 kB
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