Netfan
1 year ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with
80 additions and
9 deletions
-
docs/src/components/common-ui/vben-modal.md
-
packages/@core/ui-kit/popup-ui/src/modal/__tests__/modal-api.test.ts
-
packages/@core/ui-kit/popup-ui/src/modal/modal-api.ts
-
packages/@core/ui-kit/popup-ui/src/modal/modal.ts
-
packages/@core/ui-kit/popup-ui/src/modal/modal.vue
-
packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogContent.vue
-
playground/src/views/examples/modal/base-demo.vue
|
|
|
@ -110,12 +110,14 @@ const [Modal, modalApi] = useVbenModal({ |
|
|
|
|
|
|
|
以下事件,只有在 `useVbenModal({onCancel:()=>{}})` 中传入才会生效。 |
|
|
|
|
|
|
|
| 事件名 | 描述 | 类型 | |
|
|
|
| --- | --- | --- | |
|
|
|
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` | |
|
|
|
| onCancel | 点击取消按钮触发 | `()=>void` | |
|
|
|
| onConfirm | 点击确认按钮触发 | `()=>void` | |
|
|
|
| onOpenChange | 关闭或者打开弹窗时触发 | `(isOpen:boolean)=>void` | |
|
|
|
| 事件名 | 描述 | 类型 | 版本号 | |
|
|
|
| --- | --- | --- | --- | |
|
|
|
| onBeforeClose | 关闭前触发,返回 `false`则禁止关闭 | `()=>boolean` | | |
|
|
|
| onCancel | 点击取消按钮触发 | `()=>void` | | |
|
|
|
| onClosed | 关闭动画播放完毕时触发 | `()=>void` | >5.4.3 | |
|
|
|
| onConfirm | 点击确认按钮触发 | `()=>void` | | |
|
|
|
| onOpenChange | 关闭或者打开弹窗时触发 | `(isOpen:boolean)=>void` | | |
|
|
|
| onOpened | 打开动画播放完毕时触发 | `()=>void` | >5.4.3 | |
|
|
|
|
|
|
|
### Slots |
|
|
|
|
|
|
|
|
|
|
|
@ -110,4 +110,19 @@ describe('modalApi', () => { |
|
|
|
expect(modalApi.store.state.title).toBe('Batch Title'); |
|
|
|
expect(modalApi.store.state.confirmText).toBe('Batch Confirm'); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should call onClosed callback when provided', () => { |
|
|
|
const onClosed = vi.fn(); |
|
|
|
const modalApiWithHook = new ModalApi({ onClosed }); |
|
|
|
modalApiWithHook.onClosed(); |
|
|
|
expect(onClosed).toHaveBeenCalled(); |
|
|
|
}); |
|
|
|
|
|
|
|
it('should call onOpened callback when provided', () => { |
|
|
|
const onOpened = vi.fn(); |
|
|
|
const modalApiWithHook = new ModalApi({ onOpened }); |
|
|
|
modalApiWithHook.open(); |
|
|
|
modalApiWithHook.onOpened(); |
|
|
|
expect(onOpened).toHaveBeenCalled(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
@ -6,7 +6,12 @@ import { bindMethods, isFunction } from '@vben-core/shared/utils'; |
|
|
|
export class ModalApi { |
|
|
|
private api: Pick< |
|
|
|
ModalApiOptions, |
|
|
|
'onBeforeClose' | 'onCancel' | 'onConfirm' | 'onOpenChange' |
|
|
|
| 'onBeforeClose' |
|
|
|
| 'onCancel' |
|
|
|
| 'onClosed' |
|
|
|
| 'onConfirm' |
|
|
|
| 'onOpenChange' |
|
|
|
| 'onOpened' |
|
|
|
>; |
|
|
|
// private prevState!: ModalState;
|
|
|
|
private state!: ModalState; |
|
|
|
@ -23,8 +28,10 @@ export class ModalApi { |
|
|
|
connectedComponent: _, |
|
|
|
onBeforeClose, |
|
|
|
onCancel, |
|
|
|
onClosed, |
|
|
|
onConfirm, |
|
|
|
onOpenChange, |
|
|
|
onOpened, |
|
|
|
...storeState |
|
|
|
} = options; |
|
|
|
|
|
|
|
@ -77,8 +84,10 @@ export class ModalApi { |
|
|
|
this.api = { |
|
|
|
onBeforeClose, |
|
|
|
onCancel, |
|
|
|
onClosed, |
|
|
|
onConfirm, |
|
|
|
onOpenChange, |
|
|
|
onOpened, |
|
|
|
}; |
|
|
|
bindMethods(this); |
|
|
|
} |
|
|
|
@ -115,6 +124,15 @@ export class ModalApi { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 弹窗关闭动画播放完毕后的回调 |
|
|
|
*/ |
|
|
|
onClosed() { |
|
|
|
if (!this.state.isOpen) { |
|
|
|
this.api.onClosed?.(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 确认操作 |
|
|
|
*/ |
|
|
|
@ -122,6 +140,15 @@ export class ModalApi { |
|
|
|
this.api.onConfirm?.(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 弹窗打开动画播放完毕后的回调 |
|
|
|
*/ |
|
|
|
onOpened() { |
|
|
|
if (this.state.isOpen) { |
|
|
|
this.api.onOpened?.(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
open() { |
|
|
|
this.store.setState((prev) => ({ ...prev, isOpen: true })); |
|
|
|
} |
|
|
|
|
|
|
|
@ -139,6 +139,11 @@ export interface ModalApiOptions extends ModalState { |
|
|
|
* 点击取消按钮的回调 |
|
|
|
*/ |
|
|
|
onCancel?: () => void; |
|
|
|
/** |
|
|
|
* 弹窗关闭动画结束的回调 |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
onClosed?: () => void; |
|
|
|
/** |
|
|
|
* 点击确定按钮的回调 |
|
|
|
*/ |
|
|
|
@ -149,4 +154,9 @@ export interface ModalApiOptions extends ModalState { |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
onOpenChange?: (isOpen: boolean) => void; |
|
|
|
/** |
|
|
|
* 弹窗打开动画结束的回调 |
|
|
|
* @returns |
|
|
|
*/ |
|
|
|
onOpened?: () => void; |
|
|
|
} |
|
|
|
|
|
|
|
@ -188,10 +188,12 @@ function handleFocusOutside(e: Event) { |
|
|
|
:show-close="closable" |
|
|
|
close-class="top-3" |
|
|
|
@close-auto-focus="handleFocusOutside" |
|
|
|
@closed="() => modalApi?.onClosed()" |
|
|
|
@escape-key-down="escapeKeyDown" |
|
|
|
@focus-outside="handleFocusOutside" |
|
|
|
@interact-outside="interactOutside" |
|
|
|
@open-auto-focus="handerOpenAutoFocus" |
|
|
|
@opened="() => modalApi?.onOpened()" |
|
|
|
@pointer-down-outside="pointerDownOutside" |
|
|
|
> |
|
|
|
<DialogHeader |
|
|
|
|
|
|
|
@ -27,7 +27,9 @@ const props = withDefaults( |
|
|
|
>(), |
|
|
|
{ showClose: true }, |
|
|
|
); |
|
|
|
const emits = defineEmits<{ close: [] } & DialogContentEmits>(); |
|
|
|
const emits = defineEmits< |
|
|
|
{ close: []; closed: []; opened: [] } & DialogContentEmits |
|
|
|
>(); |
|
|
|
|
|
|
|
const delegatedProps = computed(() => { |
|
|
|
const { |
|
|
|
@ -44,7 +46,13 @@ const delegatedProps = computed(() => { |
|
|
|
const forwarded = useForwardPropsEmits(delegatedProps, emits); |
|
|
|
|
|
|
|
const contentRef = ref<InstanceType<typeof DialogContent> | null>(null); |
|
|
|
|
|
|
|
function onAnimationEnd() { |
|
|
|
if (props.open) { |
|
|
|
emits('opened'); |
|
|
|
} else { |
|
|
|
emits('closed'); |
|
|
|
} |
|
|
|
} |
|
|
|
defineExpose({ |
|
|
|
getContentRef: () => contentRef.value, |
|
|
|
}); |
|
|
|
@ -57,6 +65,7 @@ defineExpose({ |
|
|
|
</Transition> |
|
|
|
<DialogContent |
|
|
|
ref="contentRef" |
|
|
|
@animationend="onAnimationEnd" |
|
|
|
v-bind="forwarded" |
|
|
|
:class=" |
|
|
|
cn( |
|
|
|
|
|
|
|
@ -7,10 +7,16 @@ const [Modal, modalApi] = useVbenModal({ |
|
|
|
onCancel() { |
|
|
|
modalApi.close(); |
|
|
|
}, |
|
|
|
onClosed() { |
|
|
|
message.info('onClosed:关闭动画结束'); |
|
|
|
}, |
|
|
|
onConfirm() { |
|
|
|
message.info('onConfirm'); |
|
|
|
// modalApi.close(); |
|
|
|
}, |
|
|
|
onOpened() { |
|
|
|
message.info('onOpened:打开动画结束'); |
|
|
|
}, |
|
|
|
}); |
|
|
|
</script> |
|
|
|
<template> |
|
|
|
|