feat: modal&drawer support appendToMain and zIndex (#5092)
* feat: modal/drawer support append to main content * feat: modal zIndex support * fix: drawer prop define * chore: type * fix: modal/drawer position fixed while append to body * docs: typo * chore: add full-width drawer in content area * chore: remove unnecessary class
This commit is contained in:
@@ -7,6 +7,11 @@ import type { Component, Ref } from 'vue';
|
||||
export type DrawerPlacement = 'bottom' | 'left' | 'right' | 'top';
|
||||
|
||||
export interface DrawerProps {
|
||||
/**
|
||||
* 是否挂载到内容区域
|
||||
* @default false
|
||||
*/
|
||||
appendToMain?: boolean;
|
||||
/**
|
||||
* 取消按钮文字
|
||||
*/
|
||||
@@ -59,12 +64,12 @@ export interface DrawerProps {
|
||||
* 弹窗头部样式
|
||||
*/
|
||||
headerClass?: ClassType;
|
||||
|
||||
/**
|
||||
* 弹窗是否显示
|
||||
* @default false
|
||||
*/
|
||||
loading?: boolean;
|
||||
|
||||
/**
|
||||
* 是否显示遮罩
|
||||
* @default true
|
||||
@@ -74,12 +79,12 @@ export interface DrawerProps {
|
||||
* 是否自动聚焦
|
||||
*/
|
||||
openAutoFocus?: boolean;
|
||||
|
||||
/**
|
||||
* 抽屉位置
|
||||
* @default right
|
||||
*/
|
||||
placement?: DrawerPlacement;
|
||||
|
||||
/**
|
||||
* 是否显示取消按钮
|
||||
* @default true
|
||||
@@ -98,6 +103,10 @@ export interface DrawerProps {
|
||||
* 弹窗标题提示
|
||||
*/
|
||||
titleTooltip?: string;
|
||||
/**
|
||||
* 抽屉层级
|
||||
*/
|
||||
zIndex?: number;
|
||||
}
|
||||
|
||||
export interface DrawerState extends DrawerProps {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
import type { DrawerProps, ExtendedDrawerApi } from './drawer';
|
||||
|
||||
import { provide, ref, useId, watch } from 'vue';
|
||||
import { computed, provide, ref, useId, watch } from 'vue';
|
||||
|
||||
import {
|
||||
useIsMobile,
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
VbenLoading,
|
||||
VisuallyHidden,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
import { ELEMENT_ID_MAIN_CONTENT } from '@vben-core/shared/constants';
|
||||
import { globalShareState } from '@vben-core/shared/global-state';
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
@@ -31,7 +32,9 @@ interface Props extends DrawerProps {
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
appendToMain: false,
|
||||
drawerApi: undefined,
|
||||
zIndex: 1000,
|
||||
});
|
||||
|
||||
const components = globalShareState.getComponents();
|
||||
@@ -46,6 +49,7 @@ const { isMobile } = useIsMobile();
|
||||
const state = props.drawerApi?.useStore?.();
|
||||
|
||||
const {
|
||||
appendToMain,
|
||||
cancelText,
|
||||
class: drawerClass,
|
||||
closable,
|
||||
@@ -67,6 +71,7 @@ const {
|
||||
showConfirmButton,
|
||||
title,
|
||||
titleTooltip,
|
||||
zIndex,
|
||||
} = usePriorityValues(props, state);
|
||||
|
||||
watch(
|
||||
@@ -110,6 +115,10 @@ function handleFocusOutside(e: Event) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
const getAppendTo = computed(() => {
|
||||
return appendToMain.value ? `#${ELEMENT_ID_MAIN_CONTENT}` : undefined;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Sheet
|
||||
@@ -118,6 +127,7 @@ function handleFocusOutside(e: Event) {
|
||||
@update:open="() => drawerApi?.close()"
|
||||
>
|
||||
<SheetContent
|
||||
:append-to="getAppendTo"
|
||||
:class="
|
||||
cn('flex w-[520px] flex-col', drawerClass, {
|
||||
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
|
||||
@@ -127,6 +137,7 @@ function handleFocusOutside(e: Event) {
|
||||
:modal="modal"
|
||||
:open="state?.isOpen"
|
||||
:side="placement"
|
||||
:z-index="zIndex"
|
||||
@close-auto-focus="handleFocusOutside"
|
||||
@escape-key-down="escapeKeyDown"
|
||||
@focus-outside="handleFocusOutside"
|
||||
|
@@ -3,6 +3,11 @@ import type { ModalApi } from './modal-api';
|
||||
import type { Component, Ref } from 'vue';
|
||||
|
||||
export interface ModalProps {
|
||||
/**
|
||||
* 是否要挂载到内容区域
|
||||
* @default false
|
||||
*/
|
||||
appendToMain?: boolean;
|
||||
/**
|
||||
* 是否显示边框
|
||||
* @default false
|
||||
@@ -12,7 +17,6 @@ export interface ModalProps {
|
||||
* 取消按钮文字
|
||||
*/
|
||||
cancelText?: string;
|
||||
|
||||
/**
|
||||
* 是否居中
|
||||
* @default false
|
||||
@@ -20,6 +24,7 @@ export interface ModalProps {
|
||||
centered?: boolean;
|
||||
|
||||
class?: string;
|
||||
|
||||
/**
|
||||
* 是否显示右上角的关闭按钮
|
||||
* @default true
|
||||
@@ -112,6 +117,10 @@ export interface ModalProps {
|
||||
* 弹窗标题提示
|
||||
*/
|
||||
titleTooltip?: string;
|
||||
/**
|
||||
* 弹窗层级
|
||||
*/
|
||||
zIndex?: number;
|
||||
}
|
||||
|
||||
export interface ModalState extends ModalProps {
|
||||
|
@@ -22,6 +22,7 @@ import {
|
||||
VbenLoading,
|
||||
VisuallyHidden,
|
||||
} from '@vben-core/shadcn-ui';
|
||||
import { ELEMENT_ID_MAIN_CONTENT } from '@vben-core/shared/constants';
|
||||
import { globalShareState } from '@vben-core/shared/global-state';
|
||||
import { cn } from '@vben-core/shared/utils';
|
||||
|
||||
@@ -32,6 +33,7 @@ interface Props extends ModalProps {
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
appendToMain: false,
|
||||
modalApi: undefined,
|
||||
});
|
||||
|
||||
@@ -52,6 +54,7 @@ const { isMobile } = useIsMobile();
|
||||
const state = props.modalApi?.useStore?.();
|
||||
|
||||
const {
|
||||
appendToMain,
|
||||
bordered,
|
||||
cancelText,
|
||||
centered,
|
||||
@@ -78,6 +81,7 @@ const {
|
||||
showConfirmButton,
|
||||
title,
|
||||
titleTooltip,
|
||||
zIndex,
|
||||
} = usePriorityValues(props, state);
|
||||
|
||||
const shouldFullscreen = computed(
|
||||
@@ -161,6 +165,9 @@ function handleFocusOutside(e: Event) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
const getAppendTo = computed(() => {
|
||||
return appendToMain.value ? `#${ELEMENT_ID_MAIN_CONTENT}` : undefined;
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Dialog
|
||||
@@ -170,6 +177,7 @@ function handleFocusOutside(e: Event) {
|
||||
>
|
||||
<DialogContent
|
||||
ref="contentRef"
|
||||
:append-to="getAppendTo"
|
||||
:class="
|
||||
cn(
|
||||
'left-0 right-0 top-[10vh] mx-auto flex max-h-[80%] w-[520px] flex-col p-0 sm:rounded-[var(--radius)]',
|
||||
@@ -187,6 +195,7 @@ function handleFocusOutside(e: Event) {
|
||||
:modal="modal"
|
||||
:open="state?.isOpen"
|
||||
:show-close="closable"
|
||||
:z-index="zIndex"
|
||||
close-class="top-3"
|
||||
@close-auto-focus="handleFocusOutside"
|
||||
@closed="() => modalApi?.onClosed()"
|
||||
|
Reference in New Issue
Block a user