fix: autoAdjustOffsetDuringDrag stale offset and missing reorder - #606
fix: autoAdjustOffsetDuringDrag stale offset and missing reorder#606MatiPl01 wants to merge 1 commit into
Conversation
Two bugs in Sortable.Grid autoAdjustOffsetDuringDrag with collapsible items: - An at-rest size change (e.g. a collapse/expand toggle) after a drag resolved a stale prevActiveItemKey, applied a bogus offset and set sortEnabled=false with no drop event to restore it, permanently disabling sorting. Pass through when no item is active. - A drag with no mid-drag size change never reordered because othersLayout was gated on additionalCrossOffset being non-null. Compute it unconditionally and hold ordering only during the mid-drag size transition, snapshotting the drag-start cross sizes via a reaction so consecutive same-key drags keep working.
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
lordpotato89
left a comment
There was a problem hiding this comment.
What matches our patch exactly
Bug 1 guard (AutoOffsetAdjustmentProvider.tsx): if (activeItemKey.value === null) return props; at the identical location (after the post-drop restore branch, before snapBasedOffset). Semantically character-for-character our fix — stops the at-rest "collapse all" from applying a stale-key offset and permanently killing sortEnabled.
Bug 2 null-gate removal (GridLayoutProvider/updates/common.ts): othersLayout computed unconditionally with startCrossOffset: additionalCrossOffset?.value ?? 0. Verified premise: calculateLayout already does startCrossOffset ?? 0 (layout.ts:29, 85). Vanilla grids (no auto-offset provider) are behaviorally unchanged (additionalCrossOffset === undefined short-circuits the new gate).
Transition-hold gate in the order updater: hold ordering only while additionalCrossOffset.value === null && dragStartSnapshot !== currentCrossSizes (reference equality) — exactly our round-8 companion fix that prevents the far-jump reorder during the mid-drag size flip.
The one difference — and it fixes a latent bug in OUR patch
Ours: snapshot taken lazily inside the updater via if (activeKey !== lastActiveKey.value). lastActiveKey never resets between drags, so dragging the same card twice in a row with an at-rest re-measure between (e.g. expand-all → collapse-all toggle) never re-snapshots → stale object → gate stays closed → if no mid-drag size change applies the offset, no reorder for the entire second drag (bug 2 resurfaces for that sequence). Reachable in our app when all cards are already collapsed.
PR: snapshot captured by a useAnimatedReaction on activeItemKey. Verified in source that activeItemKey cycles key → null → key on every drag (DragProvider.ts:531–537, handleDragEnd nulls it, prevActiveItemKey keeps the stale copy) — so the reaction re-fires on every drag start, same-key or not. The PR body explicitly calls this scenario out and its test matrix covers it ("Same item dragged twice with a toggle between").
|
Are you merging your solution? Regards |
Description
Fixes two bugs in
Sortable.Grid'sautoAdjustOffsetDuringDragwhen items change size (collapsible cards), reported in #605.Bug 1 - an at-rest size change after a drag permanently disables sorting.
handleDragEndleavesprevActiveItemKeyset to the just-dropped key (cleared only at the next drag start). InadaptLayoutProps,itemKey = activeItemKey ?? prevActiveItemKeythen resolves to that stale key on an at-rest "collapse/expand all", so the offset-application block runs and setssortEnabled = falsewith no drop event to restore it. Fix: pass the props through unchanged when no item is being dragged.Bug 2 - a drag with no mid-drag size change never reorders.
othersLayoutwas gated tonullwhileadditionalCrossOffsetwasnull, and that only becomes non-null once a mid-drag size change routes through the offset block, so a drag over uniform (already-collapsed) items never produced an order change. Fix: computeothersLayoutunconditionally (calculateLayoutalready treatsstartCrossOffsetas?? 0) and hold ordering only during the mid-drag size transition, when comparing the finger's old-layout position against a new-sizes/offset-0 model would otherwise fire a far-jump reorder.The drag-start cross sizes are snapshotted via a reaction on
activeItemKey, re-captured on every drag start, so ordering keeps working even when the same item is dragged twice in a row (a plain per-drag flag would go stale after an at-rest re-measure between two same-key drags).Testing
Reproduced and verified on the iOS simulator with a minimal collapsible-cards grid (the reporter's repro). Before/after, from app-side callbacks:
DRAG ACTIVATED, noORDER CHANGE, drop revertstouchonly,DRAG ACTIVATEDnever fires (sorting dead)autoAdjustOffsetDuringDragyarn lib typecheck,eslint, andyarn lib test(34/34) all pass.Closes #605