Pagination.tsx 2.4 KB
Newer Older
1 2
// cSpell:words hellip

3 4
import React, {FunctionComponent, useCallback, useEffect, useState} from 'react';
import {WithStyled, em} from '~/utils/style';
5

6 7
import Button from '~/components/Button';
import Input from '~/components/Input';
8
import styled from 'styled-components';
9
import {useTranslation} from 'react-i18next';
10 11 12

const Wrapper = styled.nav`
    display: flex;
13 14 15 16 17 18 19 20 21 22 23 24
    justify-content: space-between;
    align-items: center;

    > div {
        > a:not(:last-child),
        > span {
            margin-right: ${em(15)};
        }
        > input {
            width: ${em(80)};
            margin-right: ${em(6)};
        }
25 26 27 28
    }
`;

type PaginationProps = {
29
    page?: number;
30 31 32 33 34
    total: number;
    onChange?: (page: number) => unknown;
};

const Pagination: FunctionComponent<PaginationProps & WithStyled> = ({page, total, className, onChange}) => {
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
    const {t} = useTranslation('common');

    const [currentPage, setCurrentPage] = useState(page ?? 1);
    const [jumpPage, setJumpPage] = useState('');

    useEffect(() => setCurrentPage(page ?? 1), [page]);

    const setPage = useCallback(
        (value: unknown) => {
            const p = 'number' === typeof value ? value : Number.parseInt(value + '');
            if (Number.isNaN(p) || p > total || p < 1 || p === currentPage) {
                return;
            }
            setCurrentPage(p);
            setJumpPage('');
            onChange?.(p);
        },
        [currentPage, onChange, total]
53 54 55 56
    );

    return (
        <Wrapper className={className}>
57 58
            <div>
                <Button disabled={currentPage <= 1} onClick={() => setPage(currentPage - 1)}>
P
Peter Pan 已提交
59
                    {t('common:previous-page')}
60 61
                </Button>
                <Button disabled={currentPage >= total} onClick={() => setPage(currentPage + 1)}>
P
Peter Pan 已提交
62
                    {t('common:next-page')}
63 64 65
                </Button>
            </div>
            <div>
P
Peter Pan 已提交
66
                <span>{t('common:total-page', {count: total})}</span>
67 68 69 70 71 72
                <Input
                    value={jumpPage}
                    onChange={value => setJumpPage(value)}
                    onKeyDown={e => e.key === 'Enter' && setPage(jumpPage)}
                />
                <Button onClick={() => setPage(jumpPage)} type="primary">
P
Peter Pan 已提交
73
                    {t('common:confirm')}
74 75
                </Button>
            </div>
76 77 78 79 80
        </Wrapper>
    );
};

export default Pagination;