При вводе в поле приглашения («Список игроков») под инпутом всплывают до 3 подходящих игроков — аватар + ник, в стилистике строк топов. Клик подставляет ник в поле (приглашение отправляется кнопкой/Enter), уже состоящие в группе не предлагаются. Детали: компонент PlayerSuggestions (выбор по mousedown — до blur инпута), хук useUserSearch с дебаунсом 250 мс и keepPreviousData, классы .suggest-* в духе .notif-panel/.lb-row. В поиске общего списка подсказки не нужны — таблица уже фильтруется вживую при вводе. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
45 lines
1.4 KiB
TypeScript
45 lines
1.4 KiB
TypeScript
import { Avatar } from "./Avatar";
|
||
|
||
export interface PlayerSuggestion {
|
||
user_id: number;
|
||
nickname: string;
|
||
avatar_url?: string | null;
|
||
}
|
||
|
||
/**
|
||
* Выпадающие подсказки ников под инпутом. Родитель оборачивает инпут в
|
||
* .suggest-wrap, управляет видимостью и решает, что делать по выбору
|
||
* (подставить ник, перейти в профиль и т.п.).
|
||
*/
|
||
export function PlayerSuggestions({
|
||
items,
|
||
onPick,
|
||
}: {
|
||
items: PlayerSuggestion[];
|
||
onPick: (item: PlayerSuggestion) => void;
|
||
}) {
|
||
if (items.length === 0) return null;
|
||
return (
|
||
<div className="suggest-list" role="listbox">
|
||
{items.map((u) => (
|
||
<button
|
||
key={u.user_id}
|
||
type="button"
|
||
className="suggest-row"
|
||
role="option"
|
||
// mousedown, а не click: mousedown срабатывает ДО blur инпута — иначе
|
||
// onBlur родителя скрыл бы список раньше клика. preventDefault
|
||
// оставляет фокус в инпуте.
|
||
onMouseDown={(e) => {
|
||
e.preventDefault();
|
||
onPick(u);
|
||
}}
|
||
>
|
||
<Avatar url={u.avatar_url} nickname={u.nickname} size={28} />
|
||
<span className="nick">{u.nickname}</span>
|
||
</button>
|
||
))}
|
||
</div>
|
||
);
|
||
}
|