import { withSchema } from '@websolutespa/bom-core'; import { useCurrentState, useLabel } from '@websolutespa/bom-mixer-hooks'; import React, { useEffect, useMemo } from 'react'; import styled from 'styled-components'; import { UIStyledComponentProps } from '../../components/types'; import { getCssResponsive } from '../../components/utils'; import { pickChild } from '../utils'; import { PaginationConfig, PaginationContext, PaginationUpdateType } from './pagination-context'; import { PaginationNext } from './pagination-next'; import { PaginationPages } from './pagination-pages'; import { PaginationPrevious } from './pagination-previous'; type Props = { className?: string; count?: number; initialPage?: number; limit?: number; page?: number; onChange?: (val: number) => void; urlResolver?: (page: number) => string; }; export type PaginationProps = UIStyledComponentProps; const StyledPagination = styled.div` --pagination-size: 2rem; display: flex; justify-content: center; ${props => getCssResponsive(props)} `; const StyledNav = styled.ul` list-style: none; margin: 0; padding: 0; display: flex; align-items: center; justify-content: center; font-variant: tabular-nums; font-feature-settings: 'tnum'; font-size: 0.875rem; &>li { padding: 0; } :global(button:last-of-type) { margin-right: 0; } `; function PaginationBase({ className = '', initialPage = 1, count = 1, limit = 7, page: customPage, children, onChange, urlResolver, ...props }: React.PropsWithChildren) { const label = useLabel(); const [page, setPage, pageRef] = useCurrentState(initialPage); const [prevChildren] = pickChild(PaginationPrevious, children); const [nextChildren] = pickChild(PaginationNext, children); const [prevItem, nextItem] = useMemo(() => { const hasChildren = (c: any) => React.Children.count(c) > 0; const prevDefault = prev; const nextDefault = next; return [ hasChildren(prevChildren) ? prevChildren : prevDefault, hasChildren(nextChildren) ? nextChildren : nextDefault, ]; }, [prevChildren, nextChildren]); const update = (type: PaginationUpdateType) => { if (type === 'prev' && pageRef.current > 1) { setPage(last => last - 1); } if (type === 'next' && pageRef.current < count) { setPage(last => last + 1); } }; const values = useMemo(() => { return { currentPage: page, isFirst: page <= 1, isLast: page >= count, update, resolveUrl: (page: number) => (urlResolver ? urlResolver(page) : undefined), }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [page, count]); useEffect(() => { onChange && onChange(page); // eslint-disable-next-line react-hooks/exhaustive-deps }, [page]); useEffect(() => { if (customPage !== undefined) { setPage(customPage); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [customPage]); return ( {prevItem} {nextItem} ); } export const Pagination = withSchema( PaginationBase, { Previous: PaginationPrevious, Next: PaginationNext, });