fix: vertical nav prefers closest element over widest overlap

Down from Identity name input now lands on Personal button (closest)
instead of Continue (wider overlap but further away).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dorian 2026-03-30 09:50:50 +01:00
parent 18b65cd434
commit 6fbdda772f

View File

@ -149,13 +149,23 @@ function findNearestInDirection(
})
scored.sort((a, b) => {
if (b.overlap !== a.overlap) return b.overlap - a.overlap
if (a.dist !== b.dist) return a.dist - b.dist
// Tiebreaker: prefer leftmost for up/down
if (direction === 'up' || direction === 'down') {
return a.el.getBoundingClientRect().left - b.el.getBoundingClientRect().left
const isVertical = direction === 'up' || direction === 'down'
// For vertical nav: prefer closest element first, use overlap as tiebreaker.
// This prevents a distant full-width element from winning over a closer narrow one.
if (isVertical) {
// Both have overlap — prefer closer distance
if (a.overlap > 0 && b.overlap > 0) {
if (a.dist !== b.dist) return a.dist - b.dist
if (b.overlap !== a.overlap) return b.overlap - a.overlap
return a.el.getBoundingClientRect().left - b.el.getBoundingClientRect().left
}
// One has overlap, the other doesn't — prefer the one with overlap
if (a.overlap !== b.overlap) return b.overlap - a.overlap
return a.dist - b.dist
}
return 0
// Horizontal: overlap first (same row), then distance
if (b.overlap !== a.overlap) return b.overlap - a.overlap
return a.dist - b.dist
})
return scored[0]?.el ?? null