@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
| Component | Description |
|---|---|
DataGrid.Root | Main container with title, add button |
DataGrid.FilterForm | Auto-generated filter form from schema |
Table | Lower-level table component |
Pagination | Pagination controls |
useDataGrid Options
| Option | Description |
|---|---|
tableOptions | TanStack Table options (columns, state) |
query | Remote query function |
filterSchema | Zod schema for filters |
getRowLink | Function to generate row links |
URL State
Sorting, pagination, and filters are automatically synced to URL params for shareable links.