Files
skills/docs/ui/react/react-ui/src/i18n/tanstack-bridge/tanstack-bridge.md
2026-05-29 08:20:56 +01:00

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 TanStack SortingFn. 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.Collator cache — one collator per (locale) for sort, one for filter; cleared via clearTanstackBridgeCaches() 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 useMemo keyed on locale.
  • localeAwareSortingFn does 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.