Skip to main content

Custom Strategies

The data grid uses three strategy interfaces for sorting, pagination, and filtering. Default strategies use URL params. You can replace any or all of them.

SortingStrategy

import type { SortingState } from '@tanstack/svelte-table';
import type { ColumnSort } from '@tanstack/table-core';

interface SortingStrategy {
get: (options: { url?: URL; sortingDefault?: ColumnSort[] }) => SortingState;
set: (state: SortingState) => void;
}

Example: Local State Sort

import type { SortingStrategy } from '@repo/table';

let localSorting: SortingState = $state([]);

const localSortStrategy: SortingStrategy = {
get: ({ sortingDefault }) => localSorting.length ? localSorting : (sortingDefault ?? []),
set: (state) => { localSorting = state },
};

PaginationStrategy

import type { PaginationState } from '@tanstack/table-core';

interface PaginationStrategy {
get: (options: { url?: URL; default?: PaginationState }) => PaginationState;
set: (state: PaginationState) => void;
}

Example: Local State Pagination

import type { PaginationStrategy } from '@repo/table';

let localPagination: PaginationState = $state({ pageIndex: 0, pageSize: 20 });

const localPaginationStrategy: PaginationStrategy = {
get: () => localPagination,
set: (state) => { localPagination = state },
};

FilterStrategy

import type { z } from 'zod/v4';

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>;
}

Example: Local State Filter

import type { FilterStrategy } from '@repo/table';

let localFilters: Record<string, unknown> = $state({});

const localFilterStrategy: FilterStrategy = {
get: () => localFilters,
set: async ({ data }) => { localFilters = data },
};

Using Custom Strategies

Pass to useDataGrid:

import { useDataGrid } from '@repo/table';

const { table, dataGrid } = useDataGrid({
tableOptions: { columns: [...] },
data: { data: items, count },
sortStrategy: localSortStrategy,
paginationStrategy: localPaginationStrategy,
filterStrategy: localFilterStrategy,
});

Overriding Defaults

To override only one strategy while keeping URL-based behavior for the rest:

import { useDataGrid, urlSortStrategy, urlPaginationStrategy } from '@repo/table';

const { table, dataGrid } = useDataGrid({
tableOptions: { columns: [...] },
data: { data: items, count },
sortStrategy: urlSortStrategy, // keep default
paginationStrategy: urlPaginationStrategy, // keep default
filterStrategy: localFilterStrategy, // custom
});

Only the strategies you pass are overridden. Omitted strategies fall back to defaultStrategies (all URL-based).

Default Strategies Reference

import { defaultStrategies } from '@repo/table';

// defaultStrategies = {
// sortStrategy: urlSortStrategy,
// filterStrategy: urlFilterStrategy,
// paginationStrategy: urlPaginationStrategy,
// }