/**
* @file pagination
*/
import {Button, Input, Pagination, PaginationProps, Select} from 'antd';
import React, {ChangeEvent, FC, useCallback, useEffect, useState} from 'react';
import './index.less';
function countMaxPage(total: number, pageSize: number) {
return Math.ceil(total / pageSize);
}
const BizPagination: FC<PaginationProps> = (props: PaginationProps) => {
const {pageSize, pageSizeOptions, current, showSizeChanger, onChange, total, ...others} = props;
const [pageSizeInner, setPageSizeInner] = useState(10);
const [currentInner, setCurrentInner] = useState(1);
const [jumperPageNo, setJumperPageNo] = useState('');
useEffect(() => {
if (typeof pageSize === 'number') {
setPageSizeInner(pageSize);
}
}, [pageSize]
);
useEffect(() => {
if (typeof current === 'number') {
setCurrentInner(current);
}
}, [current]
);
const handleChange = useCallback(
(page: number, pageSize: number) => {
if (typeof onChange === 'function') {
onChange(page, pageSize);
}
},
[onChange]
);
const handlePagerOptionsChange = useCallback(
(value) => {
const val = Number(value);
setPageSizeInner(val);
const maxPage = countMaxPage(Number(total), val);
let current = currentInner;
if (currentInner > maxPage) {
current = maxPage;
setCurrentInner(current);
}
handleChange(current, val);
},
[handleChange, currentInner, total]
);
const handlePagerChange = useCallback(
(page) => {
setCurrentInner(page);
handleChange(page, pageSizeInner);
},
[handleChange, pageSizeInner]
);
const inputJumperPageNo = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setJumperPageNo(e.target.value);
}, []
);
const jumpToPage = useCallback(() => {
if (jumperPageNo && Number(jumperPageNo) > 0) {
let pageNo = Number(jumperPageNo);
const maxPage = countMaxPage(Number(total), pageSizeInner);
if (pageNo > maxPage) {
pageNo = maxPage;
}
handleChange(pageNo, pageSizeInner);
}
setJumperPageNo('');
}, [jumperPageNo, handleChange, pageSizeInner, total]
);
if (others.hideOnSinglePage && (!total || total <= pageSizeInner)) {
return null;
}
return (
<div className="biz-pagination">
{showSizeChanger && (
<div className="biz-pagination-options">
<span>每页显示</span>
<Select className="biz-pagination-select" value={pageSizeInner} onChange={handlePagerOptionsChange}>
{pageSizeOptions?.map((opt) => (
<Select.Option value={opt} key={opt}>
{opt}
</Select.Option>
))}
</Select>
</div>
)}
<Pagination
{...others}
total={total}
pageSize={pageSizeInner}
current={currentInner}
showQuickJumper={false}
showSizeChanger={false}
onChange={handlePagerChange}
/>
{showSizeChanger && (
<div className="biz-pagination-jumper">
<span className="biz-pagination-jumper-text">跳转至</span>
<Input.Group compact>
<Input
className="biz-pagination-jumper-input"
value={jumperPageNo}
onChange={inputJumperPageNo}
/>
<Button className="biz-pagination-jumper-btn" onClick={jumpToPage}>
GO
</Button>
</Input.Group>
</div>
)}
</div>
);
};
BizPagination.defaultProps = {
current: 1,
pageSize: 10,
total: 1,
pageSizeOptions: ['10', '20', '50']
};
export default BizPagination;
index.css
.biz-pagination {
display: flex;
align-items: center;
justify-content: flex-end;
margin: 16px 0;
&-options {
color: rgba(8, 14, 26, .5);
}
&-select {
width: 80px;
margin: 0 8px;
border-color: rgba(8, 14, 26, .2);
}
&-jumper {
display: flex;
align-items: center;
justify-content: center;
&-text {
flex: 0 0 auto;
margin: 0 8px;
color: rgba(8, 14, 26, .5);
}
& &-input {
width: 40px;
height: 32px;
border-color: rgba(8, 14, 26, .2);
}
&-btn {
width: 40px;
padding: 0;
border-color: rgba(8, 14, 26, .2);
color: rgba(8, 14, 26, .95);
}
}
.ant-pagination-item {
margin: 0;
}
.ant-pagination-item a {
color: rgba(8, 14, 26, .95);
}
.ant-pagination-item,
.ant-pagination-prev,
.ant-pagination-next {
border-width: 0;
& .ant-pagination-item-link {
border-width: 0;
}
}
.ant-pagination-item-active {
border-width: 1px;
& a {
color: @primary-color;
}
}
}