Files
vf_react/src/views/Company/components/StockQuoteCard/components/StockHeader.tsx
zdl 61e159f29b refactor(StockQuoteCard): 子组件提取与 DEEP_SPACE_THEME 统一
- PriceDisplay: 更新为 DEEP_SPACE_THEME,添加发光效果
- StockHeader: 更新为 DEEP_SPACE_THEME,金色边框和发光
- MetricRow: 新建指标行组件,支持普通和高亮模式
- 主组件从 321 行精简到 180 行(-44%)
- 统一使用提取的子组件,移除内联代码

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-19 13:03:21 +08:00

142 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* StockHeader - 股票头部原子组件
*
* 深空 FUI 设计风格:
* - 股票名称带金色发光
* - 行业标签使用金色边框
* - 操作按钮悬停态有玻璃效果
*/
import React, { memo } from 'react';
import { Flex, HStack, Text, Badge, IconButton, Tooltip } from '@chakra-ui/react';
import { Share2 } from 'lucide-react';
import FavoriteButton from '@components/FavoriteButton';
import CompareStockInput from './CompareStockInput';
import { DEEP_SPACE_THEME as T } from './theme';
export interface StockHeaderProps {
/** 股票名称 */
name: string;
/** 股票代码 */
code: string;
/** 一级行业 */
industryL1?: string;
/** 二级行业 */
industry?: string;
/** 指数标签沪深300、中证500等 */
indexTags?: string[];
/** 更新时间 */
updateTime?: string;
// 关注相关
isInWatchlist?: boolean;
isWatchlistLoading?: boolean;
onWatchlistToggle?: () => void;
// 分享
onShare?: () => void;
// 对比相关
isCompareLoading?: boolean;
onCompare?: (stockCode: string) => void;
}
/**
* 股票头部组件
*
* 包含:
* - 左侧:股票名称、代码、行业标签、指数标签
* - 右侧:对比输入、关注按钮、分享按钮、更新时间
*/
export const StockHeader: React.FC<StockHeaderProps> = memo(({
name,
code,
industryL1,
industry,
indexTags,
updateTime,
isInWatchlist = false,
isWatchlistLoading = false,
onWatchlistToggle,
onShare,
isCompareLoading = false,
onCompare,
}) => {
return (
<Flex justify="space-between" align="center">
{/* 左侧:股票名称 + 行业标签 + 指数标签 */}
<HStack spacing={4} align="center">
{/* 股票名称 - 金色发光效果 */}
<Text
fontSize="24px"
fontWeight="800"
color={T.textPrimary}
textShadow={`0 0 20px ${T.gold}40`}
>
{name}
</Text>
<Text fontSize="16px" color={T.textMuted} fontWeight="normal">
({code})
</Text>
{/* 行业标签 - 金色边框 */}
{(industryL1 || industry) && (
<Badge
bg="transparent"
color={T.textSecondary}
fontSize="13px"
fontWeight="500"
border="1px solid"
borderColor={T.borderGold}
px={3}
py={1}
borderRadius={T.radiusMD}
>
{industryL1 && industry
? `${industryL1} · ${industry}`
: industry || industryL1}
</Badge>
)}
{/* 指数标签 */}
{indexTags && indexTags.length > 0 && (
<Text fontSize="13px" color={T.textMuted}>
{indexTags.join('、')}
</Text>
)}
</HStack>
{/* 右侧:对比 + 关注 + 分享 + 时间 */}
<HStack spacing={3}>
{/* 股票对比输入 */}
<CompareStockInput
onCompare={onCompare || (() => {})}
isLoading={isCompareLoading}
currentStockCode={code}
/>
<FavoriteButton
isFavorite={isInWatchlist}
isLoading={isWatchlistLoading}
onClick={onWatchlistToggle || (() => {})}
colorScheme="gold"
size="sm"
/>
<Tooltip label="分享" placement="top">
<IconButton
aria-label="分享"
icon={<Share2 size={18} />}
variant="ghost"
color={T.textSecondary}
size="sm"
borderRadius={T.radiusSM}
onClick={onShare}
_hover={{ bg: T.borderGlass, color: T.textPrimary }}
/>
</Tooltip>
<Text fontSize="13px" color={T.textMuted}>
{updateTime?.split(' ')[1] || '--:--'}
</Text>
</HStack>
</Flex>
);
});
StockHeader.displayName = 'StockHeader';