Skip to main content

@repo/table

Data grid system built on TanStack Table with URL-based state management.

Usage

Query Endpoint

Create a query endpoint that handles pagination, sorting, and filtering:

// users.remote.ts
import { query } from '$app/server'
import { countSelect, overviewToQuery } from '@repo/db'
import { createOverviewQuerySchema } from '@repo/table/remote'

export const getUsersQuery = query(
createOverviewQuerySchema(userFilterSchema),
async (data) => {
const { db, usersTable } = await getTenantDb()

return await overviewToQuery(
db
.select({
id: usersTable.id,
name: usersTable.name,
count: countSelect, // Required for pagination
})
.from(usersTable)
.$dynamic(),
usersTable,
data,
)
},
)

DataGrid Component

<script lang="ts">
import type { QueryDataPoint } from '@repo/table/remote'
import { getUsersQuery } from '$lib/domains/users/database/users.remote'
import { userFilterSchema } from '$lib/domains/users/utils/schemas'
import { DataGrid, useDataGrid } from '@repo/table/remote'
import { createColumnHelper } from '@tanstack/table-core'

const ch = createColumnHelper<QueryDataPoint<typeof getUsersQuery>>()

const { table, dataGrid } = await useDataGrid({
tableOptions: {
columns: [
ch.accessor('name', { header: 'Name' }),
ch.accessor('createdAt', { header: 'Created At' }),
],
state: {
sorting: [{ id: 'name', desc: false }],
},
},
query: getUsersQuery,
filterSchema: userFilterSchema,
getRowLink: row => `users/${row.id}`,
})
</script>

<DataGrid.Root title="Users" {table} {dataGrid} add="/users/add">
<DataGrid.FilterForm schema={userFilterSchema} />
</DataGrid.Root>

Components

ComponentDescription
DataGrid.RootMain container with title, add button
DataGrid.FilterFormAuto-generated filter form from schema
TableLower-level table component
PaginationPagination controls

useDataGrid Options

OptionDescription
tableOptionsTanStack Table options (columns, state)
queryRemote query function
filterSchemaZod schema for filters
getRowLinkFunction to generate row links

URL State

Sorting, pagination, and filters are automatically synced to URL params for shareable links.