Skip to content

Commit

Permalink
add svelte table example
Browse files Browse the repository at this point in the history
  • Loading branch information
MarcusVirg committed Nov 13, 2023
1 parent 3b56dae commit f2f015d
Show file tree
Hide file tree
Showing 15 changed files with 4,139 additions and 1,828 deletions.
24 changes: 24 additions & 0 deletions examples/svelte/table/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
6 changes: 6 additions & 0 deletions examples/svelte/table/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 dev` or `yarn dev`
11 changes: 11 additions & 0 deletions examples/svelte/table/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
25 changes: 25 additions & 0 deletions examples/svelte/table/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "tanstack-svelte-virtual-example-table",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview",
"check": "svelte-check --tsconfig ./tsconfig.json"
},
"dependencies": {
"@tanstack/svelte-table": "^8.10.7",
"@tanstack/svelte-virtual": "^3.0.0-beta.69"
},
"devDependencies": {
"@sveltejs/vite-plugin-svelte": "^2.4.2",
"@tsconfig/svelte": "^5.0.0",
"svelte": "^4.0.5",
"svelte-check": "^3.4.6",
"tslib": "^2.6.0",
"typescript": "^5.0.2",
"vite": "^4.4.5"
}
}
184 changes: 184 additions & 0 deletions examples/svelte/table/src/App.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<script lang="ts">
import {
createSvelteTable,
getCoreRowModel,
getSortedRowModel,
type ColumnDef,
type SortingState,
type Updater,
flexRender,
type TableOptions,
} from '@tanstack/svelte-table'
import { createVirtualizer } from '@tanstack/svelte-virtual'
import { makeData, type Person } from './makeData'
import { writable } from 'svelte/store'
let virtualListEl: HTMLDivElement
let sorting: SortingState = []
function setSorting(updater: Updater<SortingState>) {
if (updater instanceof Function) sorting = updater(sorting)
else sorting = updater
tableOptions.update((opts) => ({
...opts,
state: {
...opts.state,
sorting,
},
}))
}
const columns: ColumnDef<Person>[] = [
{
accessorKey: 'id',
header: 'ID',
size: 60,
},
{
accessorKey: 'firstName',
header: 'First Name',
cell: (info) => info.getValue(),
},
{
accessorFn: (row) => row.lastName,
id: 'lastName',
header: 'Last Name',
cell: (info) => info.getValue(),
},
{
accessorKey: 'age',
header: 'Age',
size: 50,
},
{
accessorKey: 'visits',
header: 'Visits',
size: 50,
},
{
accessorKey: 'status',
header: 'Status',
},
{
accessorKey: 'progress',
header: 'Profile Progress',
size: 80,
},
{
accessorKey: 'createdAt',
header: 'Created At',
cell: (info) => info.getValue<Date>().toLocaleString(),
},
]
const tableOptions = writable<TableOptions<Person>>({
data: makeData(50_000),
columns,
state: {
sorting,
},
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getSortedRowModel: getSortedRowModel(),
debugTable: true,
})
const table = createSvelteTable(tableOptions)
$: rows = $table.getRowModel().rows
$: virtualizer = createVirtualizer<HTMLDivElement, HTMLTableRowElement>({
count: rows.length,
getScrollElement: () => virtualListEl,
estimateSize: () => 34,
overscan: 20,
})
</script>

<main>
<p>
For tables, the basis for the offset of the translate css function is from
the row's initial position itself. Because of this, we need to calculate the
translateY pixel count different and base it off the the index.
</p>

<div class="list scroll-container" bind:this={virtualListEl}>
<div style="position: relative; height: {$virtualizer.getTotalSize()}px;">
<table>
<thead>
{#each $table.getHeaderGroups() as headerGroup (headerGroup.id)}
<tr>
{#each headerGroup.headers as header (header.id)}
<th
colspan={header.colSpan}
style="width: {header.getSize()}px;"
>
{#if !header.isPlaceholder}
<button
class:sortable-header={header.column.getCanSort()}
disabled={!header.column.getCanSort()}
on:click={header.column.getToggleSortingHandler()}
>
<svelte:component
this={flexRender(
header.column.columnDef.header,
header.getContext(),
)}
/>
{#if header.column.getIsSorted()}
{header.column.getIsSorted() === 'desc' ? ' 🔽' : ' 🔼'}
{/if}
</button>
{/if}
</th>
{/each}
</tr>
{/each}
</thead>
<tbody>
{#each $virtualizer.getVirtualItems() as row, idx (row.index)}
<tr
style="height: {row.size}px; transform: translateY({row.start -
idx * row.size}px);"
>
{#each rows[row.index].getVisibleCells() as cell (cell.id)}
<td>
<svelte:component
this={flexRender(
cell.column.columnDef.cell,
cell.getContext(),
)}
/>
</td>
{/each}
</tr>
{/each}
</tbody>
</table>
</div>
</div>
</main>

<style>
button {
background: none;
border: none;
padding: 0;
margin: 0;
font: inherit;
color: inherit;
cursor: pointer;
outline: inherit;
}
.scroll-container {
height: 600px;
width: 100%;
overflow: auto;
}
.sortable-header {
cursor: pointer;
user-select: none;
}
</style>
28 changes: 28 additions & 0 deletions examples/svelte/table/src/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
html {
font-family: sans-serif;
font-size: 14px;
}

body {
padding: 1rem;
}

.list {
border: 1px solid #e6e4dc;
max-width: 100%;
}

.list-item-even,
.list-item-odd {
display: flex;
align-items: center;
justify-content: center;
}

.list-item-even {
background-color: #e6e4dc;
}

button {
border: 1px solid gray;
}
8 changes: 8 additions & 0 deletions examples/svelte/table/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import './app.css'
import App from './App.svelte'

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

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

export type Person = {
id: number
firstName: string
lastName: string
age: number
visits: number
progress: number
status: 'relationship' | 'complicated' | 'single'
createdAt: Date
}

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

const newPerson = (index: number): Person => {
return {
id: index + 1,
firstName: faker.name.firstName(),
lastName: faker.name.lastName(),
age: faker.datatype.number(40),
visits: faker.datatype.number(1000),
progress: faker.datatype.number(100),
createdAt: faker.datatype.datetime({ max: new Date().getTime() }),
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(d),
}
})
}

return makeDataLevel()
}
2 changes: 2 additions & 0 deletions examples/svelte/table/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/// <reference types="svelte" />
/// <reference types="vite/client" />
7 changes: 7 additions & 0 deletions examples/svelte/table/svelte.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

export default {
// Consult https://svelte.dev/docs#compile-time-svelte-preprocess
// for more information about preprocessors
preprocess: vitePreprocess(),
}
20 changes: 20 additions & 0 deletions examples/svelte/table/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"module": "ESNext",
"resolveJsonModule": true,
/**
* Typecheck JS in `.svelte` and `.js` files by default.
* Disable checkJs if you'd like to use dynamic types in JS.
* Note that setting allowJs false does not prevent the use
* of JS in `.svelte` files.
*/
"allowJs": true,
"checkJs": true,
"isolatedModules": true
},
"include": ["src/**/*.d.ts", "src/**/*.ts", "src/**/*.js", "src/**/*.svelte"],
"references": [{ "path": "./tsconfig.node.json" }]
}
9 changes: 9 additions & 0 deletions examples/svelte/table/tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"skipLibCheck": true,
"module": "ESNext",
"moduleResolution": "bundler"
},
"include": ["vite.config.ts"]
}
7 changes: 7 additions & 0 deletions examples/svelte/table/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'

// https://vitejs.dev/config/
export default defineConfig({
plugins: [svelte()],
})
Loading

0 comments on commit f2f015d

Please sign in to comment.