3.6 KiB
tanstack-bridge
(no submodules)
Purpose
Locale-aware sortingFn and filterFn factories for @tanstack/react-table columns, backed by Intl.Collator. Manual a.localeCompare(b) calls on column data do not pick up the active runtime locale unless explicitly threaded through; these factories take a locale and return functions that respect that locale's collation rules — Swedish places ä after z, German default folds ß to ss, Turkish dotted/dotless i are distinct. Use these for any TanStack Table whose column values are strings users see in the active language.
Features
localeAwareSortingFn(locale)— collator-backed comparator suitable as a TanStackSortingFn. Variant sensitivity (case + diacritics distinguished). Undefined / null values sort first.localeAwareFilterFn(locale)— case + diacritic insensitive substring match (sensitivity: "base",usage: "search"). Empty filter matches every row.- Per-locale
Intl.Collatorcache — one collator per(locale)for sort, one for filter; cleared viaclearTanstackBridgeCaches()in tests. - Structural typing — does not pin a TanStack version.
Usage: Basic Example
import { localeAwareSortingFn, localeAwareFilterFn } from "@suaveplan/react-ui";
const columns: ColumnDef<Customer>[] = [
{
accessorKey: "name",
sortingFn: localeAwareSortingFn(locale),
filterFn: localeAwareFilterFn(locale),
},
];
Usage: Advanced Example
Wire the locale once per render via useReactUiLocale and reuse across every string column:
import {
localeAwareFilterFn,
localeAwareSortingFn,
useReactUiLocale,
} from "@suaveplan/react-ui";
function CustomerTable() {
const { locale } = useReactUiLocale();
const sort = useMemo(() => localeAwareSortingFn(locale), [locale]);
const filter = useMemo(() => localeAwareFilterFn(locale), [locale]);
const columns = useMemo<ColumnDef<Customer>[]>(
() => [
{ accessorKey: "name", sortingFn: sort, filterFn: filter },
{ accessorKey: "company", sortingFn: sort, filterFn: filter },
],
[sort, filter]
);
return <DataTable columns={columns} data={rows} />;
}
API Reference
localeAwareSortingFn(locale: string)
Returns (rowA, rowB, columnId) => number. Compares column values via a cached Intl.Collator(locale, { sensitivity: "variant" }). Equal values return 0; undefined / null values return -1 / 1 so empty rows cluster.
localeAwareFilterFn(locale: string)
Returns (row, columnId, filterValue) => boolean. Performs a substring match through a cached Intl.Collator(locale, { sensitivity: "base", usage: "search" }). Empty / null filter matches every row.
clearTanstackBridgeCaches()
Test helper; releases the per-locale collator caches.
Implementation Notes
- The filter implementation is an O(n*m) sliding window comparing every needle-length substring via the collator. This is fine for in-memory tables of a few thousand rows; for 10k+ rows or noisy keystroke inputs, prefer a server-side filter or debounce the input.
- The factories return closures — calling twice with the same locale returns two different function references. To avoid TanStack's column-config invalidation, memoize the returned function with
useMemokeyed on locale. localeAwareSortingFndoes NOT respect the table's per-column sort direction toggle — TanStack flips the sign of the comparator's return value when the user clicks "sort descending". Our function returns the natural ascending comparator and TanStack handles the rest.