fix(widget): correct reorder drop indicator position when container is scrolled

The drop indicator top position was calculated using only
getBoundingClientRect() offsets (post-CSS-transform viewport space)
without accounting for container.scrollTop (pre-transform layout space).
This caused the indicator to drift upward as the user scrolled down,
eventually disappearing entirely.

Fixed by adding container.scrollTop to the position calculation and
only dividing the GBCR visual-diff portion by scale, since scrollTop
is already in pre-transform coordinate space.
This commit is contained in:
Will Miao
2026-07-19 22:40:07 +08:00
parent 9a8f5bf2d6
commit c68d7559a0

View File

@@ -438,7 +438,9 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
if (firstEntry) { if (firstEntry) {
const rect = firstEntry.getBoundingClientRect(); const rect = firstEntry.getBoundingClientRect();
const containerRect = container.getBoundingClientRect(); const containerRect = container.getBoundingClientRect();
dropIndicator.style.top = `${(rect.top - containerRect.top - 2) / scale}px`; // Convert GBCR visual offset to container-local space (rect/containerRect are post-scale,
// scrollTop is pre-scale), so only the visual-diff portion is divided by scale
dropIndicator.style.top = `${(rect.top - containerRect.top) / scale + container.scrollTop - 2}px`;
dropIndicator.style.opacity = '1'; dropIndicator.style.opacity = '1';
} }
} else if (targetIndex < entries.length) { } else if (targetIndex < entries.length) {
@@ -447,7 +449,7 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
if (targetEntry) { if (targetEntry) {
const rect = targetEntry.getBoundingClientRect(); const rect = targetEntry.getBoundingClientRect();
const containerRect = container.getBoundingClientRect(); const containerRect = container.getBoundingClientRect();
dropIndicator.style.top = `${(rect.top - containerRect.top - 2) / scale}px`; dropIndicator.style.top = `${(rect.top - containerRect.top) / scale + container.scrollTop - 2}px`;
dropIndicator.style.opacity = '1'; dropIndicator.style.opacity = '1';
} }
} else { } else {
@@ -456,7 +458,7 @@ export function initReorderDrag(dragHandle, loraName, widget, renderFunction) {
if (lastEntry) { if (lastEntry) {
const rect = lastEntry.getBoundingClientRect(); const rect = lastEntry.getBoundingClientRect();
const containerRect = container.getBoundingClientRect(); const containerRect = container.getBoundingClientRect();
dropIndicator.style.top = `${(rect.bottom - containerRect.top + 2) / scale}px`; dropIndicator.style.top = `${(rect.bottom - containerRect.top) / scale + container.scrollTop + 2}px`;
dropIndicator.style.opacity = '1'; dropIndicator.style.opacity = '1';
} }
} }