Filtering
Filters use Zod schemas for validation and SuperForms for form handling. Filter state is persisted in URL params by default.
Setup
1. Define a filter schema
import { z } from 'zod/v4';
const filterSchema = z.object({
name: z.string().optional(),
status: z.enum(['active', 'inactive']).optional(),
createdAt: z.date().optional(),
});
2. Create a SuperForm on the server
import { superValidate } from 'sveltekit-superforms/server';
import { zod4 } from 'sveltekit-superforms/adapters';
// In +page.server.ts (metadata only -- no data loading)
export const load = async () => {
const filterForm = await superValidate(zod4(filterSchema));
return { filterForm };
};
3. Pass to useDataGrid
<script lang="ts">
import { DataGrid, useDataGrid } from '@repo/table';
const { data } = $props();
const { table, dataGrid } = useDataGrid({
tableOptions: { columns: [...] },
data: { data: data.users, count: data.totalCount },
filterSchema,
filterForm: data.filterForm,
});
</script>
4. Render filter fields via snippet
<DataGrid {dataGrid} {table} title="Users">
{#snippet filterFields()}
<!-- Your filter form fields here -->
<input type="text" name="name" placeholder="Search by name" />
<select name="status">
<option value="">All</option>
<option value="active">Active</option>
<option value="inactive">Inactive</option>
</select>
{/snippet}
</DataGrid>
The DataGrid component renders a filter button. Clicking it opens a sidebar with your filterFields snippet.
FilterStrategy Interface
interface FilterStrategy {
get: <T extends z.ZodType>(options: { url?: URL; schema: T }) => z.infer<T>;
set: <T extends z.ZodType>(options: {
data: z.infer<T>;
options: OnResultOptions;
schema: T;
}) => MaybePromise<void>;
}
The default urlFilterStrategy encodes filters as URL params: ?filters=name:Alice,status:active.
Custom Filter Strategy
Use getURLFilterStrategy with custom serializers:
import { getURLFilterStrategy } from '@repo/table';
const customFilterStrategy = getURLFilterStrategy({
serialize: (data) => ({ /* custom serialization */ }),
deserialize: (params) => ({ /* custom deserialization */ }),
});
Or implement FilterStrategy from scratch. See Custom Strategies.