refactor(base): destructure useListKeyboardNav and use clsx in person cell

This commit is contained in:
Philipinho
2026-04-18 14:55:59 +01:00
parent 2ca27f16a1
commit 4cefa40f5b
@@ -1,6 +1,7 @@
import { useState, useRef, useEffect, useCallback, useMemo } from "react"; import { useState, useRef, useEffect, useCallback, useMemo } from "react";
import { Popover } from "@mantine/core"; import { Popover } from "@mantine/core";
import { IconX } from "@tabler/icons-react"; import { IconX } from "@tabler/icons-react";
import clsx from "clsx";
import { import {
IBaseProperty, IBaseProperty,
PersonTypeOptions, PersonTypeOptions,
@@ -61,7 +62,8 @@ export function CellPerson({
) )
: members; : members;
const nav = useListKeyboardNav(filteredMembers.length, [search, isEditing]); const { activeIndex, setActiveIndex, handleNavKey, setOptionRef } =
useListKeyboardNav(filteredMembers.length, [search, isEditing]);
const handleSelect = useCallback( const handleSelect = useCallback(
(memberId: string) => { (memberId: string) => {
@@ -104,11 +106,11 @@ export function CellPerson({
onCancel(); onCancel();
return; return;
} }
if (nav.handleNavKey(e)) return; if (handleNavKey(e)) return;
if (e.key === "Enter") { if (e.key === "Enter") {
if (nav.activeIndex < 0 || nav.activeIndex >= filteredMembers.length) return; if (activeIndex < 0 || activeIndex >= filteredMembers.length) return;
e.preventDefault(); e.preventDefault();
handleSelect(filteredMembers[nav.activeIndex].id); handleSelect(filteredMembers[activeIndex].id);
return; return;
} }
if (e.key === "Backspace" && search === "" && personIds.length > 0) { if (e.key === "Backspace" && search === "" && personIds.length > 0) {
@@ -116,7 +118,7 @@ export function CellPerson({
handleRemove(personIds[personIds.length - 1]); handleRemove(personIds[personIds.length - 1]);
} }
}, },
[onCancel, nav, filteredMembers, handleSelect, search, personIds, handleRemove], [onCancel, handleNavKey, activeIndex, filteredMembers, handleSelect, search, personIds, handleRemove],
); );
const selectedSet = new Set(personIds); const selectedSet = new Set(personIds);
@@ -183,20 +185,16 @@ export function CellPerson({
<div className={cellClasses.selectDropdown}> <div className={cellClasses.selectDropdown}>
{filteredMembers.map((member, idx) => { {filteredMembers.map((member, idx) => {
const isSelected = selectedSet.has(member.id); const isSelected = selectedSet.has(member.id);
const isKeyboardActive = idx === nav.activeIndex;
const className = [
cellClasses.selectOption,
isSelected ? cellClasses.selectOptionActive : "",
isKeyboardActive ? cellClasses.selectOptionKeyboardActive : "",
]
.filter(Boolean)
.join(" ");
return ( return (
<div <div
key={member.id} key={member.id}
ref={nav.setOptionRef(idx)} ref={setOptionRef(idx)}
className={className} className={clsx(
onMouseEnter={() => nav.setActiveIndex(idx)} cellClasses.selectOption,
isSelected && cellClasses.selectOptionActive,
idx === activeIndex && cellClasses.selectOptionKeyboardActive,
)}
onMouseEnter={() => setActiveIndex(idx)}
onMouseDown={(e) => { onMouseDown={(e) => {
// Keep focus on the search input so click doesn't blur + close popover. // Keep focus on the search input so click doesn't blur + close popover.
e.preventDefault(); e.preventDefault();