mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
refactor(base): destructure useListKeyboardNav and use clsx in person cell
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user