import type { FormEvent, KeyboardEvent, FocusEvent, MutableRefObject } from "react"; import { StockSearchForm } from "@/features/trade/components/search/StockSearchForm"; import { StockSearchHistory } from "@/features/trade/components/search/StockSearchHistory"; import { StockSearchResults } from "@/features/trade/components/search/StockSearchResults"; import type { DashboardStockItem, DashboardStockSearchHistoryItem, DashboardStockSearchItem, } from "@/features/trade/types/trade.types"; import { cn } from "@/lib/utils"; interface TradeSearchSectionProps { canSearch: boolean; isSearchPanelOpen: boolean; isSearching: boolean; keyword: string; selectedStock: DashboardStockItem | null; selectedSymbol?: string; currentPrice?: number; change?: number; changeRate?: number; searchResults: DashboardStockSearchItem[]; searchHistory: DashboardStockSearchHistoryItem[]; searchShellRef: MutableRefObject; onKeywordChange: (value: string) => void; onSearchSubmit: (event: FormEvent) => void; onSearchFocus: () => void; onSearchShellBlur: (event: FocusEvent) => void; onSearchShellKeyDown: (event: KeyboardEvent) => void; onSelectStock: (item: DashboardStockSearchItem) => void; onRemoveHistory: (symbol: string) => void; onClearHistory: () => void; } /** * @description 트레이드 화면 상단의 검색 입력/결과/종목 요약 통합 영역을 렌더링합니다. * @summary UI 흐름: TradeContainer -> TradeSearchSection -> (검색 입력/선택) + (선택 종목 실시간 요약) 반영 * @see features/trade/components/TradeContainer.tsx - 검색 상태/선택 종목 실시간 데이터를 전달합니다. */ export function TradeSearchSection({ canSearch, isSearchPanelOpen, isSearching, keyword, selectedStock, selectedSymbol, currentPrice, change, changeRate, searchResults, searchHistory, searchShellRef, onKeywordChange, onSearchSubmit, onSearchFocus, onSearchShellBlur, onSearchShellKeyDown, onSelectStock, onRemoveHistory, onClearHistory, }: TradeSearchSectionProps) { return (
{/* ========== TOP BAR (검색 + 종목 요약 통합) ========== */}
{/* ========== SEARCH SHELL ========== */}
{/* ========== SEARCH DROPDOWN ========== */} {isSearchPanelOpen && canSearch && (
{searchResults.length > 0 ? ( ) : keyword.trim() ? (
{isSearching ? "검색 중..." : "검색 결과가 없습니다."}
) : searchHistory.length > 0 ? ( ) : (
최근 검색 종목이 없습니다.
)}
)}
); } /** * @description 검색창 우측의 선택 종목/보유 종목 요약 배지를 렌더링합니다. * @see features/trade/components/search/TradeSearchSection.tsx - 상단 1줄 통합 바에서 사용합니다. */ function InlineStockSummary({ stock, currentPrice, change, changeRate, }: { stock: DashboardStockItem | null; currentPrice?: number; change?: number; changeRate?: number; }) { if (!stock) { return (
종목을 선택하면 현재가/보유손익이 여기에 표시됩니다.
); } const displayPrice = currentPrice ?? stock.currentPrice; const displayChange = change ?? stock.change; const displayChangeRate = changeRate ?? stock.changeRate; const isRise = displayChangeRate > 0; const isFall = displayChangeRate < 0; const priceToneClass = isRise ? "text-red-600 dark:text-red-400" : isFall ? "text-blue-600 dark:text-blue-400" : "text-foreground dark:text-brand-50"; return (

{stock.name}

{stock.symbol} · {stock.market}

{displayPrice.toLocaleString("ko-KR")}

{isRise ? "+" : ""} {displayChange.toLocaleString("ko-KR")} ( {isRise ? "+" : ""} {displayChangeRate.toFixed(2)}%)

); } /** * @description 검색 헤더 1줄 안에서 시세 핵심 값(고가/저가/거래량)을 표시하는 칩입니다. * @summary UI 흐름: InlineStockSummary -> CompactMetric -> 종목 핵심 지표를 축약 표기 * @see features/trade/components/search/TradeSearchSection.tsx - 상단 통합 헤더의 우측 지표 영역 */ function CompactMetric({ label, value, tone, }: { label: string; value: string; tone?: "ask" | "bid"; }) { return (

{label}

{value}

); }