import type { ExtractPropTypes, PropType } from 'vue'; import { onMounted, ref, defineComponent, onBeforeUnmount } from 'vue'; import Button from '../button'; import type { ButtonProps } from '../button'; import type { LegacyButtonType } from '../button/buttonTypes'; import { convertLegacyProps } from '../button/buttonTypes'; const actionButtonProps = { type: { type: String as PropType, }, actionFn: Function as PropType<(...args: any[]) => any | PromiseLike>, close: Function, autofocus: Boolean, prefixCls: String, buttonProps: Object as PropType, emitEvent: Boolean, quitOnNullishReturnValue: Boolean, }; export type ActionButtonProps = ExtractPropTypes; function isThenable(thing?: PromiseLike): boolean { return !!(thing && !!thing.then); } export default defineComponent({ name: 'ActionButton', props: actionButtonProps, setup(props, { slots }) { const clickedRef = ref(false); const buttonRef = ref(); const loading = ref(false); let timeoutId: any; onMounted(() => { if (props.autofocus) { timeoutId = setTimeout(() => buttonRef.value.$el?.focus()); } }); onBeforeUnmount(() => { clearTimeout(timeoutId); }); const handlePromiseOnOk = (returnValueOfOnOk?: PromiseLike) => { const { close } = props; if (!isThenable(returnValueOfOnOk)) { return; } loading.value = true; returnValueOfOnOk!.then( (...args: any[]) => { loading.value = false; close(...args); clickedRef.value = false; }, (e: Error) => { // Emit error when catch promise reject // eslint-disable-next-line no-console console.error(e); // See: https://github.com/ant-design/ant-design/issues/6183 loading.value = false; clickedRef.value = false; }, ); }; const onClick = (e: MouseEvent) => { const { actionFn, close = () => {} } = props; if (clickedRef.value) { return; } clickedRef.value = true; if (!actionFn) { close(); return; } let returnValueOfOnOk; if (props.emitEvent) { returnValueOfOnOk = actionFn(e); if (props.quitOnNullishReturnValue && !isThenable(returnValueOfOnOk)) { clickedRef.value = false; close(e); return; } } else if (actionFn.length) { returnValueOfOnOk = actionFn(close); // https://github.com/ant-design/ant-design/issues/23358 clickedRef.value = false; } else { returnValueOfOnOk = actionFn(); if (!returnValueOfOnOk) { close(); return; } } handlePromiseOnOk(returnValueOfOnOk); }; return () => { const { type, prefixCls, buttonProps } = props; return ( ); }; }, });