"use client" import { useRef, useState } from "react" import { useRouter } from "next/navigation" import { Search, X } from "lucide-react" import { DriveSearchSuggestionsPanel } from "@/components/drive/drive-search-suggestions" import { Button } from "@/components/ui/button" import type { DriveFileInfo } from "@/lib/api/types" import { useDriveSearchSuggestions } from "@/lib/api/hooks/use-drive-queries" import { openDriveItem } from "@/lib/drive/drive-open-item" import { type DriveSearchScope, buildDriveSearchUrl, defaultDriveSearchScope, fileBrowserViewForSearchScope, } from "@/lib/drive/drive-search" import { useDriveRouteRoot } from "@/lib/drive/drive-route-context" import type { DriveView } from "@/lib/drive/drive-url" import { useDebouncedValue } from "@/lib/hooks/use-debounced-value" import { useDriveUIStore } from "@/lib/stores/drive-ui-store" import { DRIVE_SEARCH_INPUT_WRAP_CLASS } from "@/lib/drive/drive-chrome-classes" import { cn } from "@/lib/utils" interface DriveSearchBarProps { value: string onChange: (value: string) => void scope: DriveSearchScope onScopeChange: (scope: DriveSearchScope) => void folderPath: string contextView: DriveView /** When true, suggestions panel hidden (search results page). */ resultsMode?: boolean className?: string autoFocus?: boolean } export function DriveSearchBar({ value, onChange, scope, onScopeChange, folderPath, contextView, resultsMode = false, className, autoFocus = false, }: DriveSearchBarProps) { const router = useRouter() const routeRoot = useDriveRouteRoot() const openPreview = useDriveUIStore((s) => s.openPreview) const inputRef = useRef(null) const [focused, setFocused] = useState(false) const debouncedQuery = useDebouncedValue(value, 250) const showFolderScope = folderPath !== "/" const effectiveScope = scope === "folder" && !showFolderScope ? defaultDriveSearchScope(contextView, folderPath) : scope const searchPath = effectiveScope === "folder" ? folderPath : "/" const { data, isFetching } = useDriveSearchSuggestions( debouncedQuery, effectiveScope, searchPath, focused && !resultsMode && debouncedQuery.trim().length >= 2 ) const suggestions = data?.files ?? [] const showPanel = !resultsMode && focused && value.trim().length >= 2 const submitSearch = (query?: string) => { const q = (query ?? value).trim() if (!q) return router.push( buildDriveSearchUrl( { query: q, scope: effectiveScope, folderPath: effectiveScope === "folder" ? folderPath : "/", }, routeRoot ) ) inputRef.current?.blur() } const openSuggestion = (item: DriveFileInfo) => { openDriveItem(item, { router, openPreview, view: fileBrowserViewForSearchScope(effectiveScope), contextItems: suggestions, }) inputRef.current?.blur() } return (
onChange(e.target.value)} onFocus={() => setFocused(true)} onBlur={() => window.setTimeout(() => setFocused(false), 150)} onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault() submitSearch() } if (e.key === "Escape") { onChange("") inputRef.current?.blur() } }} autoFocus={autoFocus} className={cn( "h-full w-full rounded-full border-0 bg-transparent text-sm text-foreground outline-none placeholder:text-muted-foreground", value ? "pl-11 pr-12" : "pl-11 pr-4" )} autoComplete="off" /> {value && ( )}
{showPanel ? ( submitSearch()} /> ) : null}
) }