button.js 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. "use strict";
  2. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  3. Object.defineProperty(exports, "__esModule", {
  4. value: true
  5. });
  6. Object.defineProperty(exports, "buttonProps", {
  7. enumerable: true,
  8. get: function () {
  9. return _buttonTypes.default;
  10. }
  11. });
  12. exports.default = void 0;
  13. var _vue = require("vue");
  14. var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
  15. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  16. var _wave = _interopRequireDefault(require("../_util/wave"));
  17. var _buttonTypes = _interopRequireDefault(require("./buttonTypes"));
  18. var _propsUtil = require("../_util/props-util");
  19. var _useConfigInject = _interopRequireDefault(require("../config-provider/hooks/useConfigInject"));
  20. var _DisabledContext = require("../config-provider/DisabledContext");
  21. var _devWarning = _interopRequireDefault(require("../vc-util/devWarning"));
  22. var _LoadingIcon = _interopRequireDefault(require("./LoadingIcon"));
  23. var _style = _interopRequireDefault(require("./style"));
  24. var _buttonGroup = require("./button-group");
  25. var _Compact = require("../space/Compact");
  26. const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/;
  27. const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar);
  28. function isUnBorderedButtonType(type) {
  29. return type === 'text' || type === 'link';
  30. }
  31. var _default = exports.default = (0, _vue.defineComponent)({
  32. compatConfig: {
  33. MODE: 3
  34. },
  35. name: 'AButton',
  36. inheritAttrs: false,
  37. __ANT_BUTTON: true,
  38. props: (0, _propsUtil.initDefaultProps)((0, _buttonTypes.default)(), {
  39. type: 'default'
  40. }),
  41. slots: Object,
  42. // emits: ['click', 'mousedown'],
  43. setup(props, _ref) {
  44. let {
  45. slots,
  46. attrs,
  47. emit,
  48. expose
  49. } = _ref;
  50. const {
  51. prefixCls,
  52. autoInsertSpaceInButton,
  53. direction,
  54. size
  55. } = (0, _useConfigInject.default)('btn', props);
  56. const [wrapSSR, hashId] = (0, _style.default)(prefixCls);
  57. const groupSizeContext = _buttonGroup.GroupSizeContext.useInject();
  58. const disabledContext = (0, _DisabledContext.useInjectDisabled)();
  59. const mergedDisabled = (0, _vue.computed)(() => {
  60. var _a;
  61. return (_a = props.disabled) !== null && _a !== void 0 ? _a : disabledContext.value;
  62. });
  63. const buttonNodeRef = (0, _vue.shallowRef)(null);
  64. const delayTimeoutRef = (0, _vue.shallowRef)(undefined);
  65. let isNeedInserted = false;
  66. const innerLoading = (0, _vue.shallowRef)(false);
  67. const hasTwoCNChar = (0, _vue.shallowRef)(false);
  68. const autoInsertSpace = (0, _vue.computed)(() => autoInsertSpaceInButton.value !== false);
  69. const {
  70. compactSize,
  71. compactItemClassnames
  72. } = (0, _Compact.useCompactItemContext)(prefixCls, direction);
  73. // =============== Update Loading ===============
  74. const loadingOrDelay = (0, _vue.computed)(() => typeof props.loading === 'object' && props.loading.delay ? props.loading.delay || true : !!props.loading);
  75. (0, _vue.watch)(loadingOrDelay, val => {
  76. clearTimeout(delayTimeoutRef.value);
  77. if (typeof loadingOrDelay.value === 'number') {
  78. delayTimeoutRef.value = setTimeout(() => {
  79. innerLoading.value = val;
  80. }, loadingOrDelay.value);
  81. } else {
  82. innerLoading.value = val;
  83. }
  84. }, {
  85. immediate: true
  86. });
  87. const classes = (0, _vue.computed)(() => {
  88. const {
  89. type,
  90. shape = 'default',
  91. ghost,
  92. block,
  93. danger
  94. } = props;
  95. const pre = prefixCls.value;
  96. const sizeClassNameMap = {
  97. large: 'lg',
  98. small: 'sm',
  99. middle: undefined
  100. };
  101. const sizeFullname = compactSize.value || (groupSizeContext === null || groupSizeContext === void 0 ? void 0 : groupSizeContext.size) || size.value;
  102. const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : '';
  103. return [compactItemClassnames.value, {
  104. [hashId.value]: true,
  105. [`${pre}`]: true,
  106. [`${pre}-${shape}`]: shape !== 'default' && shape,
  107. [`${pre}-${type}`]: type,
  108. [`${pre}-${sizeCls}`]: sizeCls,
  109. [`${pre}-loading`]: innerLoading.value,
  110. [`${pre}-background-ghost`]: ghost && !isUnBorderedButtonType(type),
  111. [`${pre}-two-chinese-chars`]: hasTwoCNChar.value && autoInsertSpace.value,
  112. [`${pre}-block`]: block,
  113. [`${pre}-dangerous`]: !!danger,
  114. [`${pre}-rtl`]: direction.value === 'rtl'
  115. }];
  116. });
  117. const fixTwoCNChar = () => {
  118. // Fix for HOC usage like <FormatMessage />
  119. const node = buttonNodeRef.value;
  120. if (!node || autoInsertSpaceInButton.value === false) {
  121. return;
  122. }
  123. const buttonText = node.textContent;
  124. if (isNeedInserted && isTwoCNChar(buttonText)) {
  125. if (!hasTwoCNChar.value) {
  126. hasTwoCNChar.value = true;
  127. }
  128. } else if (hasTwoCNChar.value) {
  129. hasTwoCNChar.value = false;
  130. }
  131. };
  132. const handleClick = event => {
  133. // https://github.com/ant-design/ant-design/issues/30207
  134. if (innerLoading.value || mergedDisabled.value) {
  135. event.preventDefault();
  136. return;
  137. }
  138. emit('click', event);
  139. };
  140. const handleMousedown = event => {
  141. emit('mousedown', event);
  142. };
  143. const insertSpace = (child, needInserted) => {
  144. const SPACE = needInserted ? ' ' : '';
  145. if (child.type === _vue.Text) {
  146. let text = child.children.trim();
  147. if (isTwoCNChar(text)) {
  148. text = text.split('').join(SPACE);
  149. }
  150. return (0, _vue.createVNode)("span", null, [text]);
  151. }
  152. return child;
  153. };
  154. (0, _vue.watchEffect)(() => {
  155. (0, _devWarning.default)(!(props.ghost && isUnBorderedButtonType(props.type)), 'Button', "`link` or `text` button can't be a `ghost` button.");
  156. });
  157. (0, _vue.onMounted)(fixTwoCNChar);
  158. (0, _vue.onUpdated)(fixTwoCNChar);
  159. (0, _vue.onBeforeUnmount)(() => {
  160. delayTimeoutRef.value && clearTimeout(delayTimeoutRef.value);
  161. });
  162. const focus = () => {
  163. var _a;
  164. (_a = buttonNodeRef.value) === null || _a === void 0 ? void 0 : _a.focus();
  165. };
  166. const blur = () => {
  167. var _a;
  168. (_a = buttonNodeRef.value) === null || _a === void 0 ? void 0 : _a.blur();
  169. };
  170. expose({
  171. focus,
  172. blur
  173. });
  174. return () => {
  175. var _a, _b;
  176. const {
  177. icon = (_a = slots.icon) === null || _a === void 0 ? void 0 : _a.call(slots)
  178. } = props;
  179. const children = (0, _propsUtil.flattenChildren)((_b = slots.default) === null || _b === void 0 ? void 0 : _b.call(slots));
  180. isNeedInserted = children.length === 1 && !icon && !isUnBorderedButtonType(props.type);
  181. const {
  182. type,
  183. htmlType,
  184. href,
  185. title,
  186. target
  187. } = props;
  188. const iconType = innerLoading.value ? 'loading' : icon;
  189. const buttonProps = (0, _extends2.default)((0, _extends2.default)({}, attrs), {
  190. title,
  191. disabled: mergedDisabled.value,
  192. class: [classes.value, attrs.class, {
  193. [`${prefixCls.value}-icon-only`]: children.length === 0 && !!iconType
  194. }],
  195. onClick: handleClick,
  196. onMousedown: handleMousedown
  197. });
  198. // https://github.com/vueComponent/ant-design-vue/issues/4930
  199. if (!mergedDisabled.value) {
  200. delete buttonProps.disabled;
  201. }
  202. const iconNode = icon && !innerLoading.value ? icon : (0, _vue.createVNode)(_LoadingIcon.default, {
  203. "existIcon": !!icon,
  204. "prefixCls": prefixCls.value,
  205. "loading": !!innerLoading.value
  206. }, null);
  207. const kids = children.map(child => insertSpace(child, isNeedInserted && autoInsertSpace.value));
  208. if (href !== undefined) {
  209. return wrapSSR((0, _vue.createVNode)("a", (0, _objectSpread2.default)((0, _objectSpread2.default)({}, buttonProps), {}, {
  210. "href": href,
  211. "target": target,
  212. "ref": buttonNodeRef
  213. }), [iconNode, kids]));
  214. }
  215. let buttonNode = (0, _vue.createVNode)("button", (0, _objectSpread2.default)((0, _objectSpread2.default)({}, buttonProps), {}, {
  216. "ref": buttonNodeRef,
  217. "type": htmlType
  218. }), [iconNode, kids]);
  219. if (!isUnBorderedButtonType(type)) {
  220. const _buttonNode = function () {
  221. return buttonNode;
  222. }();
  223. buttonNode = (0, _vue.createVNode)(_wave.default, {
  224. "ref": "wave",
  225. "disabled": !!innerLoading.value
  226. }, {
  227. default: () => [_buttonNode]
  228. });
  229. }
  230. return wrapSSR(buttonNode);
  231. };
  232. }
  233. });