Portal/rsconcept/frontend/src/components/data-table/pagination-tools.tsx

95 lines
3.1 KiB
TypeScript
Raw Normal View History

'use no memo';
2025-03-12 21:07:01 +03:00
'use client';
2024-06-07 20:17:03 +03:00
2025-02-20 20:22:05 +03:00
import { type Table } from '@tanstack/react-table';
2024-06-07 20:17:03 +03:00
2025-03-12 12:04:23 +03:00
import { IconPageFirst, IconPageLast, IconPageLeft, IconPageRight } from '../icons';
2025-04-16 15:22:04 +03:00
import { SelectPagination } from './select-pagination';
2024-06-07 20:17:03 +03:00
interface PaginationToolsProps<TData> {
id?: string;
table: Table<TData>;
paginationOptions: number[];
onChangePaginationOption?: (newValue: number) => void;
2024-06-07 20:17:03 +03:00
}
export function PaginationTools<TData>({
id,
table,
onChangePaginationOption,
paginationOptions
}: PaginationToolsProps<TData>) {
2024-06-07 20:17:03 +03:00
return (
2025-04-12 21:47:46 +03:00
<div className='flex justify-end items-center my-2 text-sm cc-controls select-none'>
2024-06-07 20:17:03 +03:00
<span className='mr-3'>
{`${table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1}
-
${Math.min(
table.getFilteredRowModel().rows.length,
(table.getState().pagination.pageIndex + 1) * table.getState().pagination.pageSize
)}
из
${table.getFilteredRowModel().rows.length}`}
</span>
<div className='flex'>
<button
type='button'
2025-03-20 18:24:07 +03:00
aria-label='Первая страница'
2025-04-12 21:47:46 +03:00
className='cc-hover cc-controls cc-animate-color focus-outline'
2024-06-07 20:17:03 +03:00
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
<IconPageFirst size='1.5rem' />
</button>
<button
type='button'
2025-03-20 18:24:07 +03:00
aria-label='Предыдущая страница'
2025-04-12 21:47:46 +03:00
className='cc-hover cc-controls cc-animate-color focus-outline'
2024-06-07 20:17:03 +03:00
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
<IconPageLeft size='1.5rem' />
</button>
<input
id={id ? `${id}__page` : undefined}
title='Номер страницы. Выделите для ручного ввода'
2025-03-20 18:24:07 +03:00
aria-label='Номер страницы'
2025-04-12 21:47:46 +03:00
className='w-6 text-center bg-transparent focus-outline'
2024-06-07 20:17:03 +03:00
value={table.getState().pagination.pageIndex + 1}
onChange={event => {
const page = event.target.value ? Number(event.target.value) - 1 : 0;
if (page + 1 <= table.getPageCount()) {
table.setPageIndex(page);
}
}}
/>
<button
type='button'
2025-03-20 18:24:07 +03:00
aria-label='Следующая страница'
2025-04-12 21:47:46 +03:00
className='cc-hover cc-controls cc-animate-color focus-outline'
2024-06-07 20:17:03 +03:00
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
<IconPageRight size='1.5rem' />
</button>
<button
type='button'
2025-03-20 18:24:07 +03:00
aria-label='Последняя страница'
2025-04-12 21:47:46 +03:00
className='cc-hover cc-controls cc-animate-color focus-outline'
2024-06-07 20:17:03 +03:00
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
<IconPageLast size='1.5rem' />
</button>
</div>
2025-04-16 15:22:04 +03:00
<SelectPagination
2024-06-07 20:17:03 +03:00
id={id ? `${id}__per_page` : undefined}
2025-04-16 15:22:04 +03:00
table={table}
paginationOptions={paginationOptions}
onChange={onChangePaginationOption}
/>
2024-06-07 20:17:03 +03:00
</div>
);
}