Land Finder file drops positionally, header release topmost
04's settled clauses were mostly shipped already — the create landing resolved through DropSlotMath.cardSlot with one nominal shadow per importable file — but a release on the lane header fell through to the card zones, which clamp inward, so a scrolled lane could propose behind the header stripe. FileDropZones now folds header, attach hit-test, and card-slot resolution into one pure seam asked in that order, the header answering topmost per the ruling; lane headers register their frames for it. FinderDrop.shadowCount names the floor-at-one rule. New tests pin the header boundary, a differential against cardSlot's own zones (same zones, not similar), and a store-level differential proving a file landing takes the very ranks a card move there takes. Claude-Session: https://claude.ai/code/session_01SR4XGjmBE16ZUYWpfFHXwY
This commit is contained in:
@@ -132,6 +132,15 @@ struct LaneView: View {
|
||||
)
|
||||
}
|
||||
.onDrag(startLaneDrag, preview: { dragReplica })
|
||||
// **The header is the file drop's topmost position** (04-interactions.md ▸ Drag and drop,
|
||||
// settled 2026-07-28: "a release on the lane header resolves to the topmost position —
|
||||
// forgiving beats a dead stripe"). Its frame is registered rather than derived from the
|
||||
// grid's because the grid is scroll-view *content*: scrolled down, its top edge climbs
|
||||
// past the header and would stop being a boundary at all. The bar itself never moves.
|
||||
.onGeometryChange(for: CGRect.self) { $0.frame(in: .global) } action: { frame in
|
||||
drops.registry.update(header: frame, for: lane.id)
|
||||
}
|
||||
.onDisappear { drops.registry.removeHeader(lane.id) }
|
||||
.overlay(alignment: .trailing) { newCardButton }
|
||||
.contextMenu { laneMenu }
|
||||
// The lane's half of the Style… popover. Anchored on the header because that is the
|
||||
|
||||
Reference in New Issue
Block a user