Files
road-monitoring-ui/src/components/data-table/Footer/index.tsx

124 lines
3.7 KiB
TypeScript

'use client';
import { Table } from '@tanstack/react-table';
import {
ChevronLeft,
ChevronRight,
ChevronsLeft,
ChevronsRight,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select';
const PAGE_SIZE_OPTIONS = [10, 20, 40, 50, 100];
export function TableFooter<TData>({
table,
totalItems,
pageSize,
onPageSizeChange,
}: {
table: Table<TData>;
totalItems: number;
pageSize?: number;
onPageSizeChange?: (pageSize: number) => void;
}) {
const currentPageSize = pageSize ?? table.getState().pagination.pageSize;
const selectedRowCount = Object.keys(table.getState().rowSelection).length;
const pageIndex = table.getState().pagination.pageIndex;
const rawPageCount = table.getPageCount();
const pageCount = Math.max(
1,
Number.isFinite(rawPageCount) && rawPageCount > 0 ? rawPageCount : 1,
);
return (
<div className="flex flex-col gap-3 px-4 text-sm text-muted-foreground sm:flex-row sm:items-center sm:justify-between">
<div>
{selectedRowCount} of {totalItems} row(s) selected.
</div>
<div className="flex flex-wrap items-center gap-4 sm:justify-end">
{onPageSizeChange ? (
<div className="flex items-center gap-2 text-foreground">
<span className="font-medium">Rows per page</span>
<Select
value={String(currentPageSize)}
onValueChange={(value) => table.setPageSize(Number(value))}
>
<SelectTrigger className="h-8 w-20 border-border bg-background shadow-none">
<SelectValue />
</SelectTrigger>
<SelectContent align="end">
{PAGE_SIZE_OPTIONS.map((size) => (
<SelectItem key={size} value={String(size)}>
{size}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
) : null}
<div className="min-w-24 text-foreground font-medium">
Page {pageIndex + 1} of {pageCount}
</div>
<div className="flex items-center gap-2">
<Button
type="button"
variant="outline"
size="icon-sm"
className="size-8 shadow-none"
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
aria-label="Go to first page"
>
<ChevronsLeft className="size-4" />
</Button>
<Button
type="button"
variant="outline"
size="icon-sm"
className="size-8 shadow-none"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
aria-label="Go to previous page"
>
<ChevronLeft className="size-4" />
</Button>
<Button
type="button"
variant="outline"
size="icon-sm"
className="size-8 shadow-none"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
aria-label="Go to next page"
>
<ChevronRight className="size-4" />
</Button>
<Button
type="button"
variant="outline"
size="icon-sm"
className="size-8 shadow-none"
onClick={() => table.setPageIndex(pageCount - 1)}
disabled={!table.getCanNextPage()}
aria-label="Go to last page"
>
<ChevronsRight className="size-4" />
</Button>
</div>
</div>
</div>
);
}