update ui
This commit is contained in:
@@ -146,7 +146,7 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
>
|
||||
<CardBody p={3} pb={2}>
|
||||
{/* 右上角:关注按钮 */}
|
||||
<Box position="absolute" top={2} right={2} zIndex={1}>
|
||||
<Box position="absolute" top={2} right={2} zIndex={2}>
|
||||
<EventFollowButton
|
||||
isFollowing={isFollowing}
|
||||
followerCount={followerCount}
|
||||
@@ -156,6 +156,18 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Keywords梦幻轮播 - 绝对定位在卡片右侧空白处 */}
|
||||
{event.keywords && event.keywords.length > 0 && (
|
||||
<KeywordsCarousel
|
||||
keywords={event.keywords}
|
||||
interval={4000}
|
||||
onKeywordClick={(keyword) => {
|
||||
console.log('Keyword clicked:', keyword);
|
||||
// TODO: 实现关键词筛选功能
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<VStack align="stretch" spacing={1.5}>
|
||||
{/* 标题 - 最多两行,hover 显示完整内容 */}
|
||||
<Tooltip
|
||||
@@ -173,7 +185,7 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
cursor="pointer"
|
||||
onClick={(e) => onTitleClick?.(e, event)}
|
||||
mt={1}
|
||||
paddingRight="10px"
|
||||
paddingRight="120px"
|
||||
>
|
||||
<Text
|
||||
fontSize="md"
|
||||
@@ -188,37 +200,13 @@ const HorizontalDynamicNewsEventCard = ({
|
||||
</Box>
|
||||
</Tooltip>
|
||||
|
||||
{/* 第二行:涨跌幅数据 + Keywords轮播 */}
|
||||
<HStack spacing={3} align="center" justify="space-between" w="full">
|
||||
{/* 左侧:涨跌幅数据 */}
|
||||
{/* 第二行:涨跌幅数据 */}
|
||||
<StockChangeIndicators
|
||||
avgChange={event.related_avg_chg}
|
||||
maxChange={event.related_max_chg}
|
||||
weekChange={event.related_week_chg}
|
||||
size={indicatorSize}
|
||||
/>
|
||||
|
||||
{/* 右侧:Keywords轮播(半透明效果) */}
|
||||
{event.keywords && event.keywords.length > 0 && (
|
||||
<Box
|
||||
flex="1"
|
||||
minW={0}
|
||||
opacity={0.85}
|
||||
_hover={{ opacity: 1 }}
|
||||
transition="opacity 0.2s"
|
||||
>
|
||||
<KeywordsCarousel
|
||||
keywords={event.keywords}
|
||||
displayCount={3}
|
||||
interval={3500}
|
||||
onKeywordClick={(keyword) => {
|
||||
console.log('Keyword clicked:', keyword);
|
||||
// TODO: 实现关键词筛选功能
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
)}
|
||||
</HStack>
|
||||
</VStack>
|
||||
</CardBody>
|
||||
</Card>
|
||||
|
||||
@@ -1,31 +1,31 @@
|
||||
// src/views/Community/components/EventCard/KeywordsCarousel.js
|
||||
// Keywords标签轮播组件
|
||||
// Keywords标签梦幻淡入淡出轮播组件
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Box, Tag, HStack, useColorModeValue, Tooltip } from '@chakra-ui/react';
|
||||
import { Box, Text, useColorModeValue } from '@chakra-ui/react';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
const MotionBox = motion(Box);
|
||||
|
||||
/**
|
||||
* Keywords标签轮播组件
|
||||
* Keywords标签梦幻轮播组件(单个显示,淡入淡出)
|
||||
* @param {Array} keywords - 关键词数组
|
||||
* @param {number} displayCount - 显示的标签数量(默认3个)
|
||||
* @param {number} interval - 轮播间隔(毫秒,默认3000ms)
|
||||
* @param {number} interval - 轮播间隔(毫秒,默认4000ms)
|
||||
* @param {Function} onKeywordClick - 关键词点击回调
|
||||
*/
|
||||
const KeywordsCarousel = ({
|
||||
keywords = [],
|
||||
displayCount = 3,
|
||||
interval = 3000,
|
||||
interval = 4000,
|
||||
onKeywordClick
|
||||
}) => {
|
||||
const [currentIndex, setCurrentIndex] = useState(0);
|
||||
const [isPaused, setIsPaused] = useState(false);
|
||||
|
||||
// 颜色配置
|
||||
const tagBg = useColorModeValue('rgba(66, 153, 225, 0.1)', 'rgba(66, 153, 225, 0.2)');
|
||||
const tagColor = useColorModeValue('blue.600', 'blue.300');
|
||||
const tagBorder = useColorModeValue('blue.200', 'blue.600');
|
||||
// 颜色配置 - 梦幻渐变效果
|
||||
const textColor = useColorModeValue(
|
||||
'linear(to-r, purple.400, pink.400, blue.400)',
|
||||
'linear(to-r, purple.300, pink.300, blue.300)'
|
||||
);
|
||||
const hoverBg = useColorModeValue('rgba(159, 122, 234, 0.1)', 'rgba(159, 122, 234, 0.15)');
|
||||
|
||||
// 如果没有keywords,不渲染
|
||||
if (!keywords || keywords.length === 0) {
|
||||
@@ -34,98 +34,66 @@ const KeywordsCarousel = ({
|
||||
|
||||
// 自动轮播
|
||||
useEffect(() => {
|
||||
if (isPaused || keywords.length <= displayCount) return;
|
||||
if (isPaused || keywords.length <= 1) return;
|
||||
|
||||
const timer = setInterval(() => {
|
||||
setCurrentIndex((prev) => (prev + 1) % keywords.length);
|
||||
}, interval);
|
||||
|
||||
return () => clearInterval(timer);
|
||||
}, [isPaused, keywords.length, displayCount, interval]);
|
||||
}, [isPaused, keywords.length, interval]);
|
||||
|
||||
// 获取当前显示的关键词
|
||||
const getVisibleKeywords = () => {
|
||||
if (keywords.length <= displayCount) {
|
||||
return keywords;
|
||||
}
|
||||
|
||||
const visible = [];
|
||||
for (let i = 0; i < displayCount; i++) {
|
||||
const index = (currentIndex + i) % keywords.length;
|
||||
visible.push(keywords[index]);
|
||||
}
|
||||
return visible;
|
||||
};
|
||||
|
||||
const visibleKeywords = getVisibleKeywords();
|
||||
const currentKeyword = keywords[currentIndex];
|
||||
|
||||
return (
|
||||
<Box
|
||||
onMouseEnter={() => setIsPaused(true)}
|
||||
onMouseLeave={() => setIsPaused(false)}
|
||||
position="relative"
|
||||
>
|
||||
<HStack spacing={1.5} flexWrap="wrap">
|
||||
<AnimatePresence mode="wait">
|
||||
{visibleKeywords.map((keyword, index) => (
|
||||
<MotionBox
|
||||
key={`${keyword}-${currentIndex}-${index}`}
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.8 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
>
|
||||
<Tooltip
|
||||
label={`点击筛选"${keyword}"`}
|
||||
placement="top"
|
||||
hasArrow
|
||||
>
|
||||
<Tag
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
bg={tagBg}
|
||||
color={tagColor}
|
||||
borderWidth="1px"
|
||||
borderColor={tagBorder}
|
||||
cursor="pointer"
|
||||
fontSize="10px"
|
||||
fontWeight="medium"
|
||||
px={2}
|
||||
py={0.5}
|
||||
borderRadius="full"
|
||||
_hover={{
|
||||
bg: useColorModeValue('blue.100', 'blue.700'),
|
||||
transform: 'scale(1.05)',
|
||||
boxShadow: 'md'
|
||||
}}
|
||||
transition="all 0.2s"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onKeywordClick?.(keyword);
|
||||
}}
|
||||
>
|
||||
#{keyword}
|
||||
</Tag>
|
||||
</Tooltip>
|
||||
</MotionBox>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
</HStack>
|
||||
|
||||
{/* 如果有更多关键词,显示指示器 */}
|
||||
{keywords.length > displayCount && (
|
||||
<Box
|
||||
position="absolute"
|
||||
right={-2}
|
||||
right={4}
|
||||
top="50%"
|
||||
transform="translateY(-50%)"
|
||||
fontSize="10px"
|
||||
color="gray.400"
|
||||
fontWeight="bold"
|
||||
onMouseEnter={() => setIsPaused(true)}
|
||||
onMouseLeave={() => setIsPaused(false)}
|
||||
pointerEvents="auto"
|
||||
zIndex={1}
|
||||
>
|
||||
+{keywords.length - displayCount}
|
||||
</Box>
|
||||
)}
|
||||
<AnimatePresence mode="wait">
|
||||
<MotionBox
|
||||
key={`keyword-${currentKeyword}-${currentIndex}`}
|
||||
initial={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}
|
||||
animate={{ opacity: 1, scale: 1, filter: 'blur(0px)' }}
|
||||
exit={{ opacity: 0, scale: 0.8, filter: 'blur(4px)' }}
|
||||
transition={{
|
||||
duration: 0.8,
|
||||
ease: [0.4, 0, 0.2, 1]
|
||||
}}
|
||||
cursor="pointer"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onKeywordClick?.(currentKeyword);
|
||||
}}
|
||||
px={3}
|
||||
py={1.5}
|
||||
borderRadius="full"
|
||||
bg="transparent"
|
||||
_hover={{
|
||||
bg: hoverBg,
|
||||
transform: 'scale(1.05)',
|
||||
}}
|
||||
transition="background 0.3s, transform 0.2s"
|
||||
>
|
||||
<Text
|
||||
bgGradient={textColor}
|
||||
bgClip="text"
|
||||
fontSize="md"
|
||||
fontWeight="bold"
|
||||
letterSpacing="wide"
|
||||
whiteSpace="nowrap"
|
||||
textShadow="0 0 20px rgba(159, 122, 234, 0.3)"
|
||||
>
|
||||
{currentKeyword}
|
||||
</Text>
|
||||
</MotionBox>
|
||||
</AnimatePresence>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user