diff options
Diffstat (limited to 'components/client-data-table/data-table-column-simple-header.tsx')
| -rw-r--r-- | components/client-data-table/data-table-column-simple-header.tsx | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/components/client-data-table/data-table-column-simple-header.tsx b/components/client-data-table/data-table-column-simple-header.tsx new file mode 100644 index 00000000..0f3997c6 --- /dev/null +++ b/components/client-data-table/data-table-column-simple-header.tsx @@ -0,0 +1,61 @@ +"use client" + +import * as React from "react" +import { cn } from "@/lib/utils" +import { type Column } from "@tanstack/react-table" +import { ArrowDown, ArrowUp, ChevronsUpDown } from "lucide-react" + +interface DataTableColumnHeaderSimpleProps<TData, TValue> + extends React.HTMLAttributes<HTMLDivElement> { + column: Column<TData, TValue> + title: string +} + +export function ClientDataTableColumnHeaderSimple<TData, TValue>({ + column, + title, + className, +}: DataTableColumnHeaderSimpleProps<TData, TValue>) { + // 정렬 불가능 시 → 제목만 보여주기 + if (!column.getCanSort()) { + return <div className={cn(className)}>{title}</div> + } + + // 정렬 상태: "asc" | "desc" | false + const sorted = column.getIsSorted() + + // 아이콘 결정 + let icon = <ChevronsUpDown className="ml-1 size-4" aria-hidden="true" /> + if (sorted === "asc") { + icon = <ArrowUp className="ml-1 size-4" aria-hidden="true" /> + } else if (sorted === "desc") { + icon = <ArrowDown className="ml-1 size-4" aria-hidden="true" /> + } + + // 클릭 핸들러: 무정렬 → asc → desc → 무정렬 + function handleClick() { + if (!sorted) { + // 현재 무정렬 → asc + column.toggleSorting(false) + } else if (sorted === "asc") { + // asc → desc + column.toggleSorting(true) + } else { + // desc → 무정렬 + column.toggleSorting(false) + } + } + + return ( + <div + onClick={handleClick} + className={cn( + "flex cursor-pointer select-none items-center gap-1", + className + )} + > + <span>{title}</span> + {icon} + </div> + ) +}
\ No newline at end of file |
