From 9d17cd7d9c3b1d50b83ac853870c44fd81c7e49e Mon Sep 17 00:00:00 2001 From: Kacper Date: Mon, 15 Dec 2025 23:38:05 +0100 Subject: [PATCH] refactor(board-view): extract BoardSearchBar component --- apps/app/src/components/views/board-view.tsx | 59 ++---------- .../views/board-view/BoardSearchBar.tsx | 89 +++++++++++++++++++ 2 files changed, 97 insertions(+), 51 deletions(-) create mode 100644 apps/app/src/components/views/board-view/BoardSearchBar.tsx diff --git a/apps/app/src/components/views/board-view.tsx b/apps/app/src/components/views/board-view.tsx index d782806e..a9fb5662 100644 --- a/apps/app/src/components/views/board-view.tsx +++ b/apps/app/src/components/views/board-view.tsx @@ -64,6 +64,7 @@ import { BoardBackgroundModal } from "@/components/dialogs/board-background-moda import { AddFeatureDialog } from "./board-view/AddFeatureDialog"; import { EditFeatureDialog } from "./board-view/EditFeatureDialog"; import { BoardHeader } from "./board-view/BoardHeader"; +import { BoardSearchBar } from "./board-view/BoardSearchBar"; import { Plus, RefreshCw, @@ -285,7 +286,6 @@ export function BoardView() { const startNextFeaturesRef = useRef<() => void>(() => {}); // Ref for search input to enable keyboard shortcut focus - const searchInputRef = useRef(null); // Keyboard shortcuts for this view const boardShortcuts: KeyboardShortcut[] = useMemo(() => { @@ -300,11 +300,6 @@ export function BoardView() { action: () => startNextFeaturesRef.current(), description: "Start next features from backlog", }, - { - key: "/", - action: () => searchInputRef.current?.focus(), - description: "Focus search input", - }, ]; // Add shortcuts for in-progress cards (1-9 and 0 for 10th) @@ -1735,51 +1730,13 @@ export function BoardView() {
{/* Search Bar Row */}
-
-
- - setSearchQuery(e.target.value)} - className="pl-9 pr-12 border-border" - data-testid="kanban-search-input" - /> - {searchQuery ? ( - - ) : ( - - / - - )} -
- {/* Spec Creation Loading Badge */} - {isCreatingSpec && - currentProject?.path === creatingSpecProjectPath && ( -
- - - Creating spec - -
- )} -
+ {/* Board Background & Detail Level Controls */} {isMounted && ( diff --git a/apps/app/src/components/views/board-view/BoardSearchBar.tsx b/apps/app/src/components/views/board-view/BoardSearchBar.tsx new file mode 100644 index 00000000..b1843d68 --- /dev/null +++ b/apps/app/src/components/views/board-view/BoardSearchBar.tsx @@ -0,0 +1,89 @@ +"use client"; + +import { useRef, useEffect } from "react"; +import { Input } from "@/components/ui/input"; +import { Search, X, Loader2 } from "lucide-react"; + +interface BoardSearchBarProps { + searchQuery: string; + onSearchChange: (query: string) => void; + isCreatingSpec: boolean; + creatingSpecProjectPath?: string; + currentProjectPath?: string; +} + +export function BoardSearchBar({ + searchQuery, + onSearchChange, + isCreatingSpec, + creatingSpecProjectPath, + currentProjectPath, +}: BoardSearchBarProps) { + const searchInputRef = useRef(null); + + // Focus search input when "/" is pressed + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + // Only focus if not typing in an input/textarea + if ( + e.key === "/" && + !(e.target instanceof HTMLInputElement) && + !(e.target instanceof HTMLTextAreaElement) + ) { + e.preventDefault(); + searchInputRef.current?.focus(); + } + }; + + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, []); + + return ( +
+
+ + onSearchChange(e.target.value)} + className="pl-9 pr-12 border-border" + data-testid="kanban-search-input" + /> + {searchQuery ? ( + + ) : ( + + / + + )} +
+ {/* Spec Creation Loading Badge */} + {isCreatingSpec && + currentProjectPath === creatingSpecProjectPath && ( +
+ + + Creating spec + +
+ )} +
+ ); +}