feat(MarketDataView): 添加股票行情骨架屏
- 创建 MarketDataSkeleton 组件(摘要卡片 + K线图表 + Tab) - 配置 Suspense fallback,点击时直接显示骨架屏 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* 股票行情骨架屏组件
|
||||
*/
|
||||
|
||||
import React, { memo } from 'react';
|
||||
import {
|
||||
Box,
|
||||
Container,
|
||||
VStack,
|
||||
HStack,
|
||||
Skeleton,
|
||||
SkeletonText,
|
||||
SimpleGrid,
|
||||
Card,
|
||||
CardBody,
|
||||
} from '@chakra-ui/react';
|
||||
|
||||
// 黑金主题配色
|
||||
const SKELETON_COLORS = {
|
||||
startColor: 'rgba(26, 32, 44, 0.6)',
|
||||
endColor: 'rgba(212, 175, 55, 0.2)',
|
||||
};
|
||||
|
||||
/**
|
||||
* 股票摘要卡片骨架屏
|
||||
*/
|
||||
const SummaryCardSkeleton: React.FC = memo(() => (
|
||||
<Card bg="gray.900" border="1px solid" borderColor="rgba(212, 175, 55, 0.3)">
|
||||
<CardBody>
|
||||
<HStack spacing={8} align="flex-start">
|
||||
{/* 左侧:股票名称和价格 */}
|
||||
<VStack align="flex-start" spacing={2} minW="200px">
|
||||
<Skeleton height="28px" width="150px" {...SKELETON_COLORS} />
|
||||
<Skeleton height="40px" width="120px" {...SKELETON_COLORS} />
|
||||
<HStack spacing={4}>
|
||||
<Skeleton height="20px" width="80px" {...SKELETON_COLORS} />
|
||||
<Skeleton height="20px" width="60px" {...SKELETON_COLORS} />
|
||||
</HStack>
|
||||
</VStack>
|
||||
|
||||
{/* 右侧:指标网格 */}
|
||||
<SimpleGrid columns={4} spacing={4} flex={1}>
|
||||
{[1, 2, 3, 4, 5, 6, 7, 8].map((i) => (
|
||||
<VStack key={i} align="flex-start" spacing={1}>
|
||||
<Skeleton height="14px" width="50px" {...SKELETON_COLORS} />
|
||||
<Skeleton height="20px" width="70px" {...SKELETON_COLORS} />
|
||||
</VStack>
|
||||
))}
|
||||
</SimpleGrid>
|
||||
</HStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
));
|
||||
|
||||
SummaryCardSkeleton.displayName = 'SummaryCardSkeleton';
|
||||
|
||||
/**
|
||||
* K线图表骨架屏
|
||||
*/
|
||||
const ChartSkeleton: React.FC = memo(() => (
|
||||
<Card bg="gray.900" border="1px solid" borderColor="rgba(212, 175, 55, 0.3)">
|
||||
<CardBody>
|
||||
{/* 工具栏 */}
|
||||
<HStack justify="space-between" mb={4}>
|
||||
<HStack spacing={2}>
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<Skeleton key={i} height="32px" width="60px" borderRadius="md" {...SKELETON_COLORS} />
|
||||
))}
|
||||
</HStack>
|
||||
<HStack spacing={2}>
|
||||
<Skeleton height="32px" width="100px" borderRadius="md" {...SKELETON_COLORS} />
|
||||
<Skeleton height="32px" width="32px" borderRadius="md" {...SKELETON_COLORS} />
|
||||
</HStack>
|
||||
</HStack>
|
||||
|
||||
{/* 图表区域 */}
|
||||
<Skeleton height="400px" borderRadius="md" {...SKELETON_COLORS} />
|
||||
</CardBody>
|
||||
</Card>
|
||||
));
|
||||
|
||||
ChartSkeleton.displayName = 'ChartSkeleton';
|
||||
|
||||
/**
|
||||
* Tab 区域骨架屏
|
||||
*/
|
||||
const TabSkeleton: React.FC = memo(() => (
|
||||
<Card bg="gray.900" border="1px solid" borderColor="rgba(212, 175, 55, 0.3)">
|
||||
<CardBody p={0}>
|
||||
{/* Tab 栏 */}
|
||||
<HStack
|
||||
spacing={2}
|
||||
p={3}
|
||||
borderBottom="1px solid"
|
||||
borderColor="rgba(212, 175, 55, 0.2)"
|
||||
>
|
||||
{[1, 2, 3, 4].map((i) => (
|
||||
<Skeleton
|
||||
key={i}
|
||||
height="36px"
|
||||
width="100px"
|
||||
borderRadius="md"
|
||||
{...SKELETON_COLORS}
|
||||
/>
|
||||
))}
|
||||
</HStack>
|
||||
{/* Tab 内容 */}
|
||||
<Box p={4}>
|
||||
<SkeletonText
|
||||
noOfLines={6}
|
||||
spacing={4}
|
||||
skeletonHeight={4}
|
||||
{...SKELETON_COLORS}
|
||||
/>
|
||||
</Box>
|
||||
</CardBody>
|
||||
</Card>
|
||||
));
|
||||
|
||||
TabSkeleton.displayName = 'TabSkeleton';
|
||||
|
||||
/**
|
||||
* 股票行情完整骨架屏
|
||||
*/
|
||||
const MarketDataSkeleton: React.FC = memo(() => (
|
||||
<Box bg="#1A202C" minH="100vh">
|
||||
<Container maxW="container.xl" py={6}>
|
||||
<VStack align="stretch" spacing={6}>
|
||||
<SummaryCardSkeleton />
|
||||
<ChartSkeleton />
|
||||
<TabSkeleton />
|
||||
</VStack>
|
||||
</Container>
|
||||
</Box>
|
||||
));
|
||||
|
||||
MarketDataSkeleton.displayName = 'MarketDataSkeleton';
|
||||
|
||||
export { MarketDataSkeleton };
|
||||
export default MarketDataSkeleton;
|
||||
@@ -5,3 +5,4 @@ export { default as ThemedCard } from './ThemedCard';
|
||||
export { default as MarkdownRenderer } from './MarkdownRenderer';
|
||||
export { default as StockSummaryCard } from './StockSummaryCard';
|
||||
export { default as AnalysisModal, AnalysisContent } from './AnalysisModal';
|
||||
export { MarketDataSkeleton } from './MarketDataSkeleton';
|
||||
|
||||
Reference in New Issue
Block a user