Skip to content

Commit

Permalink
fix(drawer): 解决Drawer抽屉在拖拽改变大小的时候获取宽度可能不正确的问题
Browse files Browse the repository at this point in the history
解决Drawer抽屉在拖拽改变大小的时候获取宽度可能不正确的问题
  • Loading branch information
wonkzhang committed Mar 7, 2025
1 parent 64e91ed commit 23bb7d1
Showing 1 changed file with 48 additions and 36 deletions.
84 changes: 48 additions & 36 deletions packages/components/drawer/hooks/useDrag.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, useState } from 'react';
import { useCallback, useMemo, useRef, useState } from 'react';
import { TdDrawerProps } from '../type';
import { Styles } from '../../common';
import { getSizeDraggable, calcMoveSize } from '../../../common/js/drawer/utils';
Expand All @@ -9,36 +9,43 @@ const useDrag = (
onSizeDragEnd: TdDrawerProps['onSizeDragEnd'],
) => {
const [dragSizeValue, changeDragSizeValue] = useState<string>(null);
// 使用 ref 来存储当前拖拽的宽度值
const dragSizeNumberRef = useRef<number>(0);

const handleMousemove = (e: MouseEvent) => {
// 鼠标移动时计算draggedSizeValue的值
const { x, y } = e;
const handleMousemove = useCallback(
(e: MouseEvent) => {
// 鼠标移动时计算draggedSizeValue的值
const { x, y } = e;

const maxHeight = document.documentElement.clientHeight;
const maxWidth = document.documentElement.clientWidth;
const offsetHeight = 8;
const offsetWidth = 8;
// x 轴方向使用最大宽度,y轴方向使用最大高度
const max = placement === 'left' || placement === 'right' ? maxWidth : maxHeight;
// x 轴方向使用默认最小宽度,y轴方向使用默认最小高度
const min = placement === 'left' || placement === 'right' ? offsetWidth : offsetHeight;
const maxHeight = document.documentElement.clientHeight;
const maxWidth = document.documentElement.clientWidth;
const offsetHeight = 8;
const offsetWidth = 8;
// x 轴方向使用最大宽度,y轴方向使用最大高度
const max = placement === 'left' || placement === 'right' ? maxWidth : maxHeight;
// x 轴方向使用默认最小宽度,y轴方向使用默认最小高度
const min = placement === 'left' || placement === 'right' ? offsetWidth : offsetHeight;

const { allowSizeDraggable, max: limitMax, min: limitMin } = getSizeDraggable(sizeDraggable, { max, min });
const { allowSizeDraggable, max: limitMax, min: limitMin } = getSizeDraggable(sizeDraggable, { max, min });

if (!allowSizeDraggable) return;
if (!allowSizeDraggable) return;

const moveSize = calcMoveSize(placement, {
x,
y,
maxWidth,
maxHeight,
max: limitMax,
min: limitMin,
});
const moveSize = calcMoveSize(placement, {
x,
y,
maxWidth,
maxHeight,
max: limitMax,
min: limitMin,
});

if (typeof moveSize === 'undefined') return;
changeDragSizeValue(`${moveSize}px`);
dragSizeNumberRef.current = moveSize;
},
[placement, sizeDraggable],
);

if (typeof moveSize === 'undefined') return;
changeDragSizeValue(`${moveSize}px`);
};
const draggableLineStyles: Styles = useMemo(() => {
// 设置拖拽control的样式
const isHorizontal = ['right', 'left'].includes(placement);
Expand All @@ -58,20 +65,25 @@ const useDrag = (
cursor: isHorizontal ? 'col-resize' : 'row-resize',
};
}, [placement]);
const handleMouseup = (e: MouseEvent) => {
document.removeEventListener('mouseup', handleMouseup, true);
document.removeEventListener('mousemove', handleMousemove, true);
onSizeDragEnd?.({
e,
size: parseInt(dragSizeValue, 10),
});
};

const enableDrag = () => {
// mousedown绑定mousemove和mouseup事件
const handleMouseup = useCallback(
(e: MouseEvent) => {
document.removeEventListener('mouseup', handleMouseup, true);
document.removeEventListener('mousemove', handleMousemove, true);
onSizeDragEnd?.({
e,
// 此处不要使用 dragSizeValue,useState 的更新是异步的,在鼠标拖拽的同步操作中取不到最新的值
size: dragSizeNumberRef.current,
});
},
[handleMousemove, onSizeDragEnd],
);

const enableDrag = useCallback(() => {
// mousedown 绑定 mousemove 和 mouseup 事件
document.addEventListener('mouseup', handleMouseup, true);
document.addEventListener('mousemove', handleMousemove, true);
};
}, [handleMousemove, handleMouseup]);

return { dragSizeValue, enableDrag, draggableLineStyles };
};
Expand Down

0 comments on commit 23bb7d1

Please sign in to comment.