Selectable list now responds to arrow key presses
This commit is contained in:
parent
d95ba45867
commit
237267ff3a
@ -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}>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user