UI: подсказки ников при приглашении игрока в группу

При вводе в поле приглашения («Список игроков») под инпутом всплывают
до 3 подходящих игроков — аватар + ник, в стилистике строк топов.
Клик подставляет ник в поле (приглашение отправляется кнопкой/Enter),
уже состоящие в группе не предлагаются.

Детали: компонент PlayerSuggestions (выбор по mousedown — до blur
инпута), хук useUserSearch с дебаунсом 250 мс и keepPreviousData,
классы .suggest-* в духе .notif-panel/.lb-row. В поиске общего списка
подсказки не нужны — таблица уже фильтруется вживую при вводе.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-17 02:30:55 +03:00
co-authored by Claude Fable 5
parent e5b7420bae
commit ddbcd74058
5 changed files with 147 additions and 8 deletions
@@ -0,0 +1,44 @@
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>
);
}