first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
# `tanstack-bridge`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## 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
```tsx
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:
```tsx
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.