deno.land / x / netzo@0.5.16 / components / blocks / table / table-filters.tsx
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184import type { ComponentType, JSX } from "preact";import type { Column, Table } from "../../../deps/@tanstack/react-table.ts";import { Badge } from "../../badge.tsx";import { Button } from "../../button.tsx";import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator,} from "../../command.tsx";import { Popover, PopoverContent, PopoverTrigger } from "../../popover.tsx";import { Separator } from "../../separator.tsx";import { cn } from "../../utils.ts";
export type TableFilter<TData = unknown, TValue = unknown> = { column?: Column<TData, TValue>; title?: string; options: { label: string; value: string; icon?: ComponentType<{ className?: string }>; }[];};
export function TableFilters<TData>({ className, table,}: JSX.IntrinsicElements["div"] & { table: Table<TData> }) { if (!table.options?.initialState?.filters) { console.error(`Missing "filters" property in table.options.initialState`); return null; }
const filters = table.options.initialState?.filters as TableFilter< TData, unknown >[];
const isFiltered = table.getState().columnFilters.length > 0;
return ( <div className={cn("flex space-x-2", className)}> {filters?.map(({ column, title, options }) => table.getColumn(column) && ( <TableFilter column={table.getColumn(column)} title={title} options={options} /> ) )}
{isFiltered && ( <Button variant="ghost" onClick={() => table.resetColumnFilters()} className="h-8 px-2 lg:px-3" > Reset <i className="mdi-close w-4 h-4 ml-2" /> </Button> )} </div> );}
export function TableFilter<TData, TValue>({ column, title, options,}: TableFilter<TData, TValue>) { const facets = column?.getFacetedUniqueValues(); const selectedValues = new Set(column?.getFilterValue() as string[]);
return ( <Popover> <PopoverTrigger asChild> <Button variant="outline" size="sm" className="h-8 border-dashed"> <i className="mdi-plus-circle mr-2 h-4 w-4" /> {title} {selectedValues?.size > 0 && ( <> <Separator orientation="vertical" className="mx-2 h-4" /> <Badge variant="secondary" className="rounded-sm px-1 font-normal lg:hidden" > {selectedValues.size} </Badge> <div className="hidden space-x-1 lg:flex"> {selectedValues.size > 2 ? ( <Badge variant="secondary" className="rounded-sm px-1 font-normal" > {selectedValues.size} selected </Badge> ) : ( options .filter((option) => selectedValues.has(option.value)) .map((option) => ( <Badge variant="secondary" key={option.value} className="rounded-sm px-1 font-normal" > {option.label} </Badge> )) )} </div> </> )} </Button> </PopoverTrigger> <PopoverContent className="w-[200px] p-0" align="start"> <Command> <CommandInput placeholder={title} /> <CommandList> <CommandEmpty>No results found.</CommandEmpty> <CommandGroup> {options.map((option) => { const isSelected = selectedValues.has(option.value); return ( <CommandItem key={option.value} onSelect={() => { if (isSelected) { selectedValues.delete(option.value); } else { selectedValues.add(option.value); } const filterValues = Array.from(selectedValues); column?.setFilterValue( filterValues.length ? filterValues : undefined, ); }} > <div className={cn( "mr-2 flex h-4 w-4 items-center justify-center rounded-sm border border-primary", isSelected ? "bg-primary text-primary-foreground mdi-checkbox-marked" : "opacity-50 mdi-checkbox-blank-outline", )} /> {option.icon && ( <option.icon className="mr-2 h-4 w-4 text-muted-foreground" /> )} <span>{option.label}</span> {facets?.get(option.value) && ( <span className="ml-auto flex h-4 w-4 items-center justify-center font-mono text-xs"> {facets.get(option.value)} </span> )} </CommandItem> ); })} </CommandGroup> {selectedValues.size > 0 && ( <> <CommandSeparator /> <CommandGroup> <CommandItem onSelect={() => column?.setFilterValue(undefined)} className="justify-center text-center" > Clear filters </CommandItem> </CommandGroup> </> )} </CommandList> </Command> </PopoverContent> </Popover> );}
Version Info