diff options
| author | joonhoekim <26rote@gmail.com> | 2025-11-28 20:30:23 +0900 |
|---|---|---|
| committer | joonhoekim <26rote@gmail.com> | 2025-11-28 20:30:23 +0900 |
| commit | 9cabe879404f1ec05dbf4e65d55162b5573aeced (patch) | |
| tree | 942d54a4e21fa9ce757e92191060c88b7a4b241e /components/client-table/client-table-filter.tsx | |
| parent | 748f68bb7b5d02450664651ae5025c9a38fb71a5 (diff) | |
(김준회) dynamic table - init
Diffstat (limited to 'components/client-table/client-table-filter.tsx')
| -rw-r--r-- | components/client-table/client-table-filter.tsx | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/components/client-table/client-table-filter.tsx b/components/client-table/client-table-filter.tsx new file mode 100644 index 00000000..138f77eb --- /dev/null +++ b/components/client-table/client-table-filter.tsx @@ -0,0 +1,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> + ) +} |
