diff --git a/src/components/common/SelectableList.tsx b/src/components/common/SelectableList.tsx index 43e5969..06f605b 100644 --- a/src/components/common/SelectableList.tsx +++ b/src/components/common/SelectableList.tsx @@ -12,16 +12,13 @@ export const SelectableList = ( ): JSX.Element => { const { items, selectedValue, renderLabel, onSelect } = props; - // Track focus state of the list itself const listRef = useRef(null); const isFocusedRef = useRef(false); - // One ref per item so we can focus + scroll it const itemRefs = useRef<(HTMLLIElement | null)[]>([]); const handleKeyDown = useCallback( (e: React.KeyboardEvent) => { - // Ignore keyboard input unless the list itself is focused if (!isFocusedRef.current) return; if (!items.length) return; @@ -44,9 +41,8 @@ export const SelectableList = ( [items, selectedValue, onSelect], ); - // Only focus the selected item if the list itself already has focus useEffect(() => { - if (!isFocusedRef.current) return; // Do NOT steal focus + if (!isFocusedRef.current) return; if (!selectedValue) return; const index = items.indexOf(selectedValue); @@ -64,6 +60,10 @@ export const SelectableList = ( ref={listRef} className="selectable-list" tabIndex={0} + role="listbox" + aria-activedescendant={ + selectedValue ? `option-${items.indexOf(selectedValue)}` : undefined + } onFocus={() => (isFocusedRef.current = true)} onBlur={() => (isFocusedRef.current = false)} onKeyDown={handleKeyDown} @@ -75,8 +75,11 @@ export const SelectableList = ( return (
  • (itemRefs.current[index] = el)} tabIndex={isSelected ? 0 : -1} + role="option" + aria-selected={isSelected} onClick={() => onSelect(item)} className={className} >