Merge branch 'fork/HaroldZhangCode91/feature/fix_freeze_scrollbar_of_modal'
commit
6544340d80
|
|
@ -1,16 +1,7 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import type { ExtendedModalApi, ModalProps } from './modal';
|
import type { ExtendedModalApi, ModalProps } from './modal';
|
||||||
|
|
||||||
import {
|
import { computed, nextTick, onDeactivated, ref, unref, watch } from 'vue';
|
||||||
computed,
|
|
||||||
nextTick,
|
|
||||||
onDeactivated,
|
|
||||||
provide,
|
|
||||||
ref,
|
|
||||||
unref,
|
|
||||||
useId,
|
|
||||||
watch,
|
|
||||||
} from 'vue';
|
|
||||||
|
|
||||||
import { usePriorityValues, useSimpleLocale } from '@vben-core/composables';
|
import { usePriorityValues, useSimpleLocale } from '@vben-core/composables';
|
||||||
import { Expand, Shrink } from '@vben-core/icons';
|
import { Expand, Shrink } from '@vben-core/icons';
|
||||||
|
|
@ -53,10 +44,6 @@ const headerRef = ref();
|
||||||
// @ts-expect-error unused
|
// @ts-expect-error unused
|
||||||
const footerRef = ref();
|
const footerRef = ref();
|
||||||
|
|
||||||
const id = useId();
|
|
||||||
|
|
||||||
provide('DISMISSABLE_MODAL_ID', id);
|
|
||||||
|
|
||||||
const { $t } = useSimpleLocale();
|
const { $t } = useSimpleLocale();
|
||||||
const state = props.modalApi?.useStore?.();
|
const state = props.modalApi?.useStore?.();
|
||||||
|
|
||||||
|
|
@ -194,15 +181,8 @@ function handleOpenAutoFocus(e: Event) {
|
||||||
|
|
||||||
// pointer-down-outside
|
// pointer-down-outside
|
||||||
function pointerDownOutside(e: Event) {
|
function pointerDownOutside(e: Event) {
|
||||||
const target = e.target as HTMLElement;
|
if (!closeOnClickModal.value || submitting.value) {
|
||||||
const isDismissableModal = target?.dataset.dismissableModal;
|
|
||||||
if (
|
|
||||||
!closeOnClickModal.value ||
|
|
||||||
isDismissableModal !== id ||
|
|
||||||
submitting.value
|
|
||||||
) {
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -211,6 +191,10 @@ function handleFocusOutside(e: Event) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCloseAutoFocus(_e: Event) {
|
||||||
|
// allow reka-ui to return focus to the trigger element on close
|
||||||
|
}
|
||||||
|
|
||||||
const getForceMount = computed(() => {
|
const getForceMount = computed(() => {
|
||||||
return !unref(destroyOnClose) && unref(firstOpened);
|
return !unref(destroyOnClose) && unref(firstOpened);
|
||||||
});
|
});
|
||||||
|
|
@ -228,7 +212,7 @@ function handleClosed() {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Dialog
|
<Dialog
|
||||||
:modal="false"
|
:modal="modal"
|
||||||
:open="state?.isOpen"
|
:open="state?.isOpen"
|
||||||
@update:open="() => (!submitting ? modalApi?.close() : undefined)"
|
@update:open="() => (!submitting ? modalApi?.close() : undefined)"
|
||||||
>
|
>
|
||||||
|
|
@ -261,7 +245,7 @@ function handleClosed() {
|
||||||
:z-index="zIndex"
|
:z-index="zIndex"
|
||||||
:overlay-blur="overlayBlur"
|
:overlay-blur="overlayBlur"
|
||||||
close-class="top-3"
|
close-class="top-3"
|
||||||
@close-auto-focus="handleFocusOutside"
|
@close-auto-focus="handleCloseAutoFocus"
|
||||||
@closed="handleClosed"
|
@closed="handleClosed"
|
||||||
:close-disabled="submitting"
|
:close-disabled="submitting"
|
||||||
@escape-key-down="escapeKeyDown"
|
@escape-key-down="escapeKeyDown"
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,16 @@ import type { ClassType } from '@vben-core/typings';
|
||||||
|
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
|
|
||||||
import { useScrollLock } from '@vben-core/composables';
|
|
||||||
import { cn } from '@vben-core/shared/utils';
|
import { cn } from '@vben-core/shared/utils';
|
||||||
|
|
||||||
import { X } from '@lucide/vue';
|
import { X } from '@lucide/vue';
|
||||||
import { DialogClose, DialogContent, useForwardPropsEmits } from 'reka-ui';
|
import {
|
||||||
|
DialogClose,
|
||||||
import DialogOverlay from './DialogOverlay.vue';
|
DialogContent,
|
||||||
|
DialogOverlay,
|
||||||
|
DialogPortal,
|
||||||
|
useForwardPropsEmits,
|
||||||
|
} from 'reka-ui';
|
||||||
|
|
||||||
const props = withDefaults(
|
const props = withDefaults(
|
||||||
defineProps<
|
defineProps<
|
||||||
|
|
@ -64,8 +67,6 @@ const position = computed(() => {
|
||||||
return isAppendToBody() ? 'fixed' : 'absolute';
|
return isAppendToBody() ? 'fixed' : 'absolute';
|
||||||
});
|
});
|
||||||
|
|
||||||
useScrollLock();
|
|
||||||
|
|
||||||
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
||||||
|
|
||||||
const contentRef = ref<InstanceType<typeof DialogContent> | null>(null);
|
const contentRef = ref<InstanceType<typeof DialogContent> | null>(null);
|
||||||
|
|
@ -85,19 +86,21 @@ defineExpose({
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Teleport defer :to="appendTo">
|
<DialogPortal :to="appendTo">
|
||||||
<Transition name="fade">
|
<DialogOverlay
|
||||||
<DialogOverlay
|
v-if="open && modal"
|
||||||
v-if="open && modal"
|
:style="{
|
||||||
:style="{
|
...(zIndex ? { zIndex } : {}),
|
||||||
...(zIndex ? { zIndex } : {}),
|
position,
|
||||||
position,
|
backdropFilter:
|
||||||
backdropFilter:
|
overlayBlur && overlayBlur > 0 ? `blur(${overlayBlur}px)` : 'none',
|
||||||
overlayBlur && overlayBlur > 0 ? `blur(${overlayBlur}px)` : 'none',
|
}"
|
||||||
}"
|
:class="
|
||||||
@click="() => emits('close')"
|
cn(
|
||||||
/>
|
'z-popup bg-overlay inset-0 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed',
|
||||||
</Transition>
|
)
|
||||||
|
"
|
||||||
|
/>
|
||||||
<DialogContent
|
<DialogContent
|
||||||
ref="contentRef"
|
ref="contentRef"
|
||||||
:style="{ ...(zIndex ? { zIndex } : {}), position }"
|
:style="{ ...(zIndex ? { zIndex } : {}), position }"
|
||||||
|
|
@ -130,5 +133,5 @@ defineExpose({
|
||||||
<X class="h-4 w-4" />
|
<X class="h-4 w-4" />
|
||||||
</DialogClose>
|
</DialogClose>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Teleport>
|
</DialogPortal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -1,31 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script lang="ts">
|
||||||
import type { DialogOverlayProps } from 'reka-ui';
|
|
||||||
|
|
||||||
import type { HTMLAttributes } from 'vue';
|
|
||||||
|
|
||||||
import { cn } from '@vben-core/shared/utils';
|
|
||||||
|
|
||||||
import { reactiveOmit } from '@vueuse/core';
|
|
||||||
import { DialogOverlay } from 'reka-ui';
|
import { DialogOverlay } from 'reka-ui';
|
||||||
|
|
||||||
const props = defineProps<
|
export default DialogOverlay;
|
||||||
DialogOverlayProps & { class?: HTMLAttributes['class'] }
|
|
||||||
>();
|
|
||||||
|
|
||||||
const delegatedProps = reactiveOmit(props, 'class');
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<DialogOverlay
|
|
||||||
data-slot="dialog-overlay"
|
|
||||||
v-bind="delegatedProps"
|
|
||||||
:class="
|
|
||||||
cn(
|
|
||||||
'z-popup bg-overlay inset-0 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed',
|
|
||||||
props.class,
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
|
||||||
</DialogOverlay>
|
|
||||||
</template>
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue