62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
interface Props {
|
||
page: number;
|
||
pageSize: number;
|
||
totalItems: number;
|
||
totalPages: number;
|
||
onPageChange: (page: number) => void;
|
||
onPageSizeChange: (size: number) => void;
|
||
}
|
||
|
||
export function Pagination({
|
||
page,
|
||
pageSize,
|
||
totalItems,
|
||
totalPages,
|
||
onPageChange,
|
||
onPageSizeChange,
|
||
}: Props) {
|
||
const from = (page - 1) * pageSize + 1;
|
||
const to = Math.min(page * pageSize, totalItems);
|
||
|
||
return (
|
||
<div className="pagination">
|
||
<div className="pagination__info">
|
||
{totalItems > 0
|
||
? `Показано ${from}–${to} из ${totalItems}`
|
||
: 'Нет записей'}
|
||
</div>
|
||
<div className="pagination__controls">
|
||
<select
|
||
className="pagination__size"
|
||
value={pageSize}
|
||
onChange={(e) => onPageSizeChange(Number(e.target.value))}
|
||
aria-label="Количество операций на странице"
|
||
>
|
||
<option value={10}>10</option>
|
||
<option value={50}>50</option>
|
||
<option value={100}>100</option>
|
||
</select>
|
||
<button
|
||
className="icon-button"
|
||
disabled={page <= 1}
|
||
onClick={() => onPageChange(page - 1)}
|
||
aria-label="Предыдущая страница"
|
||
>
|
||
←
|
||
</button>
|
||
<span className="pagination__current">
|
||
{page} / {totalPages || 1}
|
||
</span>
|
||
<button
|
||
className="icon-button"
|
||
disabled={page >= totalPages}
|
||
onClick={() => onPageChange(page + 1)}
|
||
aria-label="Следующая страница"
|
||
>
|
||
→
|
||
</button>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|