This commit is contained in:
dap
2025-04-28 13:19:57 +08:00
90 changed files with 380 additions and 260 deletions

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/design",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/icons",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/shared",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,3 +1,4 @@
// eslint-disable-next-line vue/prefer-import-from-vue
import { isFunction, isObject, isString } from '@vue/shared';
/**

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/typings",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/composables",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/preferences",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/form-ui",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/layout-ui",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/menu-ui",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {

View File

@@ -10,7 +10,7 @@ import { VbenIcon } from '@vben-core/shadcn-ui';
import { useMenuContext } from '../hooks';
interface Props extends MenuItemProps {
isMenuMore: boolean;
isMenuMore?: boolean;
isTopLevelMenuSubmenu: boolean;
level?: number;
}

View File

@@ -47,6 +47,10 @@ function onAlertClosed() {
isConfirm.value = false;
}
function onEscapeKeyDown() {
isConfirm.value = false;
}
const getIconRender = computed(() => {
let iconRender: Component | null = null;
if (props.icon) {
@@ -116,13 +120,11 @@ function handleCancel() {
const loading = ref(false);
async function handleOpenChange(val: boolean) {
const confirmState = isConfirm.value;
isConfirm.value = false;
await nextTick();
await nextTick(); // 等待标记isConfirm状态
if (!val && props.beforeClose) {
loading.value = true;
try {
const res = await props.beforeClose({ isConfirm: confirmState });
const res = await props.beforeClose({ isConfirm: isConfirm.value });
if (res !== false) {
open.value = false;
}
@@ -142,6 +144,7 @@ async function handleOpenChange(val: boolean) {
:overlay-blur="overlayBlur"
@opened="emits('opened')"
@closed="onAlertClosed"
@escape-key-down="onEscapeKeyDown"
:class="
cn(
containerClass,

View File

@@ -52,6 +52,10 @@ export interface DrawerProps {
* 弹窗描述
*/
description?: string;
/**
* 在关闭时销毁抽屉
*/
destroyOnClose?: boolean;
/**
* 是否显示底部
* @default true
@@ -143,10 +147,6 @@ export interface DrawerApiOptions extends DrawerState {
* 独立的抽屉组件
*/
connectedComponent?: Component;
/**
* 在关闭时销毁抽屉。仅在使用 connectedComponent 时有效
*/
destroyOnClose?: boolean;
/**
* 关闭前的回调,返回 false 可以阻止关闭
* @returns

View File

@@ -1,7 +1,7 @@
<script lang="ts" setup>
import type { DrawerProps, ExtendedDrawerApi } from './drawer';
import { computed, provide, ref, useId, watch } from 'vue';
import { computed, provide, ref, unref, useId, watch } from 'vue';
import {
useIsMobile,
@@ -35,6 +35,7 @@ interface Props extends DrawerProps {
const props = withDefaults(defineProps<Props>(), {
appendToMain: false,
closeIconPlacement: 'right',
destroyOnClose: true,
drawerApi: undefined,
submitting: false,
zIndex: 1000,
@@ -63,6 +64,7 @@ const {
confirmText,
contentClass,
description,
destroyOnClose,
footer: showFooter,
footerClass,
header: showHeader,
@@ -131,6 +133,29 @@ const getAppendTo = computed(() => {
? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
: undefined;
});
/**
* destroyOnClose功能完善
*/
// 是否打开过
const hasOpened = ref(false);
const isClosed = ref(true);
watch(
() => state?.value?.isOpen,
(value) => {
isClosed.value = false;
if (value && !unref(hasOpened)) {
hasOpened.value = true;
}
},
);
function handleClosed() {
isClosed.value = true;
props.drawerApi?.onClosed();
}
const getForceMount = computed(() => {
return !unref(destroyOnClose) && unref(hasOpened);
});
</script>
<template>
<Sheet
@@ -144,15 +169,17 @@ const getAppendTo = computed(() => {
cn('flex w-[520px] flex-col', drawerClass, {
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
'max-h-[100vh]': placement === 'bottom' || placement === 'top',
hidden: isClosed,
})
"
:modal="modal"
:open="state?.isOpen"
:side="placement"
:z-index="zIndex"
:force-mount="getForceMount"
:overlay-blur="overlayBlur"
@close-auto-focus="handleFocusOutside"
@closed="() => drawerApi?.onClosed()"
@closed="handleClosed"
@escape-key-down="escapeKeyDown"
@focus-outside="handleFocusOutside"
@interact-outside="interactOutside"

View File

@@ -21,7 +21,9 @@ import VbenDrawer from './drawer.vue';
const USER_DRAWER_INJECT_KEY = Symbol('VBEN_DRAWER_INJECT');
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {};
const DEFAULT_DRAWER_PROPS: Partial<DrawerProps> = {
destroyOnClose: true,
};
export function setDefaultDrawerProps(props: Partial<DrawerProps>) {
Object.assign(DEFAULT_DRAWER_PROPS, props);

View File

@@ -17,7 +17,9 @@ import VbenModal from './modal.vue';
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {};
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {
destroyOnClose: true,
};
export function setDefaultModalProps(props: Partial<ModalProps>) {
Object.assign(DEFAULT_MODAL_PROPS, props);
@@ -86,7 +88,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
mergedOptions.onClosed = () => {
options.onClosed?.();
if (options.destroyOnClose) {
if (mergedOptions.destroyOnClose) {
injectData.reCreateModal?.();
}
};

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/shadcn-ui",
"version": "5.5.4",
"version": "5.5.5",
"#main": "./dist/index.mjs",
"#module": "./dist/index.mjs",
"homepage": "https://github.com/vbenjs/vue-vben-admin",

View File

@@ -41,7 +41,6 @@ watch(
innerValue.value.length > 0 ? innerValue.value[0] : undefined;
}
},
{ immediate: true },
);
watch(
@@ -60,7 +59,7 @@ watch(
innerValue.value = val === undefined ? [] : [val as ValueType];
}
},
{ deep: true },
{ deep: true, immediate: true },
);
async function onBtnClick(value: ValueType) {

View File

@@ -10,7 +10,7 @@ import TabsIndicator from './tabs-indicator.vue';
interface Props {
defaultValue?: string;
tabs: SegmentedItem[];
tabs?: SegmentedItem[];
}
const props = withDefaults(defineProps<Props>(), {

View File

@@ -1,4 +1,6 @@
<script lang="ts" setup>
import { CircleX } from '@vben-core/icons';
import {
Select,
SelectContent,
@@ -8,6 +10,7 @@ import {
} from '../../ui';
interface Props {
allowClear?: boolean;
class?: any;
// 弹出层的类名
contentClass?: any;
@@ -15,12 +18,27 @@ interface Props {
placeholder?: string;
}
const props = defineProps<Props>();
const props = withDefaults(defineProps<Props>(), {
allowClear: false,
});
const modelValue = defineModel<string>();
function handleClear() {
modelValue.value = undefined;
}
</script>
<template>
<Select>
<SelectTrigger :class="props.class">
<SelectValue :placeholder="placeholder" />
<Select v-model="modelValue">
<SelectTrigger :class="props.class" class="flex w-full items-center">
<SelectValue class="flex-auto text-left" :placeholder="placeholder" />
<CircleX
@pointerdown.stop
@click.stop.prevent="handleClear"
v-if="allowClear && modelValue"
data-clear-button
class="mr-1 size-4 cursor-pointer opacity-50 hover:opacity-100"
/>
</SelectTrigger>
<SelectContent :class="props.contentClass">
<template v-for="item in options" :key="item.value">

View File

@@ -1,6 +1,6 @@
{
"name": "@vben-core/tabs-ui",
"version": "5.5.4",
"version": "5.5.5",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {