Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: modal&drawer support appendToMain and zIndex #5091

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/src/components/common-ui/vben-drawer.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ const [Drawer, drawerApi] = useVbenDrawer({

| 属性名 | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| appendToMain | 是否挂载到内容区域(默认挂载到body) | `boolean` | `false` |
| title | 标题 | `string\|slot` | - |
| titleTooltip | 标题提示信息 | `string\|slot` | - |
| description | 描述信息 | `string\|slot` | - |
Expand All @@ -95,6 +96,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
| contentClass | modal内容区域的class | `string` | - |
| footerClass | modal底部区域的class | `string` | - |
| headerClass | modal顶部区域的class | `string` | - |
| zIndex | 抽屉的ZIndex层级 | `number` | `1000` |

### Event

Expand Down
2 changes: 2 additions & 0 deletions docs/src/components/common-ui/vben-modal.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const [Modal, modalApi] = useVbenModal({

| 属性名 | 描述 | 类型 | 默认值 |
| --- | --- | --- | --- |
| appendToMain | 是否挂载到内容区域(默认挂载到body) | `boolean` | `false` |
| title | 标题 | `string\|slot` | - |
| titleTooltip | 标题提示信息 | `string\|slot` | - |
| description | 描述信息 | `string\|slot` | - |
Expand All @@ -106,6 +107,7 @@ const [Modal, modalApi] = useVbenModal({
| footerClass | modal底部区域的class | `string` | - |
| headerClass | modal顶部区域的class | `string` | - |
| bordered | 是否显示border | `boolean` | `false` |
| zIndex | 抽屉的ZIndex层级 | `number` | `1000` |

### Event

Expand Down
3 changes: 3 additions & 0 deletions packages/@core/base/shared/src/constants/globals.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ export const CSS_VARIABLE_LAYOUT_HEADER_HEIGHT = `--vben-header-height`;
/** layout footer 组件的高度 */
export const CSS_VARIABLE_LAYOUT_FOOTER_HEIGHT = `--vben-footer-height`;

/** 内容区域的组件ID */
export const ELEMENT_ID_MAIN_CONTENT = `__vben_main_content`;

/**
* @zh_CN 默认命名空间
*/
Expand Down
1 change: 1 addition & 0 deletions packages/@core/ui-kit/layout-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"@vben-core/composables": "workspace:*",
"@vben-core/icons": "workspace:*",
"@vben-core/shadcn-ui": "workspace:*",
"@vben-core/shared": "workspace:*",
"@vben-core/typings": "workspace:*",
"@vueuse/core": "catalog:",
"vue": "catalog:"
Expand Down
4 changes: 4 additions & 0 deletions packages/@core/ui-kit/layout-ui/src/vben-layout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from '@vben-core/composables';
import { Menu } from '@vben-core/icons';
import { VbenIconButton } from '@vben-core/shadcn-ui';
import { ELEMENT_ID_MAIN_CONTENT } from '@vben-core/shared/constants';

import { useMouse, useScroll, useThrottleFn } from '@vueuse/core';

Expand Down Expand Up @@ -457,6 +458,8 @@ function handleHeaderToggle() {
emit('toggleSidebar');
}
}

const idMainContent = ELEMENT_ID_MAIN_CONTENT;
</script>

<template>
Expand Down Expand Up @@ -553,6 +556,7 @@ function handleHeaderToggle() {

<!-- </div> -->
<LayoutContent
:id="idMainContent"
:content-compact="contentCompact"
:content-compact-width="contentCompactWidth"
:padding="contentPadding"
Expand Down
13 changes: 11 additions & 2 deletions packages/@core/ui-kit/popup-ui/src/drawer/drawer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ import type { Component, Ref } from 'vue';
export type DrawerPlacement = 'bottom' | 'left' | 'right' | 'top';

export interface DrawerProps {
/**
* 是否挂载到内容区域
* @default false
*/
appendToMain?: boolean;
/**
* 取消按钮文字
*/
Expand Down Expand Up @@ -59,12 +64,12 @@ export interface DrawerProps {
* 弹窗头部样式
*/
headerClass?: ClassType;

/**
* 弹窗是否显示
* @default false
*/
loading?: boolean;

/**
* 是否显示遮罩
* @default true
Expand All @@ -74,12 +79,12 @@ export interface DrawerProps {
* 是否自动聚焦
*/
openAutoFocus?: boolean;

/**
* 抽屉位置
* @default right
*/
placement?: DrawerPlacement;

/**
* 是否显示取消按钮
* @default true
Expand All @@ -98,6 +103,10 @@ export interface DrawerProps {
* 弹窗标题提示
*/
titleTooltip?: string;
/**
* 抽屉层级
*/
zIndex?: number;
}

export interface DrawerState extends DrawerProps {
Expand Down
13 changes: 12 additions & 1 deletion packages/@core/ui-kit/popup-ui/src/drawer/drawer.vue
Original file line number Diff line number Diff line change
@@ -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,
Expand All @@ -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';

Expand All @@ -31,7 +32,9 @@ interface Props extends DrawerProps {
}

const props = withDefaults(defineProps<Props>(), {
appendToMain: false,
drawerApi: undefined,
zIndex: 1000,
});

const components = globalShareState.getComponents();
Expand All @@ -46,6 +49,7 @@ const { isMobile } = useIsMobile();
const state = props.drawerApi?.useStore?.();

const {
appendToMain,
cancelText,
class: drawerClass,
closable,
Expand All @@ -67,6 +71,7 @@ const {
showConfirmButton,
title,
titleTooltip,
zIndex,
} = usePriorityValues(props, state);

watch(
Expand Down Expand Up @@ -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
Expand All @@ -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',
Expand All @@ -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"
Expand Down
11 changes: 10 additions & 1 deletion packages/@core/ui-kit/popup-ui/src/modal/modal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -12,14 +17,14 @@ export interface ModalProps {
* 取消按钮文字
*/
cancelText?: string;

/**
* 是否居中
* @default false
*/
centered?: boolean;

class?: string;

/**
* 是否显示右上角的关闭按钮
* @default true
Expand Down Expand Up @@ -112,6 +117,10 @@ export interface ModalProps {
* 弹窗标题提示
*/
titleTooltip?: string;
/**
* 弹窗层级
*/
zIndex?: number;
}

export interface ModalState extends ModalProps {
Expand Down
9 changes: 9 additions & 0 deletions packages/@core/ui-kit/popup-ui/src/modal/modal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand All @@ -32,6 +33,7 @@ interface Props extends ModalProps {
}

const props = withDefaults(defineProps<Props>(), {
appendToMain: false,
modalApi: undefined,
});

Expand All @@ -52,6 +54,7 @@ const { isMobile } = useIsMobile();
const state = props.modalApi?.useStore?.();

const {
appendToMain,
bordered,
cancelText,
centered,
Expand All @@ -78,6 +81,7 @@ const {
showConfirmButton,
title,
titleTooltip,
zIndex,
} = usePriorityValues(props, state);

const shouldFullscreen = computed(
Expand Down Expand Up @@ -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
Expand All @@ -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)]',
Expand All @@ -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()"
Expand Down
15 changes: 11 additions & 4 deletions packages/@core/ui-kit/shadcn-ui/src/ui/dialog/DialogContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,16 @@ import DialogOverlay from './DialogOverlay.vue';
const props = withDefaults(
defineProps<
{
appendTo?: HTMLElement | string;
class?: ClassType;
closeClass?: ClassType;
modal?: boolean;
open?: boolean;
showClose?: boolean;
zIndex?: number;
} & DialogContentProps
>(),
{ showClose: true },
{ appendTo: 'body', showClose: true, zIndex: 1000 },
mynetfan marked this conversation as resolved.
Show resolved Hide resolved
);
const emits = defineEmits<
{ close: []; closed: []; opened: [] } & DialogContentEmits
Expand Down Expand Up @@ -64,17 +66,22 @@ defineExpose({
</script>

<template>
<DialogPortal>
<DialogPortal :to="appendTo">
<Transition name="fade">
<DialogOverlay v-if="open && modal" @click="() => emits('close')" />
<DialogOverlay
v-if="open && modal"
:style="{ zIndex }"
@click="() => emits('close')"
/>
</Transition>
<DialogContent
ref="contentRef"
:style="{ zIndex }"
@animationend="onAnimationEnd"
v-bind="forwarded"
:class="
cn(
'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%] fixed z-[1000] w-full p-6 shadow-lg outline-none sm:rounded-xl',
'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%] absolute w-full p-6 shadow-lg outline-none sm:rounded-xl',
props.class,
)
"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,5 @@ useScrollLock();
const id = inject('DISMISSABLE_MODAL_ID');
</script>
<template>
<div
:data-dismissable-modal="id"
class="bg-overlay fixed inset-0 z-[1000]"
></div>
<div :data-dismissable-modal="id" class="bg-overlay absolute inset-0"></div>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ import {
useForwardPropsEmits,
} from 'radix-vue';

const props = defineProps<{ class?: any } & DialogContentProps>();
const props = withDefaults(
defineProps<{ class?: any; zIndex?: number } & DialogContentProps>(),
{ zIndex: 1000 },
);
const emits = defineEmits<DialogContentEmits>();

const delegatedProps = computed(() => {
Expand All @@ -29,7 +32,8 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
<template>
<DialogPortal>
<DialogOverlay
class="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border fixed inset-0 z-[1000] grid place-items-center overflow-y-auto border bg-black/80"
:style="{ zIndex }"
class="data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 border-border absolute inset-0 grid place-items-center overflow-y-auto border bg-black/80"
>
<DialogContent
:class="
Expand All @@ -38,6 +42,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
props.class,
)
"
:style="{ zIndex }"
v-bind="forwarded"
@pointer-down-outside="
(event) => {
Expand Down
Loading
Loading