import type { MaybeRef } from 'vue' import { ref, watchEffect } from 'vue' type UseDialogOptions = { isOpen: MaybeRef persistent: MaybeRef onClosing?: () => void onClose?: () => void animationOptions: MaybeRef dialogKeyframes: MaybeRef contentKeyframes: MaybeRef } export function useDialog(options: UseDialogOptions) { const dialogRef = ref(null) const contentRef = ref(null) const persistent = ref(options.persistent) const isOpen = ref(options.isOpen) const animationOptions = ref(options.animationOptions) const dialogKeyframes = ref(options.dialogKeyframes) function handleClose(event: Event) { event.preventDefault() if (persistent.value === true) return if (options.onClosing) { options.onClosing() } const dialogFadeOut = dialogRef.value?.animate(dialogKeyframes.value, animationOptions.value) dialogFadeOut?.addEventListener('finish', () => { dialogRef.value?.close() if (options.onClose) { options.onClose() } }) } watchEffect((onCleanup) => { if (isOpen.value) { dialogRef.value?.addEventListener('close', handleClose) dialogRef.value?.showModal() dialogRef.value?.animate(dialogKeyframes.value, animationOptions.value) contentRef.value?.animate(dialogKeyframes.value, animationOptions.value) } else { handleClose(new Event('close')) dialogRef.value?.removeEventListener('close', handleClose) } onCleanup(() => { dialogRef.value?.removeEventListener('close', handleClose) }) }) return [ { dialog: dialogRef, content: contentRef, }, { handleClose, }, ] as const }