UNPKG

eventx-design-system

Version:
108 lines (104 loc) 5.07 kB
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" })] })] })] })); };