- 新增 CardGlow 组件到 @components/FUI,支持多种颜色主题 (gold/cyan/purple) - 拆分 StockQuoteCard 子组件:GlassSection、LoadingSkeleton - 更新 KeyMetrics、MainForceInfo、SecondaryQuote 使用 DEEP_SPACE_THEME - 主组件从 540 行精简到 321 行(减少 40%) - 删除重复的 GlowDecorations,统一使用 FUI/CardGlow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
141 lines
3.5 KiB
TypeScript
141 lines
3.5 KiB
TypeScript
/**
|
||
* CardGlow - 卡片级装饰光效组件
|
||
*
|
||
* 为卡片提供 FUI 风格的装饰元素:
|
||
* - 顶部光条(Ash Thorp 风格)
|
||
* - 角落发光效果(James Turrell 风格)
|
||
* - 可选背景网格
|
||
*
|
||
* 与 AmbientGlow 的区别:
|
||
* - AmbientGlow: 页面级环境光,position: fixed
|
||
* - CardGlow: 卡片级装饰光,相对于父容器定位
|
||
*
|
||
* @example
|
||
* ```tsx
|
||
* <Box position="relative" overflow="hidden">
|
||
* <CardGlow variant="gold" />
|
||
* {children}
|
||
* </Box>
|
||
* ```
|
||
*/
|
||
|
||
import React, { memo } from 'react';
|
||
import { Box } from '@chakra-ui/react';
|
||
|
||
export interface CardGlowProps {
|
||
/** 预设主题 */
|
||
variant?: 'gold' | 'cyan' | 'purple' | 'default';
|
||
/** 是否显示背景网格 */
|
||
showGrid?: boolean;
|
||
/** 自定义主色(覆盖 variant) */
|
||
primaryColor?: string;
|
||
/** 自定义次色(覆盖 variant) */
|
||
secondaryColor?: string;
|
||
}
|
||
|
||
// 预设颜色配置
|
||
const COLOR_PRESETS = {
|
||
gold: {
|
||
primary: 'rgba(212, 175, 55, 1)',
|
||
secondary: 'rgba(0, 212, 255, 0.1)',
|
||
grid: 'rgba(212, 175, 55, 0.03)',
|
||
},
|
||
cyan: {
|
||
primary: 'rgba(0, 212, 255, 1)',
|
||
secondary: 'rgba(212, 175, 55, 0.1)',
|
||
grid: 'rgba(0, 212, 255, 0.03)',
|
||
},
|
||
purple: {
|
||
primary: 'rgba(168, 85, 247, 1)',
|
||
secondary: 'rgba(0, 212, 255, 0.1)',
|
||
grid: 'rgba(168, 85, 247, 0.03)',
|
||
},
|
||
default: {
|
||
primary: 'rgba(255, 255, 255, 0.6)',
|
||
secondary: 'rgba(255, 255, 255, 0.1)',
|
||
grid: 'rgba(255, 255, 255, 0.02)',
|
||
},
|
||
};
|
||
|
||
/**
|
||
* 卡片装饰光效组件
|
||
*
|
||
* 纯展示组件,需要父容器设置 position: relative 和 overflow: hidden
|
||
*/
|
||
const CardGlow = memo<CardGlowProps>(({
|
||
variant = 'gold',
|
||
showGrid = true,
|
||
primaryColor,
|
||
secondaryColor,
|
||
}) => {
|
||
const preset = COLOR_PRESETS[variant];
|
||
const primary = primaryColor || preset.primary;
|
||
const secondary = secondaryColor || preset.secondary;
|
||
const gridColor = preset.grid;
|
||
|
||
return (
|
||
<>
|
||
{/* 顶部光条 - Ash Thorp 风格数据终端效果 */}
|
||
<Box
|
||
position="absolute"
|
||
top={0}
|
||
left="50%"
|
||
transform="translateX(-50%)"
|
||
width="60%"
|
||
height="1px"
|
||
background={`linear-gradient(90deg, transparent, ${primary}, transparent)`}
|
||
opacity={0.6}
|
||
pointerEvents="none"
|
||
/>
|
||
|
||
{/* 左上角光晕 - James Turrell 风格光影效果 */}
|
||
<Box
|
||
position="absolute"
|
||
top="-40px"
|
||
left="-40px"
|
||
width="80px"
|
||
height="80px"
|
||
borderRadius="50%"
|
||
background={`radial-gradient(circle, ${primary.replace('1)', '0.15)')} 0%, transparent 70%)`}
|
||
filter="blur(20px)"
|
||
pointerEvents="none"
|
||
/>
|
||
|
||
{/* 右下角光晕 - 补充色,增加层次感 */}
|
||
<Box
|
||
position="absolute"
|
||
bottom="-40px"
|
||
right="-40px"
|
||
width="80px"
|
||
height="80px"
|
||
borderRadius="50%"
|
||
background={`radial-gradient(circle, ${secondary} 0%, transparent 70%)`}
|
||
filter="blur(20px)"
|
||
pointerEvents="none"
|
||
/>
|
||
|
||
{/* 背景网格 - 微妙的科技感纹理 */}
|
||
{showGrid && (
|
||
<Box
|
||
position="absolute"
|
||
top={0}
|
||
left={0}
|
||
right={0}
|
||
bottom={0}
|
||
backgroundImage={`
|
||
linear-gradient(${gridColor} 1px, transparent 1px),
|
||
linear-gradient(90deg, ${gridColor} 1px, transparent 1px)
|
||
`}
|
||
backgroundSize="40px 40px"
|
||
pointerEvents="none"
|
||
opacity={0.5}
|
||
/>
|
||
)}
|
||
</>
|
||
);
|
||
});
|
||
|
||
CardGlow.displayName = 'CardGlow';
|
||
|
||
export default CardGlow;
|