eventx-design-system
Version:
Design System do EventX
108 lines (104 loc) • 5.07 kB
JavaScript
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
import React from 'react';
import styled from 'styled-components';
import { colors, typography, spacing, borderRadius } from '../../tokens/design-tokens';
const PaginationContainer = styled.div `
display: flex;
align-items: center;
justify-content: space-between;
gap: ${spacing[4]};
flex-wrap: wrap;
`;
const PaginationInfo = styled.div `
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.sm};
color: ${colors.neutral[600]};
`;
const PaginationControls = styled.div `
display: flex;
align-items: center;
gap: ${spacing[1]};
`;
const PageButton = styled.button `
min-width: 32px;
height: 32px;
padding: 0 ${spacing[2]};
border: 1px solid ${({ active }) => active ? colors.brand.primary[500] : colors.neutral[300]};
background-color: ${({ active }) => active ? colors.brand.primary[500] : colors.neutral[50]};
color: ${({ active, disabled }) => {
if (disabled)
return colors.neutral[400];
if (active)
return colors.neutral[50];
return colors.neutral[700];
}};
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.sm};
font-weight: ${({ active }) => active ? typography.fontWeight.semibold : typography.fontWeight.normal};
border-radius: ${borderRadius.base};
cursor: ${({ disabled }) => disabled ? 'not-allowed' : 'pointer'};
transition: all 0.2s ease-in-out;
display: flex;
align-items: center;
justify-content: center;
&:hover:not(:disabled) {
background-color: ${({ active }) => active ? colors.brand.primary[600] : colors.neutral[100]};
border-color: ${({ active }) => active ? colors.brand.primary[600] : colors.neutral[400]};
}
&:focus {
outline: none;
box-shadow: 0 0 0 2px ${colors.brand.primary[200]};
}
`;
const NavigationButton = styled(PageButton) `
font-weight: ${typography.fontWeight.medium};
`;
const Ellipsis = styled.span `
padding: 0 ${spacing[1]};
color: ${colors.neutral[500]};
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.sm};
`;
const PageSizeSelect = styled.select `
padding: ${spacing[1]} ${spacing[2]};
border: 1px solid ${colors.neutral[300]};
border-radius: ${borderRadius.base};
font-family: ${typography.fontFamily.primary};
font-size: ${typography.fontSize.sm};
background-color: ${colors.neutral[50]};
color: ${colors.neutral[700]};
cursor: pointer;
&:focus {
outline: none;
box-shadow: 0 0 0 2px ${colors.brand.primary[200]};
border-color: ${colors.brand.primary[500]};
}
`;
export const Pagination = ({ currentPage, totalPages, totalItems, pageSize, pageSizeOptions = [10, 20, 50, 100], onPageChange, onPageSizeChange, showPageSizeSelector = false, showTotalInfo = true, className, }) => {
const startItem = (currentPage - 1) * pageSize + 1;
const endItem = Math.min(currentPage * pageSize, totalItems);
const getVisiblePages = () => {
const delta = 2; // Number of pages to show on each side of current page
const range = [];
const rangeWithDots = [];
for (let i = Math.max(2, currentPage - delta); i <= Math.min(totalPages - 1, currentPage + delta); i++) {
range.push(i);
}
if (currentPage - delta > 2) {
rangeWithDots.push(1, '...');
}
else {
rangeWithDots.push(1);
}
rangeWithDots.push(...range);
if (currentPage + delta < totalPages - 1) {
rangeWithDots.push('...', totalPages);
}
else {
rangeWithDots.push(totalPages);
}
return rangeWithDots;
};
const visiblePages = getVisiblePages();
return (_jsxs(PaginationContainer, { className: className, children: [showTotalInfo && (_jsxs(PaginationInfo, { children: ["Showing ", startItem, " to ", endItem, " of ", totalItems, " items"] })), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: spacing[4] }, children: [showPageSizeSelector && onPageSizeChange && (_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: spacing[2] }, children: [_jsx("span", { style: { fontSize: typography.fontSize.sm, color: colors.neutral[600] }, children: "Show:" }), _jsx(PageSizeSelect, { value: pageSize, onChange: (e) => onPageSizeChange(Number(e.target.value)), children: pageSizeOptions.map(size => (_jsx("option", { value: size, children: size }, size))) })] })), _jsxs(PaginationControls, { children: [_jsx(NavigationButton, { onClick: () => onPageChange(currentPage - 1), disabled: currentPage <= 1, title: "Previous page", children: "\u2190" }), visiblePages.map((page, index) => (_jsx(React.Fragment, { children: page === '...' ? (_jsx(Ellipsis, { children: "..." })) : (_jsx(PageButton, { active: page === currentPage, onClick: () => onPageChange(page), children: page })) }, index))), _jsx(NavigationButton, { onClick: () => onPageChange(currentPage + 1), disabled: currentPage >= totalPages, title: "Next page", children: "\u2192" })] })] })] }));
};