Files
vf_react/src/views/Company/components/LoadingState.tsx
zdl 7496609d8c fix(types): 修复 ECharts 类型导出和组件类型冲突
- echarts.ts: 将 EChartsOption 改为 EChartsCoreOption 的类型别名
- FuiCorners: 移除 extends BoxProps,position 重命名为 corner
- KLineChartModal/TimelineChartModal/ConcentrationCard: 使用导入的 EChartsOption
- LoadingState: 新增骨架屏 variant 支持
- FinancialPanorama: 使用骨架屏加载状态
- useFinancialData/financialService: 优化数据获取逻辑
- Company/index: 简化组件结构

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-18 18:42:19 +08:00

115 lines
2.8 KiB
TypeScript

// src/views/Company/components/LoadingState.tsx
// 统一的加载状态组件 - 黑金主题
import React, { memo } from "react";
import { Center, VStack, Spinner, Text, Box, Skeleton, SimpleGrid } from "@chakra-ui/react";
// 黑金主题配置
const THEME = {
gold: "#D4AF37",
goldLight: "rgba(212, 175, 55, 0.3)",
bgInset: "rgba(26, 32, 44, 0.6)",
borderGlass: "rgba(212, 175, 55, 0.2)",
textSecondary: "gray.400",
radiusSM: "md",
radiusMD: "lg",
};
interface LoadingStateProps {
message?: string;
height?: string;
/** 使用骨架屏模式(更好的视觉体验) */
variant?: "spinner" | "skeleton";
/** 骨架屏行数 */
skeletonRows?: number;
}
/**
* 骨架屏组件(黑金主题)
*/
const SkeletonContent: React.FC<{ rows: number }> = memo(({ rows }) => (
<VStack align="stretch" spacing={4} w="100%">
{/* 头部骨架 */}
<Box display="flex" justifyContent="space-between" alignItems="center">
<Skeleton
height="28px"
width="180px"
startColor={THEME.bgInset}
endColor={THEME.borderGlass}
borderRadius={THEME.radiusSM}
/>
<Skeleton
height="24px"
width="100px"
startColor={THEME.bgInset}
endColor={THEME.borderGlass}
borderRadius={THEME.radiusSM}
/>
</Box>
{/* 内容骨架行 */}
<SimpleGrid columns={{ base: 2, md: 4 }} spacing={4}>
{Array.from({ length: Math.min(rows, 8) }).map((_, i) => (
<Skeleton
key={i}
height="60px"
startColor={THEME.bgInset}
endColor={THEME.borderGlass}
borderRadius={THEME.radiusMD}
/>
))}
</SimpleGrid>
{/* 图表区域骨架 */}
<Skeleton
height="200px"
startColor={THEME.bgInset}
endColor={THEME.borderGlass}
borderRadius={THEME.radiusMD}
/>
</VStack>
));
SkeletonContent.displayName = "SkeletonContent";
/**
* 统一的加载状态组件(黑金主题)
*
* 用于所有一级 Tab 的 loading 状态展示
* @param variant - "spinner"(默认)或 "skeleton"(骨架屏)
*/
const LoadingState: React.FC<LoadingStateProps> = memo(({
message = "加载中...",
height = "300px",
variant = "spinner",
skeletonRows = 4,
}) => {
if (variant === "skeleton") {
return (
<Box h={height} p={4}>
<SkeletonContent rows={skeletonRows} />
</Box>
);
}
return (
<Center h={height}>
<VStack spacing={4}>
<Spinner
size="xl"
color={THEME.gold}
thickness="4px"
speed="0.65s"
/>
<Text fontSize="sm" color={THEME.textSecondary}>
{message}
</Text>
</VStack>
</Center>
);
});
LoadingState.displayName = "LoadingState";
export default LoadingState;