From cc16a0052ad26aaff7b5fe6e290c553cd38c68e2 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Sun, 4 Jan 2026 17:31:53 +0800 Subject: [PATCH] =?UTF-8?q?refactor(FlexScreen):=20=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E6=A1=86=E7=A7=BB=E5=88=B0=E6=A0=87=E9=A2=98=E6=A0=8F=EF=BC=8C?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E6=94=B6=E8=B5=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 搜索框从内容区移到标题栏右侧,始终可见 - 灵活屏默认收起状态 - 删除废弃的 SearchPanel 组件 - 搜索框边框改为金色 --- .../components/FlexScreenHeader.tsx | 127 ++++++++++++++++- .../FlexScreen/components/SearchPanel.tsx | 128 ------------------ .../components/FlexScreen/components/index.ts | 1 - .../components/FlexScreen/index.tsx | 34 ++--- .../components/FlexScreen/types.ts | 8 ++ 5 files changed, 141 insertions(+), 157 deletions(-) delete mode 100644 src/views/StockOverview/components/FlexScreen/components/SearchPanel.tsx diff --git a/src/views/StockOverview/components/FlexScreen/components/FlexScreenHeader.tsx b/src/views/StockOverview/components/FlexScreen/components/FlexScreenHeader.tsx index cd412a54..9fc5e766 100644 --- a/src/views/StockOverview/components/FlexScreen/components/FlexScreenHeader.tsx +++ b/src/views/StockOverview/components/FlexScreen/components/FlexScreenHeader.tsx @@ -1,11 +1,12 @@ /** * FlexScreenHeader - 灵活屏头部组件 - * 包含标题、连接状态、操作按钮 + * 包含标题、连接状态、搜索框、操作按钮 */ import React, { memo } from 'react'; import { Flex, HStack, + VStack, Heading, Text, IconButton, @@ -13,11 +14,20 @@ import { Badge, Tooltip, Spacer, + Box, + Input, + InputGroup, + InputLeftElement, + InputRightElement, + List, + ListItem, + Spinner, + Center, } from '@chakra-ui/react'; -import { Monitor, Wifi, ChevronDown, ChevronUp } from 'lucide-react'; +import { Monitor, Wifi, ChevronDown, ChevronUp, Search, X, Plus } from 'lucide-react'; -import type { FlexScreenHeaderProps } from '../types'; -import { COLORS, actionButtonStyles, collapseButtonStyles } from '../styles'; +import type { FlexScreenHeaderProps, SearchResultItem } from '../types'; +import { COLORS, actionButtonStyles, collapseButtonStyles, searchDropdownStyles } from '../styles'; const FlexScreenHeader: React.FC = memo(({ connectionStatus, @@ -26,10 +36,19 @@ const FlexScreenHeader: React.FC = memo(({ onToggleCollapse, onClearWatchlist, onResetWatchlist, + // 搜索相关 + searchQuery, + onSearchQueryChange, + searchResults, + isSearching, + showResults, + onAddSecurity, + onClearSearch, }) => { return ( - - + + {/* 左侧:标题和状态 */} + 灵活屏 @@ -47,8 +66,102 @@ const FlexScreenHeader: React.FC = memo(({ + - + + {/* 中间:搜索框 */} + + + + + + onSearchQueryChange(e.target.value)} + bg={COLORS.searchBg} + borderRadius="md" + borderColor="#d4a853" + color={COLORS.text} + fontSize="xs" + _placeholder={{ color: COLORS.subText }} + _hover={{ borderColor: '#e6be6a' }} + _focus={{ + borderColor: '#e6be6a', + boxShadow: '0 0 0 1px #d4a853', + }} + /> + {searchQuery && ( + + } + variant="ghost" + color={COLORS.subText} + _hover={{ bg: COLORS.hoverBg, color: COLORS.text }} + onClick={onClearSearch} + aria-label="清空" + /> + + )} + + + {/* 搜索结果下拉 */} + {showResults && ( + + {isSearching ? ( +
+ +
+ ) : searchResults.length > 0 ? ( + + {searchResults.map((stock: SearchResultItem, index: number) => ( + onAddSecurity(stock)} + borderBottomWidth={index < searchResults.length - 1 ? '1px' : '0'} + borderColor={COLORS.border} + > + + + + + {stock.stock_name} + + + {stock.isIndex ? '指数' : '股票'} + + + + {stock.stock_code} + + + + + + ))} + + ) : ( +
+ + 未找到相关证券 + +
+ )} +
+ )} +
+ + {/* 右侧:操作按钮 */} + {/* 清空列表 */} = memo(({ - searchQuery, - onSearchQueryChange, - searchResults, - isSearching, - showResults, - onAddSecurity, - onClearSearch, -}) => { - return ( - - - - - - onSearchQueryChange(e.target.value)} - {...searchInputStyles} - /> - {searchQuery && ( - - } - variant="ghost" - color={COLORS.subText} - _hover={{ bg: COLORS.hoverBg, color: COLORS.text }} - onClick={onClearSearch} - aria-label="清空" - /> - - )} - - - {/* 搜索结果下拉 */} - - - {isSearching ? ( -
- -
- ) : searchResults.length > 0 ? ( - - {searchResults.map((stock, index) => ( - onAddSecurity(stock)} - borderBottomWidth={index < searchResults.length - 1 ? '1px' : '0'} - borderColor={COLORS.border} - > - - - - - {stock.stock_name} - - - {stock.isIndex ? '指数' : '股票'} - - - - {stock.stock_code} - - - } - size="xs" - colorScheme="purple" - variant="ghost" - aria-label="添加" - /> - - - ))} - - ) : ( -
- - 未找到相关证券 - -
- )} -
-
-
- ); -}); - -SearchPanel.displayName = 'SearchPanel'; - -export default SearchPanel; diff --git a/src/views/StockOverview/components/FlexScreen/components/index.ts b/src/views/StockOverview/components/FlexScreen/components/index.ts index 910665c2..894f810e 100644 --- a/src/views/StockOverview/components/FlexScreen/components/index.ts +++ b/src/views/StockOverview/components/FlexScreen/components/index.ts @@ -6,5 +6,4 @@ export { default as MiniTimelineChart } from './MiniTimelineChart'; export { default as OrderBookPanel } from './OrderBookPanel'; export { default as QuoteTile } from './QuoteTile'; export { default as FlexScreenHeader } from './FlexScreenHeader'; -export { default as SearchPanel } from './SearchPanel'; export { default as HotRecommendations } from './HotRecommendations'; diff --git a/src/views/StockOverview/components/FlexScreen/index.tsx b/src/views/StockOverview/components/FlexScreen/index.tsx index 4859cdf2..6f50804d 100644 --- a/src/views/StockOverview/components/FlexScreen/index.tsx +++ b/src/views/StockOverview/components/FlexScreen/index.tsx @@ -17,7 +17,6 @@ import { Text, SimpleGrid, Icon, - Collapse, Center, useToast, } from '@chakra-ui/react'; @@ -28,7 +27,6 @@ import { getFullCode } from './hooks/utils'; import { QuoteTile, FlexScreenHeader, - SearchPanel, HotRecommendations, } from './components'; import { logger } from '@utils/logger'; @@ -62,7 +60,7 @@ const FlexScreen: React.FC = () => { const [searchResults, setSearchResults] = useState([]); const [isSearching, setIsSearching] = useState(false); const [showResults, setShowResults] = useState(false); - // 面板状态 + // 面板状态(默认收起) const [isCollapsed, setIsCollapsed] = useState(true); // 获取订阅的证券代码列表 @@ -240,7 +238,7 @@ const FlexScreen: React.FC = () => { borderRadius="16px" > - {/* 头部 */} + {/* 头部(含搜索框) */} { onToggleCollapse={toggleCollapse} onClearWatchlist={clearWatchlist} onResetWatchlist={resetWatchlist} + searchQuery={searchQuery} + onSearchQueryChange={setSearchQuery} + searchResults={searchResults} + isSearching={isSearching} + showResults={showResults} + onAddSecurity={addSecurity} + onClearSearch={clearSearch} /> - {/* 搜索框 - 仅展开时显示 */} - - - - {/* 热门推荐 - 仅展开且列表为空时显示 */} - {watchlist.length === 0 && ( - - )} - + {/* 热门推荐 - 仅展开且列表为空时显示 */} + {!isCollapsed && watchlist.length === 0 && ( + + )} {/* 自选列表 */} {watchlist.length > 0 ? ( diff --git a/src/views/StockOverview/components/FlexScreen/types.ts b/src/views/StockOverview/components/FlexScreen/types.ts index aaa17161..dc60cd11 100644 --- a/src/views/StockOverview/components/FlexScreen/types.ts +++ b/src/views/StockOverview/components/FlexScreen/types.ts @@ -407,6 +407,14 @@ export interface FlexScreenHeaderProps { onToggleCollapse: () => void; onClearWatchlist: () => void; onResetWatchlist: () => void; + // 搜索相关 + searchQuery: string; + onSearchQueryChange: (query: string) => void; + searchResults: SearchResultItem[]; + isSearching: boolean; + showResults: boolean; + onAddSecurity: (security: SearchResultItem) => void; + onClearSearch: () => void; } /** SearchPanel Props */