fix(ui): a removed chip's focus outlives its neighbour; a scroll restore yields to the reader
A chip handed its focus to a Clear all or +N that went in the same removal, and the focus fell to the body. The restore now stops when the reader scrolls, and finishes the way once the Back-to-top spacer brings the saved spot within reach.
This commit is contained in:
@@ -49,6 +49,27 @@ export function focusNeighbour(el: HTMLElement): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Run `remove`, which takes `el` off the page, without dropping `el`'s focus: it goes to the
|
||||
* neighbour first (`focusNeighbour`). That neighbour may go in the same removal — the "Clear all"
|
||||
* that only shows beside two filters, the "+1" of the last hidden one (E28 review round 3) — so
|
||||
* once the removal has rendered, a focus left on <body> goes to what preceded `el`, else to the
|
||||
* first control left in its row. Only when the focus was lost: a focus the reader moved stays. */
|
||||
export function handOffFocus(el: HTMLElement, remove: () => void): void {
|
||||
const before = firstFocusable(el.previousSibling, true);
|
||||
const row = el.parentElement;
|
||||
focusNeighbour(el);
|
||||
remove();
|
||||
// A timer, not a frame: a page the browser is not painting runs no requestAnimationFrame.
|
||||
window.setTimeout(() => {
|
||||
const now = document.activeElement;
|
||||
if (now && now !== document.body && now.isConnected) return;
|
||||
const stayed = before?.isConnected && shown(before) ? before : null;
|
||||
(stayed ?? (row?.isConnected ? firstFocusable(row.firstChild) : null))?.focus({
|
||||
preventScroll: true,
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
|
||||
// The element the keeper last put the focus on, while it still holds it. A Back that swaps the page
|
||||
// or a sub-view removes the held control too, and the keeper's stand-in then sat where
|
||||
// `restoreNavPosition` looks for an untouched <body>: the restore gave up and Back left the focus on
|
||||
|
||||
Reference in New Issue
Block a user