diff options
| author | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-03-25 15:55:45 +0900 |
| commit | 1a2241c40e10193c5ff7008a7b7b36cc1d855d96 (patch) | |
| tree | 8a5587f10ca55b162d7e3254cb088b323a34c41b /components/data-table/data-table-pagination.tsx | |
initial commit
Diffstat (limited to 'components/data-table/data-table-pagination.tsx')
| -rw-r--r-- | components/data-table/data-table-pagination.tsx | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/components/data-table/data-table-pagination.tsx b/components/data-table/data-table-pagination.tsx new file mode 100644 index 00000000..7a2a03f8 --- /dev/null +++ b/components/data-table/data-table-pagination.tsx @@ -0,0 +1,132 @@ +"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. + </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> + ) +}
\ No newline at end of file |
