fix(drag): continue autoscroll when widget dragged past root container edge - #3311
fix(drag): continue autoscroll when widget dragged past root container edge#3311developerVibhay wants to merge 1 commit into
Conversation
…r edge When the scroll container is the document root, dragging a widget fully above or below the visible area should keep scrolling. Previously the 'fully outside' early return in _getClipping stopped scrolling in that case, making it impossible to scroll up by aggressively dragging near the top edge. Fix: skip the early-return only for nested (non-root) scroll containers. Add 6 unit tests covering both the nested-stop and root-continue cases.
|
shouldn't scrolling stop when we have nothing else to scroll instead of where item is relative to scrollRect ? I mean the original scrollElement shoud continue reguadless if we enter a parent grid or not. Also your check for main view but could be a regular parent div that still above all grid, so your logic isn't matching to wording anyway... |
|
@developerVibhay I don't agree with that. if I drag an item out of a grid, either to drop into another grid or trash can to delete, I surely wouldn't expect the old scrolled area to continue scrolling.... I think you code would possibly break nested grid gesture as well. closing. |
|
from gemini 3.1 pro, wiht my feedback above That is an excellent point and a very common UX concern. If you drag an element clearly out of a container to drop it somewhere else (like a sidebar trash can or an adjacent grid), it feels wrong if the original container keeps uncontrollably scrolling just because your mouse is vertically above or below it. You are right that stopping the scroll when you "leave" the area is important. But we still need to solve the edge-case from PR 3311, where an aggressive flick upward to scroll the current grid temporarily pushes the dragged widget fully above the grid, halting the scroll by mistake. The Solution: Horizontal Bounds When you flick a widget up or down to scroll, you usually stay roughly in the same column (horizontally aligned with the grid). But when you drag to a trash can or another grid, you move completely out of the grid's left/right boundaries. We can update the clipping function to stop scrolling only if the widget is completely outside the grid horizontally: /** @internal compute how many pixels the element is clipped */
protected _getClipping(el: HTMLElement, scrollEl: HTMLElement): number {
const elRect = el.getBoundingClientRect();
const scrollRect = scrollEl.getBoundingClientRect();
const viewportH = window.innerHeight || document.documentElement.clientHeight;
// 💡 NEW: If completely horizontally outside, assume the user left the area (e.g. to a sidebar/trash) and stop scrolling!
if (elRect.right < scrollRect.left || elRect.left > scrollRect.right) {
return 0;
}
const clippedBelow = elRect.bottom - Math.min(scrollRect.bottom, viewportH);
const clippedAbove = elRect.top - Math.max(scrollRect.top, 0);
if (clippedAbove < 0) return clippedAbove;
if (clippedBelow > 0) return clippedBelow;
return 0;
}Why this addresses both concerns: |
Description
When a gridstack container is scrollable and you drag a widget aggressively toward the top of the browser window — pulling it fully above the container's visible area — autoscroll stops instead of continuing
to scroll up (or down when dragged below).
Root cause:
_getClipping()indd-draggable.tshad an early return for the "fully outside" case:This is correct for nested grid containers (the widget has left that grid, so the parent should take over). But when the scroll container is the document root, there is no parent to hand off to — scrolling
should continue at full speed.
Fix: Added an isRoot check so the early return only applies to nested containers:
Example: Create a gridstack grid taller than the viewport (so the page scrolls). Grab the last widget and quickly drag it toward the top of the browser window past the visible area. Before this fix, autoscroll
would halt as soon as the widget left the visible bounds. After this fix, the container continues scrolling up until it reaches the top.