Spaces:
Running
Running
File size: 3,298 Bytes
91677d6 15d8696 91677d6 15d8696 91677d6 8899818 91677d6 15d8696 91677d6 15d8696 91677d6 95e3d2a 91677d6 | 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 102 103 104 105 | <script lang="ts" generics="TData">
import type { Table } from '@tanstack/table-core';
import { Input } from '$lib/components/ui/input';
import { Button } from '$lib/components/ui/button';
import * as DropdownMenu from '$lib/components/ui/dropdown-menu';
import * as Select from '$lib/components/ui/select';
import MagnifyingGlassIcon from 'phosphor-svelte/lib/MagnifyingGlassIcon';
import SlidersHorizontalIcon from 'phosphor-svelte/lib/SlidersHorizontalIcon';
import XIcon from 'phosphor-svelte/lib/XIcon';
import { prettyMap } from '$lib/utils/format';
interface Props {
table: Table<TData>;
searchPlaceholder?: string;
mapOptions?: string[];
}
let { table, searchPlaceholder = 'Search…', mapOptions = [] }: Props = $props();
const globalFilter = $derived((table.getState().globalFilter as string) ?? '');
const mapFilter = $derived((table.getColumn('map_name')?.getFilterValue() as string) ?? '__all');
const isFiltered = $derived(
(table.getState().globalFilter as string)?.length > 0 ||
table.getState().columnFilters.length > 0
);
</script>
<div class="flex flex-wrap items-center gap-2 py-3">
<div class="relative">
<MagnifyingGlassIcon
size={14}
weight="bold"
class="absolute top-1/2 left-2.5 -translate-y-1/2 text-muted-foreground"
/>
<Input
placeholder={searchPlaceholder}
value={globalFilter}
oninput={(e) => table.setGlobalFilter(e.currentTarget.value)}
class="h-8 w-[200px] pl-8 lg:w-[260px]"
/>
</div>
{#if mapOptions.length > 0 && table.getColumn('map_name')}
<Select.Root
type="single"
value={mapFilter}
onValueChange={(v) => {
table.getColumn('map_name')?.setFilterValue(v === '__all' ? undefined : v);
}}
>
<Select.Trigger size="sm" class="h-8 min-w-[130px] capitalize">
{mapFilter === '__all' ? 'All maps' : prettyMap(mapFilter)}
</Select.Trigger>
<Select.Content>
<Select.Item value="__all">All maps</Select.Item>
{#each mapOptions as map (map)}
<Select.Item value={map} class="capitalize">{prettyMap(map)}</Select.Item>
{/each}
</Select.Content>
</Select.Root>
{/if}
{#if isFiltered}
<Button
variant="ghost"
size="sm"
class="h-8 px-2"
onclick={() => {
table.setGlobalFilter('');
table.resetColumnFilters();
}}
>
Reset
<XIcon size={12} weight="bold" class="ml-1" />
</Button>
{/if}
<div class="ml-auto flex items-center gap-2">
<DropdownMenu.Root>
<DropdownMenu.Trigger>
{#snippet child({ props })}
<Button {...props} variant="outline" size="sm" class="h-8">
<SlidersHorizontalIcon size={12} weight="bold" />
View
</Button>
{/snippet}
</DropdownMenu.Trigger>
<DropdownMenu.Content align="end" class="w-[180px]">
<DropdownMenu.Label>Toggle columns</DropdownMenu.Label>
<DropdownMenu.Separator />
{#each table.getAllColumns().filter((c) => c.getCanHide()) as column (column.id)}
<DropdownMenu.CheckboxItem
class="capitalize"
checked={column.getIsVisible()}
onCheckedChange={(v) => column.toggleVisibility(!!v)}
>
{(column.columnDef.meta as { label?: string } | undefined)?.label ??
column.id.replace(/_/g, ' ')}
</DropdownMenu.CheckboxItem>
{/each}
</DropdownMenu.Content>
</DropdownMenu.Root>
</div>
</div>
|