import { useCallback, useMemo } from '@wordpress/element'; import clsx from 'clsx'; export interface PaginationProps { total: number; page: number; pageSize?: number; onPageChange: (page: number) => void; } interface PaginationNumIconProps { page: number; number: number; onClick: (page: number) => void; } const PREFIX = 'lks-pagination'; const SHOW_MIDDLE_PAGE_NUM = 5; const SHOW_MORE_ICON_NUM = SHOW_MIDDLE_PAGE_NUM - 2; export const PaginationNumIcon = ({ number, page, onClick, }: PaginationNumIconProps) => (
  • onClick(number)} className={clsx( `${PREFIX}__btn`, `${PREFIX}__btn--number`, `${PREFIX}__btn--${number}`, { [`${PREFIX}__btn--active`]: page === number, }, )} > {number}
  • ); export const Pagination = ({ total, page, pageSize = 10, onPageChange, }: PaginationProps) => { const pageTotal = useMemo( () => Math.ceil(total / pageSize), [total, pageSize], ); const pageNumberList = useMemo( () => new Array(pageTotal).fill(1).map((num, index) => num + index), [pageTotal], ); const previousDisabled = useMemo(() => page <= 1, [page]); const nextDisabled = useMemo( () => !pageTotal || page >= pageTotal, [page, pageTotal], ); const showMorePreviousIcon = useMemo( () => !!page && page - SHOW_MORE_ICON_NUM > 1, [page], ); const showMoreNextIcon = useMemo( () => !!pageTotal && pageTotal - SHOW_MORE_ICON_NUM > page, [page, pageTotal], ); const shownPageNumberList = useMemo(() => { const numberList = [...pageNumberList]; const startNum = numberList.shift() || 1; const endNum = numberList.pop(); const middleAverage = Math.floor(SHOW_MIDDLE_PAGE_NUM / 2); const middleRangeStartIndex = Math.min( Math.max(page - SHOW_MIDDLE_PAGE_NUM + 1, 0), pageTotal - SHOW_MIDDLE_PAGE_NUM - 1, ); const middleRangeEndIndex = Math.max( Math.min(page + middleAverage - 1, numberList.length), SHOW_MIDDLE_PAGE_NUM - 1, ); const middleNumberList = numberList.slice( middleRangeStartIndex, middleRangeEndIndex, ); return { startNum, endNum, middleNumberList, }; }, [page, pageTotal, pageNumberList]); const handleChangePage = useCallback( (pageValue: number) => { const nextPage = Math.max(1, Math.min(pageValue, pageTotal)); onPageChange?.(nextPage); }, [pageTotal, onPageChange], ); return ( ); };