fix(feed): clamp the view menu's roving index to the option list
Guards the shared switcher against a caller whose option list shrinks while the menu is open, which would leave every item un-tabbable.
This commit is contained in:
@@ -54,9 +54,12 @@ export default function ViewSwitcher<T extends string>({
|
||||
setFocusIdx(currentIdx);
|
||||
setOpen(true);
|
||||
}
|
||||
// Clamped at render, so a caller whose option list shrinks while the menu is open can't leave
|
||||
// the roving tabindex pointing past the end (which would make every item un-tabbable).
|
||||
const rovingIdx = Math.min(focusIdx, options.length - 1);
|
||||
useEffect(() => {
|
||||
if (open) itemRefs.current[focusIdx]?.focus();
|
||||
}, [open, focusIdx]);
|
||||
if (open) itemRefs.current[rovingIdx]?.focus();
|
||||
}, [open, rovingIdx]);
|
||||
|
||||
const current = options[currentIdx];
|
||||
if (!current) return null;
|
||||
@@ -122,7 +125,7 @@ export default function ViewSwitcher<T extends string>({
|
||||
}}
|
||||
role="menuitemradio"
|
||||
aria-checked={on}
|
||||
tabIndex={i === focusIdx ? 0 : -1}
|
||||
tabIndex={i === rovingIdx ? 0 : -1}
|
||||
onClick={() => {
|
||||
onChange(o.id);
|
||||
close();
|
||||
|
||||
Reference in New Issue
Block a user