UNPKG

choerodon-ui

Version:

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

484 lines (415 loc) 17.7 kB
import _extends from "@babel/runtime/helpers/extends"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _objectSpread from "@babel/runtime/helpers/objectSpread2"; import _classCallCheck from "@babel/runtime/helpers/classCallCheck"; import _createClass from "@babel/runtime/helpers/createClass"; import _get from "@babel/runtime/helpers/get"; import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf"; import _inherits from "@babel/runtime/helpers/inherits"; import _createSuper from "@babel/runtime/helpers/createSuper"; import _typeof from "@babel/runtime/helpers/typeof"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import { __decorate } from "tslib"; import React, { Children } from 'react'; import classNames from 'classnames'; import omit from 'lodash/omit'; import noop from 'lodash/noop'; import debounce from 'lodash/debounce'; import isString from 'lodash/isString'; import { computed, observable, runInAction, action, isArrayLike } from 'mobx'; import { observer } from 'mobx-react'; import isPromise from 'is-promise'; import { isFragment as isReactFragment } from 'react-is'; import { ProgressType } from '../../../es/progress/enum'; import Icon from '../icon'; import FormContext from '../form/FormContext'; import Progress from '../progress'; import Ripple from '../ripple'; import { ButtonTooltip, ButtonType, FuncType } from './enum'; import { DataSetStatus } from '../data-set/enum'; import { Size, WaitType } from '../core/enum'; import DataSetComponent from '../data-set/DataSetComponent'; import autobind from '../_util/autobind'; import { hide, show } from '../tooltip/singleton'; import isOverflow from '../overflow-tip/util'; import getReactNodeText from '../_util/getReactNodeText'; import { cloneElement } from '../_util/reactNode'; var rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; var isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); // Insert one space between two chinese characters automatically. function insertSpace(child, needInserted) { // Check the child if is undefined or null. if (child == null) { return; } var SPACE = needInserted ? ' ' : ''; // strictNullChecks oops. if (typeof child !== 'string' && typeof child !== 'number' && isString(child.type) && isTwoCNChar(child.props.children)) { return cloneElement(child, { children: child.props.children.split('').join(SPACE) }); } if (typeof child === 'string') { return isTwoCNChar(child) ? /*#__PURE__*/React.createElement("span", null, child.split('').join(SPACE)) : /*#__PURE__*/React.createElement("span", null, child); } if (isReactFragment(child)) { return /*#__PURE__*/React.createElement("span", null, child); } return child; } function spaceChildren(children, needInserted) { var isPrevChildPure = false; var childList = []; React.Children.forEach(children, function (child) { var type = _typeof(child); var isCurrentChildPure = type === 'string' || type === 'number'; if (isPrevChildPure && isCurrentChildPure) { var lastIndex = childList.length - 1; var lastChild = childList[lastIndex]; childList[lastIndex] = "".concat(lastChild).concat(child); } else { childList.push(child); } isPrevChildPure = isCurrentChildPure; }); // Pass to React.Children.map to auto fill key return React.Children.map(childList, function (child) { return insertSpace(child, needInserted); }); } var Button = /*#__PURE__*/function (_DataSetComponent) { _inherits(Button, _DataSetComponent); var _super = _createSuper(Button); function Button(props, context) { var _this; _classCallCheck(this, Button); _this = _super.call(this, props, context); _this.handleClickWait = _this.getHandleClick(props); return _this; } _createClass(Button, [{ key: "loading", get: function get() { var _this$observableProps = this.observableProps, type = _this$observableProps.type, dataSet = _this$observableProps.dataSet, loading = _this$observableProps.loading; return loading || type === ButtonType.submit && !!dataSet && dataSet.status === DataSetStatus.submitting; }, set: function set(loading) { var _this2 = this; runInAction(function () { _this2.observableProps.loading = loading; }); } }, { key: "getObservableProps", value: function getObservableProps(props, context) { return _objectSpread(_objectSpread({}, _get(_getPrototypeOf(Button.prototype), "getObservableProps", this).call(this, props, context)), {}, { dataSet: 'dataSet' in props ? props.dataSet : context.dataSet, loading: 'loading' in props ? props.loading : this.observableProps ? this.observableProps.loading : false, type: props.type, disabled: context.disabled || props.disabled }); } }, { key: "fixTwoCNChar", value: function fixTwoCNChar() { // For HOC usage var autoInsertSpace = this.getContextConfig('autoInsertSpaceInButton') !== false; if (!this.element || !autoInsertSpace) { return; } var buttonText = this.element.textContent; if (this.isNeedInserted() && isTwoCNChar(buttonText)) { if (!this.hasTwoCNChar) { this.hasTwoCNChar = true; } } else if (this.hasTwoCNChar) { this.hasTwoCNChar = false; } } }, { key: "componentDidMount", value: function componentDidMount() { _get(_getPrototypeOf(Button.prototype), "componentDidMount", this).call(this); this.fixTwoCNChar(); } }, { key: "componentWillReceiveProps", value: function componentWillReceiveProps(nextProps, nextContext) { _get(_getPrototypeOf(Button.prototype), "componentWillReceiveProps", this).call(this, nextProps, nextContext); var _this$props = this.props, wait = _this$props.wait, waitType = _this$props.waitType; if (wait !== nextProps.wait || waitType !== nextProps.waitType) { this.handleClickWait = this.getHandleClick(nextProps); } } }, { key: "componentWillUnmount", value: function componentWillUnmount() { this.handleClickWait.cancel(); if (this.isTooltipShown) { hide(); delete this.isTooltipShown; } } }, { key: "getHandleClick", value: function getHandleClick(props) { var wait = props.wait, waitType = props.waitType; if (wait && waitType) { var options = { leading: true, trailing: true }; if (waitType === WaitType.throttle) { options.trailing = false; options.maxWait = wait; } else if (waitType === WaitType.debounce) { options.leading = false; } return debounce(this.handleClick, wait, options); } return debounce(this.handleClick, 0); } }, { key: "handleClickIfBubble", value: function handleClickIfBubble(e) { var _this$props2 = this.props, wait = _this$props2.wait, waitType = _this$props2.waitType; if (wait && waitType) { e.stopPropagation(); this.handleClickWait(e); } else { this.handleClick(e); } } }, { key: "handleClick", value: function () { var _handleClick = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(e) { var onButtonClick, target, _this$props3, children, icon, promise, onClick, afterClick; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: onButtonClick = this.context.getConfig('onButtonClick'); if (onButtonClick && e) { target = e.target; _this$props3 = this.props, children = _this$props3.children, icon = _this$props3.icon; promise = Promise.resolve(target && target.textContent || getReactNodeText(children)); promise.then(function (title) { return onButtonClick({ icon: icon, title: title }); }); } onClick = this.props.onClick; if (!onClick) { _context.next = 13; break; } afterClick = onClick(e); if (!isPromise(afterClick)) { _context.next = 13; break; } _context.prev = 6; this.loading = true; _context.next = 10; return afterClick; case 10: _context.prev = 10; this.loading = false; return _context.finish(10); case 13: case "end": return _context.stop(); } } }, _callee, this, [[6,, 10, 13]]); })); function handleClick(_x) { return _handleClick.apply(this, arguments); } return handleClick; }() }, { key: "handleMouseEnter", value: function handleMouseEnter(e) { var _this$context = this.context, getTooltip = _this$context.getTooltip, getTooltipTheme = _this$context.getTooltipTheme, getTooltipPlacement = _this$context.getTooltipPlacement; var _this$props4 = this.props, _this$props4$tooltip = _this$props4.tooltip, tooltip = _this$props4$tooltip === void 0 ? getTooltip('button') : _this$props4$tooltip, children = _this$props4.children; var element = this.element; if (tooltip === ButtonTooltip.always || tooltip === ButtonTooltip.overflow && isOverflow(element)) { show(element, { title: children, theme: getTooltipTheme('button'), placement: getTooltipPlacement('button') }); this.isTooltipShown = true; } else if (isArrayLike(tooltip)) { var tooltipType = tooltip[0]; var buttonTooltipProps = tooltip[1] || {}; var duration = (buttonTooltipProps.mouseEnterDelay || 0.1) * 1000; if (tooltipType === ButtonTooltip.always || tooltipType === ButtonTooltip.overflow && isOverflow(element)) { show(element, _objectSpread({ theme: getTooltipTheme('button'), placement: getTooltipPlacement('button'), title: buttonTooltipProps.title ? buttonTooltipProps.title : children }, buttonTooltipProps), duration); this.isTooltipShown = true; } } var _this$props$onMouseEn = this.props.onMouseEnter, onMouseEnter = _this$props$onMouseEn === void 0 ? noop : _this$props$onMouseEn; onMouseEnter(e); } }, { key: "handleMouseLeave", value: function handleMouseLeave(e) { var getTooltip = this.context.getTooltip; var _this$props$tooltip = this.props.tooltip, tooltip = _this$props$tooltip === void 0 ? getTooltip('button') : _this$props$tooltip; if (isArrayLike(tooltip)) { var buttonTooltipProps = tooltip[1] || {}; var duration = (buttonTooltipProps.mouseLeaveDelay || 0.1) * 1000; hide(duration); } else { hide(); } var _this$props$onMouseLe = this.props.onMouseLeave, onMouseLeave = _this$props$onMouseLe === void 0 ? noop : _this$props$onMouseLe; onMouseLeave(e); } }, { key: "getOmitPropsKeys", value: function getOmitPropsKeys() { return _get(_getPrototypeOf(Button.prototype), "getOmitPropsKeys", this).call(this).concat(['icon', 'funcType', 'color', 'loading', 'wait', 'waitType', 'tooltip', 'block', 'onClick']); } }, { key: "getOtherProps", value: function getOtherProps() { var otherProps = _get(_getPrototypeOf(Button.prototype), "getOtherProps", this).call(this); var getTooltip = this.context.getTooltip; var _this$props$tooltip2 = this.props.tooltip, tooltip = _this$props$tooltip2 === void 0 ? getTooltip('button') : _this$props$tooltip2; if (!this.disabled && !this.loading) { otherProps.onClick = this.handleClickIfBubble; } if (isString(tooltip) && [ButtonTooltip.always, ButtonTooltip.overflow].includes(tooltip) || isArrayLike(tooltip) && [ButtonTooltip.always, ButtonTooltip.overflow].includes(tooltip[0])) { otherProps.onMouseEnter = this.handleMouseEnter; otherProps.onMouseLeave = this.handleMouseLeave; } return otherProps; } }, { key: "isNeedInserted", value: function isNeedInserted() { var _this$props5 = this.props, _this$props5$funcType = _this$props5.funcType, funcType = _this$props5$funcType === void 0 ? this.getContextConfig('buttonFuncType') : _this$props5$funcType, children = _this$props5.children, icon = _this$props5.icon; return Children.count(children) === 1 && !icon && !(funcType === FuncType.link || funcType === FuncType.flat); } }, { key: "getClassName", value: function getClassName() { var _get2, _ref; var prefixCls = this.prefixCls, _this$props6 = this.props, _this$props6$color = _this$props6.color, color = _this$props6$color === void 0 ? this.getContextConfig('buttonColor') : _this$props6$color, _this$props6$funcType = _this$props6.funcType, funcType = _this$props6$funcType === void 0 ? this.getContextConfig('buttonFuncType') : _this$props6$funcType, children = _this$props6.children, icon = _this$props6.icon, block = _this$props6.block; var childrenCount = Children.count(children); var autoInsertSpace = this.getContextConfig('autoInsertSpaceInButton') !== false; for (var _len = arguments.length, props = new Array(_len), _key = 0; _key < _len; _key++) { props[_key] = arguments[_key]; } return (_get2 = _get(_getPrototypeOf(Button.prototype), "getClassName", this)).call.apply(_get2, [this, (_ref = {}, _defineProperty(_ref, "".concat(prefixCls, "-").concat(funcType), funcType), _defineProperty(_ref, "".concat(prefixCls, "-").concat(color), color), _defineProperty(_ref, "".concat(prefixCls, "-icon-only"), icon ? childrenCount === 0 || children === false : childrenCount === 1 && children.type && children.type.__C7N_ICON), _defineProperty(_ref, "".concat(prefixCls, "-block"), block), _defineProperty(_ref, "".concat(prefixCls, "-loading"), this.loading), _defineProperty(_ref, "".concat(prefixCls, "-two-chinese-chars"), this.hasTwoCNChar && autoInsertSpace), _ref)].concat(props)); } }, { key: "render", value: function render() { var _this$props7 = this.props, children = _this$props7.children, icon = _this$props7.icon, href = _this$props7.href, funcType = _this$props7.funcType; var loading = this.loading, disabled = this.disabled; var autoInsertSpace = this.getContextConfig('autoInsertSpaceInButton') !== false; var buttonIcon = loading ? /*#__PURE__*/React.createElement(Progress, { key: "loading", type: ProgressType.loading, size: Size.small }) : icon && /*#__PURE__*/React.createElement(Icon, { type: icon }); var hasString = Children.toArray(children).some(function (child) { return isString(child); }); var Cmp = href ? 'a' : 'button'; var props = this.getMergedProps(); var onMouseEnter = props.onMouseEnter, onMouseLeave = props.onMouseLeave; var tooltipWrapper = disabled && !href && (onMouseEnter || onMouseLeave); var omits = []; if (tooltipWrapper) { omits.push('className', 'style'); } if (href) { omits.push('type'); if (disabled || loading) { omits.push('href'); } } var kids = children || children === 0 ? spaceChildren(children, this.isNeedInserted() && autoInsertSpace) : null; var button = /*#__PURE__*/React.createElement(Ripple, { disabled: disabled || funcType === FuncType.link }, /*#__PURE__*/React.createElement(Cmp, _extends({}, omit(props, omits)), buttonIcon, hasString ? /*#__PURE__*/React.createElement("span", null, kids) : kids)); return tooltipWrapper ? /*#__PURE__*/React.createElement("span", { className: classNames(props.className, "".concat(this.prefixCls, "-disabled-wrapper")), style: props.style, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }, button) : button; } }], [{ key: "contextType", get: function get() { return FormContext; } }]); return Button; }(DataSetComponent); Button.displayName = 'Button'; // eslint-disable-next-line camelcase Button.__PRO_BUTTON = true; Button.defaultProps = { suffixCls: 'btn', type: ButtonType.button, waitType: WaitType.throttle }; __decorate([observable], Button.prototype, "hasTwoCNChar", void 0); __decorate([computed], Button.prototype, "loading", null); __decorate([autobind, action], Button.prototype, "fixTwoCNChar", null); __decorate([autobind], Button.prototype, "handleClickIfBubble", null); __decorate([autobind], Button.prototype, "handleClick", null); __decorate([autobind], Button.prototype, "handleMouseEnter", null); __decorate([autobind], Button.prototype, "handleMouseLeave", null); Button = __decorate([observer], Button); export default Button; //# sourceMappingURL=Button.js.map