summaryrefslogtreecommitdiff
path: root/components/data-table/data-table-column-resizable.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'components/data-table/data-table-column-resizable.tsx')
-rw-r--r--components/data-table/data-table-column-resizable.tsx57
1 files changed, 57 insertions, 0 deletions
diff --git a/components/data-table/data-table-column-resizable.tsx b/components/data-table/data-table-column-resizable.tsx
new file mode 100644
index 00000000..2a91c998
--- /dev/null
+++ b/components/data-table/data-table-column-resizable.tsx
@@ -0,0 +1,57 @@
+"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 DataTableColumnHeaderProps<TData, TValue>
+ extends React.HTMLAttributes<HTMLDivElement> {
+ column: Column<TData, TValue>
+ title: string
+}
+
+export function DataTableColumnHeaderResizable<TData, TValue>({
+ column,
+ title,
+ className,
+}: DataTableColumnHeaderProps<TData, TValue>) {
+ // 정렬 상태: "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 className={cn("relative flex items-center", className)}>
+ <div
+ onClick={handleClick}
+ className={cn(
+ "flex cursor-pointer select-none items-center gap-1"
+ )}
+ >
+ <span>{title}</span>
+ {column.getCanSort() && icon}
+ </div>
+ </div>
+ )
+} \ No newline at end of file