feat: confirm add showCancel & promise
parent
a36d858d7d
commit
a041b5bace
|
@ -4,6 +4,7 @@ import Button from '../button';
|
||||||
import type { ButtonProps } from '../button';
|
import type { ButtonProps } from '../button';
|
||||||
import type { LegacyButtonType } from '../button/buttonTypes';
|
import type { LegacyButtonType } from '../button/buttonTypes';
|
||||||
import { convertLegacyProps } from '../button/buttonTypes';
|
import { convertLegacyProps } from '../button/buttonTypes';
|
||||||
|
import useDestroyed from './hooks/useDestroyed';
|
||||||
|
|
||||||
const actionButtonProps = {
|
const actionButtonProps = {
|
||||||
type: {
|
type: {
|
||||||
|
@ -32,6 +33,7 @@ export default defineComponent({
|
||||||
const buttonRef = ref();
|
const buttonRef = ref();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
let timeoutId: any;
|
let timeoutId: any;
|
||||||
|
const isDestroyed = useDestroyed();
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (props.autofocus) {
|
if (props.autofocus) {
|
||||||
timeoutId = setTimeout(() => buttonRef.value.$el?.focus());
|
timeoutId = setTimeout(() => buttonRef.value.$el?.focus());
|
||||||
|
@ -49,7 +51,9 @@ export default defineComponent({
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
returnValueOfOnOk!.then(
|
returnValueOfOnOk!.then(
|
||||||
(...args: any[]) => {
|
(...args: any[]) => {
|
||||||
loading.value = false;
|
if (!isDestroyed.value) {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
close(...args);
|
close(...args);
|
||||||
clickedRef.value = false;
|
clickedRef.value = false;
|
||||||
},
|
},
|
||||||
|
@ -58,7 +62,9 @@ export default defineComponent({
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error(e);
|
console.error(e);
|
||||||
// See: https://github.com/ant-design/ant-design/issues/6183
|
// See: https://github.com/ant-design/ant-design/issues/6183
|
||||||
loading.value = false;
|
if (!isDestroyed.value) {
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
clickedRef.value = false;
|
clickedRef.value = false;
|
||||||
},
|
},
|
||||||
);
|
);
|
|
@ -1,7 +1,7 @@
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import type { ModalFuncProps } from './Modal';
|
import type { ModalFuncProps } from './Modal';
|
||||||
import Dialog from './Modal';
|
import Dialog from './Modal';
|
||||||
import ActionButton from './ActionButton';
|
import ActionButton from '../_util/ActionButton';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
|
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
|
||||||
import { getTransitionName } from '../_util/transition';
|
import { getTransitionName } from '../_util/transition';
|
||||||
|
|
|
@ -62,3 +62,9 @@ exports[`renders ./components/popconfirm/demo/placement.vue correctly 1`] = `
|
||||||
</div>
|
</div>
|
||||||
</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 />
|
<icon />
|
||||||
<placement />
|
<placement />
|
||||||
<dynamic-trigger />
|
<dynamic-trigger />
|
||||||
|
<promiseVue />
|
||||||
</demo-sort>
|
</demo-sort>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -13,6 +14,7 @@ import Local from './local.vue';
|
||||||
import Icon from './icon.vue';
|
import Icon from './icon.vue';
|
||||||
import Placement from './placement.vue';
|
import Placement from './placement.vue';
|
||||||
import DynamicTrigger from './dynamic-trigger.vue';
|
import DynamicTrigger from './dynamic-trigger.vue';
|
||||||
|
import promiseVue from './promise.vue';
|
||||||
import CN from '../index.zh-CN.md';
|
import CN from '../index.zh-CN.md';
|
||||||
import US from '../index.en-US.md';
|
import US from '../index.en-US.md';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
@ -21,6 +23,7 @@ export default defineComponent({
|
||||||
CN,
|
CN,
|
||||||
US,
|
US,
|
||||||
components: {
|
components: {
|
||||||
|
promiseVue,
|
||||||
Basic,
|
Basic,
|
||||||
Local,
|
Local,
|
||||||
Icon,
|
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` | |
|
| okText | text of the Confirm button | string\|slot | `Confirm` | |
|
||||||
| okButton | custom render confirm button | slot | - | 3.0 |
|
| okButton | custom render confirm button | slot | - | 3.0 |
|
||||||
| okType | Button `type` of the Confirm button | string | `primary` | |
|
| 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 | - | |
|
| title | title of the confirmation box | string\|slot | - | |
|
||||||
| visible (v-model) | hide or show | boolean | - | |
|
| visible (v-model) | hide or show | boolean | - | |
|
||||||
| icon | customize icon of confirmation | vNode\|slot | <Icon type="exclamation-circle" /> | |
|
| icon | customize icon of confirmation | vNode\|slot | <Icon type="exclamation-circle" /> | |
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { getTransitionName } from '../_util/transition';
|
||||||
import { cloneVNodes } from '../_util/vnode';
|
import { cloneVNodes } from '../_util/vnode';
|
||||||
import omit from '../_util/omit';
|
import omit from '../_util/omit';
|
||||||
import { tooltipDefaultProps } from '../tooltip/Tooltip';
|
import { tooltipDefaultProps } from '../tooltip/Tooltip';
|
||||||
|
import ActionButton from '../_util/ActionButton';
|
||||||
|
|
||||||
export const popconfirmProps = () => ({
|
export const popconfirmProps = () => ({
|
||||||
...abstractTooltipProps(),
|
...abstractTooltipProps(),
|
||||||
|
@ -36,6 +37,9 @@ export const popconfirmProps = () => ({
|
||||||
icon: PropTypes.any,
|
icon: PropTypes.any,
|
||||||
okButtonProps: PropTypes.object,
|
okButtonProps: PropTypes.object,
|
||||||
cancelButtonProps: 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>>>;
|
export type PopconfirmProps = Partial<ExtractPropTypes<ReturnType<typeof popconfirmProps>>>;
|
||||||
|
@ -61,7 +65,7 @@ const Popconfirm = defineComponent({
|
||||||
disabled: false,
|
disabled: false,
|
||||||
}),
|
}),
|
||||||
slots: ['title', 'content', 'okText', 'icon', 'cancelText', 'cancelButton', 'okButton'],
|
slots: ['title', 'content', 'okText', 'icon', 'cancelText', 'cancelButton', 'okButton'],
|
||||||
emits: ['update:visible', 'confirm', 'cancel', 'visibleChange'],
|
emits: ['update:visible', 'visibleChange'],
|
||||||
setup(props: PopconfirmProps, { slots, emit, expose }) {
|
setup(props: PopconfirmProps, { slots, emit, expose }) {
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
devWarning(
|
devWarning(
|
||||||
|
@ -71,7 +75,6 @@ const Popconfirm = defineComponent({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
const tooltipRef = ref();
|
const tooltipRef = ref();
|
||||||
|
|
||||||
expose({
|
expose({
|
||||||
getPopupDomNode: () => {
|
getPopupDomNode: () => {
|
||||||
return tooltipRef.value?.getPopupDomNode?.();
|
return tooltipRef.value?.getPopupDomNode?.();
|
||||||
|
@ -91,14 +94,17 @@ const Popconfirm = defineComponent({
|
||||||
emit('visibleChange', value, e);
|
emit('visibleChange', value, e);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onConfirm = (e: MouseEvent) => {
|
const close = (e: MouseEvent) => {
|
||||||
settingVisible(false, e);
|
settingVisible(false, e);
|
||||||
emit('confirm', e);
|
};
|
||||||
|
|
||||||
|
const onConfirm = (e: MouseEvent) => {
|
||||||
|
return props.onConfirm?.(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onCancel = (e: MouseEvent) => {
|
const onCancel = (e: MouseEvent) => {
|
||||||
settingVisible(false, e);
|
settingVisible(false, e);
|
||||||
emit('cancel', e);
|
props.onCancel?.(e);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onKeyDown = (e: KeyboardEvent) => {
|
const onKeyDown = (e: KeyboardEvent) => {
|
||||||
|
@ -114,9 +120,10 @@ const Popconfirm = defineComponent({
|
||||||
}
|
}
|
||||||
settingVisible(value);
|
settingVisible(value);
|
||||||
};
|
};
|
||||||
const { prefixCls: prefixClsConfirm, configProvider } = useConfigInject('popconfirm', props);
|
const { prefixCls: prefixClsConfirm, getPrefixCls } = useConfigInject('popconfirm', props);
|
||||||
const rootPrefixCls = computed(() => configProvider.getPrefixCls());
|
const rootPrefixCls = computed(() => getPrefixCls());
|
||||||
const popoverPrefixCls = computed(() => configProvider.getPrefixCls('popover'));
|
const popoverPrefixCls = computed(() => getPrefixCls('popover'));
|
||||||
|
const btnPrefixCls = computed(() => getPrefixCls('btn'));
|
||||||
const [popconfirmLocale] = useLocaleReceiver('Popconfirm', defaultLocale.Popconfirm);
|
const [popconfirmLocale] = useLocaleReceiver('Popconfirm', defaultLocale.Popconfirm);
|
||||||
const renderOverlay = () => {
|
const renderOverlay = () => {
|
||||||
const {
|
const {
|
||||||
|
@ -127,6 +134,7 @@ const Popconfirm = defineComponent({
|
||||||
okText = slots.okText?.(),
|
okText = slots.okText?.(),
|
||||||
okType,
|
okType,
|
||||||
icon = slots.icon?.(),
|
icon = slots.icon?.(),
|
||||||
|
showCancel = true,
|
||||||
} = props;
|
} = props;
|
||||||
const { cancelButton, okButton } = slots;
|
const { cancelButton, okButton } = slots;
|
||||||
const cancelProps: ButtonProps = {
|
const cancelProps: ButtonProps = {
|
||||||
|
@ -147,15 +155,26 @@ const Popconfirm = defineComponent({
|
||||||
<div class={`${popoverPrefixCls.value}-message-title`}>{title}</div>
|
<div class={`${popoverPrefixCls.value}-message-title`}>{title}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class={`${popoverPrefixCls.value}-buttons`}>
|
<div class={`${popoverPrefixCls.value}-buttons`}>
|
||||||
{cancelButton ? (
|
{showCancel ? (
|
||||||
cancelButton(cancelProps)
|
cancelButton ? (
|
||||||
) : (
|
cancelButton(cancelProps)
|
||||||
<Button {...cancelProps}>{cancelText || popconfirmLocale.value.cancelText}</Button>
|
) : (
|
||||||
)}
|
<Button {...cancelProps}>{cancelText || popconfirmLocale.value.cancelText}</Button>
|
||||||
|
)
|
||||||
|
) : null}
|
||||||
{okButton ? (
|
{okButton ? (
|
||||||
okButton(okProps)
|
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>
|
||||||
</div>
|
</div>
|
||||||
|
@ -170,6 +189,8 @@ const Popconfirm = defineComponent({
|
||||||
'cancelText',
|
'cancelText',
|
||||||
'okText',
|
'okText',
|
||||||
'onUpdate:visible',
|
'onUpdate:visible',
|
||||||
|
'onConfirm',
|
||||||
|
'onCancel',
|
||||||
]);
|
]);
|
||||||
const overlayClassNames = classNames(prefixClsConfirm.value, overlayClassName);
|
const overlayClassNames = classNames(prefixClsConfirm.value, overlayClassName);
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -23,6 +23,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/fjMCD9xRq/Popconfirm.svg
|
||||||
| okText | 确认按钮文字 | string\|slot | 确定 | |
|
| okText | 确认按钮文字 | string\|slot | 确定 | |
|
||||||
| okButton | 完全自定义确认按钮 | slot | - | 3.0 |
|
| okButton | 完全自定义确认按钮 | slot | - | 3.0 |
|
||||||
| okType | 确认按钮类型 | string | primary | |
|
| okType | 确认按钮类型 | string | primary | |
|
||||||
|
| showCancel | 是否显示取消按钮 | boolean | true | 3.0 |
|
||||||
| title | 确认框的描述 | string\|slot | 无 | |
|
| title | 确认框的描述 | string\|slot | 无 | |
|
||||||
| visible (v-model) | 是否显示 | boolean | - | |
|
| visible (v-model) | 是否显示 | boolean | - | |
|
||||||
| icon | 自定义弹出气泡 Icon 图标 | vNode | <Icon type="exclamation-circle" /> | |
|
| icon | 自定义弹出气泡 Icon 图标 | vNode | <Icon type="exclamation-circle" /> | |
|
||||||
|
|
Loading…
Reference in New Issue