feat: VerticalModeLayout 详情/列表模式自动切换

- 点击事件自动切换到详情模式
- 切换到列表模式时重置详情面板(通过 key 强制重新渲染)
- 添加独立滚动容器,支持左右两侧独立滚动
- 优化布局高度控制,使用 h="100%" 撑满父容器

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zdl
2025-11-06 14:13:06 +08:00
parent f5328ec3a1
commit 291362b88d

View File

@@ -1,7 +1,7 @@
// src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js // src/views/Community/components/DynamicNewsCard/VerticalModeLayout.js
// 纵向分栏模式布局组件 // 纵向分栏模式布局组件
import React, { useState } from 'react'; import React, { useState, useEffect } from 'react';
import { Box, IconButton, Tooltip, VStack, Flex } 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';
@@ -35,9 +35,25 @@ const VerticalModeLayout = ({
// 布局模式状态:'detail' = 聚焦详情(默认),'list' = 聚焦列表 // 布局模式状态:'detail' = 聚焦详情(默认),'list' = 聚焦列表
const [layoutMode, setLayoutMode] = useState('list'); const [layoutMode, setLayoutMode] = useState('list');
// 详情面板重置 key切换到 list 模式时改变,强制重新渲染)
const [detailPanelKey, setDetailPanelKey] = useState(0);
// 监听事件选择 - 自动切换到详情模式
useEffect(() => {
if (selectedEvent) {
setLayoutMode('detail');
}
}, [selectedEvent]);
// 切换布局模式 // 切换布局模式
const toggleLayoutMode = () => { const toggleLayoutMode = () => {
setLayoutMode(prev => prev === 'detail' ? 'list' : 'detail'); const newMode = layoutMode === 'detail' ? 'list' : 'detail';
setLayoutMode(newMode);
// 如果切换到 list 模式,重置详情面板(收起所有 CollapsibleSection
if (newMode === 'list') {
setDetailPanelKey(prev => prev + 1); // 改变 key强制重新渲染
}
}; };
// 根据模式计算 flex 比例 // 根据模式计算 flex 比例
@@ -50,9 +66,33 @@ const VerticalModeLayout = ({
gap={6} gap={6}
position="relative" position="relative"
transition="all 0.3s ease-in-out" transition="all 0.3s ease-in-out"
h="100%"
overflow="hidden"
> >
{/* 左侧:事件列表 - 使用分页模式 */} {/* 左侧:事件列表 - 独立滚动 */}
<Box flex={leftFlex} minWidth={0}> <Box
flex={leftFlex}
minWidth={0}
overflowY="auto"
h="100%"
data-scroll-container="true"
css={{
overscrollBehavior: 'contain',
'&::-webkit-scrollbar': {
width: '6px',
},
'&::-webkit-scrollbar-track': {
background: '#f1f1f1',
},
'&::-webkit-scrollbar-thumb': {
background: '#888',
borderRadius: '3px',
},
'&::-webkit-scrollbar-thumb:hover': {
background: '#555',
},
}}
>
{/* 事件列表 */} {/* 事件列表 */}
<VStack <VStack
spacing={2} spacing={2}
@@ -76,12 +116,13 @@ const VerticalModeLayout = ({
</VStack> </VStack>
</Box> </Box>
{/* 右侧:事件详情 */} {/* 右侧:事件详情 - 独立滚动 */}
<Box <Box
flex={rightFlex} flex={rightFlex}
minHeight={0} minHeight={0}
position="relative" position="relative"
overflow="hidden" overflow="hidden"
h="100%"
> >
{/* 布局切换按钮 */} {/* 布局切换按钮 */}
<Tooltip <Tooltip
@@ -104,6 +145,7 @@ const VerticalModeLayout = ({
{/* 详情面板 */} {/* 详情面板 */}
<EventDetailScrollPanel <EventDetailScrollPanel
key={detailPanelKey}
selectedEvent={selectedEvent} selectedEvent={selectedEvent}
/> />
</Box> </Box>