-
Notifications
You must be signed in to change notification settings - Fork 3
/
+page.svelte
157 lines (150 loc) · 4.46 KB
/
+page.svelte
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
<script lang="ts">
import GithubLogo from 'svelte-radix/GithubLogo.svelte';
import ArrowLeft from 'svelte-radix/ArrowLeft.svelte';
import ArrowRight from 'svelte-radix/ArrowRight.svelte';
import { DataTable } from '$lib/DataTable.svelte';
import * as Table from '$lib/components/ui/table/index.js';
import * as Menubar from '$lib/components/ui/menubar/index.js';
import { Input } from '$lib/components/ui/input/index.js';
import { Button } from '$lib/components/ui/button/index.js';
import { Badge } from '$lib/components/ui/badge/index.js';
let { data } = $props();
const table = new DataTable({
pageSize: 25,
data: data.users,
columns: [
{ id: 'id', key: 'id', name: 'ID' },
{ id: 'name', key: 'name', name: 'Name' },
{ id: 'status', key: 'status', name: 'Status', sortable: false }
]
});
const statuses = [
{ label: 'Active', value: 'active' },
{ label: 'Inactive', value: 'inactive' }
];
</script>
<div class="mx-auto h-dvh max-w-7xl px-4 sm:px-6 lg:px-8">
<div class="grid h-full grid-cols-1 grid-rows-[auto,auto,1fr,auto]">
<div class="flex justify-between gap-4 pb-4 pt-12">
<div>
<h1 class="text-4xl font-extrabold tracking-tight lg:text-5xl">Svelte Data Table</h1>
<p class="text-lg text-muted-foreground">
Small, fast data table library for Svelte 5 with client-side sorting, filtering, and
pagination.
</p>
</div>
<Button
class="shrink-0"
size="icon"
variant="ghost"
href="https://github.com/Careswitch/svelte-data-table"
>
<GithubLogo class="size-6" />
</Button>
</div>
<div class="flex flex-col gap-4 py-4 md:flex-row md:items-center md:gap-0 print:hidden">
<Menubar.Root>
<Menubar.Menu>
<Menubar.Trigger>Filter</Menubar.Trigger>
<Menubar.Content>
<Menubar.Sub>
<Menubar.SubTrigger>Status</Menubar.SubTrigger>
<Menubar.SubContent class="w-40">
{#each statuses as status}
<Menubar.CheckboxItem
checked={table.isFilterActive('status', status.value)}
onCheckedChange={() => table.toggleFilter('status', status.value)}
>
{status.label}
</Menubar.CheckboxItem>
{/each}
<Menubar.Separator />
<Menubar.Item inset on:click={() => table.clearFilter('status')}>
Clear
</Menubar.Item>
</Menubar.SubContent>
</Menubar.Sub>
</Menubar.Content>
</Menubar.Menu>
</Menubar.Root>
<Input
type="text"
placeholder="Search"
class="md:ml-auto md:max-w-[200px]"
bind:value={table.globalFilter}
/>
</div>
<Table.Root>
<Table.Header>
<Table.Row class="sticky top-0 z-10 *:bg-background">
{#each table.columns as column (column.id)}
<Table.Head>
<button
class="flex items-center"
onclick={() => table.toggleSort(column.id)}
disabled={!table.isSortable(column.id)}
>
{column.name}
{#if table.isSortable(column.id)}
<span class="ml-2">
{#if table.getSortState(column.id) === 'asc'}
↑
{:else if table.getSortState(column.id) === 'desc'}
↓
{:else}
↕
{/if}
</span>
{/if}
</button>
</Table.Head>
{/each}
</Table.Row>
</Table.Header>
<Table.Body>
{#each table.rows as row (row.id)}
<Table.Row>
{#each table.columns as column (column.id)}
{#if column.id === 'status'}
<Table.Cell>
<Badge variant={row.status === 'active' ? 'secondary' : 'outline'}>
{row.status === 'active' ? 'Active' : 'Inactive'}
</Badge>
</Table.Cell>
{:else}
<Table.Cell>{row[column.key]}</Table.Cell>
{/if}
{/each}
</Table.Row>
{/each}
</Table.Body>
</Table.Root>
<div class="flex items-center gap-2 border-t py-2">
<div class="flex items-center gap-0">
<Button
size="icon"
variant="ghost"
disabled={!table.canGoBack}
on:click={() => table.currentPage--}
>
<ArrowLeft class="h-5 w-5" />
</Button>
<Button
size="icon"
variant="ghost"
disabled={!table.canGoForward}
on:click={() => table.currentPage++}
>
<ArrowRight class="h-5 w-5" />
</Button>
</div>
<p class="text-sm">
Page <span class="font-semibold">{table.currentPage}</span> of
<span class="font-semibold">{table.totalPages}</span>
</p>
<span class="text-xs">
({table.allRows.length} / {table.baseRows.length})
</span>
</div>
</div>
</div>