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
|
"use client"
import * as React from "react"
import { Column } from "@tanstack/react-table"
import { Input } from "@/components/ui/input"
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select"
import { ClientTableColumnMeta } from "./types"
interface ClientTableFilterProps<TData, TValue> {
column: Column<TData, TValue>
}
export function ClientTableFilter<TData, TValue>({
column,
}: ClientTableFilterProps<TData, TValue>) {
const columnFilterValue = column.getFilterValue()
// Cast meta to our local type
const meta = column.columnDef.meta as ClientTableColumnMeta | undefined
// Handle Boolean Filter
if (meta?.filterType === "boolean") {
return (
<div onClick={(e) => e.stopPropagation()} className="mt-2">
<Select
value={(columnFilterValue as string) ?? "all"}
onValueChange={(value) =>
column.setFilterValue(value === "all" ? undefined : value === "true")
}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="All" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All</SelectItem>
<SelectItem value="true">Yes</SelectItem>
<SelectItem value="false">No</SelectItem>
</SelectContent>
</Select>
</div>
)
}
// Handle Select Filter (for specific options)
if (meta?.filterType === "select" && meta.filterOptions) {
return (
<div onClick={(e) => e.stopPropagation()} className="mt-2">
<Select
value={(columnFilterValue as string) ?? "all"}
onValueChange={(value) =>
column.setFilterValue(value === "all" ? undefined : value)
}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="All" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All</SelectItem>
{meta.filterOptions.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
)
}
// Default Text Filter
const [value, setValue] = React.useState(columnFilterValue)
React.useEffect(() => {
setValue(columnFilterValue)
}, [columnFilterValue])
React.useEffect(() => {
const timeout = setTimeout(() => {
column.setFilterValue(value)
}, 500)
return () => clearTimeout(timeout)
}, [value, column])
return (
<div onClick={(e) => e.stopPropagation()} className="mt-2">
<Input
type="text"
value={(value ?? "") as string}
onChange={(e) => setValue(e.target.value)}
placeholder="Search..."
className="h-8 w-full font-normal bg-background"
/>
</div>
)
}
|