Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,10 @@
"to": "framework/svelte/examples/column-visibility",
"label": "Column Visibility"
},
{
"to": "framework/svelte/examples/filtering",
"label": "Filtering"
},
{
"to": "framework/svelte/examples/sorting",
"label": "Sorting"
Expand Down
8 changes: 8 additions & 0 deletions examples/svelte/filtering/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
node_modules
.DS_Store
dist
dist-ssr
*.local

src/**/*.d.ts
src/**/*.map
6 changes: 6 additions & 0 deletions examples/svelte/filtering/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Example

To run this example:

- `npm install` or `yarn`
- `npm run start` or `yarn start`
14 changes: 14 additions & 0 deletions examples/svelte/filtering/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite App</title>
<script type="module" src="https://cdn.skypack.dev/twind/shim"></script>
</head>

<body>
<div id="root"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
24 changes: 24 additions & 0 deletions examples/svelte/filtering/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "tanstack-table-example-svelte-filtering",
"version": "0.0.0",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview",
"test:types": "svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"@faker-js/faker": "^8.3.1",
"@rollup/plugin-replace": "^5.0.5",
"@sveltejs/vite-plugin-svelte": "^3.0.1",
"@tanstack/match-sorter-utils": "^8.11.8",
"@tanstack/svelte-table": "^8.12.0",
"@tsconfig/svelte": "^5.0.2",
"svelte": "^4.2.8",
"svelte-check": "^3.6.3",
"typescript": "5.3.3",
"vite": "^5.0.11"
}
}
102 changes: 102 additions & 0 deletions examples/svelte/filtering/src/App.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<script lang="ts">
import './index.css';
import { writable } from 'svelte/store';

import './index.css';

import {
createSvelteTable,
flexRender,
getCoreRowModel,
getFilteredRowModel,
getPaginationRowModel,
type FilterFn
} from '@tanstack/svelte-table';

import { type RankingInfo, rankItem } from '@tanstack/match-sorter-utils';

import { makeData, type Person } from './makeData';

declare module '@tanstack/table-core' {
interface FilterFns {
fuzzy: FilterFn<unknown>;
}
interface FilterMeta {
itemRank: RankingInfo;
}
}

let globalFilter = ''

const fuzzyFilter: FilterFn<any> = (row, columnId, value, addMeta) => {
// Rank the item
const itemRank = rankItem(row.getValue(columnId), value)

// Store the itemRank info
addMeta({ itemRank })

// Return if the item should be filtered in/out
return itemRank.passed
}

const options = writable<TableOptions<any>>({
data: makeData(25),
columns: [
{
accessorFn: (row) => `${row.firstName} ${row.lastName}`,
id: 'fullName',
header: 'Name',
cell: (info) => info.getValue(),
footer: (props) => props.column.id,
filterFn: 'fuzzy',
},
],
filterFns: {
fuzzy: fuzzyFilter,
},
enableMultiRowSelection: true,
getPaginationRowModel: getPaginationRowModel(),
getCoreRowModel: getCoreRowModel(),
globalFilterFn: fuzzyFilter,
getFilteredRowModel: getFilteredRowModel(),
})

const table = createSvelteTable(options)
</script>
<input type="text" placeholder="Global filter" class="border w-full p-1" bind:value={globalFilter} on:keyup={(e) => $table.setGlobalFilter(String(e.target.value))} />
<div class="h-2" />
<table class="w-full">
<thead>
{#each $table.getHeaderGroups() as headerGroup}
<tr>
{#each headerGroup.headers as header, idx}
<th scope="col">
{#if !header.isPlaceholder}
<svelte:component
this={flexRender(
header.column.columnDef.header,
header.getContext()
)}
/>
{/if}
</th>
{/each}
</tr>
{/each}
</thead>
<tbody>
{#each $table.getRowModel().rows as row}
<tr>
{#each row.getVisibleCells() as cell}
<td>
<svelte:component
this={flexRender(cell.column.columnDef.cell, cell.getContext())}
/>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>
<div class="h-2" />
<pre>"globalFilter": "{$table.getState().globalFilter}"</pre>
26 changes: 26 additions & 0 deletions examples/svelte/filtering/src/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
html {
font-family: sans-serif;
font-size: 14px;
}

table {
border: 1px solid lightgray;
}

tbody {
border-bottom: 1px solid lightgray;
}

th {
border-bottom: 1px solid lightgray;
border-right: 1px solid lightgray;
padding: 2px 4px;
}

tfoot {
color: gray;
}

tfoot th {
font-weight: normal;
}
8 changes: 8 additions & 0 deletions examples/svelte/filtering/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// @ts-ignore
import App from './App.svelte'

const app = new App({
target: document.getElementById('root')!,
})

export default app
48 changes: 48 additions & 0 deletions examples/svelte/filtering/src/makeData.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { faker } from '@faker-js/faker'

export type Person = {
firstName: string
lastName: string
age: number
visits: number
progress: number
status: 'relationship' | 'complicated' | 'single'
subRows?: Person[]
}

const range = (len: number) => {
const arr: number[] = []
for (let i = 0; i < len; i++) {
arr.push(i)
}
return arr
}

const newPerson = (): Person => {
return {
firstName: faker.person.firstName(),
lastName: faker.person.lastName(),
age: faker.number.int(40),
visits: faker.number.int(1000),
progress: faker.number.int(100),
status: faker.helpers.shuffle<Person['status']>([
'relationship',
'complicated',
'single',
])[0]!,
}
}

export function makeData(...lens: number[]) {
const makeDataLevel = (depth = 0): Person[] => {
const len = lens[depth]!
return range(len).map((d): Person => {
return {
...newPerson(),
subRows: lens[depth + 1] ? makeDataLevel(depth + 1) : undefined,
}
})
}

return makeDataLevel()
}
5 changes: 5 additions & 0 deletions examples/svelte/filtering/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

export default {
preprocess: vitePreprocess(),
}
13 changes: 13 additions & 0 deletions examples/svelte/filtering/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"resolveJsonModule": true,
"allowJs": true,
"checkJs": true,
"isolatedModules": true
},
"include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"]
}
17 changes: 17 additions & 0 deletions examples/svelte/filtering/vite.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import rollupReplace from '@rollup/plugin-replace'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [
rollupReplace({
preventAssignment: true,
values: {
__DEV__: JSON.stringify(true),
'process.env.NODE_ENV': JSON.stringify('development'),
},
}),
svelte(),
],
})