From 179c3658ad9f9117cf0a9596351bd2147f220a1f Mon Sep 17 00:00:00 2001 From: Lukas Date: Sat, 14 Mar 2026 12:35:38 +0100 Subject: [PATCH] Use useDeferredValue for search dropdown rendering Defer rendering of bestiary suggestions and player character matches in ActionBar so the input stays responsive as the bestiary grows. Keyboard navigation and selection logic still use the latest values. Co-Authored-By: Claude Opus 4.6 --- apps/web/src/components/action-bar.tsx | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/apps/web/src/components/action-bar.tsx b/apps/web/src/components/action-bar.tsx index 5f86014..8aeea6d 100644 --- a/apps/web/src/components/action-bar.tsx +++ b/apps/web/src/components/action-bar.tsx @@ -9,7 +9,12 @@ import { Plus, Users, } from "lucide-react"; -import { type FormEvent, type RefObject, useState } from "react"; +import { + type FormEvent, + type RefObject, + useDeferredValue, + useState, +} from "react"; import type { SearchResult } from "../hooks/use-bestiary.js"; import { cn } from "../lib/utils.js"; import { D20Icon } from "./d20-icon.js"; @@ -270,6 +275,8 @@ export function ActionBar({ const [nameInput, setNameInput] = useState(""); const [suggestions, setSuggestions] = useState([]); const [pcMatches, setPcMatches] = useState([]); + const deferredSuggestions = useDeferredValue(suggestions); + const deferredPcMatches = useDeferredValue(pcMatches); const [suggestionIndex, setSuggestionIndex] = useState(-1); const [queued, setQueued] = useState(null); const [customInit, setCustomInit] = useState(""); @@ -394,7 +401,8 @@ export function ActionBar({ } }; - const hasSuggestions = suggestions.length > 0 || pcMatches.length > 0; + const hasSuggestions = + deferredSuggestions.length > 0 || deferredPcMatches.length > 0; const handleKeyDown = (e: React.KeyboardEvent) => { if (!hasSuggestions) return; @@ -495,10 +503,10 @@ export function ActionBar({ )} )} - {browseMode && suggestions.length > 0 && ( + {browseMode && deferredSuggestions.length > 0 && (
    - {suggestions.map((result, i) => ( + {deferredSuggestions.map((result, i) => (