Selectable list now responds to arrow key presses

This commit is contained in:
Colin Dawson 2026-02-16 00:00:17 +00:00
parent d95ba45867
commit 237267ff3a

View File

@ -1,4 +1,4 @@
import React from "react";
import React, { useCallback, useRef } from "react";
export interface SelectableListProps<T> {
items: T[];
@ -12,15 +12,41 @@ export const SelectableList = <T,>(
): JSX.Element => {
const { items, selectedValue, renderLabel, onSelect } = props;
const listClassName = "selectable-list";
const listRef = useRef<HTMLUListElement | null>(null);
const handleKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLUListElement>) => {
if (!items.length) return;
const currentIndex = selectedValue ? items.indexOf(selectedValue) : -1;
if (e.key === "ArrowDown") {
e.preventDefault();
const nextIndex =
currentIndex < items.length - 1 ? currentIndex + 1 : 0;
onSelect(items[nextIndex]);
}
if (e.key === "ArrowUp") {
e.preventDefault();
const prevIndex =
currentIndex > 0 ? currentIndex - 1 : items.length - 1;
onSelect(items[prevIndex]);
}
},
[items, selectedValue, onSelect],
);
return (
<ul className={listClassName}>
<ul
ref={listRef}
className="selectable-list"
tabIndex={0}
onKeyDown={handleKeyDown}
>
{items.map((item, index) => {
const isSelected = selectedValue === item;
const className = isSelected
? ["selected"].filter(Boolean).join(" ")
: "";
const className = isSelected ? "selected" : "";
return (
<li key={index} onClick={() => onSelect(item)} className={className}>