feat(pagination): add server-side pagination support and controls
- Implement pagination control UI with page navigation and size selector - Enable server-side callbacks for page changes and size adjustments - Integrate pagination into Griddy component with data count handling
This commit is contained in:
81
src/Griddy/features/pagination/PaginationControl.tsx
Normal file
81
src/Griddy/features/pagination/PaginationControl.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import type { Table } from '@tanstack/react-table'
|
||||
|
||||
import { ActionIcon, Group, Select, Text } from '@mantine/core'
|
||||
import { IconChevronLeft, IconChevronRight, IconChevronsLeft, IconChevronsRight } from '@tabler/icons-react'
|
||||
|
||||
import styles from '../../styles/griddy.module.css'
|
||||
|
||||
interface PaginationControlProps<T> {
|
||||
pageSizeOptions?: number[]
|
||||
table: Table<T>
|
||||
}
|
||||
|
||||
export function PaginationControl<T>({ pageSizeOptions = [10, 25, 50, 100], table }: PaginationControlProps<T>) {
|
||||
const pageIndex = table.getState().pagination.pageIndex
|
||||
const pageSize = table.getState().pagination.pageSize
|
||||
const pageCount = table.getPageCount()
|
||||
const canPreviousPage = table.getCanPreviousPage()
|
||||
const canNextPage = table.getCanNextPage()
|
||||
|
||||
return (
|
||||
<Group className={styles['griddy-pagination']} gap="md" justify="space-between" p="xs">
|
||||
<Group gap="xs">
|
||||
<Text c="dimmed" size="sm">
|
||||
Page {pageIndex + 1} of {pageCount}
|
||||
</Text>
|
||||
</Group>
|
||||
|
||||
<Group gap="xs">
|
||||
<ActionIcon
|
||||
disabled={!canPreviousPage}
|
||||
onClick={() => table.setPageIndex(0)}
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
<IconChevronsLeft size={16} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
disabled={!canPreviousPage}
|
||||
onClick={() => table.previousPage()}
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
<IconChevronLeft size={16} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
disabled={!canNextPage}
|
||||
onClick={() => table.nextPage()}
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
<IconChevronRight size={16} />
|
||||
</ActionIcon>
|
||||
<ActionIcon
|
||||
disabled={!canNextPage}
|
||||
onClick={() => table.setPageIndex(pageCount - 1)}
|
||||
size="sm"
|
||||
variant="subtle"
|
||||
>
|
||||
<IconChevronsRight size={16} />
|
||||
</ActionIcon>
|
||||
</Group>
|
||||
|
||||
<Group gap="xs">
|
||||
<Text c="dimmed" size="sm">
|
||||
Rows per page:
|
||||
</Text>
|
||||
<Select
|
||||
data={pageSizeOptions.map(size => ({ label: String(size), value: String(size) }))}
|
||||
onChange={(value) => {
|
||||
if (value) {
|
||||
table.setPageSize(Number(value))
|
||||
}
|
||||
}}
|
||||
size="xs"
|
||||
value={String(pageSize)}
|
||||
w={70}
|
||||
/>
|
||||
</Group>
|
||||
</Group>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user