refactor(ui): share surface keyboard lifecycle

This commit is contained in:
Sameh Khamis committed 2026-09-12 18:45:30 -07:00
1 parent d5b09efa74
commit e1ffb9c572
11 files changed
+367 -128

No files matched your search

+18
View File
@@ -195,3 +195,21 @@ or moving focus. Call it before removing or replacing the controls.
reactions to state changes. Map Source selection and Location draft cleanup are
provided through callbacks. The component imports no globe, data, application
or server modules. Package checks and scoped formatting cover this entry.
## Surface keyboard handling
`gods-eye-view/ui/surfaces` exports `createSurfaceKeyboard` from
`src/ui/surfaceKeyboard.js`. It receives a root DOM node, an optional document,
an `isActive` predicate, an `onEscape` action and an optional return-focus fallback.
Construction is inert. `activate()` remembers the opener and installs one capture
listener; repeated activation is harmless. `deactivate({ restoreFocus: true })`
removes that listener and restores the opener when connected, otherwise invoking
the supplied fallback. Omit return focus when yielding to another surface.
`destroy()` permanently releases ownership without moving focus.
The welcome launcher and Provider Settings retain content, visibility, initial
focus, animation and screen-specific policy. Tab boundaries are read from the
current visible/enabled controls for each key; ordinary movement within those
boundaries remains native. The component honors already-handled keys and has no
app, server, storage or network dependencies. Its package boundary is checked
independently from the standalone screens that consume it.
+12
View File
@@ -1,5 +1,17 @@
# God's Eye View Current State
## Surface keyboard lifecycle
`ui/surfaces` owns the capture-phase keyboard listener, Tab cycling and return
focus shared by the first-run launcher and Provider Settings. Each caller
activates it while open and deactivates it on dismissal; destruction releases
keyboard ownership without moving focus. Reopening captures the current opener.
The launcher retains its hit-test/exclusive-surface arbitration and dismissal
preferences. Provider Settings retains its existing visibility and save policy.
Initial focus, transitions and DOM content remain with each screen. This
component does not add modal semantics or make the map inert.
## Panel disclosure lifecycle
Panel collapse buttons, nested Escape handling and dock hover/focus timing now