The pickup seeds its own slot — the lift and the shadow become one transaction
"At drag start it replaces the item's original space" is now true from the very first frame: begin takes the run's own resting slot as a seed, set in the same transaction that lifts the run out. Without it the vacated gap closed un-animated and sprang back open at the first dropUpdated — a shuffle carrying no information. The seed bypasses propose deliberately (a pickup is not a new landing spot, so no alignment tick), and the first real sample's re-propose of the same slot is the early-out's ordinary silence. A ⌥-pickup seeds nothing — a copy's resting layout keeps the originals in place, so there is no vacated space to hold. Card pickups compute the seed through the same LaneView.rendered rules the retargets count in; lane pickups seed their strip slot the same way. DRAG-REORDER.md's own-slot paragraph records the rule, and SeededPickupTests pins all four corners. Claude-Session: https://claude.ai/code/session_014PtZdPwqZuqEDLc6wZMtEy
This commit is contained in:
@@ -587,7 +587,17 @@ struct LaneView: View, Equatable {
|
||||
// The dragged items' own sizes, frozen at drag start — the one thing that is
|
||||
// (03-board-ui.md § Motion).
|
||||
units: members.map { LaneLayoutMath.displayUnits(of: $0) },
|
||||
source: store
|
||||
source: store,
|
||||
// The strip's own-slot seed (`DragSession.begin`): the grabbed lane's position among
|
||||
// the lanes with the dragged run removed — the strip proposal's own index space. A
|
||||
// within-board lane drag never resolves to `.copy` (⌥ is ignored there), so unlike the
|
||||
// card seed this one carries no modifier clause.
|
||||
seed: DropTarget(
|
||||
boardRoot: store.rootKey,
|
||||
container: .strip,
|
||||
index: store.snapshot.lanes.prefix { $0.id != lane.id }
|
||||
.count { !ids.contains($0.id) }
|
||||
)
|
||||
)
|
||||
return payload.itemProvider()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user