Features reference
A "feature" is a small bundle of state + helpers the grid engine checks for when wiring its row-model pipeline. Register only what you use - each feature ships about 1-2 KB gzipped and adds a small per-update cost.
import {
tableFeatures,
rowSortingFeature,
columnFilteringFeature,
columnGroupingFeature,
rowExpandingFeature,
rowPaginationFeature,
rowSelectionFeature,
} from 'sv-grid-community'
const features = tableFeatures({
rowSortingFeature,
columnFilteringFeature,
rowSelectionFeature,
})
The features object is the contract the headless core checks for
optional capabilities. The wrapper reads it once at mount and wires
the matching row-model pipeline (core → filtered → sorted → grouped →
expanded). Features you don't register are tree-shaken out.
The feature catalogue
| Feature | Enables | Topic |
|---|---|---|
rowSortingFeature |
Click headers to sort; Shift-click for multi-sort. | Row sorting |
columnFilteringFeature |
Per-column filter menu, global search, filter row. | Filter overview |
rowPaginationFeature |
Page slicing + the footer pager. | Row pagination |
rowSelectionFeature |
Checkbox column + Shift/Ctrl multi-select. | Styling rows |
columnGroupingFeature |
Group-by-column + aggregated footer summaries. | Grouping & aggregation |
rowExpandingFeature |
Tree / master-detail expand-collapse. | Tree rows |
tableFeatures(features) factory
function tableFeatures<TFeatures extends Partial<TableFeatures>>(
features: TFeatures,
): TFeatures
Identity at runtime - just a typed pass-through. Its job is to give
TypeScript a precise type for the features object that
<SvGrid features={...}> and ColumnDef<TFeatures, TData> both
consume.
Row-model factories (headless)
Each feature has a matching row-model factory exported from the
package. When you use the <SvGrid> wrapper, the factories get wired
in for you. When you drop down to createSvGrid directly, register
them yourself:
import {
createSvGrid,
createCoreRowModel,
createFilteredRowModel,
createSortedRowModel,
createGroupedRowModel,
createExpandedRowModel,
createPaginatedRowModel,
tableFeatures,
rowSortingFeature,
columnFilteringFeature,
rowPaginationFeature,
sortFns,
filterFns,
} from 'sv-grid-community'
const grid = createSvGrid({
_features: tableFeatures({
rowSortingFeature,
columnFilteringFeature,
rowPaginationFeature,
}),
_rowModels: {
coreRowModel: createCoreRowModel(),
filteredRowModel: createFilteredRowModel(),
sortedRowModel: createSortedRowModel(sortFns),
paginatedRowModel: createPaginatedRowModel(),
},
columns,
data,
})
| Factory | Order in pipeline | Notes |
|---|---|---|
createCoreRowModel |
1 | Identity. Always required. |
createFilteredRowModel |
2 | Applies the grid's columnFilters state. |
createSortedRowModel |
3 | Applies sorting state; comparator picked by column editorType. |
createGroupedRowModel |
4 | Applies grouping state; emits group rows. |
createExpandedRowModel |
5 | Filters out collapsed children. |
createPaginatedRowModel |
6 | Slices to the current page. NOT used by the wrapper - see below. |
Wrapper pagination note. The
<SvGrid>wrapper does not putpaginatedRowModelin the pipeline. It paginates after its own filter overlays so the filter UI sees the full dataset, not the visible page. See Row pagination.
Sort + filter function registries
sortFns
import { sortFns } from 'sv-grid-community'
// sortFns.auto - lexical (default for unknown / mixed types)
// sortFns.number - numeric, NaN-safe
// sortFns.date - parsed via new Date(...)
Pick a comparator yourself by setting the column's editorType -
'number', 'date', 'datetime' map to sortFns.number /
sortFns.date automatically.
filterFns
import { filterFns } from 'sv-grid-community'
// includesString, equalsString, arrIncludes,
// inNumberRange, isAfter, isBefore, isEmpty, isNotEmpty
Reference a filter function by name on a column-filter clause:
const columnFilters = [{ id: 'age', value: 30, fn: 'equals' }]
Extend the registry yourself - it's a plain mutable object:
import { filterFns } from 'sv-grid-community'
declare module 'sv-grid-community' {
interface FilterFnsRegistry {
inListCSV: (value: unknown, query: string) => boolean
}
}
;(filterFns as any).inListCSV = (value, query) => {
const items = String(query).split(',').map((s) => s.trim().toLowerCase())
return items.includes(String(value ?? '').toLowerCase())
}
See also
<SvGrid>- where features get passed inSvGridApi- imperative sort/filter/group setters- Why headless? - when to use the row-model factories directly