feat: confirm add showCancel & promise

feat-css-var
tangjinzhou 3 years ago
parent a36d858d7d
commit a041b5bace

@ -4,6 +4,7 @@ import Button from '../button';
import type { ButtonProps } from '../button';
import type { LegacyButtonType } from '../button/buttonTypes';
import { convertLegacyProps } from '../button/buttonTypes';
import useDestroyed from './hooks/useDestroyed';
const actionButtonProps = {
type: {
@ -32,6 +33,7 @@ export default defineComponent({
const buttonRef = ref();
const loading = ref(false);
let timeoutId: any;
const isDestroyed = useDestroyed();
onMounted(() => {
if (props.autofocus) {
timeoutId = setTimeout(() => buttonRef.value.$el?.focus());
@ -49,7 +51,9 @@ export default defineComponent({
loading.value = true;
returnValueOfOnOk!.then(
(...args: any[]) => {
loading.value = false;
if (!isDestroyed.value) {
loading.value = false;
}
close(...args);
clickedRef.value = false;
},
@ -58,7 +62,9 @@ export default defineComponent({
// eslint-disable-next-line no-console
console.error(e);
// See: https://github.com/ant-design/ant-design/issues/6183
loading.value = false;
if (!isDestroyed.value) {
loading.value = false;
}
clickedRef.value = false;
},
);

@ -1,7 +1,7 @@
import classNames from '../_util/classNames';
import type { ModalFuncProps } from './Modal';
import Dialog from './Modal';
import ActionButton from './ActionButton';
import ActionButton from '../_util/ActionButton';
import { defineComponent } from 'vue';
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
import { getTransitionName } from '../_util/transition';

@ -62,3 +62,9 @@ exports[`renders ./components/popconfirm/demo/placement.vue correctly 1`] = `
</div>
</div>
`;
exports[`renders ./components/popconfirm/demo/promise.vue correctly 1`] = `
<!----><button class="ant-btn ant-btn-primary" type="button">
<!----><span>Open Popconfirm with Promise</span>
</button>
`;

@ -5,6 +5,7 @@
<icon />
<placement />
<dynamic-trigger />
<promiseVue />
</demo-sort>
</template>
<script lang="ts">
@ -13,6 +14,7 @@ import Local from './local.vue';
import Icon from './icon.vue';
import Placement from './placement.vue';
import DynamicTrigger from './dynamic-trigger.vue';
import promiseVue from './promise.vue';
import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
import { defineComponent } from 'vue';
@ -21,6 +23,7 @@ export default defineComponent({
CN,
US,
components: {
promiseVue,
Basic,
Local,
Icon,

@ -0,0 +1,47 @@
<docs>
---
order: 7
version: 3.0
title:
zh-CN: 基于 Promise 的异步关闭 (3.0+)
en-US: Asynchronously close on Promise (3.0+)
---
## zh-CN
点击确定后异步关闭 Popconfirm例如提交表单
## en-US
Asynchronously close a popconfirm when the OK button is pressed. For example, you can use this pattern when you submit a form.
</docs>
<template>
<a-popconfirm title="Title" @confirm="confirm" @cancel="cancel">
<a-button type="primary">Open Popconfirm with Promise</a-button>
</a-popconfirm>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { message } from 'ant-design-vue';
export default defineComponent({
setup() {
const confirm = (e: MouseEvent) => {
console.log(e);
return new Promise(resolve => {
setTimeout(() => resolve(true), 3000);
});
};
const cancel = (e: MouseEvent) => {
console.log(e);
message.error('Click on No');
};
return {
confirm,
cancel,
};
},
});
</script>

@ -24,6 +24,7 @@ The difference with the 'confirm' modal dialog is that it's more lightweight tha
| okText | text of the Confirm button | string\|slot | `Confirm` | |
| okButton | custom render confirm button | slot | - | 3.0 |
| okType | Button `type` of the Confirm button | string | `primary` | |
| showCancel | Show cancel button | boolean | true | 3.0 |
| title | title of the confirmation box | string\|slot | - | |
| visible (v-model) | hide or show | boolean | - | |
| icon | customize icon of confirmation | vNode\|slot | &lt;Icon type="exclamation-circle" /&gt; | |

@ -20,6 +20,7 @@ import { getTransitionName } from '../_util/transition';
import { cloneVNodes } from '../_util/vnode';
import omit from '../_util/omit';
import { tooltipDefaultProps } from '../tooltip/Tooltip';
import ActionButton from '../_util/ActionButton';
export const popconfirmProps = () => ({
...abstractTooltipProps(),
@ -36,6 +37,9 @@ export const popconfirmProps = () => ({
icon: PropTypes.any,
okButtonProps: PropTypes.object,
cancelButtonProps: PropTypes.object,
showCancel: { type: Boolean, default: true },
onConfirm: Function as PropType<(e: MouseEvent) => void>,
onCancel: Function as PropType<(e: MouseEvent) => void>,
});
export type PopconfirmProps = Partial<ExtractPropTypes<ReturnType<typeof popconfirmProps>>>;
@ -61,7 +65,7 @@ const Popconfirm = defineComponent({
disabled: false,
}),
slots: ['title', 'content', 'okText', 'icon', 'cancelText', 'cancelButton', 'okButton'],
emits: ['update:visible', 'confirm', 'cancel', 'visibleChange'],
emits: ['update:visible', 'visibleChange'],
setup(props: PopconfirmProps, { slots, emit, expose }) {
onMounted(() => {
devWarning(
@ -71,7 +75,6 @@ const Popconfirm = defineComponent({
);
});
const tooltipRef = ref();
expose({
getPopupDomNode: () => {
return tooltipRef.value?.getPopupDomNode?.();
@ -91,14 +94,17 @@ const Popconfirm = defineComponent({
emit('visibleChange', value, e);
};
const onConfirm = (e: MouseEvent) => {
const close = (e: MouseEvent) => {
settingVisible(false, e);
emit('confirm', e);
};
const onConfirm = (e: MouseEvent) => {
return props.onConfirm?.(e);
};
const onCancel = (e: MouseEvent) => {
settingVisible(false, e);
emit('cancel', e);
props.onCancel?.(e);
};
const onKeyDown = (e: KeyboardEvent) => {
@ -114,9 +120,10 @@ const Popconfirm = defineComponent({
}
settingVisible(value);
};
const { prefixCls: prefixClsConfirm, configProvider } = useConfigInject('popconfirm', props);
const rootPrefixCls = computed(() => configProvider.getPrefixCls());
const popoverPrefixCls = computed(() => configProvider.getPrefixCls('popover'));
const { prefixCls: prefixClsConfirm, getPrefixCls } = useConfigInject('popconfirm', props);
const rootPrefixCls = computed(() => getPrefixCls());
const popoverPrefixCls = computed(() => getPrefixCls('popover'));
const btnPrefixCls = computed(() => getPrefixCls('btn'));
const [popconfirmLocale] = useLocaleReceiver('Popconfirm', defaultLocale.Popconfirm);
const renderOverlay = () => {
const {
@ -127,6 +134,7 @@ const Popconfirm = defineComponent({
okText = slots.okText?.(),
okType,
icon = slots.icon?.(),
showCancel = true,
} = props;
const { cancelButton, okButton } = slots;
const cancelProps: ButtonProps = {
@ -147,15 +155,26 @@ const Popconfirm = defineComponent({
<div class={`${popoverPrefixCls.value}-message-title`}>{title}</div>
</div>
<div class={`${popoverPrefixCls.value}-buttons`}>
{cancelButton ? (
cancelButton(cancelProps)
) : (
<Button {...cancelProps}>{cancelText || popconfirmLocale.value.cancelText}</Button>
)}
{showCancel ? (
cancelButton ? (
cancelButton(cancelProps)
) : (
<Button {...cancelProps}>{cancelText || popconfirmLocale.value.cancelText}</Button>
)
) : null}
{okButton ? (
okButton(okProps)
) : (
<Button {...okProps}>{okText || popconfirmLocale.value.okText}</Button>
<ActionButton
buttonProps={{ size: 'small', ...convertLegacyProps(okType), ...okButtonProps }}
actionFn={onConfirm}
close={close}
prefixCls={btnPrefixCls.value}
quitOnNullishReturnValue
emitEvent
>
{okText || popconfirmLocale.value.okText}
</ActionButton>
)}
</div>
</div>
@ -170,6 +189,8 @@ const Popconfirm = defineComponent({
'cancelText',
'okText',
'onUpdate:visible',
'onConfirm',
'onCancel',
]);
const overlayClassNames = classNames(prefixClsConfirm.value, overlayClassName);
return (

@ -23,6 +23,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/fjMCD9xRq/Popconfirm.svg
| okText | 确认按钮文字 | string\|slot | 确定 | |
| okButton | 完全自定义确认按钮 | slot | - | 3.0 |
| okType | 确认按钮类型 | string | primary | |
| showCancel | 是否显示取消按钮 | boolean | true | 3.0 |
| title | 确认框的描述 | string\|slot | 无 | |
| visible (v-model) | 是否显示 | boolean | - | |
| icon | 自定义弹出气泡 Icon 图标 | vNode | &lt;Icon type="exclamation-circle" /&gt; | |

Loading…
Cancel
Save