feat(ui): render the Cockpit signal rows from a store, keeping focus

The Cockpit controller no longer reconciles the live signal rows by hand.
publishCockpitSignals turns its signal items into rows, keyed by the
signal and its action target as before, with repeats of a key numbered,
and publishes them to the gev-cockpit store; a new CockpitSignalList
component renders them with a keyed v-for inside the briefing card.

Rows reorder several times a second, and a browser blurs any element it
moves. The new v-focus-safe-children directive turns Vue's move of the
row holding focus into moves of the rows around it, reaching the same
order while the focused row stays connected, and before the focused row
is removed it hands focus to the shown briefing page's tab, or the
collapse toggle, as the reconciler did. Selection stays with the
controller's click listener.

The focus test now runs the real components over happy-dom and counts
any move or removal of the focused row as a loss, including across 60
random reorders. The Cockpit QA script publishes and waits a frame
before reading the rows.
This commit is contained in:
Sameh Khamis committed 2026-10-31 16:39:08 -07:00
1 parent a2bca0fb22
commit 58504e370c
12 files changed
+438 -387

No files matched your search

+9 -8
View File
@@ -136,14 +136,15 @@ They contain no application state.
starting from `cockpitBriefPages.js`, `cockpitContextState.js` and
`cockpitInstrumentState.js`, which both read; the odometer readouts
(`CockpitRollingValue`) keep their throttle and roll in
`cockpitRollingValue.js`. The instruments publish on every HUD update
(about 10 Hz); in a dev build their Vue patch costs about 0.5 ms, close
to the DOM writes it replaced. The controls keep the controller's
listeners, and the cards' visibility, collapse and layout stay with the
controller. The signal rows and the radio controls follow; the signal
rows become a
component that keeps their focus-safe reorder, since a keyed Vue list
would move the focused row and drop focus several times a second).
`cockpitRollingValue.js`. `CockpitSignalList` renders the live signal
rows; `v-focus-safe-children` turns Vue's move of the focused row into
moves of the rows around it, and hands focus to the shown briefing tab
before the focused row is removed, so a keyed list reorders several times
a second without dropping keyboard focus. The instruments publish on
every HUD update (about 10 Hz); in a dev build their Vue patch costs
about 0.5 ms, close to the DOM writes it replaced. The controls keep the
controller's listeners, and the cards' visibility, collapse and layout
stay with the controller. The radio controls follow).
Layers that write into the right rail directly gain a slot instead.
4. **Cleanup.** The build-time template expansion and the attribute