refactor: 提取翻页按钮为可复用组件
- 创建 PageNavigationButton 组件 · 通过 direction 参数区分上一页/下一页 · 内置主题适配和模式判断逻辑 · 自动处理显示条件(只在单排/双排模式显示) - 重构 EventScrollList · 删除重复的翻页按钮代码(减少 66 行) · 使用 PageNavigationButton 组件替换原有按钮 · 移除未使用的导入(IconButton, ChevronLeftIcon, ChevronRightIcon) · 移除翻页按钮主题色定义(已移至子组件) 优点: - 消除重复代码,提升可维护性 - 职责分离,逻辑更清晰 - 易于扩展(可添加首页/末页按钮)
This commit is contained in:
@@ -7,7 +7,6 @@ import {
|
|||||||
Flex,
|
Flex,
|
||||||
Grid,
|
Grid,
|
||||||
GridItem,
|
GridItem,
|
||||||
IconButton,
|
|
||||||
Button,
|
Button,
|
||||||
ButtonGroup,
|
ButtonGroup,
|
||||||
Center,
|
Center,
|
||||||
@@ -17,13 +16,13 @@ import {
|
|||||||
Text,
|
Text,
|
||||||
useColorModeValue
|
useColorModeValue
|
||||||
} from '@chakra-ui/react';
|
} from '@chakra-ui/react';
|
||||||
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
|
|
||||||
import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard';
|
import DynamicNewsEventCard from '../EventCard/DynamicNewsEventCard';
|
||||||
import CompactEventCard from '../EventCard/CompactEventCard';
|
import CompactEventCard from '../EventCard/CompactEventCard';
|
||||||
import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard';
|
import HorizontalDynamicNewsEventCard from '../EventCard/HorizontalDynamicNewsEventCard';
|
||||||
import DynamicNewsDetailPanel from '../DynamicNewsDetail';
|
import DynamicNewsDetailPanel from '../DynamicNewsDetail';
|
||||||
import PaginationControl from './PaginationControl';
|
import PaginationControl from './PaginationControl';
|
||||||
import VirtualizedFourRowGrid from './VirtualizedFourRowGrid';
|
import VirtualizedFourRowGrid from './VirtualizedFourRowGrid';
|
||||||
|
import PageNavigationButton from './PageNavigationButton';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 事件列表组件 - 支持两种展示模式
|
* 事件列表组件 - 支持两种展示模式
|
||||||
@@ -68,10 +67,6 @@ const EventScrollList = ({
|
|||||||
const timelineBorderColor = useColorModeValue('gray.400', 'gray.500');
|
const timelineBorderColor = useColorModeValue('gray.400', 'gray.500');
|
||||||
const timelineTextColor = useColorModeValue('blue.600', 'blue.400');
|
const timelineTextColor = useColorModeValue('blue.600', 'blue.400');
|
||||||
|
|
||||||
// 翻页按钮颜色
|
|
||||||
const arrowBtnBg = useColorModeValue('rgba(255, 255, 255, 0.9)', 'rgba(0, 0, 0, 0.6)');
|
|
||||||
const arrowBtnHoverBg = useColorModeValue('rgba(255, 255, 255, 1)', 'rgba(0, 0, 0, 0.8)');
|
|
||||||
|
|
||||||
// 滚动条颜色
|
// 滚动条颜色
|
||||||
const scrollbarTrackBg = useColorModeValue('#f1f1f1', '#2D3748');
|
const scrollbarTrackBg = useColorModeValue('#f1f1f1', '#2D3748');
|
||||||
const scrollbarThumbBg = useColorModeValue('#888', '#4A5568');
|
const scrollbarThumbBg = useColorModeValue('#888', '#4A5568');
|
||||||
@@ -140,68 +135,21 @@ const EventScrollList = ({
|
|||||||
{/* 横向滚动区域 */}
|
{/* 横向滚动区域 */}
|
||||||
<Box position="relative">
|
<Box position="relative">
|
||||||
|
|
||||||
{/* 左侧翻页按钮 - 上一页 */}
|
{/* 翻页导航按钮 */}
|
||||||
{currentPage > 1 && (
|
<PageNavigationButton
|
||||||
<IconButton
|
direction="prev"
|
||||||
icon={<ChevronLeftIcon boxSize={6} color="blue.500" />}
|
currentPage={currentPage}
|
||||||
position="absolute"
|
totalPages={totalPages}
|
||||||
left="0"
|
onPageChange={onPageChange}
|
||||||
top="50%"
|
mode={mode}
|
||||||
transform="translateY(-50%)"
|
|
||||||
zIndex={2}
|
|
||||||
onClick={() => {
|
|
||||||
console.log(`%c🔵 [翻页] 点击上一页: 当前页${currentPage} → 目标页${currentPage - 1} (共${totalPages}页)`, 'color: #3B82F6; font-weight: bold;');
|
|
||||||
onPageChange(currentPage - 1);
|
|
||||||
}}
|
|
||||||
variant="ghost"
|
|
||||||
size="md"
|
|
||||||
w="40px"
|
|
||||||
h="40px"
|
|
||||||
minW="40px"
|
|
||||||
borderRadius="full"
|
|
||||||
bg={arrowBtnBg}
|
|
||||||
boxShadow="0 2px 8px rgba(0, 0, 0, 0.15)"
|
|
||||||
_hover={{
|
|
||||||
bg: arrowBtnHoverBg,
|
|
||||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2)',
|
|
||||||
transform: 'translateY(-50%) scale(1.05)'
|
|
||||||
}}
|
|
||||||
aria-label="上一页"
|
|
||||||
title="上一页"
|
|
||||||
/>
|
/>
|
||||||
)}
|
<PageNavigationButton
|
||||||
|
direction="next"
|
||||||
{/* 右侧翻页按钮 - 下一页 */}
|
currentPage={currentPage}
|
||||||
{currentPage < totalPages && (
|
totalPages={totalPages}
|
||||||
<IconButton
|
onPageChange={onPageChange}
|
||||||
icon={<ChevronRightIcon boxSize={6} color="blue.500" />}
|
mode={mode}
|
||||||
position="absolute"
|
|
||||||
right="0"
|
|
||||||
top="50%"
|
|
||||||
transform="translateY(-50%)"
|
|
||||||
zIndex={2}
|
|
||||||
onClick={() => {
|
|
||||||
console.log(`%c🔵 [翻页] 点击下一页: 当前页${currentPage} → 目标页${currentPage + 1} (共${totalPages}页)`, 'color: #3B82F6; font-weight: bold;');
|
|
||||||
onPageChange(currentPage + 1);
|
|
||||||
}}
|
|
||||||
variant="ghost"
|
|
||||||
size="md"
|
|
||||||
w="40px"
|
|
||||||
h="40px"
|
|
||||||
minW="40px"
|
|
||||||
borderRadius="full"
|
|
||||||
bg={arrowBtnBg}
|
|
||||||
boxShadow="0 2px 8px rgba(0, 0, 0, 0.15)"
|
|
||||||
_hover={{
|
|
||||||
bg: arrowBtnHoverBg,
|
|
||||||
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2)',
|
|
||||||
transform: 'translateY(-50%) scale(1.05)'
|
|
||||||
}}
|
|
||||||
isDisabled={currentPage >= totalPages}
|
|
||||||
aria-label="下一页"
|
|
||||||
title="下一页"
|
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 事件卡片容器 */}
|
{/* 事件卡片容器 */}
|
||||||
<Box
|
<Box
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
// src/views/Community/components/DynamicNewsCard/PageNavigationButton.js
|
||||||
|
// 翻页导航按钮组件
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { IconButton, useColorModeValue } from '@chakra-ui/react';
|
||||||
|
import { ChevronLeftIcon, ChevronRightIcon } from '@chakra-ui/icons';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 翻页导航按钮组件
|
||||||
|
* @param {Object} props
|
||||||
|
* @param {'prev'|'next'} props.direction - 按钮方向(prev=上一页,next=下一页)
|
||||||
|
* @param {number} props.currentPage - 当前页码
|
||||||
|
* @param {number} props.totalPages - 总页数
|
||||||
|
* @param {Function} props.onPageChange - 翻页回调
|
||||||
|
* @param {string} props.mode - 显示模式(只在carousel/grid模式下显示)
|
||||||
|
*/
|
||||||
|
const PageNavigationButton = ({
|
||||||
|
direction,
|
||||||
|
currentPage,
|
||||||
|
totalPages,
|
||||||
|
onPageChange,
|
||||||
|
mode
|
||||||
|
}) => {
|
||||||
|
// 主题适配
|
||||||
|
const arrowBtnBg = useColorModeValue('rgba(255, 255, 255, 0.9)', 'rgba(0, 0, 0, 0.6)');
|
||||||
|
const arrowBtnHoverBg = useColorModeValue('rgba(255, 255, 255, 1)', 'rgba(0, 0, 0, 0.8)');
|
||||||
|
|
||||||
|
// 根据方向计算配置
|
||||||
|
const isPrev = direction === 'prev';
|
||||||
|
const isNext = direction === 'next';
|
||||||
|
|
||||||
|
const Icon = isPrev ? ChevronLeftIcon : ChevronRightIcon;
|
||||||
|
const position = isPrev ? 'left' : 'right';
|
||||||
|
const label = isPrev ? '上一页' : '下一页';
|
||||||
|
const targetPage = isPrev ? currentPage - 1 : currentPage + 1;
|
||||||
|
const shouldShow = isPrev
|
||||||
|
? currentPage > 1
|
||||||
|
: currentPage < totalPages;
|
||||||
|
const isDisabled = isNext ? currentPage >= totalPages : false;
|
||||||
|
|
||||||
|
// 判断是否显示(只在单排/双排模式显示)
|
||||||
|
const shouldRender = shouldShow && (mode === 'carousel' || mode === 'grid');
|
||||||
|
|
||||||
|
if (!shouldRender) return null;
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
console.log(
|
||||||
|
`%c🔵 [翻页] 点击${label}: 当前页${currentPage} → 目标页${targetPage} (共${totalPages}页)`,
|
||||||
|
'color: #3B82F6; font-weight: bold;'
|
||||||
|
);
|
||||||
|
onPageChange(targetPage);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<IconButton
|
||||||
|
icon={<Icon boxSize={6} color="blue.500" />}
|
||||||
|
position="absolute"
|
||||||
|
{...{ [position]: 0 }}
|
||||||
|
top="50%"
|
||||||
|
transform="translateY(-50%)"
|
||||||
|
zIndex={2}
|
||||||
|
onClick={handleClick}
|
||||||
|
variant="ghost"
|
||||||
|
size="md"
|
||||||
|
w="40px"
|
||||||
|
h="40px"
|
||||||
|
minW="40px"
|
||||||
|
borderRadius="full"
|
||||||
|
bg={arrowBtnBg}
|
||||||
|
boxShadow="0 2px 8px rgba(0, 0, 0, 0.15)"
|
||||||
|
_hover={{
|
||||||
|
bg: arrowBtnHoverBg,
|
||||||
|
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.2)',
|
||||||
|
transform: 'translateY(-50%) scale(1.05)'
|
||||||
|
}}
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
aria-label={label}
|
||||||
|
title={label}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PageNavigationButton;
|
||||||
Reference in New Issue
Block a user