Quellcode durchsuchen

fix: alert animation (#5927)

Netfan vor 1 Monat
Ursprung
Commit
4a2c7b313f

+ 4 - 0
packages/@core/ui-kit/popup-ui/src/alert/alert.ts

@@ -36,6 +36,10 @@ export type AlertProps = {
   contentMasking?: boolean;
   /** 弹窗的图标(在标题的前面) */
   icon?: Component | IconType;
+  /**
+   * 弹窗遮罩模糊效果
+   */
+  overlayBlur?: number;
   /** 是否显示取消按钮 */
   showCancel?: boolean;
   /** 弹窗标题 */

+ 11 - 11
packages/@core/ui-kit/popup-ui/src/alert/alert.vue

@@ -3,7 +3,7 @@ import type { Component } from 'vue';
 
 import type { AlertProps } from './alert';
 
-import { computed, h, nextTick, ref, watch } from 'vue';
+import { computed, h, nextTick, ref } from 'vue';
 
 import { useSimpleLocale } from '@vben-core/composables';
 import {
@@ -39,14 +39,12 @@ const open = defineModel<boolean>('open', { default: false });
 const { $t } = useSimpleLocale();
 const components = globalShareState.getComponents();
 const isConfirm = ref(false);
-watch(open, async (val) => {
-  await nextTick();
-  if (val) {
-    isConfirm.value = false;
-  } else {
-    emits('closed', isConfirm.value);
-  }
-});
+
+function onAlertClosed() {
+  emits('closed', isConfirm.value);
+  isConfirm.value = false;
+}
+
 const getIconRender = computed(() => {
   let iconRender: Component | null = null;
   if (props.icon) {
@@ -100,6 +98,7 @@ function handleCancel() {
 
 const loading = ref(false);
 async function handleOpenChange(val: boolean) {
+  await nextTick();
   if (!val && props.beforeClose) {
     loading.value = true;
     try {
@@ -120,15 +119,16 @@ async function handleOpenChange(val: boolean) {
     <AlertDialogContent
       :open="open"
       :centered="centered"
+      :overlay-blur="overlayBlur"
       @opened="emits('opened')"
+      @closed="onAlertClosed"
       :class="
         cn(
           containerClass,
-          'left-0 right-0 top-[10vh] mx-auto flex max-h-[80%] flex-col p-0 duration-300 sm:rounded-[var(--radius)] md:w-[520px] md:max-w-[80%]',
+          'left-0 right-0 mx-auto flex max-h-[80%] flex-col p-0 duration-300 sm:rounded-[var(--radius)] md:w-[520px] md:max-w-[80%]',
           {
             'border-border border': bordered,
             'shadow-3xl': !bordered,
-            'top-1/2 !-translate-y-1/2': centered,
           },
         )
       "

+ 12 - 2
packages/@core/ui-kit/shadcn-ui/src/ui/alert-dialog/AlertDialogContent.vue

@@ -61,7 +61,7 @@ defineExpose({
 
 <template>
   <AlertDialogPortal>
-    <Transition name="fade">
+    <Transition name="fade" appear>
       <AlertDialogOverlay
         v-if="open && modal"
         :style="{
@@ -80,7 +80,17 @@ defineExpose({
       v-bind="forwarded"
       :class="
         cn(
-          'z-popup bg-background data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-top-[48%] w-full p-6 shadow-lg outline-none sm:rounded-xl',
+          'z-popup bg-background w-full p-6 shadow-lg outline-none sm:rounded-xl',
+          'data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95',
+          'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',
+          {
+            'data-[state=open]:slide-in-from-top-[48%] data-[state=closed]:slide-out-to-top-[48%]':
+              !centered,
+            'data-[state=open]:slide-in-from-top-[98%] data-[state=closed]:slide-out-to-top-[148%]':
+              centered,
+            'top-[10vh]': !centered,
+            'top-1/2 -translate-y-1/2': centered,
+          },
           props.class,
         )
       "

+ 2 - 0
playground/src/views/examples/modal/index.vue

@@ -138,6 +138,7 @@ function openConfirm() {
         }, 1000);
       });
     },
+    centered: false,
     content: '这是一个确认弹窗',
     icon: 'question',
   })
@@ -160,6 +161,7 @@ async function openPrompt() {
     componentProps: { placeholder: '不能吃芝士...' },
     content: '中午吃了什么?',
     icon: 'question',
+    overlayBlur: 3,
   })
     .then((res) => {
       message.success(`用户输入了:${res}`);