UNPKG

eventx-design-system

Version:
185 lines (178 loc) 6.93 kB
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" }))] })); };