fix(nav): Back restores the focus after a click on the page's blank area
The page region is <main tabIndex=-1>, so a background click focused it and the Back restore took that for the reader's choice. A resting place is marked and one predicate (focusIsUnclaimed) decides "the focus is nowhere" everywhere.
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useRef, useState, type RefObject } from "react";
|
||||
import { dispatch, useKeyScope } from "./keymap";
|
||||
import { scrollParent } from "./listPaging";
|
||||
import { isStandInFocus } from "./useFocusKeeper";
|
||||
import { focusIsUnclaimed } from "./useFocusKeeper";
|
||||
|
||||
// ── Keyboard navigation over lists and grids (E11 S4, UX-6) ──────────────────────────────────────
|
||||
// Before this, a feed card cost ~10 Tab stops (thumb, play, info, title, channel, five actions), so
|
||||
@@ -148,6 +148,9 @@ function onFocusIn(e: FocusEvent): void {
|
||||
const list =
|
||||
item && lists.get(item.parentElement?.closest<HTMLElement>(`[${LIST}]`) as HTMLElement);
|
||||
if (item && list) last = { list, index: indexOf(item), el: item };
|
||||
// The focus coming to REST on the page region (a click on its background) is not leaving the list
|
||||
// for other content — like a click on <body>, which fires no focusin at all.
|
||||
else if (focusIsUnclaimed(target)) return;
|
||||
// Focus went on to page content that is not an item — the search box, a filter chip: the reader
|
||||
// left the list, and whatever it shows next (new results) is not "the slot they were in" (deep-review
|
||||
// E11 round 2). A layer opened FROM the item — its menu, a confirm, the Undo toast its removal put
|
||||
@@ -375,8 +378,7 @@ function refocusSlot(list: NavList, index: number, removed: HTMLElement): void {
|
||||
if (++frames < REMOVE_FRAMES) requestAnimationFrame(wait);
|
||||
return;
|
||||
}
|
||||
const active = document.activeElement;
|
||||
if (active && active !== document.body && !isStandInFocus(active)) return;
|
||||
if (!focusIsUnclaimed()) return;
|
||||
const n = list.count();
|
||||
if (n > 0) focusIndex(list, Math.min(index, n - 1));
|
||||
};
|
||||
@@ -450,8 +452,7 @@ export function restoreNavPosition(pos: NavPosition): () => void {
|
||||
const deadline = Date.now() + RESTORE_MS;
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
const attempt = () => {
|
||||
const active = document.activeElement;
|
||||
if (active && active !== document.body && !isStandInFocus(active)) return;
|
||||
if (!focusIsUnclaimed()) return;
|
||||
const all = ordered();
|
||||
const list = pos.label
|
||||
? all.find((l) => labelOf(l) === pos.label)
|
||||
|
||||
Reference in New Issue
Block a user