feat: 调整纵向列表UI

This commit is contained in:
zdl
2025-11-05 17:50:33 +08:00
parent e617eddd46
commit 2e89469d05

View File

@@ -2,18 +2,19 @@
// 纵向分栏模式布局组件 // 纵向分栏模式布局组件
import React, { useState } from 'react'; import React, { useState } from 'react';
import { Grid, GridItem, IconButton, Tooltip, VStack } from '@chakra-ui/react'; import { Box, IconButton, Tooltip, VStack, Flex } from '@chakra-ui/react';
import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons'; import { ViewIcon, ViewOffIcon } from '@chakra-ui/icons';
import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard'; import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard';
import EventDetailScrollPanel from './EventDetailScrollPanel'; import EventDetailScrollPanel from './EventDetailScrollPanel';
import PaginationControl from './PaginationControl';
/** /**
* 纵向分栏模式布局 * 纵向分栏模式布局
* 支持两种展示模式: * 支持两种展示模式:
* - detail默认左侧事件列表 1fr | 右侧详情 2fr * - detail默认左侧事件列表 1fr | 右侧详情 2fr
* - list左侧事件列表 3fr | 右侧详情 150px * - list左侧事件列表 7fr | 右侧详情 300px
* *
* 左侧使用分页模式(不使用虚拟滚动),右侧支持布局切换 * 左侧使用分页模式,高度根据内容自适应,分页控制器在左侧列表底部
* *
* @param {Array} events - 当前页的事件列表(分页数据) * @param {Array} events - 当前页的事件列表(分页数据)
* @param {Object} selectedEvent - 当前选中的事件 * @param {Object} selectedEvent - 当前选中的事件
@@ -22,9 +23,9 @@ import EventDetailScrollPanel from './EventDetailScrollPanel';
* @param {Function} onToggleFollow - 关注按钮回调 * @param {Function} onToggleFollow - 关注按钮回调
* @param {Function} getTimelineBoxStyle - 时间线样式获取函数 * @param {Function} getTimelineBoxStyle - 时间线样式获取函数
* @param {string} borderColor - 边框颜色 * @param {string} borderColor - 边框颜色
* @param {string} scrollbarTrackBg - 滚动条轨道背景色 * @param {number} currentPage - 当前页码
* @param {string} scrollbarThumbBg - 滚动条滑块背景色 * @param {number} totalPages - 总页数
* @param {string} scrollbarThumbHoverBg - 滚动条滑块悬浮背景色 * @param {Function} onPageChange - 页码改变回调
*/ */
const VerticalModeLayout = ({ const VerticalModeLayout = ({
events, events,
@@ -34,53 +35,35 @@ const VerticalModeLayout = ({
onToggleFollow, onToggleFollow,
getTimelineBoxStyle, getTimelineBoxStyle,
borderColor, borderColor,
scrollbarTrackBg, currentPage,
scrollbarThumbBg, totalPages,
scrollbarThumbHoverBg, onPageChange,
}) => { }) => {
// 布局模式状态:'detail' = 聚焦详情(默认),'list' = 聚焦列表 // 布局模式状态:'detail' = 聚焦详情(默认),'list' = 聚焦列表
const [layoutMode, setLayoutMode] = useState('detail'); const [layoutMode, setLayoutMode] = useState('list');
// 切换布局模式 // 切换布局模式
const toggleLayoutMode = () => { const toggleLayoutMode = () => {
setLayoutMode(prev => prev === 'detail' ? 'list' : 'detail'); setLayoutMode(prev => prev === 'detail' ? 'list' : 'detail');
}; };
// 根据模式计算 Grid 的 templateColumns // 根据模式计算 flex 比例
const gridTemplateColumns = layoutMode === 'detail' ? '1fr 2fr' : '7fr 300px'; const leftFlex = layoutMode === 'detail' ? '4' : '6';
const rightFlex = layoutMode === 'detail' ? '6' : '4';
return ( return (
<Grid <Flex
templateColumns={gridTemplateColumns}
gap={6} gap={6}
h="800px"
position="relative" position="relative"
transition="grid-template-columns 0.3s ease-in-out" transition="all 0.3s ease-in-out"
> >
{/* 左侧:事件列表 - 使用分页模式 */} {/* 左侧:事件列表 - 使用分页模式 */}
<GridItem h="100%"> <Box flex={leftFlex} minWidth={0}>
{/* 事件列表 */}
<VStack <VStack
spacing={3} spacing={2}
align="stretch" align="stretch"
h="100%"
overflowY="auto"
p={2} p={2}
sx={{
'&::-webkit-scrollbar': {
width: '3px',
},
'&::-webkit-scrollbar-track': {
background: scrollbarTrackBg,
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb': {
background: scrollbarThumbBg,
borderRadius: '10px',
},
'&::-webkit-scrollbar-thumb:hover': {
background: scrollbarThumbHoverBg,
},
}}
> >
{events.map((event) => ( {events.map((event) => (
<HorizontalDynamicNewsEventCard <HorizontalDynamicNewsEventCard
@@ -93,13 +76,30 @@ const VerticalModeLayout = ({
onToggleFollow={onToggleFollow} onToggleFollow={onToggleFollow}
timelineStyle={getTimelineBoxStyle()} timelineStyle={getTimelineBoxStyle()}
borderColor={borderColor} borderColor={borderColor}
indicatorSize={layoutMode === 'detail' ? 'default' : 'comfortable'}
/> />
))} ))}
</VStack> </VStack>
</GridItem>
{/* 右侧:事件详情 (66.7%) */} {/* 分页控制器 */}
<GridItem h="100%" position="relative"> {totalPages > 1 && (
<Flex justify="center" py={3} px={2}>
<PaginationControl
currentPage={currentPage}
totalPages={totalPages}
onPageChange={onPageChange}
/>
</Flex>
)}
</Box>
{/* 右侧:事件详情 */}
<Box
flex={rightFlex}
minHeight={0}
position="relative"
overflow="hidden"
>
{/* 布局切换按钮 */} {/* 布局切换按钮 */}
<Tooltip <Tooltip
label={layoutMode === 'detail' ? '展开事件列表' : '展开详情面板'} label={layoutMode === 'detail' ? '展开事件列表' : '展开详情面板'}
@@ -109,25 +109,22 @@ const VerticalModeLayout = ({
position="absolute" position="absolute"
top={2} top={2}
right={2} right={2}
zIndex={10} zIndex={9999}
size="sm" size="md"
icon={layoutMode === 'detail' ? <ViewOffIcon /> : <ViewIcon />} icon={layoutMode === 'detail' ? <ViewOffIcon /> : <ViewIcon />}
onClick={toggleLayoutMode} onClick={toggleLayoutMode}
aria-label="切换布局模式" aria-label="切换布局模式"
colorScheme="blue" colorScheme="blue"
variant="ghost" variant="solid"
/> />
</Tooltip> </Tooltip>
{/* 详情面板 */} {/* 详情面板 */}
<EventDetailScrollPanel <EventDetailScrollPanel
selectedEvent={selectedEvent} selectedEvent={selectedEvent}
scrollbarTrackBg={scrollbarTrackBg}
scrollbarThumbBg={scrollbarThumbBg}
scrollbarThumbHoverBg={scrollbarThumbHoverBg}
/> />
</GridItem> </Box>
</Grid> </Flex>
); );
}; };