Capítulo 8 de 54
tableFeatures({...}) is v9's plugin architecture: every table statically declares which optional capabilities (sorting, filtering, pagination, ...) it needs, so unused feature code tree-shakes away and the TypeScript surface only exposes APIs for features that are actually registered.
rowSortingFeature) adds state/options/APIs; a row-model factory (e.g. createSortedRowModel()) does the actual client-side data processing; a function registry (sortFns, filterFns) supplies named implementations you reference by string. You can register a feature for its state/APIs while doing the processing server-side — just omit the row-model factory and set the matching manual* option (see Client-Side vs Server-Side Guide).tableFeatures() validates prerequisites at the type level: e.g. sortedRowModel requires rowSortingFeature, globalFilteringFeature requires columnFilteringFeature. A missing prerequisite is a type error naming what's missing, not a runtime surprise.features outside the component (module scope) — it's static config; a stable reference avoids rebuilding table structures and gives shared column helpers one typeof features type to type against.filterFns: { includesString: filterFn_includesString }) to preserve tree-shaking; spreading a full built-in registry (e.g. all of filterFns) includes every implementation in it. A function passed inline to a column option doesn't need to be registered by name at all.stockFeatures = every optional feature at once, for prototypes or "genuinely uses almost everything" tables — convenient but forfeits per-feature tree-shaking, and still doesn't add row models or function registries (add those separately).| Stock feature | Adds |
|---|---|
cellSelectionFeature | spreadsheet-style cell-range selection state/APIs |
cellSpanningFeature | cells spanning multiple rows/columns |
columnFacetingFeature | unique values / ranges / counts per column, for filter UIs |
columnFilteringFeature | per-column filter state and filtering |
columnGroupingFeature | grouping rows by column value |
columnOrderingFeature | reordering columns |
columnPinningFeature | pinning columns left/right |
columnResizingFeature | resize interactions (builds on column sizing) |
columnSizingFeature | column width state |
columnVisibilityFeature | show/hide columns |
globalFilteringFeature | cross-column search (builds on column filtering) |
rowAggregationFeature | totals/aggregates over row sets |
rowExpandingFeature | expand/collapse sub-rows |
rowPaginationFeature | page state + navigation (+ optional client-side pagination) |
rowPinningFeature | pinning rows top/bottom |
rowSelectionFeature | selected-row state/APIs |
rowSortingFeature | sort state (+ optional client-side ordering) |
Not in stockFeatures: fuzzy filtering (a recipe built from filtering + sorting) and virtualization (provided by TanStack Virtual, not a Table feature).
import {
columnFilteringFeature, createFilteredRowModel, createSortedRowModel,
filterFn_includesString, rowSortingFeature, sortFn_alphanumeric, tableFeatures,
} from '@tanstack/react-table'
const features = tableFeatures({
columnFilteringFeature,
rowSortingFeature,
filteredRowModel: createFilteredRowModel(), // client-side filtering
sortedRowModel: createSortedRowModel(), // client-side sorting
filterFns: { includesString: filterFn_includesString },
sortFns: { alphanumeric: sortFn_alphanumeric },
})
rowSortingFeature) is separate from opting into client-side processing for it (sortedRowModel: createSortedRowModel()) — server-driven tables register the feature but skip the row-model factory.tableFeatures({}), add exactly the features a table needs — this is the mechanism the whole tree-shaking story depends on.stockFeatures is a legitimate shortcut for prototypes or v8-parity, not a default to leave in production without reconsidering.tableFeatures.manual* options that pair with omitting a row model.create*RowModel() function.