Jacob314/add radio button keys (#10083)

This commit is contained in:
Jacob Richman
2025-09-28 14:50:47 -07:00
committed by GitHub
parent 1bd75f060d
commit 62ba330612
26 changed files with 263 additions and 112 deletions
+19 -26
View File
@@ -8,6 +8,7 @@ import { useReducer, useRef, useEffect } from 'react';
import { useKeypress } from './useKeypress.js';
export interface SelectionListItem<T> {
key: string;
value: T;
disabled?: boolean;
}
@@ -70,27 +71,6 @@ type SelectionListAction<T> =
const NUMBER_INPUT_TIMEOUT_MS = 1000;
/**
* Performs an equality check on two arrays of SelectionListItem<T>.
*
* It compares the length of the arrays and then the 'value' and 'disabled'
* properties of each item.
*/
const areItemsEqual = <T>(
a: Array<SelectionListItem<T>>,
b: Array<SelectionListItem<T>>,
): boolean => {
if (a.length !== b.length) {
return false;
}
for (let i = 0; i < a.length; i++) {
if (a[i]!.value !== b[i]!.value || a[i]!.disabled !== b[i]!.disabled) {
return false;
}
}
return true;
};
/**
* Helper function to find the next enabled index in a given direction, supporting wrapping.
*/
@@ -122,11 +102,20 @@ const findNextValidIndex = <T>(
const computeInitialIndex = <T>(
initialIndex: number,
items: Array<SelectionListItem<T>>,
initialKey?: string,
): number => {
if (items.length === 0) {
return 0;
}
if (initialKey !== undefined) {
for (let i = 0; i < items.length; i++) {
if (items[i]!.key === initialKey && !items[i]!.disabled) {
return i;
}
}
}
let targetIndex = initialIndex;
if (targetIndex < 0 || targetIndex >= items.length) {
@@ -184,13 +173,17 @@ function selectionListReducer<T>(
case 'INITIALIZE': {
const { initialIndex, items } = action.payload;
if (
state.initialIndex === initialIndex &&
areItemsEqual(state.items, items)
) {
const activeKey =
initialIndex === state.initialIndex &&
state.activeIndex !== state.initialIndex
? state.items[state.activeIndex]?.key
: undefined;
if (items === state.items && initialIndex === state.initialIndex) {
return state;
}
const targetIndex = computeInitialIndex(initialIndex, items);
const targetIndex = computeInitialIndex(initialIndex, items, activeKey);
return {
...state,