diff --git a/apps/client/src/features/base/components/cells/cell-status.tsx b/apps/client/src/features/base/components/cells/cell-status.tsx index c21efd88..761ff746 100644 --- a/apps/client/src/features/base/components/cells/cell-status.tsx +++ b/apps/client/src/features/base/components/cells/cell-status.tsx @@ -7,6 +7,8 @@ import { } from "@/features/base/types/base.types"; import { choiceColor } from "@/features/base/components/cells/choice-color"; import cellClasses from "@/features/base/styles/cells.module.css"; +import clsx from "clsx"; +import { useListKeyboardNav } from "@/features/base/hooks/use-list-keyboard-nav"; type CellStatusProps = { value: unknown; @@ -73,6 +75,19 @@ export function CellStatus({ return result; }, [choices, search]); + const flatChoices = useMemo( + () => groups.flatMap((g) => g.choices), + [groups], + ); + const choiceIdxMap = useMemo(() => { + const m = new Map(); + flatChoices.forEach((c, i) => m.set(c.id, i)); + return m; + }, [flatChoices]); + + const { activeIndex, setActiveIndex, handleNavKey, setOptionRef } = + useListKeyboardNav(flatChoices.length, [search, isEditing]); + const handleSelect = useCallback( (choice: Choice) => { onCommit(choice.id === selectedId ? null : choice.id); @@ -85,9 +100,16 @@ export function CellStatus({ if (e.key === "Escape") { e.preventDefault(); onCancel(); + return; + } + if (handleNavKey(e)) return; + if (e.key === "Enter") { + if (activeIndex < 0 || activeIndex >= flatChoices.length) return; + e.preventDefault(); + handleSelect(flatChoices[activeIndex]); } }, - [onCancel], + [onCancel, handleNavKey, activeIndex, flatChoices, handleSelect], ); if (isEditing) { @@ -129,24 +151,33 @@ export function CellStatus({
{group.label}
- {group.choices.map((choice) => ( -
handleSelect(choice)} - > - { + const idx = choiceIdxMap.get(choice.id) ?? -1; + const isSelected = choice.id === selectedId; + return ( +
setActiveIndex(idx)} + onMouseDown={(e) => { + e.preventDefault(); + }} + onClick={() => handleSelect(choice)} > - {choice.name} - -
- ))} + + {choice.name} + +
+ ); + })} ))}