78 lines
2.2 KiB
TypeScript
78 lines
2.2 KiB
TypeScript
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
|
import React from 'react';
|
|
import { Box } from './Box';
|
|
import { Button } from './Button';
|
|
import { Text } from './Text';
|
|
|
|
export interface PaginationProps {
|
|
currentPage: number;
|
|
totalPages: number;
|
|
onPageChange: (page: number) => void;
|
|
}
|
|
|
|
export const Pagination = ({
|
|
currentPage,
|
|
totalPages,
|
|
onPageChange
|
|
}: PaginationProps) => {
|
|
const pages = Array.from({ length: totalPages }, (_, i) => i + 1);
|
|
|
|
const visiblePages = pages.filter(page => {
|
|
if (totalPages <= 7) return true;
|
|
if (page === 1 || page === totalPages) return true;
|
|
if (page >= currentPage - 1 && page <= currentPage + 1) return true;
|
|
return false;
|
|
});
|
|
|
|
return (
|
|
<Box display="flex" alignItems="center" justifyContent="between" paddingTop={4}>
|
|
<Text size="sm" variant="low">
|
|
Page {currentPage} of {totalPages}
|
|
</Text>
|
|
|
|
<Box display="flex" alignItems="center" gap={2}>
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
disabled={currentPage === 1}
|
|
onClick={() => onPageChange(currentPage - 1)}
|
|
icon={<ChevronLeft size={16} />}
|
|
>
|
|
Previous
|
|
</Button>
|
|
|
|
<Box display="flex" alignItems="center" gap={1}>
|
|
{visiblePages.map((page, index) => {
|
|
const prevPage = visiblePages[index - 1];
|
|
const showEllipsis = prevPage && page - prevPage > 1;
|
|
|
|
return (
|
|
<React.Fragment key={page}>
|
|
{showEllipsis && <Text variant="low">...</Text>}
|
|
<Button
|
|
variant={page === currentPage ? 'primary' : 'ghost'}
|
|
size="sm"
|
|
onClick={() => onPageChange(page)}
|
|
style={{ minWidth: '2.5rem', padding: 0 }}
|
|
>
|
|
{page}
|
|
</Button>
|
|
</React.Fragment>
|
|
);
|
|
})}
|
|
</Box>
|
|
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
disabled={currentPage === totalPages}
|
|
onClick={() => onPageChange(currentPage + 1)}
|
|
icon={<ChevronRight size={16} />}
|
|
>
|
|
Next
|
|
</Button>
|
|
</Box>
|
|
</Box>
|
|
);
|
|
};
|