feat: onboarding polish, splash screen, controller nav, dev script
Onboarding flow: - Intro: improved layout and transitions - DID: better card styling and responsiveness - Path: added visual enhancements - Backup/Identity/Verify: streamlined markup - SplashScreen component added UI: - Controller navigation improvements (useControllerNav) - Style.css refinements Backend: - Runtime package fix Dev: - dev-start.sh improvements Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -115,7 +115,14 @@ function findNearestInDirection(
|
||||
|
||||
scored.sort((a, b) => {
|
||||
if (b.overlap !== a.overlap) return b.overlap - a.overlap
|
||||
return a.dist - b.dist
|
||||
if (a.dist !== b.dist) return a.dist - b.dist
|
||||
// Tiebreaker for up/down: prefer leftmost element in grid layouts
|
||||
if (direction === 'up' || direction === 'down') {
|
||||
const aLeft = a.el.getBoundingClientRect().left
|
||||
const bLeft = b.el.getBoundingClientRect().left
|
||||
return aLeft - bLeft
|
||||
}
|
||||
return 0
|
||||
})
|
||||
return scored[0]?.el ?? null
|
||||
}
|
||||
@@ -149,7 +156,7 @@ export function useControllerNav(containerRef?: { value: HTMLElement | null }) {
|
||||
|
||||
const target = e.target as HTMLElement
|
||||
if (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA') {
|
||||
// Enter in text field: blur and move to next focusable element (e.g., submit button)
|
||||
// Enter in text field: find next focusable — if it's a button, click it directly (submit)
|
||||
if (e.key === 'Enter' && target.tagName === 'INPUT' && (target as HTMLInputElement).type !== 'submit') {
|
||||
e.preventDefault()
|
||||
const root = containerRef?.value ?? document
|
||||
@@ -157,12 +164,24 @@ export function useControllerNav(containerRef?: { value: HTMLElement | null }) {
|
||||
const idx = all.indexOf(target as HTMLElement)
|
||||
const next = idx >= 0 ? all[idx + 1] : undefined
|
||||
if (next) {
|
||||
next.focus()
|
||||
next.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
|
||||
if (next.tagName === 'BUTTON' || next.getAttribute('role') === 'button') {
|
||||
next.focus()
|
||||
next.click()
|
||||
} else {
|
||||
next.focus()
|
||||
next.scrollIntoView({ block: 'nearest', behavior: 'smooth' })
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
if (e.key !== 'Escape') return
|
||||
// Up/Down arrows: exit field and navigate to element above/below
|
||||
if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
|
||||
e.preventDefault()
|
||||
;(target as HTMLElement).blur()
|
||||
// Fall through to arrow key handling below
|
||||
} else if (e.key !== 'Escape') {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const root = containerRef?.value ?? document
|
||||
|
||||
Reference in New Issue
Block a user