chore: code format

This commit is contained in:
xiaojunnuo
2025-06-29 14:09:09 +08:00
parent 04422a4637
commit 4fcfd089d8
644 changed files with 10845 additions and 13184 deletions
@@ -1,13 +1,13 @@
import type { DrawerState } from '../drawer';
import type { DrawerState } from "../drawer";
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { beforeEach, describe, expect, it, vi } from "vitest";
import { DrawerApi } from '../drawer-api';
import { DrawerApi } from "../drawer-api";
// 模拟 Store 类
vi.mock('/@/vben/shared/store', () => {
vi.mock("/@/vben/shared/store", () => {
return {
isFunction: (fn: any) => typeof fn === 'function',
isFunction: (fn: any) => typeof fn === "function",
Store: class {
get state() {
return this._state;
@@ -33,7 +33,7 @@ vi.mock('/@/vben/shared/store', () => {
};
});
describe('drawerApi', () => {
describe("drawerApi", () => {
let drawerApi: DrawerApi;
let drawerState: DrawerState;
@@ -42,24 +42,24 @@ describe('drawerApi', () => {
drawerState = drawerApi.store.state;
});
it('should initialize with default state', () => {
it("should initialize with default state", () => {
expect(drawerState.isOpen).toBe(false);
expect(drawerState.cancelText).toBe(undefined);
expect(drawerState.confirmText).toBe(undefined);
});
it('should open the drawer', () => {
it("should open the drawer", () => {
drawerApi.open();
expect(drawerApi.store.state.isOpen).toBe(true);
});
it('should close the drawer if onBeforeClose allows it', () => {
it("should close the drawer if onBeforeClose allows it", () => {
drawerApi.open();
drawerApi.close();
expect(drawerApi.store.state.isOpen).toBe(false);
});
it('should not close the drawer if onBeforeClose returns false', () => {
it("should not close the drawer if onBeforeClose returns false", () => {
const onBeforeClose = vi.fn(() => false);
const drawerApiWithHook = new DrawerApi({ onBeforeClose });
drawerApiWithHook.open();
@@ -68,7 +68,7 @@ describe('drawerApi', () => {
expect(onBeforeClose).toHaveBeenCalled();
});
it('should trigger onCancel and keep drawer open if onCancel is provided', () => {
it("should trigger onCancel and keep drawer open if onCancel is provided", () => {
const onCancel = vi.fn();
const drawerApiWithHook = new DrawerApi({ onCancel });
drawerApiWithHook.open();
@@ -77,37 +77,37 @@ describe('drawerApi', () => {
expect(drawerApiWithHook.store.state.isOpen).toBe(true); // 关闭逻辑不在 onCancel 内
});
it('should update shared data correctly', () => {
const testData = { key: 'value' };
it("should update shared data correctly", () => {
const testData = { key: "value" };
drawerApi.setData(testData);
expect(drawerApi.getData()).toEqual(testData);
});
it('should set state correctly using an object', () => {
drawerApi.setState({ title: 'New Title' });
expect(drawerApi.store.state.title).toBe('New Title');
it("should set state correctly using an object", () => {
drawerApi.setState({ title: "New Title" });
expect(drawerApi.store.state.title).toBe("New Title");
});
it('should set state correctly using a function', () => {
drawerApi.setState((prev) => ({ ...prev, confirmText: 'Yes' }));
expect(drawerApi.store.state.confirmText).toBe('Yes');
it("should set state correctly using a function", () => {
drawerApi.setState(prev => ({ ...prev, confirmText: "Yes" }));
expect(drawerApi.store.state.confirmText).toBe("Yes");
});
it('should call onOpenChange when state changes', () => {
it("should call onOpenChange when state changes", () => {
const onOpenChange = vi.fn();
const drawerApiWithHook = new DrawerApi({ onOpenChange });
drawerApiWithHook.open();
expect(onOpenChange).toHaveBeenCalledWith(true);
});
it('should call onClosed callback when provided', () => {
it("should call onClosed callback when provided", () => {
const onClosed = vi.fn();
const drawerApiWithHook = new DrawerApi({ onClosed });
drawerApiWithHook.onClosed();
expect(onClosed).toHaveBeenCalled();
});
it('should call onOpened callback when provided', () => {
it("should call onOpened callback when provided", () => {
const onOpened = vi.fn();
const drawerApiWithHook = new DrawerApi({ onOpened });
drawerApiWithHook.open();
@@ -6,7 +6,7 @@ import { bindMethods, isFunction } from "/@/vben/shared/utils";
export class DrawerApi {
// 共享数据
public sharedData: Record<"payload", any> = {
payload: {}
payload: {},
};
public store: Store<DrawerState>;
@@ -34,13 +34,13 @@ export class DrawerApi {
placement: "right",
showCancelButton: true,
showConfirmButton: true,
title: ""
title: "",
};
this.store = new Store<DrawerState>(
{
...defaultState,
...storeState
...storeState,
},
{
onUpdate: () => {
@@ -51,7 +51,7 @@ export class DrawerApi {
this.state = state;
this.api.onOpenChange?.(!!state?.isOpen);
}
}
},
}
);
this.state = this.store.state;
@@ -61,7 +61,7 @@ export class DrawerApi {
onClosed,
onConfirm,
onOpenChange,
onOpened
onOpened,
};
bindMethods(this);
}
@@ -74,7 +74,7 @@ export class DrawerApi {
// 如果 onBeforeClose 返回 false,则不关闭弹窗
const allowClose = this.api.onBeforeClose?.() ?? true;
if (allowClose) {
this.store.setState((prev) => ({ ...prev, isOpen: false }));
this.store.setState(prev => ({ ...prev, isOpen: false }));
}
}
@@ -119,7 +119,7 @@ export class DrawerApi {
}
open() {
this.store.setState((prev) => ({ ...prev, isOpen: true }));
this.store.setState(prev => ({ ...prev, isOpen: true }));
}
setData<T>(payload: T) {
@@ -131,7 +131,7 @@ export class DrawerApi {
if (isFunction(stateOrFn)) {
this.store.setState(stateOrFn);
} else {
this.store.setState((prev) => ({ ...prev, ...stateOrFn }));
this.store.setState(prev => ({ ...prev, ...stateOrFn }));
}
return this;
}
@@ -18,7 +18,7 @@ const props = withDefaults(defineProps<Props>(), {
appendToMain: false,
closeIconPlacement: "right",
drawerApi: undefined,
zIndex: 1000
zIndex: 1000,
});
const components = globalShareState.getComponents();
@@ -57,16 +57,16 @@ const {
showConfirmButton,
title,
titleTooltip,
zIndex
zIndex,
} = usePriorityValues(props, state);
watch(
() => showLoading.value,
(v) => {
v => {
if (v && wrapperRef.value) {
wrapperRef.value.scrollTo({
// behavior: 'smooth',
top: 0
top: 0,
});
}
}
@@ -113,7 +113,7 @@ const getAppendTo = computed(() => {
:class="
cn('flex w-[520px] flex-col', drawerClass, {
'!w-full': isMobile || placement === 'bottom' || placement === 'top',
'max-h-[100vh]': placement === 'bottom' || placement === 'top'
'max-h-[100vh]': placement === 'bottom' || placement === 'top',
})
"
:modal="modal"
@@ -135,7 +135,7 @@ const getAppendTo = computed(() => {
:class="
cn('!flex flex-row items-center justify-between border-b px-6 py-5', headerClass, {
'px-4 py-3': closable,
'pl-2': closable && closeIconPlacement === 'left'
'pl-2': closable && closeIconPlacement === 'left',
})
"
>
@@ -198,7 +198,7 @@ const getAppendTo = computed(() => {
ref="wrapperRef"
:class="
cn('relative flex-1 overflow-y-auto p-3', contentClass, {
'overflow-hidden': showLoading
'overflow-hidden': showLoading,
})
"
>
@@ -1,3 +1,3 @@
export type * from './drawer';
export { default as VbenDrawer } from './drawer.vue';
export { setDefaultDrawerProps, useVbenDrawer } from './use-drawer';
export type * from "./drawer";
export { default as VbenDrawer } from "./drawer.vue";
export { setDefaultDrawerProps, useVbenDrawer } from "./use-drawer";
@@ -36,18 +36,18 @@ export function useVbenDrawer<TParentDrawerProps extends DrawerProps = DrawerPro
isDrawerReady.value = false;
await nextTick();
isDrawerReady.value = true;
}
},
});
checkProps(extendedApi as ExtendedDrawerApi, {
...props,
...attrs,
...slots
...slots,
});
return () => h(isDrawerReady.value ? connectedComponent : "div", { ...props, ...attrs }, slots);
},
{
name: "VbenParentDrawer",
inheritAttrs: false
inheritAttrs: false,
}
);
return [Drawer, extendedApi as ExtendedDrawerApi] as const;
@@ -58,7 +58,7 @@ export function useVbenDrawer<TParentDrawerProps extends DrawerProps = DrawerPro
const mergedOptions = {
...DEFAULT_DRAWER_PROPS,
...injectData.options,
...options
...options,
} as DrawerApiOptions;
mergedOptions.onOpenChange = (isOpen: boolean) => {
@@ -77,7 +77,7 @@ export function useVbenDrawer<TParentDrawerProps extends DrawerProps = DrawerPro
const extendedApi: ExtendedDrawerApi = api as never;
extendedApi.useStore = (selector) => {
extendedApi.useStore = selector => {
return useStore(api.store, selector);
};
@@ -87,7 +87,7 @@ export function useVbenDrawer<TParentDrawerProps extends DrawerProps = DrawerPro
},
{
name: "VbenDrawer",
inheritAttrs: false
inheritAttrs: false,
}
);
injectData.extendApi?.(extendedApi);
@@ -1,2 +1,2 @@
export * from './drawer';
export * from './modal';
export * from "./drawer";
export * from "./modal";
@@ -1,12 +1,12 @@
import type { ModalState } from '../modal';
import type { ModalState } from "../modal";
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { beforeEach, describe, expect, it, vi } from "vitest";
import { ModalApi } from '../modal-api';
import { ModalApi } from "../modal-api";
vi.mock('/@/vben/shared/store', () => {
vi.mock("/@/vben/shared/store", () => {
return {
isFunction: (fn: any) => typeof fn === 'function',
isFunction: (fn: any) => typeof fn === "function",
Store: class {
get state() {
return this._state;
@@ -32,7 +32,7 @@ vi.mock('/@/vben/shared/store', () => {
};
});
describe('modalApi', () => {
describe("modalApi", () => {
let modalApi: ModalApi;
// 使用 modalState 而不是 state
let modalState: ModalState;
@@ -43,23 +43,23 @@ describe('modalApi', () => {
modalState = modalApi.store.state;
});
it('should initialize with default state', () => {
it("should initialize with default state", () => {
expect(modalState.isOpen).toBe(false);
expect(modalState.cancelText).toBe(undefined);
expect(modalState.confirmText).toBe(undefined);
});
it('should open the modal', () => {
it("should open the modal", () => {
modalApi.open();
expect(modalApi.store.state.isOpen).toBe(true);
});
it('should close the modal if onBeforeClose allows it', () => {
it("should close the modal if onBeforeClose allows it", () => {
modalApi.close();
expect(modalApi.store.state.isOpen).toBe(false);
});
it('should not close the modal if onBeforeClose returns false', () => {
it("should not close the modal if onBeforeClose returns false", () => {
const onBeforeClose = vi.fn(() => false);
const modalApiWithHook = new ModalApi({ onBeforeClose });
modalApiWithHook.open();
@@ -68,7 +68,7 @@ describe('modalApi', () => {
expect(onBeforeClose).toHaveBeenCalled();
});
it('should trigger onCancel and close the modal if no onCancel hook is provided', () => {
it("should trigger onCancel and close the modal if no onCancel hook is provided", () => {
const onCancel = vi.fn();
const modalApiWithHook = new ModalApi({ onCancel });
modalApiWithHook.open();
@@ -77,37 +77,37 @@ describe('modalApi', () => {
expect(modalApiWithHook.store.state.isOpen).toBe(true);
});
it('should update shared data correctly', () => {
const testData = { key: 'value' };
it("should update shared data correctly", () => {
const testData = { key: "value" };
modalApi.setData(testData);
expect(modalApi.getData()).toEqual(testData);
});
it('should set state correctly using an object', () => {
modalApi.setState({ title: 'New Title' });
expect(modalApi.store.state.title).toBe('New Title');
it("should set state correctly using an object", () => {
modalApi.setState({ title: "New Title" });
expect(modalApi.store.state.title).toBe("New Title");
});
it('should set state correctly using a function', () => {
modalApi.setState((prev) => ({ ...prev, confirmText: 'Yes' }));
expect(modalApi.store.state.confirmText).toBe('Yes');
it("should set state correctly using a function", () => {
modalApi.setState(prev => ({ ...prev, confirmText: "Yes" }));
expect(modalApi.store.state.confirmText).toBe("Yes");
});
it('should call onOpenChange when state changes', () => {
it("should call onOpenChange when state changes", () => {
const onOpenChange = vi.fn();
const modalApiWithHook = new ModalApi({ onOpenChange });
modalApiWithHook.open();
expect(onOpenChange).toHaveBeenCalledWith(true);
});
it('should call onClosed callback when provided', () => {
it("should call onClosed callback when provided", () => {
const onClosed = vi.fn();
const modalApiWithHook = new ModalApi({ onClosed });
modalApiWithHook.onClosed();
expect(onClosed).toHaveBeenCalled();
});
it('should call onOpened callback when provided', () => {
it("should call onOpened callback when provided", () => {
const onOpened = vi.fn();
const modalApiWithHook = new ModalApi({ onOpened });
modalApiWithHook.open();
@@ -1,3 +1,3 @@
export type * from './modal';
export { default as VbenModal } from './modal.vue';
export { setDefaultModalProps, useVbenModal } from './use-modal';
export type * from "./modal";
export { default as VbenModal } from "./modal.vue";
export { setDefaultModalProps, useVbenModal } from "./use-modal";
@@ -1,63 +1,46 @@
import type { ModalApiOptions, ModalState } from './modal';
import type { ModalApiOptions, ModalState } from "./modal";
import { Store } from '/@/vben/shared/store';
import { bindMethods, isFunction } from '/@/vben/shared/utils';
import { Store } from "/@/vben/shared/store";
import { bindMethods, isFunction } from "/@/vben/shared/utils";
export class ModalApi {
// 共享数据
public sharedData: Record<'payload', any> = {
public sharedData: Record<"payload", any> = {
payload: {},
};
public store: Store<ModalState>;
private api: Pick<
ModalApiOptions,
| 'onBeforeClose'
| 'onCancel'
| 'onClosed'
| 'onConfirm'
| 'onOpenChange'
| 'onOpened'
>;
private api: Pick<ModalApiOptions, "onBeforeClose" | "onCancel" | "onClosed" | "onConfirm" | "onOpenChange" | "onOpened">;
// private prevState!: ModalState;
private state!: ModalState;
constructor(options: ModalApiOptions = {}) {
const {
connectedComponent: _,
onBeforeClose,
onCancel,
onClosed,
onConfirm,
onOpenChange,
onOpened,
...storeState
} = options;
const { connectedComponent: _, onBeforeClose, onCancel, onClosed, onConfirm, onOpenChange, onOpened, ...storeState } = options;
const defaultState: ModalState = {
bordered: true,
centered: false,
class: '',
class: "",
closeOnClickModal: true,
closeOnPressEscape: true,
confirmDisabled: false,
confirmLoading: false,
contentClass: '',
contentClass: "",
draggable: false,
footer: true,
footerClass: '',
footerClass: "",
fullscreen: false,
fullscreenButton: true,
header: true,
headerClass: '',
headerClass: "",
isOpen: false,
loading: false,
modal: true,
openAutoFocus: false,
showCancelButton: true,
showConfirmButton: true,
title: '',
title: "",
};
this.store = new Store<ModalState>(
@@ -77,7 +60,7 @@ export class ModalApi {
this.api.onOpenChange?.(!!state?.isOpen);
}
},
},
}
);
this.state = this.store.state;
@@ -102,7 +85,7 @@ export class ModalApi {
// 如果 onBeforeClose 返回 false,则不关闭弹窗
const allowClose = (await this.api.onBeforeClose?.()) ?? true;
if (allowClose) {
this.store.setState((prev) => ({
this.store.setState(prev => ({
...prev,
isOpen: false,
submitting: false,
@@ -160,7 +143,7 @@ export class ModalApi {
}
open() {
this.store.setState((prev) => ({ ...prev, isOpen: true }));
this.store.setState(prev => ({ ...prev, isOpen: true }));
}
setData<T>(payload: T) {
@@ -168,15 +151,11 @@ export class ModalApi {
return this;
}
setState(
stateOrFn:
| ((prev: ModalState) => Partial<ModalState>)
| Partial<ModalState>,
) {
setState(stateOrFn: ((prev: ModalState) => Partial<ModalState>) | Partial<ModalState>) {
if (isFunction(stateOrFn)) {
this.store.setState(stateOrFn);
} else {
this.store.setState((prev) => ({ ...prev, ...stateOrFn }));
this.store.setState(prev => ({ ...prev, ...stateOrFn }));
}
return this;
}
@@ -1,8 +1,8 @@
import type { Component, Ref } from 'vue';
import type { Component, Ref } from "vue";
import type { MaybePromise } from '/@/vben/typings';
import type { MaybePromise } from "/@/vben/typings";
import type { ModalApi } from './modal-api';
import type { ModalApi } from "./modal-api";
export interface ModalProps {
/**
@@ -143,9 +143,7 @@ export interface ModalState extends ModalProps {
}
export type ExtendedModalApi = ModalApi & {
useStore: <T = NoInfer<ModalState>>(
selector?: (state: NoInfer<ModalState>) => T,
) => Readonly<Ref<T>>;
useStore: <T = NoInfer<ModalState>>(selector?: (state: NoInfer<ModalState>) => T) => Readonly<Ref<T>>;
};
export interface ModalApiOptions extends ModalState {
@@ -1,32 +1,16 @@
<script lang="ts" setup>
import type { ExtendedModalApi, ModalProps } from './modal';
import type { ExtendedModalApi, ModalProps } from "./modal";
import { computed, nextTick, provide, ref, useId, watch } from 'vue';
import { computed, nextTick, provide, ref, useId, watch } from "vue";
import {
useIsMobile,
usePriorityValues,
useSimpleLocale,
} from '/@/vben/composables';
import { Expand, Shrink } from '/@/vben/icons';
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
VbenButton,
VbenHelpTooltip,
VbenIconButton,
VbenLoading,
VisuallyHidden,
} from '/@/vben/shadcn-ui';
import { ELEMENT_ID_MAIN_CONTENT } from '/@/vben/shared/constants';
import { globalShareState } from '/@/vben/shared/global-state';
import { cn } from '/@/vben/shared/utils';
import { useIsMobile, usePriorityValues, useSimpleLocale } from "/@/vben/composables";
import { Expand, Shrink } from "/@/vben/icons";
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, VbenButton, VbenHelpTooltip, VbenIconButton, VbenLoading, VisuallyHidden } from "/@/vben/shadcn-ui";
import { ELEMENT_ID_MAIN_CONTENT } from "/@/vben/shared/constants";
import { globalShareState } from "/@/vben/shared/global-state";
import { cn } from "/@/vben/shared/utils";
import { useModalDraggable } from './use-modal-draggable';
import { useModalDraggable } from "./use-modal-draggable";
interface Props extends ModalProps {
modalApi?: ExtendedModalApi;
@@ -47,7 +31,7 @@ const footerRef = ref();
const id = useId();
provide('DISMISSABLE_MODAL_ID', id);
provide("DISMISSABLE_MODAL_ID", id);
const { $t } = useSimpleLocale();
const { isMobile } = useIsMobile();
@@ -86,23 +70,15 @@ const {
zIndex,
} = usePriorityValues(props, state);
const shouldFullscreen = computed(
() => (fullscreen.value && header.value) || isMobile.value,
);
const shouldFullscreen = computed(() => (fullscreen.value && header.value) || isMobile.value);
const shouldDraggable = computed(
() => draggable.value && !shouldFullscreen.value && header.value,
);
const shouldDraggable = computed(() => draggable.value && !shouldFullscreen.value && header.value);
const { dragging, transform } = useModalDraggable(
dialogRef,
headerRef,
shouldDraggable,
);
const { dragging, transform } = useModalDraggable(dialogRef, headerRef, shouldDraggable);
watch(
() => state?.value?.isOpen,
async (v) => {
async v => {
if (v) {
await nextTick();
if (!contentRef.value) return;
@@ -112,7 +88,7 @@ watch(
const { offsetX, offsetY } = transform;
dialogRef.value.style.transform = `translate(${offsetX}px, ${offsetY}px)`;
}
},
}
);
watch(
@@ -124,11 +100,11 @@ watch(
top: 0,
});
}
},
}
);
function handleFullscreen() {
props.modalApi?.setState((prev) => {
props.modalApi?.setState(prev => {
// if (prev.fullscreen) {
// resetPosition();
// }
@@ -157,11 +133,7 @@ function handerOpenAutoFocus(e: Event) {
function pointerDownOutside(e: Event) {
const target = e.target as HTMLElement;
const isDismissableModal = target?.dataset.dismissableModal;
if (
!closeOnClickModal.value ||
isDismissableModal !== id ||
submitting.value
) {
if (!closeOnClickModal.value || isDismissableModal !== id || submitting.value) {
e.preventDefault();
e.stopPropagation();
}
@@ -176,27 +148,18 @@ const getAppendTo = computed(() => {
});
</script>
<template>
<Dialog
:modal="false"
:open="state?.isOpen"
@update:open="() => (!submitting ? modalApi?.close() : undefined)"
>
<Dialog :modal="false" :open="state?.isOpen" @update:open="() => (!submitting ? modalApi?.close() : undefined)">
<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)]',
modalClass,
{
'border-border border': bordered,
'shadow-3xl': !bordered,
'left-0 top-0 size-full max-h-full !translate-x-0 !translate-y-0':
shouldFullscreen,
'top-1/2 !-translate-y-1/2': centered && !shouldFullscreen,
'duration-300': !dragging,
},
)
cn('left-0 right-0 top-[10vh] mx-auto flex max-h-[80%] w-[520px] flex-col p-0 sm:rounded-[var(--radius)]', modalClass, {
'border-border border': bordered,
'shadow-3xl': !bordered,
'left-0 top-0 size-full max-h-full !translate-x-0 !translate-y-0': shouldFullscreen,
'top-1/2 !-translate-y-1/2': centered && !shouldFullscreen,
'duration-300': !dragging,
})
"
:modal="modal"
:open="state?.isOpen"
@@ -223,7 +186,7 @@ const getAppendTo = computed(() => {
hidden: !header,
'cursor-move select-none': shouldDraggable,
},
headerClass,
headerClass
)
"
>
@@ -256,11 +219,7 @@ const getAppendTo = computed(() => {
})
"
>
<VbenLoading
v-if="showLoading || submitting"
class="size-full h-auto min-h-full"
spinning
/>
<VbenLoading v-if="showLoading || submitting" class="size-full h-auto min-h-full" spinning />
<slot></slot>
</div>
@@ -282,33 +241,21 @@ const getAppendTo = computed(() => {
{
'border-t': bordered,
},
footerClass,
footerClass
)
"
>
<slot name="prepend-footer"></slot>
<slot name="footer">
<component
:is="components.DefaultButton || VbenButton"
v-if="showCancelButton"
variant="ghost"
:disabled="submitting"
@click="() => modalApi?.onCancel()"
>
<component :is="components.DefaultButton || VbenButton" v-if="showCancelButton" variant="ghost" :disabled="submitting" @click="() => modalApi?.onCancel()">
<slot name="cancelText">
{{ cancelText || $t('cancel') }}
{{ cancelText || $t("cancel") }}
</slot>
</component>
<component
:is="components.PrimaryButton || VbenButton"
v-if="showConfirmButton"
:disabled="confirmDisabled"
:loading="confirmLoading || submitting"
@click="() => modalApi?.onConfirm()"
>
<component :is="components.PrimaryButton || VbenButton" v-if="showConfirmButton" :disabled="confirmDisabled" :loading="confirmLoading || submitting" @click="() => modalApi?.onConfirm()">
<slot name="confirmText">
{{ confirmText || $t('confirm') }}
{{ confirmText || $t("confirm") }}
</slot>
</component>
</slot>
@@ -3,17 +3,13 @@
* 调整部分细节
*/
import type { ComputedRef, Ref } from 'vue';
import type { ComputedRef, Ref } from "vue";
import { onBeforeUnmount, onMounted, reactive, ref, watchEffect } from 'vue';
import { onBeforeUnmount, onMounted, reactive, ref, watchEffect } from "vue";
import { unrefElement } from '@vueuse/core';
import { unrefElement } from "@vueuse/core";
export function useModalDraggable(
targetRef: Ref<HTMLElement | undefined>,
dragRef: Ref<HTMLElement | undefined>,
draggable: ComputedRef<boolean>,
) {
export function useModalDraggable(targetRef: Ref<HTMLElement | undefined>, dragRef: Ref<HTMLElement | undefined>, draggable: ComputedRef<boolean>) {
const transform = reactive({
offsetX: 0,
offsetY: 0,
@@ -63,25 +59,25 @@ export function useModalDraggable(
const onMouseup = () => {
dragging.value = false;
document.removeEventListener('mousemove', onMousemove);
document.removeEventListener('mouseup', onMouseup);
document.removeEventListener("mousemove", onMousemove);
document.removeEventListener("mouseup", onMouseup);
};
document.addEventListener('mousemove', onMousemove);
document.addEventListener('mouseup', onMouseup);
document.addEventListener("mousemove", onMousemove);
document.addEventListener("mouseup", onMouseup);
};
const onDraggable = () => {
const dragDom = unrefElement(dragRef);
if (dragDom && targetRef.value) {
dragDom.addEventListener('mousedown', onMousedown);
dragDom.addEventListener("mousedown", onMousedown);
}
};
const offDraggable = () => {
const dragDom = unrefElement(dragRef);
if (dragDom && targetRef.value) {
dragDom.removeEventListener('mousedown', onMousedown);
dragDom.removeEventListener("mousedown", onMousedown);
}
};
@@ -91,7 +87,7 @@ export function useModalDraggable(
const target = unrefElement(targetRef);
if (target) {
target.style.transform = 'none';
target.style.transform = "none";
}
};
@@ -1,21 +1,13 @@
import type { ExtendedModalApi, ModalApiOptions, ModalProps } from './modal';
import type { ExtendedModalApi, ModalApiOptions, ModalProps } from "./modal";
import {
defineComponent,
h,
inject,
nextTick,
provide,
reactive,
ref,
} from 'vue';
import { defineComponent, h, inject, nextTick, provide, reactive, ref } from "vue";
import { useStore } from '/@/vben/shared/store';
import { useStore } from "/@/vben/shared/store";
import { ModalApi } from './modal-api';
import VbenModal from './modal.vue';
import { ModalApi } from "./modal-api";
import VbenModal from "./modal.vue";
const USER_MODAL_INJECT_KEY = Symbol('VBEN_MODAL_INJECT');
const USER_MODAL_INJECT_KEY = Symbol("VBEN_MODAL_INJECT");
const DEFAULT_MODAL_PROPS: Partial<ModalProps> = {};
@@ -23,9 +15,7 @@ export function setDefaultModalProps(props: Partial<ModalProps>) {
Object.assign(DEFAULT_MODAL_PROPS, props);
}
export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
options: ModalApiOptions = {},
) {
export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(options: ModalApiOptions = {}) {
// Modal一般会抽离出来,所以如果有传入 connectedComponent,则表示为外部调用,与内部组件进行连接
// 外部的Modal通过provide/inject传递api
@@ -55,18 +45,18 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
});
return () =>
h(
isModalReady.value ? connectedComponent : 'div',
isModalReady.value ? connectedComponent : "div",
{
...props,
...attrs,
},
slots,
slots
);
},
{
inheritAttrs: false,
name: 'VbenParentModal',
},
name: "VbenParentModal",
}
);
return [Modal, extendedApi as ExtendedModalApi] as const;
}
@@ -96,7 +86,7 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
const extendedApi: ExtendedModalApi = api as never;
extendedApi.useStore = (selector) => {
extendedApi.useStore = selector => {
return useStore(api.store, selector);
};
@@ -110,13 +100,13 @@ export function useVbenModal<TParentModalProps extends ModalProps = ModalProps>(
...attrs,
modalApi: extendedApi,
},
slots,
slots
);
},
{
inheritAttrs: false,
name: 'VbenModal',
},
name: "VbenModal",
}
);
injectData.extendApi?.(extendedApi);
return [Modal, extendedApi] as const;
@@ -137,11 +127,9 @@ async function checkProps(api: ExtendedModalApi, attrs: Record<string, any>) {
const stateKeys = new Set(Object.keys(state));
for (const attr of Object.keys(attrs)) {
if (stateKeys.has(attr) && !['class'].includes(attr)) {
if (stateKeys.has(attr) && !["class"].includes(attr)) {
// connectedComponent存在时,不要传入Modal的props,会造成复杂度提升,如果你需要修改Modal的props,请使用 useModal 或者api
console.warn(
`[Vben Modal]: When 'connectedComponent' exists, do not set props or slots '${attr}', which will increase complexity. If you need to modify the props of Modal, please use useVbenModal or api.`,
);
console.warn(`[Vben Modal]: When 'connectedComponent' exists, do not set props or slots '${attr}', which will increase complexity. If you need to modify the props of Modal, please use useVbenModal or api.`);
}
}
}