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

fix(drawer): 解决Drawer抽屉在拖拽改变大小的时候获取宽度可能不正确的问题 #3420

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
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
85 changes: 49 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,44 @@ const useDrag = (
onSizeDragEnd: TdDrawerProps['onSizeDragEnd'],
) => {
const [dragSizeValue, changeDragSizeValue] = useState<string>(null);
// 使用 ref 来存储当前拖拽的宽度值
const dragSizeRef = useRef<number>(0);

const handleMousemove = (e: MouseEvent) => {
// 鼠标移动时计算draggedSizeValue的值
const { x, y } = e;
const handleMousemove = useCallback(
(e: MouseEvent) => {
// 如果 sizeDraggable 是 boolean 值的 false,则不进行后续的计算
if (sizeDraggable === false) return;

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;
// 鼠标移动时计算draggedSizeValue的值
const { x, y } = e;

const { allowSizeDraggable, max: limitMax, min: limitMin } = getSizeDraggable(sizeDraggable, { max, min });
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;

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

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`);
dragSizeRef.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 +66,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: dragSizeRef.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