eventx-design-system
Version:
Design System do EventX
185 lines (178 loc) • 6.93 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React from 'react';
import styled, { css } from 'styled-components';
import { colors, typography, spacing, borderRadius, transitions } from '../tokens/design-tokens';
// Container da paginação
const PaginationContainer = styled.nav `
display: flex;
align-items: center;
justify-content: center;
gap: ${spacing[1]};
`;
// Botão da paginação
const PaginationButton = styled.button `
display: flex;
align-items: center;
justify-content: center;
border: none;
cursor: ${({ isDisabled }) => (isDisabled ? 'not-allowed' : 'pointer')};
font-family: ${typography.fontFamily.primary};
font-weight: ${typography.fontWeight.medium};
transition: all ${transitions.duration[200]} ${transitions.easing.inOut};
border-radius: ${borderRadius.base};
min-width: ${({ size }) => {
switch (size) {
case 'sm':
return '28px';
case 'lg':
return '44px';
default:
return '36px';
}
}};
height: ${({ size }) => {
switch (size) {
case 'sm':
return '28px';
case 'lg':
return '44px';
default:
return '36px';
}
}};
${({ size }) => {
switch (size) {
case 'sm':
return css `
font-size: ${typography.fontSize.sm};
padding: ${spacing[1]} ${spacing[2]};
`;
case 'lg':
return css `
font-size: ${typography.fontSize.lg};
padding: ${spacing[2]} ${spacing[4]};
`;
default:
return css `
font-size: ${typography.fontSize.base};
padding: ${spacing[2]} ${spacing[3]};
`;
}
}}
${({ variant, isActive, isDisabled }) => {
if (isDisabled) {
return css `
background-color: ${colors.neutral[100]};
color: ${colors.neutral[400]};
opacity: 0.5;
`;
}
if (isActive) {
return variant === 'outline'
? css `
background-color: transparent;
color: ${colors.brand.primary[950]};
border: 2px solid ${colors.brand.primary[950]};
`
: css `
background-color: ${colors.brand.primary[950]};
color: ${colors.neutral[50]};
`;
}
return variant === 'outline'
? css `
background-color: transparent;
color: ${colors.neutral[600]};
border: 2px solid ${colors.neutral[300]};
&:hover {
background-color: ${colors.neutral[100]};
color: ${colors.neutral[800]};
border-color: ${colors.neutral[400]};
}
`
: css `
background-color: ${colors.neutral[50]};
color: ${colors.neutral[600]};
border: 1px solid ${colors.neutral[200]};
&:hover {
background-color: ${colors.neutral[100]};
color: ${colors.neutral[800]};
border-color: ${colors.neutral[300]};
}
`;
}}
&:focus {
outline: 2px solid ${colors.brand.primary[500]};
outline-offset: 2px;
}
`;
// Separador de páginas
const PageSeparator = styled.span `
color: ${colors.neutral[400]};
padding: 0 ${spacing[1]};
${({ size }) => {
switch (size) {
case 'sm':
return css `
font-size: ${typography.fontSize.sm};
`;
case 'lg':
return css `
font-size: ${typography.fontSize.lg};
`;
default:
return css `
font-size: ${typography.fontSize.base};
`;
}
}}
`;
export const Pagination = ({ currentPage, totalPages, onPageChange, size = 'md', variant = 'default', showFirstLast = true, showPrevNext = true, maxVisiblePages = 5, className, ...props }) => {
const handlePageChange = (page) => {
if (page >= 1 && page <= totalPages && page !== currentPage) {
onPageChange(page);
}
};
const getVisiblePages = () => {
const pages = [];
const halfVisible = Math.floor(maxVisiblePages / 2);
if (totalPages <= maxVisiblePages) {
// Mostrar todas as páginas se o total for menor que o máximo visível
for (let i = 1; i <= totalPages; i++) {
pages.push(i);
}
}
else {
// Lógica para mostrar páginas com ellipsis
if (currentPage <= halfVisible + 1) {
// Páginas iniciais
for (let i = 1; i <= maxVisiblePages - 1; i++) {
pages.push(i);
}
pages.push('...');
pages.push(totalPages);
}
else if (currentPage >= totalPages - halfVisible) {
// Páginas finais
pages.push(1);
pages.push('...');
for (let i = totalPages - maxVisiblePages + 2; i <= totalPages; i++) {
pages.push(i);
}
}
else {
// Páginas do meio
pages.push(1);
pages.push('...');
for (let i = currentPage - halfVisible; i <= currentPage + halfVisible; i++) {
pages.push(i);
}
pages.push('...');
pages.push(totalPages);
}
}
return pages;
};
const visiblePages = getVisiblePages();
return (_jsxs(PaginationContainer, { className: className, ...props, children: [showFirstLast && (_jsx(PaginationButton, { isActive: false, isDisabled: currentPage === 1, size: size, variant: variant, onClick: () => handlePageChange(1), "aria-label": "Primeira p\u00E1gina", children: "\u00AB\u00AB" })), showPrevNext && (_jsx(PaginationButton, { isActive: false, isDisabled: currentPage === 1, size: size, variant: variant, onClick: () => handlePageChange(currentPage - 1), "aria-label": "P\u00E1gina anterior", children: "\u00AB" })), visiblePages.map((page, index) => (_jsx(React.Fragment, { children: page === '...' ? (_jsx(PageSeparator, { size: size, children: "..." })) : (_jsx(PaginationButton, { isActive: page === currentPage, isDisabled: false, size: size, variant: variant, onClick: () => handlePageChange(page), "aria-label": `Página ${page}`, "aria-current": page === currentPage ? 'page' : undefined, children: page })) }, index))), showPrevNext && (_jsx(PaginationButton, { isActive: false, isDisabled: currentPage === totalPages, size: size, variant: variant, onClick: () => handlePageChange(currentPage + 1), "aria-label": "Pr\u00F3xima p\u00E1gina", children: "\u00BB" })), showFirstLast && (_jsx(PaginationButton, { isActive: false, isDisabled: currentPage === totalPages, size: size, variant: variant, onClick: () => handlePageChange(totalPages), "aria-label": "\u00DAltima p\u00E1gina", children: "\u00BB\u00BB" }))] }));
};