choerodon-ui
Version:
An enterprise-class UI design language and React-based implementation
484 lines (415 loc) • 17.7 kB
JavaScript
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