Fix workspace board shift wheel drag scroll (#2126)
This commit is contained in:
parent
7d38f5e11f
commit
34b7d08ba5
|
|
@ -333,7 +333,7 @@ export default function WorkspaceKanbanDrawer({
|
|||
left: drawerLeftCss,
|
||||
top: 36,
|
||||
height: 'calc(100% - 36px)',
|
||||
width: `min(calc(100vw - ${drawerLeftCss}), 1320px)`,
|
||||
width: `min(calc(100vw - ${drawerLeftCss}), 1294px)`,
|
||||
opacity: workspaceBoardOpacity
|
||||
} as React.CSSProperties
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,19 @@ function isEventInsideElement(event: WheelEvent, element: HTMLElement): boolean
|
|||
)
|
||||
}
|
||||
|
||||
function pointIsInsideElement(
|
||||
point: { x: number; y: number } | null,
|
||||
element: HTMLElement
|
||||
): boolean {
|
||||
if (!point) {
|
||||
return false
|
||||
}
|
||||
const rect = element.getBoundingClientRect()
|
||||
return (
|
||||
point.x >= rect.left && point.x <= rect.right && point.y >= rect.top && point.y <= rect.bottom
|
||||
)
|
||||
}
|
||||
|
||||
export function useWorkspaceKanbanShiftWheelScroll(
|
||||
boardRef: React.RefObject<HTMLElement | null>,
|
||||
scrollerRef: React.RefObject<HTMLElement | null>,
|
||||
|
|
@ -35,13 +48,23 @@ export function useWorkspaceKanbanShiftWheelScroll(
|
|||
}
|
||||
|
||||
let isWorkspaceDragActive = false
|
||||
let lastDragPoint: { x: number; y: number } | null = null
|
||||
|
||||
const stopTrackingDrag = (): void => {
|
||||
isWorkspaceDragActive = false
|
||||
lastDragPoint = null
|
||||
}
|
||||
|
||||
const handleDragStart = (event: DragEvent): void => {
|
||||
isWorkspaceDragActive = event.dataTransfer ? hasWorkspaceDragData(event.dataTransfer) : false
|
||||
lastDragPoint = isWorkspaceDragActive ? { x: event.clientX, y: event.clientY } : null
|
||||
}
|
||||
|
||||
const handleDragOver = (event: DragEvent): void => {
|
||||
if (!isWorkspaceDragActive) {
|
||||
return
|
||||
}
|
||||
lastDragPoint = { x: event.clientX, y: event.clientY }
|
||||
}
|
||||
|
||||
const handleWheel = (event: WheelEvent): void => {
|
||||
|
|
@ -52,7 +75,7 @@ export function useWorkspaceKanbanShiftWheelScroll(
|
|||
!isWorkspaceDragActive ||
|
||||
!board ||
|
||||
!scroller ||
|
||||
!isEventInsideElement(event, board)
|
||||
(!isEventInsideElement(event, board) && !pointIsInsideElement(lastDragPoint, board))
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
|
@ -62,20 +85,26 @@ export function useWorkspaceKanbanShiftWheelScroll(
|
|||
return
|
||||
}
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
event.stopImmediatePropagation()
|
||||
scroller.scrollLeft += delta
|
||||
}
|
||||
|
||||
document.addEventListener('dragstart', handleDragStart)
|
||||
document.addEventListener('dragstart', handleDragStart, true)
|
||||
document.addEventListener('dragover', handleDragOver, true)
|
||||
document.addEventListener('drop', stopTrackingDrag, true)
|
||||
document.addEventListener('dragend', stopTrackingDrag, true)
|
||||
window.addEventListener('blur', stopTrackingDrag)
|
||||
document.addEventListener('wheel', handleWheel, { passive: false })
|
||||
// Why: Chromium can cancel the native drag if Shift+wheel reaches default
|
||||
// scrolling first, so intercept before bubble listeners see the event.
|
||||
document.addEventListener('wheel', handleWheel, { capture: true, passive: false })
|
||||
return () => {
|
||||
document.removeEventListener('dragstart', handleDragStart)
|
||||
document.removeEventListener('dragstart', handleDragStart, true)
|
||||
document.removeEventListener('dragover', handleDragOver, true)
|
||||
document.removeEventListener('drop', stopTrackingDrag, true)
|
||||
document.removeEventListener('dragend', stopTrackingDrag, true)
|
||||
window.removeEventListener('blur', stopTrackingDrag)
|
||||
document.removeEventListener('wheel', handleWheel)
|
||||
document.removeEventListener('wheel', handleWheel, true)
|
||||
}
|
||||
}, [boardRef, enabled, scrollerRef])
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue