1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
"use client"
import * as React from "react"
import { type 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"
interface DataTablePaginationProps<TData> {
table: Table<TData>
pageSizeOptions?: Array<number | "All">
}
export function DataTablePagination<TData>({
table,
pageSizeOptions = [10, 20, 30, 40, 50, "All"],
}: DataTablePaginationProps<TData>) {
// 현재 테이블 pageSize
const currentPageSize = table.getState().pagination.pageSize
// "All"을 1,000,000으로 처리할 것이므로,
// 만약 현재 pageSize가 1,000,000이면 화면상 "All"로 표시
const selectValue =
currentPageSize === 1_000_000
? "All"
: String(currentPageSize)
return (
<div className="flex w-full flex-col-reverse items-center justify-between gap-4 overflow-auto p-1 sm:flex-row sm:gap-8">
<div className="flex-1 whitespace-nowrap text-sm text-muted-foreground">
{table.getFilteredSelectedRowModel().rows.length} of{" "}
{table.getFilteredRowModel().rows.length} row(s) selected.
<span className="ml-4">Total: {table.getRowCount()} records</span>
</div>
<div className="flex flex-col-reverse items-center gap-4 sm:flex-row sm:gap-6 lg:gap-8">
{/* Rows per page Select */}
<div className="flex items-center space-x-2">
<p className="whitespace-nowrap text-sm font-medium">Rows per page</p>
<Select
value={selectValue}
onValueChange={(value) => {
if (value === "All") {
// "All"을 1,000,000으로 치환
table.setPageSize(1_000_000)
} else {
table.setPageSize(Number(value))
}
}}
>
<SelectTrigger className="h-8 w-[4.5rem]">
<SelectValue placeholder={selectValue} />
</SelectTrigger>
<SelectContent side="top">
{pageSizeOptions.map((option) => {
// 화면에 표시할 라벨
const label = option === "All" ? "All" : String(option)
// value도 문자열화
const val = option === "All" ? "All" : String(option)
return (
<SelectItem key={val} value={val}>
{label}
</SelectItem>
)
})}
</SelectContent>
</Select>
</div>
{/* 현재 페이지 / 전체 페이지 */}
<div className="flex items-center justify-center text-sm font-medium">
Page {table.getState().pagination.pageIndex + 1} of{" "}
{table.getPageCount()}
</div>
{/* 페이지 이동 버튼 */}
<div className="flex items-center space-x-2">
<Button
aria-label="Go to first page"
variant="outline"
className="hidden size-8 p-0 lg:flex"
onClick={() => table.setPageIndex(0)}
disabled={!table.getCanPreviousPage()}
>
<ChevronsLeft className="size-4" aria-hidden="true" />
</Button>
<Button
aria-label="Go to previous page"
variant="outline"
size="icon"
className="size-8"
onClick={() => table.previousPage()}
disabled={!table.getCanPreviousPage()}
>
<ChevronLeft className="size-4" aria-hidden="true" />
</Button>
<Button
aria-label="Go to next page"
variant="outline"
size="icon"
className="size-8"
onClick={() => table.nextPage()}
disabled={!table.getCanNextPage()}
>
<ChevronRight className="size-4" aria-hidden="true" />
</Button>
<Button
aria-label="Go to last page"
variant="outline"
size="icon"
className="hidden size-8 lg:flex"
onClick={() => table.setPageIndex(table.getPageCount() - 1)}
disabled={!table.getCanNextPage()}
>
<ChevronsRight className="size-4" aria-hidden="true" />
</Button>
</div>
</div>
</div>
)
}
|