From bdea4209b2c80741f9565400bc697202c03eab16 Mon Sep 17 00:00:00 2001 From: zdl <3489966805@qq.com> Date: Mon, 3 Nov 2025 11:42:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=20EventScrollList.js?= =?UTF-8?q?=20=E7=BB=84=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Community/components/DynamicNewsCard.js | 158 +--------------- .../DynamicNewsCard/EventScrollList.js | 175 ++++++++++++++++++ 2 files changed, 184 insertions(+), 149 deletions(-) create mode 100644 src/views/Community/components/DynamicNewsCard/EventScrollList.js diff --git a/src/views/Community/components/DynamicNewsCard.js b/src/views/Community/components/DynamicNewsCard.js index f264d44f..e273d10a 100644 --- a/src/views/Community/components/DynamicNewsCard.js +++ b/src/views/Community/components/DynamicNewsCard.js @@ -1,7 +1,7 @@ // src/views/Community/components/DynamicNewsCard.js // 横向滚动事件卡片组件(实时要闻·动态追踪) -import React, { forwardRef, useRef, useState, useEffect } from 'react'; +import React, { forwardRef, useState, useEffect } from 'react'; import { Card, CardHeader, @@ -13,13 +13,12 @@ import { Heading, Text, Badge, - IconButton, Center, Spinner, useColorModeValue } from '@chakra-ui/react'; -import { ChevronLeftIcon, ChevronRightIcon, TimeIcon } from '@chakra-ui/icons'; -import DynamicNewsEventCard from './EventCard/DynamicNewsEventCard'; +import { TimeIcon } from '@chakra-ui/icons'; +import EventScrollList from './DynamicNewsCard/EventScrollList'; import DynamicNewsDetailPanel from './DynamicNewsDetail'; /** @@ -41,9 +40,6 @@ const DynamicNewsCard = forwardRef(({ }, ref) => { const cardBg = useColorModeValue('white', 'gray.800'); const borderColor = useColorModeValue('gray.200', 'gray.700'); - const scrollContainerRef = useRef(null); - const [showLeftArrow, setShowLeftArrow] = useState(false); - const [showRightArrow, setShowRightArrow] = useState(true); const [selectedEvent, setSelectedEvent] = useState(null); // 默认选中第一个事件 @@ -53,48 +49,6 @@ const DynamicNewsCard = forwardRef(({ } }, [events, selectedEvent]); - // 滚动到左侧 - const scrollLeft = () => { - if (scrollContainerRef.current) { - scrollContainerRef.current.scrollBy({ - left: -400, - behavior: 'smooth' - }); - } - }; - - // 滚动到右侧 - const scrollRight = () => { - if (scrollContainerRef.current) { - scrollContainerRef.current.scrollBy({ - left: 400, - behavior: 'smooth' - }); - } - }; - - // 监听滚动位置,更新箭头显示状态 - const handleScroll = (e) => { - const container = e.target; - const scrollLeft = container.scrollLeft; - const scrollWidth = container.scrollWidth; - const clientWidth = container.clientWidth; - - setShowLeftArrow(scrollLeft > 0); - setShowRightArrow(scrollLeft < scrollWidth - clientWidth - 10); - }; - - // 时间轴样式配置 - const getTimelineBoxStyle = () => { - return { - bg: useColorModeValue('gray.50', 'gray.700'), - borderColor: useColorModeValue('gray.400', 'gray.500'), - borderWidth: '2px', - textColor: useColorModeValue('blue.600', 'blue.400'), - boxShadow: 'sm', - }; - }; - return ( {/* 标题部分 */} @@ -142,106 +96,12 @@ const DynamicNewsCard = forwardRef(({ {/* 横向滚动事件列表 */} {!loading && events && events.length > 0 && ( - - {/* 左侧滚动按钮 */} - {showLeftArrow && ( - } - position="absolute" - left="-4" - top="50%" - transform="translateY(-50%)" - zIndex={2} - onClick={scrollLeft} - colorScheme="blue" - variant="solid" - size="md" - borderRadius="full" - shadow="md" - aria-label="向左滚动" - /> - )} - - {/* 右侧滚动按钮 */} - {showRightArrow && ( - } - position="absolute" - right="-4" - top="50%" - transform="translateY(-50%)" - zIndex={2} - onClick={scrollRight} - colorScheme="blue" - variant="solid" - size="md" - borderRadius="full" - shadow="md" - aria-label="向右滚动" - /> - )} - - {/* 横向滚动容器 */} - - {events.map((event, index) => ( - - { - setSelectedEvent(clickedEvent); - // 只更新详情面板,不触发父组件回调 - }} - onTitleClick={(e) => { - e.preventDefault(); - e.stopPropagation(); - setSelectedEvent(event); - // 只更新详情面板,不触发父组件回调 - }} - onToggleFollow={() => {}} - timelineStyle={getTimelineBoxStyle()} - borderColor={borderColor} - /> - - ))} - - + )} {/* 详情面板 */} diff --git a/src/views/Community/components/DynamicNewsCard/EventScrollList.js b/src/views/Community/components/DynamicNewsCard/EventScrollList.js new file mode 100644 index 00000000..75ce1959 --- /dev/null +++ b/src/views/Community/components/DynamicNewsCard/EventScrollList.js @@ -0,0 +1,175 @@ +// src/views/Community/components/DynamicNewsCard/EventScrollList.js +// 横向滚动事件列表组件 + +import React, { useRef, useState } from 'react'; +import { + Box, + Flex, + IconButton, + useColorModeValue +} from '@chakra-ui/react'; +import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons'; +import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard'; + +/** + * 横向滚动事件列表组件 + * @param {Array} events - 事件列表 + * @param {Object} selectedEvent - 当前选中的事件 + * @param {Function} onEventSelect - 事件选择回调 + * @param {string} borderColor - 边框颜色 + */ +const EventScrollList = ({ + events, + selectedEvent, + onEventSelect, + borderColor +}) => { + const scrollContainerRef = useRef(null); + const [showLeftArrow, setShowLeftArrow] = useState(false); + const [showRightArrow, setShowRightArrow] = useState(true); + + // 滚动到左侧 + const scrollLeft = () => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollBy({ + left: -400, + behavior: 'smooth' + }); + } + }; + + // 滚动到右侧 + const scrollRight = () => { + if (scrollContainerRef.current) { + scrollContainerRef.current.scrollBy({ + left: 400, + behavior: 'smooth' + }); + } + }; + + // 监听滚动位置,更新箭头显示状态 + const handleScroll = (e) => { + const container = e.target; + const scrollLeft = container.scrollLeft; + const scrollWidth = container.scrollWidth; + const clientWidth = container.clientWidth; + + setShowLeftArrow(scrollLeft > 0); + setShowRightArrow(scrollLeft < scrollWidth - clientWidth - 10); + }; + + // 时间轴样式配置 + const getTimelineBoxStyle = () => { + return { + bg: useColorModeValue('gray.50', 'gray.700'), + borderColor: useColorModeValue('gray.400', 'gray.500'), + borderWidth: '2px', + textColor: useColorModeValue('blue.600', 'blue.400'), + boxShadow: 'sm', + }; + }; + + return ( + + {/* 左侧滚动按钮 */} + {showLeftArrow && ( + } + position="absolute" + left="-4" + top="50%" + transform="translateY(-50%)" + zIndex={2} + onClick={scrollLeft} + colorScheme="blue" + variant="solid" + size="md" + borderRadius="full" + shadow="md" + aria-label="向左滚动" + /> + )} + + {/* 右侧滚动按钮 */} + {showRightArrow && ( + } + position="absolute" + right="-4" + top="50%" + transform="translateY(-50%)" + zIndex={2} + onClick={scrollRight} + colorScheme="blue" + variant="solid" + size="md" + borderRadius="full" + shadow="md" + aria-label="向右滚动" + /> + )} + + {/* 横向滚动容器 */} + + {events.map((event, index) => ( + + { + onEventSelect(clickedEvent); + }} + onTitleClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + onEventSelect(event); + }} + onToggleFollow={() => {}} + timelineStyle={getTimelineBoxStyle()} + borderColor={borderColor} + /> + + ))} + + + ); +}; + +export default EventScrollList;