Sfoglia il codice sorgente

feat: optimize modal dragging range(#6414)

* 当弹窗指定了容器时,拖拽将被限制在容器范围内
yuhengshen 3 giorni fa
parent
commit
946f91f387

+ 7 - 5
packages/@core/ui-kit/popup-ui/src/modal/modal.vue

@@ -105,10 +105,17 @@ const shouldDraggable = computed(
   () => draggable.value && !shouldFullscreen.value && header.value,
 );
 
+const getAppendTo = computed(() => {
+  return appendToMain.value
+    ? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
+    : undefined;
+});
+
 const { dragging, transform } = useModalDraggable(
   dialogRef,
   headerRef,
   shouldDraggable,
+  getAppendTo,
 );
 
 const firstOpened = ref(false);
@@ -198,11 +205,6 @@ function handleFocusOutside(e: Event) {
   e.preventDefault();
   e.stopPropagation();
 }
-const getAppendTo = computed(() => {
-  return appendToMain.value
-    ? `#${ELEMENT_ID_MAIN_CONTENT}>div:not(.absolute)>div`
-    : undefined;
-});
 
 const getForceMount = computed(() => {
   return !unref(destroyOnClose) && unref(firstOpened);

+ 26 - 9
packages/@core/ui-kit/popup-ui/src/modal/use-modal-draggable.ts

@@ -13,6 +13,7 @@ export function useModalDraggable(
   targetRef: Ref<HTMLElement | undefined>,
   dragRef: Ref<HTMLElement | undefined>,
   draggable: ComputedRef<boolean>,
+  containerSelector?: ComputedRef<string | undefined>,
 ) {
   const transform = reactive({
     offsetX: 0,
@@ -30,20 +31,36 @@ export function useModalDraggable(
     }
 
     const targetRect = targetRef.value.getBoundingClientRect();
-
     const { offsetX, offsetY } = transform;
     const targetLeft = targetRect.left;
     const targetTop = targetRect.top;
     const targetWidth = targetRect.width;
     const targetHeight = targetRect.height;
-    const docElement = document.documentElement;
-    const clientWidth = docElement.clientWidth;
-    const clientHeight = docElement.clientHeight;
-
-    const minLeft = -targetLeft + offsetX;
-    const minTop = -targetTop + offsetY;
-    const maxLeft = clientWidth - targetLeft - targetWidth + offsetX;
-    const maxTop = clientHeight - targetTop - targetHeight + offsetY;
+
+    let containerRect: DOMRect | null = null;
+
+    if (containerSelector?.value) {
+      const container = document.querySelector(containerSelector.value);
+      if (container) {
+        containerRect = container.getBoundingClientRect();
+      }
+    }
+
+    let maxLeft, maxTop, minLeft, minTop;
+    if (containerRect) {
+      minLeft = containerRect.left - targetLeft + offsetX;
+      maxLeft = containerRect.right - targetLeft - targetWidth + offsetX;
+      minTop = containerRect.top - targetTop + offsetY;
+      maxTop = containerRect.bottom - targetTop - targetHeight + offsetY;
+    } else {
+      const docElement = document.documentElement;
+      const clientWidth = docElement.clientWidth;
+      const clientHeight = docElement.clientHeight;
+      minLeft = -targetLeft + offsetX;
+      minTop = -targetTop + offsetY;
+      maxLeft = clientWidth - targetLeft - targetWidth + offsetX;
+      maxTop = clientHeight - targetTop - targetHeight + offsetY;
+    }
 
     const onMousemove = (e: MouseEvent) => {
       let moveX = offsetX + e.clientX - downX;