UNPKG

@aplus-frontend/antdv

Version:

Vue basic component library maintained based on ant-design-vue

222 lines 7.78 kB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _extends from "@babel/runtime/helpers/esm/extends"; import { computed, defineComponent, onBeforeUnmount, onMounted, onUpdated, shallowRef, Text, watch, watchEffect, createVNode as _createVNode } from 'vue'; import Wave from '../_util/wave'; import buttonProps from './buttonTypes'; import { flattenChildren, initDefaultProps } from '../_util/props-util'; import useConfigInject from '../config-provider/hooks/useConfigInject'; import { useInjectDisabled } from '../config-provider/DisabledContext'; import devWarning from '../vc-util/devWarning'; import LoadingIcon from './LoadingIcon'; import useStyle from './style'; import { GroupSizeContext } from './button-group'; import { useCompactItemContext } from '../space/Compact'; const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/; const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar); function isUnBorderedButtonType(type) { return type === 'text' || type === 'link'; } export { buttonProps }; export default defineComponent({ compatConfig: { MODE: 3 }, name: 'AButton', inheritAttrs: false, __ANT_BUTTON: true, props: initDefaultProps(buttonProps(), { type: 'default' }), slots: Object, // emits: ['click', 'mousedown'], setup(props, _ref) { let { slots, attrs, emit, expose } = _ref; const { prefixCls, autoInsertSpaceInButton, direction, size } = useConfigInject('btn', props); const [wrapSSR, hashId] = useStyle(prefixCls); const groupSizeContext = GroupSizeContext.useInject(); const disabledContext = useInjectDisabled(); const mergedDisabled = computed(() => { var _a; return (_a = props.disabled) !== null && _a !== void 0 ? _a : disabledContext.value; }); const buttonNodeRef = shallowRef(null); const delayTimeoutRef = shallowRef(undefined); let isNeedInserted = false; const innerLoading = shallowRef(false); const hasTwoCNChar = shallowRef(false); const autoInsertSpace = computed(() => autoInsertSpaceInButton.value !== false); const { compactSize, compactItemClassnames } = useCompactItemContext(prefixCls, direction); // =============== Update Loading =============== const loadingOrDelay = computed(() => typeof props.loading === 'object' && props.loading.delay ? props.loading.delay || true : !!props.loading); watch(loadingOrDelay, val => { clearTimeout(delayTimeoutRef.value); if (typeof loadingOrDelay.value === 'number') { delayTimeoutRef.value = setTimeout(() => { innerLoading.value = val; }, loadingOrDelay.value); } else { innerLoading.value = val; } }, { immediate: true }); const classes = computed(() => { const { type, shape = 'default', ghost, block, danger } = props; const pre = prefixCls.value; const sizeClassNameMap = { large: 'lg', small: 'sm', middle: undefined }; const sizeFullname = compactSize.value || (groupSizeContext === null || groupSizeContext === void 0 ? void 0 : groupSizeContext.size) || size.value; const sizeCls = sizeFullname ? sizeClassNameMap[sizeFullname] || '' : ''; return [compactItemClassnames.value, { [hashId.value]: true, [`${pre}`]: true, [`${pre}-${shape}`]: shape !== 'default' && shape, [`${pre}-${type}`]: type, [`${pre}-${sizeCls}`]: sizeCls, [`${pre}-loading`]: innerLoading.value, [`${pre}-background-ghost`]: ghost && !isUnBorderedButtonType(type), [`${pre}-two-chinese-chars`]: hasTwoCNChar.value && autoInsertSpace.value, [`${pre}-block`]: block, [`${pre}-dangerous`]: !!danger, [`${pre}-rtl`]: direction.value === 'rtl' }]; }); const fixTwoCNChar = () => { // Fix for HOC usage like <FormatMessage /> const node = buttonNodeRef.value; if (!node || autoInsertSpaceInButton.value === false) { return; } const buttonText = node.textContent; if (isNeedInserted && isTwoCNChar(buttonText)) { if (!hasTwoCNChar.value) { hasTwoCNChar.value = true; } } else if (hasTwoCNChar.value) { hasTwoCNChar.value = false; } }; const handleClick = event => { // https://github.com/ant-design/ant-design/issues/30207 if (innerLoading.value || mergedDisabled.value) { event.preventDefault(); return; } emit('click', event); }; const handleMousedown = event => { emit('mousedown', event); }; const insertSpace = (child, needInserted) => { const SPACE = needInserted ? ' ' : ''; if (child.type === Text) { let text = child.children.trim(); if (isTwoCNChar(text)) { text = text.split('').join(SPACE); } return _createVNode("span", null, [text]); } return child; }; watchEffect(() => { devWarning(!(props.ghost && isUnBorderedButtonType(props.type)), 'Button', "`link` or `text` button can't be a `ghost` button."); }); onMounted(fixTwoCNChar); onUpdated(fixTwoCNChar); onBeforeUnmount(() => { delayTimeoutRef.value && clearTimeout(delayTimeoutRef.value); }); const focus = () => { var _a; (_a = buttonNodeRef.value) === null || _a === void 0 ? void 0 : _a.focus(); }; const blur = () => { var _a; (_a = buttonNodeRef.value) === null || _a === void 0 ? void 0 : _a.blur(); }; expose({ focus, blur }); return () => { var _a, _b; const { icon = (_a = slots.icon) === null || _a === void 0 ? void 0 : _a.call(slots) } = props; const children = flattenChildren((_b = slots.default) === null || _b === void 0 ? void 0 : _b.call(slots)); isNeedInserted = children.length === 1 && !icon && !isUnBorderedButtonType(props.type); const { type, htmlType, href, title, target } = props; const iconType = innerLoading.value ? 'loading' : icon; const buttonProps = _extends(_extends({}, attrs), { title, disabled: mergedDisabled.value, class: [classes.value, attrs.class, { [`${prefixCls.value}-icon-only`]: children.length === 0 && !!iconType }], onClick: handleClick, onMousedown: handleMousedown }); // https://github.com/vueComponent/ant-design-vue/issues/4930 if (!mergedDisabled.value) { delete buttonProps.disabled; } const iconNode = icon && !innerLoading.value ? icon : _createVNode(LoadingIcon, { "existIcon": !!icon, "prefixCls": prefixCls.value, "loading": !!innerLoading.value }, null); const kids = children.map(child => insertSpace(child, isNeedInserted && autoInsertSpace.value)); if (href !== undefined) { return wrapSSR(_createVNode("a", _objectSpread(_objectSpread({}, buttonProps), {}, { "href": href, "target": target, "ref": buttonNodeRef }), [iconNode, kids])); } let buttonNode = _createVNode("button", _objectSpread(_objectSpread({}, buttonProps), {}, { "ref": buttonNodeRef, "type": htmlType }), [iconNode, kids]); if (!isUnBorderedButtonType(type)) { const _buttonNode = function () { return buttonNode; }(); buttonNode = _createVNode(Wave, { "ref": "wave", "disabled": !!innerLoading.value }, { default: () => [_buttonNode] }); } return wrapSSR(buttonNode); }; } });