feat: 调整纵向列表UI
This commit is contained in:
@@ -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,72 +35,71 @@ 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
|
||||||
key={event.id}
|
key={event.id}
|
||||||
event={event}
|
event={event}
|
||||||
isSelected={selectedEvent?.id === event.id}
|
isSelected={selectedEvent?.id === event.id}
|
||||||
onEventClick={() => onEventSelect(event)}
|
onEventClick={() => onEventSelect(event)}
|
||||||
isFollowing={eventFollowStatus[event.id]?.isFollowing}
|
isFollowing={eventFollowStatus[event.id]?.isFollowing}
|
||||||
followerCount={eventFollowStatus[event.id]?.followerCount}
|
followerCount={eventFollowStatus[event.id]?.followerCount}
|
||||||
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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user