### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
# TanStack Table
> [!NOTE]
> You may know TanStack Table by the adapter names:
>
> - [Angular Table](https://tanstack.com/table/alpha/docs/framework/angular/angular-table)
> - [Lit Table](https://tanstack.com/table/alpha/docs/framework/lit/lit-table)
> - [React Table](https://tanstack.com/table/alpha/docs/framework/react/react-table)
> - [Solid Table](https://tanstack.com/table/alpha/docs/framework/solid/solid-table)
> - [Svelte Table](https://tanstack.com/table/alpha/docs/framework/svelte/svelte-table)
> - [Vue Table](https://tanstack.com/table/alpha/docs/framework/vue/vue-table)
A headless table library for building powerful datagrids with full control over markup, styles, and behavior.
- Framework‑agnostic core with bindings for React, Vue & Solid
- 100% customizable — bring your own UI, components, and styles
- Sorting, filtering, grouping, aggregation & row selection
- Lightweight, virtualizable & server‑side friendly
### Read the Docs →
## Get Involved
- We welcome issues and pull requests!
- Participate in [GitHub discussions](https://github.com/TanStack/table/discussions)
- Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ)
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions
## Partners
We're looking for TanStack Table Partners to join our mission! Partner with us to push the boundaries of TanStack Table and build amazing things together.
While we clearly love TanStack Table, we acknowledge that it is not a "batteries" included product packed with customer support and enterprise polish. We realize that some of our users may need this though! To help out here, we want to introduce you to AG Grid, an enterprise-grade data grid solution that can supercharge your applications with its extensive feature set and robust performance. While TanStack Table is also a powerful option for implementing data grids, we believe in providing our users with a diverse range of choices that best fit their specific requirements. AG Grid is one such choice, and we're excited to highlight its capabilities for you.
## Why Choose [AG Grid](https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable)?
Here are some good reasons to consider AG Grid for your next project:
### Comprehensive Feature Set
AG Grid offers an extensive set of features, making it a versatile and powerful data grid solution. With AG Grid, you get access to a wide range of functionalities that cater to the needs of complex enterprise applications. From advanced sorting, filtering, and grouping capabilities to column pinning, multi-level headers, and tree data structure support, AG Grid provides you with the tools to create dynamic and interactive data grids that meet your application's unique demands.
### High Performance
When it comes to handling large datasets and achieving exceptional performance, AG Grid delivers outstanding results. It employs highly optimized rendering techniques, efficient data updates, and virtualization to ensure smooth scrolling and fast response times, even when dealing with thousands or millions of rows of data. AG Grid's performance optimizations make it an excellent choice for applications that require high-speed data manipulation and visualization.
### Customization and Extensibility
AG Grid is designed to be highly customizable and extensible, allowing you to tailor the grid to your specific needs. It provides a rich set of APIs and events that enable you to integrate custom functionality seamlessly. You can define custom cell renderers, editors, filters, and aggregators to enhance the grid's behavior and appearance. AG Grid also supports a variety of themes, allowing you to match the grid's visual style to your application's design.
### Support for Enterprise Needs
As an enterprise-focused solution, AG Grid caters to the requirements of complex business applications. It offers enterprise-specific features such as row grouping, column pinning, server-side row model, master/detail grids, and rich editing capabilities. AG Grid also integrates well with other enterprise frameworks and libraries, making it a reliable choice for large-scale projects.
### Active Development and Community Support
AG Grid benefits from active development and a thriving community of developers. The team behind AG Grid consistently introduces new features and enhancements, ensuring that the product evolves to meet the changing needs of the industry. The community support is robust, with forums, documentation, and examples readily available to assist you in utilizing the full potential of AG Grid.
## Conclusion
While TanStack Table remains a powerful and flexible option for implementing data grids, we understand that different projects have different requirements. AG Grid offers a compelling enterprise-grade solution that may be particularly suited to your needs. Its comprehensive feature set, high performance, customization options, and focus on enterprise requirements make AG Grid an excellent choice for projects that demand a robust and scalable data grid solution.
We encourage you to explore AG Grid further by visiting their website and trying out their demo. Remember that both TanStack Table and AG Grid have their unique strengths and considerations. We believe in providing options to our users, empowering you to make informed decisions and choose the best fit for your specific use case.
Visit the [AG Grid website](https://www.ag-grid.com).
================================================
FILE: docs/faq.md
================================================
---
title: FAQ
---
## How do I stop infinite rendering loops?
If you are using React, there is a very common pitfall that can cause infinite rendering. If you fail to give your `columns`, `data`, or `state` a stable reference, React will enter an infinite loop of re-rendering upon any change to the table state.
Why does this happen? Is this a bug in TanStack Table? **No**, it is not. *This is fundamentally how React works*, and properly managing your columns, data, and state will prevent this from happening.
TanStack Table is designed to trigger a re-render whenever either the `data` or `columns` that are passed into the table change, or whenever any of the table's state changes.
> Failing to give `columns` or `data` stable references can cause an infinite loop of re-renders.
### Pitfall 1: Creating new columns or data on every render
```js
export default function MyComponent() {
//😵 BAD: This will cause an infinite loop of re-renders because `columns` is redefined as a new array on every render!
const columns = [
// ...
];
//😵 BAD: This will cause an infinite loop of re-renders because `data` is redefined as a new array on every render!
const data = [
// ...
];
//❌ Columns and data are defined in the same scope as `useTable` without a stable reference, will cause infinite loop!
const table = useTable({
columns,
data,
});
return
...
;
}
```
### Solution 1: Stable references with useMemo or useState
In React, you can give a "stable" reference to variables by defining them outside/above the component, or by using `useMemo` or `useState`, or by using a 3rd party state management library (like Redux or React Query 😉)
```js
//✅ OK: Define columns outside of the component
const columns = [
// ...
];
//✅ OK: Define data outside of the component
const data = [
// ...
];
// Usually it's more practical to define columns and data inside the component, so use `useMemo` or `useState` to give them stable references
export default function MyComponent() {
//✅ GOOD: This will not cause an infinite loop of re-renders because `columns` is a stable reference
const columns = useMemo(() => [
// ...
], []);
//✅ GOOD: This will not cause an infinite loop of re-renders because `data` is a stable reference
const [data, setData] = useState(() => [
// ...
]);
// Columns and data are defined in a stable reference, will not cause infinite loop!
const table = useTable({
columns,
data,
});
return
...
;
}
```
### Pitfall 2: Mutating columns or data in place
Even if you give your initial `columns` and `data` stable references, you can still run into infinite loops if you mutate them in place. This is a common pitfall that you may not notice that you are doing at first. Something as simple as an inline `data.filter()` can cause an infinite loop if you are not careful.
```js
export default function MyComponent() {
//✅ GOOD
const columns = useMemo(() => [
// ...
], []);
//✅ GOOD (React Query provides stable references to data automatically)
const { data, isLoading } = useQuery({
//...
});
const table = useTable({
columns,
//❌ BAD: This will cause an infinite loop of re-renders because `data` is mutated in place (destroys stable reference)
data: data?.filter(d => d.isActive) ?? [],
});
return
...
;
}
```
### Solution 2: Memoize your data transformations
To prevent infinite loops, you should always memoize your data transformations. This can be done with `useMemo` or similar.
```js
export default function MyComponent() {
//✅ GOOD
const columns = useMemo(() => [
// ...
], []);
//✅ GOOD
const { data, isLoading } = useQuery({
//...
});
//✅ GOOD: This will not cause an infinite loop of re-renders because `filteredData` is memoized
const filteredData = useMemo(() => data?.filter(d => d.isActive) ?? [], [data]);
const table = useTable({
columns,
data: filteredData, // stable reference!
});
return
...
;
}
```
### React Forget
When React Forget is released, these problems might be a thing of the past. Or just use Solid.js... 🤓
## How do I stop my table state from automatically resetting when my data changes?
Most plugins use state that _should_ normally reset when the data sources changes, but sometimes you need to suppress that from happening if you are filtering your data externally, or immutably editing your data while looking at it, or simply doing anything external with your data that you don't want to trigger a piece of table state to reset automatically.
For those situations, each plugin provides a way to disable the state from automatically resetting internally when data or other dependencies for a piece of state change. By setting any of them to `false`, you can stop the automatic resets from being triggered.
Here is a React-based example of stopping basically every piece of state from changing as they normally do while we edit the `data` source for a table:
```js
const [data, setData] = React.useState([])
const skipPageResetRef = React.useRef()
const updateData = newData => {
// When data gets updated with this function, set a flag
// to disable all of the auto resetting
skipPageResetRef.current = true
setData(newData)
}
React.useEffect(() => {
// After the table has updated, always remove the flag
skipPageResetRef.current = false
})
useTable({
...
autoResetPageIndex: !skipPageResetRef.current,
autoResetExpanded: !skipPageResetRef.current,
})
```
Now, when we update our data, the above table states will not automatically reset!
================================================
FILE: docs/framework/angular/angular-table.md
================================================
---
title: Angular Table
---
The `@tanstack/angular-table` adapter is a wrapper around the core table logic. Most of it's job is related to managing
state using angular signals, providing types and the rendering implementation of cell/header/footer templates.
## Exports
`@tanstack/angular-table` re-exports all of `@tanstack/table-core`'s APIs and the following:
### `injectTable`
Creates and returns an Angular-reactive table instance.
`injectTable` accepts either:
- an options function `() => TableOptions`
- a computed signal returning `TableOptions`
The initializer is intentionally re-evaluated whenever any signal read inside it changes.
This is how the adapter keeps the table in sync with Angular's reactivity model.
Because of that behavior, keep expensive/static values (for example `columns`, feature setup, row models) as stable references outside the initializer, and only read reactive state (`data()`, pagination/filter/sorting signals, etc.) inside it.
Since `ColumnDef` is stricter about generics, prefer building columns with `createColumnHelper()` so feature and row types are inferred consistently.
The returned table is also signal-reactive: table state and table APIs are wired for Angular signals, so you can safely consume table methods inside `computed(...)` and `effect(...)`.
```ts
import { computed, effect, signal } from '@angular/core'
import {
createColumnHelper,
injectTable,
type ColumnDef,
rowPaginationFeature,
stockFeatures
} from '@tanstack/angular-table'
// Register all table core features
const _features = tableFeatures(stockFeatures);
// ...or register only your needed features
const _features = tableFeatures({
rowPaginationFeature,
// ...all other features
})
const columnHelper = createColumnHelper()
export class AppComponent {
readonly data = signal([])
// If you type columns manually, include both generics:
// readonly columns: ColumnDef[] = [...]
readonly columns = columnHelper.columns([
columnHelper.accessor('firstName', {
header: 'First name',
cell: info => info.getValue(),
}),
// ...
])
// This function is re-run when any signal read inside changes.
readonly table = injectTable(() => ({
_features: _features,
// Reactive state can be read directly
data: this.data(),
state: {
// ...
},
// Keep stable references outside the initializer
columns: this.columns,
}))
constructor() {
effect(() => {
console.log('Visible rows:', this.table.getRowModel().rows.length)
})
}
}
```
See [injectTable API Reference](reference/functions/injectTable)
### `createTableHook`
`createTableHook` is the Angular composition API for building reusable table infrastructure.
Use it when multiple tables should share the same defaults (features, row models, default options, and component registries) while keeping strong types across the app.
At runtime, `createTableHook` wraps `injectTable` and returns typed helpers such as:
- `injectAppTable` for creating tables with shared defaults
- `createAppColumnHelper` for strongly typed column definitions
- pre-typed context helpers (`injectTableContext`, `injectTableCellContext`, `injectTableHeaderContext`, `injectFlexRenderCellContext`, `injectFlexRenderHeaderContext`)
For full setup and patterns, see the [Table Composition Guide](./guide/table-composition.md).
### `FlexRender`
An Angular structural rendering primitive for cell/header/footer content.
It supports the same content kinds as Angular rendering:
- primitive values (`string`, `number`, plain objects)
- `TemplateRef`
- component types
- `flexRenderComponent(component, options?)` wrappers with typed `inputs`, `outputs`, `injector`, `bindings`, and `directives`
Column render functions (`header`, `cell`, `footer`) run in Angular injection context, so you can use `inject()` and signals directly in render logic.
For complete rendering details (`*flexRender`, shorthand directives, `flexRenderComponent`, `TemplateRef`, component inputs/outputs, and `injectFlexRenderContext`), see the [Rendering components Guide](./guide/rendering.md).
### Context helpers and directives
`@tanstack/angular-table` also exports Angular DI helpers and directives for table/cell/header context:
- `TanStackTable` + `injectTableContext()`
- `TanStackTableCell` + `injectTableCellContext()`
- `TanStackTableHeader` + `injectTableHeaderContext()`
These APIs provide signal-based context values and are available from nearest directives or from `*flexRender`-rendered components when matching props are present.
### Full API Reference
See [Angular API Reference](reference/index.md)
================================================
FILE: docs/framework/angular/guide/migrating.md
================================================
---
title: Migrating to TanStack Table v9 (Angular)
---
## What's New in TanStack Table v9
TanStack Table v9 is a major release that introduces significant architectural improvements while maintaining the core table logic you're familiar with. Here are the key changes:
### 1. Tree-shaking
- **Features are tree-shakeable**: Features are now treated as plugins—import only what you use. If your table only needs sorting, you won't ship filtering, pagination, or other feature code. Bundlers can eliminate unused code, so for smaller tables you can expect a meaningfully smaller bundle compared to v8. This also lets TanStack Table add features over time without bloating everyone's bundles.
- **Row models and their functions are refactored**: Row model factories (`createFilteredRowModel`, `createSortedRowModel`, etc.) now accept their processing functions (`filterFns`, `sortFns`, `aggregationFns`) as parameters. This enables tree-shaking of the functions themselves—if you use a custom filter, you don't pay for built-in filters you never use.
### 2. State Management
- **Uses TanStack Store**: The internal state system has been rebuilt on [TanStack Store](https://tanstack.com/store), providing a reactive, framework-agnostic foundation.
- **Opt-in subscriptions instead of memo hacks**: In Angular, you consume state via signals and `computed(...)`. You can keep reads scoped to the state you actually need and avoid unnecessary template work.
### 3. Composability
- **`tableOptions`**: New utilities let you compose and share table configurations. Define `_features`, `_rowModels`, and default options once, then reuse them across tables or pass them through `createTableHook`.
- **`createTableHook`** (optional, advanced): Create reusable, strongly typed Angular table factories with pre-bound features, row models, default options, and component registries.
### The Good News: Most Upgrades Are Opt-in
While v9 is a significant upgrade, **you don't have to adopt everything at once**:
- **Don't want to think about tree-shaking yet?** You can start with `stockFeatures` to include most commonly used features.
- **Your table markup is largely unchanged.** How you render `
`, ``, `
`, `
`, etc. remains the same.
The main change is **how you define a table** with the Angular adapter — specifically the new `_features` and `_rowModels` options.
---
## Quick Legacy Migration
Angular does **not** ship a legacy API.
If you're migrating an Angular project from TanStack Table v8 to v9, you will migrate directly to the v9 Angular adapter APIs (`injectTable`, `_features`, and `_rowModels`).
---
The rest of this guide focuses on migrating to the full v9 API and taking advantage of its features.
## Core Breaking Changes
### Entrypoint Change
The Angular adapter entrypoint to create a table instance is `injectTable`:
```ts
// v8
import { createAngularTable } from '@tanstack/angular-table'
const v8Table = createAngularTable(() => ({
// options
}))
// v9
import { injectTable } from '@tanstack/angular-table'
const v9Table = injectTable(() => ({
// options
}))
```
> Note: `injectTable` evaluates your initializer whenever any Angular signal read inside of it changes.
> Keep expensive/static values (like `columns`, `_features`, and `_rowModels`) as stable references outside the initializer.
### New Required Options: `_features` and `_rowModels`
In v9, you must explicitly declare which features and row models your table uses:
```ts
// v8
import { createAngularTable, getCoreRowModel } from '@tanstack/angular-table'
const v8Table = createAngularTable(() => ({
columns,
data: data(),
getCoreRowModel: getCoreRowModel(),
}))
// v9
import {
injectTable,
tableFeatures,
} from '@tanstack/angular-table'
const _features = tableFeatures({}) // Empty = core feaFtures only
// Define stable references outside the initializer
const v9Table = injectTable(() => ({
_features,
_rowModels: {}, // Core row model is automatic
columns: this.columns,
data: this.data(),
}))
```
---
## The `_features` Option
Features control what table functionality is available. In v8, all features were bundled. In v9, you import only what you need.
### Importing Individual Features
```ts
import {
tableFeatures,
// Import only the features you need
columnFilteringFeature,
rowSortingFeature,
rowPaginationFeature,
columnVisibilityFeature,
rowSelectionFeature,
} from '@tanstack/angular-table'
// Create a features object (define this outside your injectTable initializer for stable reference)
const _features = tableFeatures({
columnFilteringFeature,
rowSortingFeature,
rowPaginationFeature,
columnVisibilityFeature,
rowSelectionFeature,
})
```
### Using `stockFeatures` for v8-like Behavior
If you want all features without thinking about it (like v8), import `stockFeatures`:
```ts
import { injectTable, stockFeatures } from '@tanstack/angular-table'
class TableCmp {
readonly table = injectTable(() => ({
_features: stockFeatures, // All features included
_rowModels: { /* ... */ },
columns: this.columns,
data: this.data(),
}))
}
```
### Available Features
| Feature | Import Name |
|---------|-------------|
| Column Filtering | `columnFilteringFeature` |
| Global Filtering | `globalFilteringFeature` |
| Row Sorting | `rowSortingFeature` |
| Row Pagination | `rowPaginationFeature` |
| Row Selection | `rowSelectionFeature` |
| Row Expanding | `rowExpandingFeature` |
| Row Pinning | `rowPinningFeature` |
| Column Pinning | `columnPinningFeature` |
| Column Visibility | `columnVisibilityFeature` |
| Column Ordering | `columnOrderingFeature` |
| Column Sizing | `columnSizingFeature` |
| Column Resizing | `columnResizingFeature` |
| Column Grouping | `columnGroupingFeature` |
| Column Faceting | `columnFacetingFeature` |
---
## The `_rowModels` Option
Row models are the functions that process your data (filtering, sorting, pagination, etc.). In v9, they're configured via `_rowModels` instead of `get*RowModel` options.
### Migration Mapping
| v8 Option | v9 `_rowModels` Key | v9 Factory Function |
|-----------|---------------------|---------------------|
| `getCoreRowModel()` | (automatic) | Not needed — always included |
| `getFilteredRowModel()` | `filteredRowModel` | `createFilteredRowModel(filterFns)` |
| `getSortedRowModel()` | `sortedRowModel` | `createSortedRowModel(sortFns)` |
| `getPaginationRowModel()` | `paginatedRowModel` | `createPaginatedRowModel()` |
| `getExpandedRowModel()` | `expandedRowModel` | `createExpandedRowModel()` |
| `getGroupedRowModel()` | `groupedRowModel` | `createGroupedRowModel(aggregationFns)` |
| `getFacetedRowModel()` | `facetedRowModel` | `createFacetedRowModel()` |
| `getFacetedMinMaxValues()` | `facetedMinMaxValues` | `createFacetedMinMaxValues()` |
| `getFacetedUniqueValues()` | `facetedUniqueValues` | `createFacetedUniqueValues()` |
### Key Change: Row Model Functions Now Accept Parameters
Several row model factories now accept their processing functions as parameters. This enables better tree-shaking and explicit configuration:
```ts
import {
injectTable,
createFilteredRowModel,
createSortedRowModel,
createGroupedRowModel,
createPaginatedRowModel,
filterFns, // Built-in filter functions
sortFns, // Built-in sort functions
aggregationFns, // Built-in aggregation functions
} from '@tanstack/angular-table'
class TableCmp {
readonly table = injectTable(() => ({
_features,
_rowModels: {
filteredRowModel: createFilteredRowModel(filterFns),
sortedRowModel: createSortedRowModel(sortFns),
groupedRowModel: createGroupedRowModel(aggregationFns),
paginatedRowModel: createPaginatedRowModel(),
},
columns: this.columns,
data: this.data(),
}))
}
```
### Full Migration Example
```ts
// v8
import {
injectTable,
getCoreRowModel,
getFilteredRowModel,
getSortedRowModel,
getPaginationRowModel,
filterFns,
sortingFns,
} from '@tanstack/angular-table'
const v8Table = createAngularTable(() => ({
columns,
data: data(),
getCoreRowModel: getCoreRowModel(), // used to be called "get*RowModel()"
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
getPaginationRowModel: getPaginationRowModel(),
filterFns, // used to be passed in as a root option
sortingFns,
}))
// v9
import {
injectTable,
tableFeatures,
columnFilteringFeature,
rowSortingFeature,
rowPaginationFeature,
createFilteredRowModel,
createSortedRowModel,
createPaginatedRowModel,
filterFns,
sortFns,
} from '@tanstack/angular-table'
const _features = tableFeatures({
columnFilteringFeature,
rowSortingFeature,
rowPaginationFeature,
})
const v9Table = injectTable(() => ({
_features,
_rowModels: {
filteredRowModel: createFilteredRowModel(filterFns),
sortedRowModel: createSortedRowModel(sortFns),
paginatedRowModel: createPaginatedRowModel(),
},
columns,
data: data(),
}))
```
---
## State Management Changes
### Accessing State
In v8, you accessed state via `table.getState()`. In v9, state is accessed via the store:
```ts
// v8
const state = table.getState()
const v8 = table.getState()
const { sorting, pagination } = v8
// v9 - via the store
const fullState = table.store.state
const v9 = table.store.state
const { sorting: v9Sorting, pagination: v9Pagination } = v9
```
### Optimizing Reads with Angular Signals
In Angular, you have a few good options for consuming table state.
#### Option 1: Prefer `table.store.subscribe(...)` for a sliced signal
TanStack Store lets you subscribe to (and derive) a slice of state. With the Angular adapter, you can use that to create a signal-like value that only updates when the selected slice changes.
This is the closest equivalent to the fine-grained subscription examples you might see in other frameworks.
```ts
import { computed, effect } from '@angular/core'
class TableCmp {
readonly table = injectTable(() => ({
_features,
_rowModels: { /* ... */ },
columns: this.columns,
data: this.data(),
}))
// Create a computed to a slice of state.
// The store will only emit when this selected value changes.
private readonly pagination = this.table.computed(
state => state.pagination,
)
constructor() {
effect(() => {
const { pageIndex, pageSize } = this.pagination()
console.log('Page', pageIndex, 'Size', pageSize)
})
}
}
```
#### Option 2: Use `computed(...)` and read from `table.store.state`
You can also use Angular `computed(...)` and directly read from `table.store.state`. This is simple and works well, but for object/array slices you should provide an equality function to avoid unnecessary downstream work when the slice is recreated with the same values.
```ts
import { computed, effect } from '@angular/core'
class TableCmp {
readonly table = injectTable(() => ({
_features,
_rowModels: { /* ... */ },
columns: this.columns,
data: this.data(),
}))
// Provide an equality function for object slices
readonly pagination = computed(
() => this.table.store.state.pagination,
{
equal: (a, b) => a.pageIndex === b.pageIndex && a.pageSize === b.pageSize,
},
)
constructor() {
effect(() => {
// This effect only re-runs when pagination changes
const { pageIndex, pageSize } = this.pagination()
console.log('Page', pageIndex, 'Size', pageSize)
})
}
}
```
### Controlled State
Controlled state patterns are pretty the same as v8:
```ts
import { signal } from '@angular/core'
import type { SortingState, PaginationState } from '@tanstack/angular-table'
class TableCmp {
readonly sorting = signal([])
readonly pagination = signal({ pageIndex: 0, pageSize: 10 })
readonly table = injectTable(() => ({
_features,
_rowModels: { /* ... */ },
columns: this.columns,
data: this.data(),
state: {
sorting: this.sorting(),
pagination: this.pagination(),
},
onSortingChange: (updater) => {
updater instanceof Function
? this.sorting.update(updater)
: this.sorting.set(updater)
},
onPaginationChange: (updater) => {
updater instanceof Function
? this.pagination.update(updater)
: this.pagination.set(updater)
},
}))
}
```
---
## Column Helper Changes
The `createColumnHelper` function now requires a `TFeatures` type parameter in addition to `TData`:
```ts
// v8
import { createColumnHelper } from '@tanstack/angular-table'
const columnHelperV8 = createColumnHelper()
// v9
import { createColumnHelper, tableFeatures, rowSortingFeature } from '@tanstack/angular-table'
const _features = tableFeatures({ rowSortingFeature })
const columnHelperV9 = createColumnHelper()
```
### New `columns()` Helper Method
v9 adds a `columns()` helper for better type inference when wrapping column arrays.
```ts
const columnHelper = createColumnHelper()
// Wrap your columns array for better type inference
const columns = columnHelper.columns([
columnHelper.accessor('firstName', {
header: 'First Name',
cell: (info) => info.getValue(),
}),
columnHelper.accessor('lastName', {
id: 'lastName',
header: () => 'Last Name',
cell: (info) => info.getValue(),
}),
columnHelper.display({
id: 'actions',
header: 'Actions',
cell: () => 'Edit',
}),
])
```
### Using with `createTableHook`
When using `createTableHook`, you get a pre-bound `createAppColumnHelper` that only requires `TData`:
```ts
import { createTableHook, tableFeatures, rowSortingFeature } from '@tanstack/angular-table'
const { injectAppTable, createAppColumnHelper } = createTableHook({
_features: tableFeatures({ rowSortingFeature }),
_rowModels: { /* ... */ },
})
// TFeatures is already bound — only need TData!
const columnHelper = createAppColumnHelper()
```
---
## Rendering Changes
### `FlexRender`
The rendering primitives in the Angular adapter are `FlexRender` and the `*flexRender` directives.
In v9, you can continue to render header/cell/footer content using the Angular adapter rendering utilities, but there are a few important improvements and helper APIs to be aware of.
#### Structural directive rendering
Angular rendering is directive-based:
- `FlexRender` / `*flexRender` renders arbitrary render content (primitives, `TemplateRef`, component types, or `flexRenderComponent(...)` wrappers)
- The directive is responsible for mounting embedded views or components via `ViewContainerRef`
#### Shorthand directives
If you're rendering standard table content, prefer the shorthand helpers:
- `*flexRenderCell="cell; let value"`
- `*flexRenderHeader="header; let value"`
- `*flexRenderFooter="footer; let value"`
These automatically select the correct column definition (`columnDef.cell` / `header` / `footer`) and the right props (`cell.getContext()` / `header.getContext()`), so you don't need to manually provide `props:`.
#### DI-aware render functions + context injection
Column definition render functions (`header`, `cell`, `footer`) run inside an Angular injection context, so they can safely call `inject()` and use signals.
When a component is rendered through the FlexRender directives, you can also access the full render props object via DI using `injectFlexRenderContext()`.
#### Component rendering helper: `flexRenderComponent`
If you need to render an Angular component with explicit configuration (custom `inputs`, `outputs`, `injector`, and Angular v20+ creation-time `bindings`/`directives`), return a `flexRenderComponent(Component, options)` wrapper from your column definition.
For complete rendering details (including component rendering, `TemplateRef`, `flexRenderComponent`, and context helpers), see the [Rendering components Guide](./rendering.md).
---
## The `tableOptions()` Utility
The `tableOptions()` helper provides type-safe composition of table options. It's useful for creating reusable partial configurations that can be spread into your table setup.
### Basic Usage
```ts
import { injectTable, tableOptions, tableFeatures, rowSortingFeature } from '@tanstack/angular-table'
import { isDevMode } from '@angular/core';
// Create a reusable options object with features pre-configured
const baseOptions = tableOptions({
_features: tableFeatures({ rowSortingFeature }),
debugTable: isDevMode()
})
class TableCmp {
readonly table = injectTable(() => ({
...baseOptions,
columns: this.columns,
data: this.data(),
_rowModels: {},
}))
}
```
### Composing Partial Options
`tableOptions()` allows you to omit certain required fields (like `data`, `columns`, or `_features`) when creating partial configurations:
```ts
import {
tableOptions,
tableFeatures,
rowSortingFeature,
columnFilteringFeature,
createSortedRowModel,
createFilteredRowModel,
filterFns,
sortFns,
} from '@tanstack/angular-table'
// Partial options without data or columns
const featureOptions = tableOptions({
_features: tableFeatures({
rowSortingFeature,
columnFilteringFeature,
}),
_rowModels: {
sortedRowModel: createSortedRowModel(sortFns),
filteredRowModel: createFilteredRowModel(filterFns),
},
})
```
```ts
import { injectTable, tableOptions, createPaginatedRowModel } from '@tanstack/angular-table'
// Another partial without _features (inherits from spread)
const paginationDefaults = tableOptions({
_rowModels: {
paginatedRowModel: createPaginatedRowModel(),
},
initialState: {
pagination: { pageIndex: 0, pageSize: 25 },
},
})
class TableCmp {
readonly table = injectTable(() => ({
...featureOptions,
...paginationDefaults,
columns: this.columns,
data: this.data(),
}))
}
```
### Using with `createTableHook`
`tableOptions()` pairs well with `createTableHook` for building composable table factories:
```ts
import {
createTableHook,
tableOptions,
tableFeatures,
rowSortingFeature,
rowPaginationFeature,
createSortedRowModel,
createPaginatedRowModel,
sortFns,
} from '@tanstack/angular-table'
const sharedOptions = tableOptions({
_features: tableFeatures({ rowSortingFeature, rowPaginationFeature }),
_rowModels: {
sortedRowModel: createSortedRowModel(sortFns),
paginatedRowModel: createPaginatedRowModel(),
},
})
const { injectAppTable } = createTableHook(sharedOptions)
```
---
## `createTableHook`: Composable Table Patterns
**This is an advanced, optional feature.** You don't need to use `createTableHook`—`injectTable` is sufficient for most use cases.
For applications with multiple tables sharing the same configuration, `createTableHook` lets you define features, row models, and reusable components once.
For full setup and patterns, see the [Table composition Guide](./table-composition.md).
---
## Other Breaking Changes
### Column Pinning Option Split
The `enablePinning` option has been split into separate options:
```ts
// v8
enablePinning: true
// v9
enableColumnPinning: true
enableRowPinning: true
```
### Removed Internal APIs
All internal APIs prefixed with `_` have been removed. If you were using any of these, use their public equivalents.
### Column Sizing vs. Column Resizing Split
In v8, column sizing and resizing were combined in a single feature. In v9, they've been split into separate features for better tree-shaking.
| v8 | v9 |
|----|-----|
| `ColumnSizing` (combined feature) | `columnSizingFeature` + `columnResizingFeature` |
| `columnSizingInfo` state | `columnResizing` state |
| `setColumnSizingInfo()` | `setColumnResizing()` |
| `onColumnSizingInfoChange` option | `onColumnResizingChange` option |
If you only need column sizing (fixed widths) without interactive resizing, you can import just `columnSizingFeature`. If you need drag-to-resize functionality, import both.
### Sorting API Renames
Sorting-related APIs have been renamed for consistency:
| v8 | v9 |
|----|-----|
| `sortingFn` (column def option) | `sortFn` |
| `column.getSortingFn()` | `column.getSortFn()` |
| `column.getAutoSortingFn()` | `column.getAutoSortFn()` |
| `SortingFn` type | `SortFn` type |
| `SortingFns` interface | `SortFns` interface |
| `sortingFns` (built-in functions) | `sortFns` |
Update your column definitions.
### Row API Changes
Some row APIs have changed from private to public:
| v8 | v9 |
|----|-----|
| `row._getAllCellsByColumnId()` (private) | `row.getAllCellsByColumnId()` (public) |
---
## TypeScript Changes Summary
### Type Generics
Most types now require a `TFeatures` parameter:
```txt
// v8
type Column
type ColumnDef
type Table
type Row
type Cell
// v9
type Column
type ColumnDef
type Table
type Row
type Cell
```
### Using `typeof _features`
The easiest way to get the `TFeatures` type is with `typeof`:
```ts
const _features = tableFeatures({
rowSortingFeature,
columnFilteringFeature,
})
type MyFeatures = typeof _features
const columns: ColumnDef[] = [...]
```
### Using `StockFeatures`
If using `stockFeatures`, use the `StockFeatures` type:
```ts
import type { StockFeatures, ColumnDef } from '@tanstack/angular-table'
const columns: ColumnDef[] = [...]
```
### `ColumnMeta` Generic Change
If you're using module augmentation to extend `ColumnMeta`, note that it now requires a `TFeatures` parameter.
### `RowData` Type Restriction
The `RowData` type is now more restrictive.
---
## Migration Checklist
- [ ] Update your table setup to v9 and define `_features` using `tableFeatures()` (or use `stockFeatures`)
- [ ] Migrate `get*RowModel()` options to `_rowModels`
- [ ] Update row model factories to include `Fns` parameters where needed
- [ ] Update TypeScript types to include `TFeatures` generic
- [ ] Update state access: `table.getState()` → `table.store.state`
- [ ] Update `createColumnHelper()` → `createColumnHelper()`
- [ ] Replace `enablePinning` with `enableColumnPinning`/`enableRowPinning` if used
- [ ] Rename `sortingFn` → `sortFn` in column definitions
- [ ] Split column sizing/resizing: use both `columnSizingFeature` and `columnResizingFeature` if needed
- [ ] Rename `columnSizingInfo` state → `columnResizing` (and related options)
- [ ] Update `ColumnMeta` module augmentation to include `TFeatures` generic (if used)
- [ ] (Optional) Use `tableOptions()` for composable configurations
- [ ] (Optional) Use `createTableHook` for reusable table patterns
---
## Examples
Check out these examples to see v9 patterns in action:
- [Basic](../examples/basic)
- [Basic (App Table)](../examples/basic-app-table)
- [Filters](../examples/filters)
- [Column Ordering](../examples/column-ordering)
- [Column Pinning](../examples/column-pinning)
- [Column Visibility](../examples/column-visibility)
- [Expanding](../examples/expanding)
- [Grouping](../examples/grouping)
- [Row Selection](../examples/row-selection)
- [Composable Tables](../examples/composable-tables)
================================================
FILE: docs/framework/angular/guide/rendering.md
================================================
---
title: Rendering components
---
The `@tanstack/angular-table` adapter provides structural directives and dependency injection primitives for rendering table content in Angular templates.
## FlexRender
[`FlexRender`](../reference/variables/FlexRender) is the rendering primitive.
It is exported as a tuple of two directives:
- [`FlexRenderDirective`](../reference/classes/FlexRenderDirective) — the base structural directive (`*flexRender`)
- [`FlexRenderCell`](../reference/classes/FlexRenderCell.md) — shorthand directives (`*flexRenderCell`, `*flexRenderHeader`, `*flexRenderFooter`)
Import `FlexRender` to get both:
```ts
import { Component } from '@angular/core'
import { FlexRender } from '@tanstack/angular-table'
@Component({
imports: [FlexRender],
templateUrl: './app.html',
})
export class AppComponent {}
```
### How it works
`FlexRender` is an Angular **structural directive**. Internally, it resolves the column definition's `header`, `cell`, or `footer` function and renders the result using [`ViewContainerRef`](https://angular.dev/api/core/ViewContainerRef):
- **Primitives** (`string`, `number`): rendered via `createEmbeddedView` into the host `ng-template`. The value is exposed as the template's implicit context (`let value`).
- **`TemplateRef`**: rendered via `createEmbeddedView`. The render context (`CellContext`, `HeaderContext`) is passed as `$implicit`.
- **`flexRenderComponent(...)`**: rendered via `createComponent` with explicit `inputs`, `outputs`, `bindings`, `directives`, and `injector`.
- **Component type** (`Type`): rendered via [`createComponent`](https://angular.dev/api/core/ViewContainerRef#createComponent). All properties from the render context are set as component inputs through [`ComponentRef.setInput`](https://angular.dev/api/core/ComponentRef#setInput).
Column definition functions (`header`, `cell`, `footer`) are called inside [`runInInjectionContext`](https://angular.dev/api/core/runInInjectionContext), which means you can call `inject()`, use signals, and access DI tokens directly in your render logic.
## Cell rendering
Prefer the shorthand directives for standard rendering:
| Directive | Input | Column definition |
|---|---|---|
| `*flexRenderCell` | `Cell` | `columnDef.cell` |
| `*flexRenderHeader` | `Header` | `columnDef.header` |
| `*flexRenderFooter` | `Header` | `columnDef.footer` |
Each shorthand resolves the correct column definition function and render context automatically through a `computed` signal, so no manual `props` mapping is needed.
### Example
```html
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {
@for (header of headerGroup.headers; track header.id) {
@if (!header.isPlaceholder) {
{{ value }}
}
}
}
@for (row of table.getRowModel().rows; track row.id) {
@for (cell of row.getVisibleCells(); track cell.id) {
{{ value }}
}
}
```
## Cell rendering with custom props
When you need full control over the `props` passed to the render function, use `*flexRender` directly.
`FlexRenderDirective` accepts two inputs:
- `flexRender` — the render definition (a column def function, a string, a `TemplateRef`, a component type, or a `flexRenderComponent(...)` wrapper)
- `flexRenderProps` — the props object passed to the render function and used as the implicit template context
Standard usage:
```html
{{ rendered }}
```
You can pass a custom props object to override the default context shape:
```html
{{ rendered }}
```
Inside rendered components, the full props object is available via [`injectFlexRenderContext()`](#injectflexrendercontext).
## Component rendering
You can render Angular components from column definitions in two ways:
### Using `flexRenderComponent`
[`flexRenderComponent(component, options?)`](../reference/functions/flexRenderComponent) wraps a component type with explicit options for `inputs`, `outputs`, `injector`, `bindings`, and `directives`.
Use this when you need to:
- pass custom inputs not derived from the render context
- subscribe to component outputs
- provide a custom `Injector`
- use creation-time `bindings` (Angular v20+)
- apply host directives and binding values at runtime
```ts
import { flexRenderComponent, type ColumnDef } from '@tanstack/angular-table'
const columns: ColumnDef[] = [
{
id: 'custom-cell',
cell: ctx =>
flexRenderComponent(CustomCellComponent, {
inputs: {
content: ctx.row.original.firstName,
},
outputs: {
clicked: value => {
console.log(value)
},
},
}),
},
]
```
#### How inputs and outputs work
**Inputs** are applied through [`ComponentRef.setInput(key, value)`](https://angular.dev/api/core/ComponentRef#setInput). This works with both `input()` signals and `@Input()` decorators. Inputs are diffed on every change detection cycle using `KeyValueDiffers` — only changed values trigger `setInput`.
For object-like inputs, updates are reference-based: if the object reference is stable, Angular's default input equality semantics prevent unnecessary updates.
**Outputs** work through `OutputEmitterRef` subscriptions. The factory reads the component instance property by name, checks that it is an `OutputEmitterRef`, and subscribes to it. When the output emits, the corresponding callback from `outputs` is invoked. Subscriptions are cleaned up automatically when the component is destroyed.
#### `bindings` API (Angular v20+)
`flexRenderComponent` also accepts `bindings` and `directives`, forwarded directly to [`ViewContainerRef.createComponent`](https://angular.dev/api/core/ViewContainerRef#createComponent) at creation time.
This supports Angular programmatic rendering APIs for passing host directives and binding values at runtime.
Unlike `inputs`/`outputs` (which are applied imperatively after creation), `bindings` are applied **at creation time** — they participate in the component's initial change detection cycle.
```ts
import {
inputBinding,
outputBinding,
twoWayBinding,
signal,
} from '@angular/core'
import { flexRenderComponent } from '@tanstack/angular-table'
readonly name = signal('Ada')
cell: () =>
flexRenderComponent(EditableNameCellComponent, {
bindings: [
inputBinding('value', this.name),
outputBinding('valueChange', value => {
console.log('changed', value)
}),
twoWayBinding('value', this.name),
],
})
```
> Avoid mixing `bindings` with `inputs`/`outputs` on the same property. `bindings` are applied at creation, while `inputs`/`outputs` are applied post-creation — mixing them can lead to double initialization or conflicting values.
See the Angular docs for details:
- [Programmatic rendering — Binding inputs/outputs/directives](https://angular.dev/guide/components/programmatic-rendering#binding-inputs-outputs-and-setting-host-directives-at-creation)
- [`inputBinding`](https://angular.dev/api/core/inputBinding), [`outputBinding`](https://angular.dev/api/core/outputBinding), [`twoWayBinding`](https://angular.dev/api/core/twoWayBinding)
### Returning a component class
Return a component class from `header`, `cell`, or `footer`.
The render context properties (`table`, `column`, `header`, `cell`, `row`, `getValue`, etc.) are automatically set as component inputs via `ComponentRef.setInput(...)`.
Define input signals matching the context property names you need:
```ts
import { Component, input } from '@angular/core'
import type { ColumnDef, Table, CellContext } from '@tanstack/angular-table'
const columns: ColumnDef[] = [
{
id: 'select',
header: () => TableHeadSelectionComponent,
cell: () => TableRowSelectionComponent,
},
]
@Component({
template: `
`,
})
export class TableHeadSelectionComponent {
readonly table = input.required
>();
// column = input.required>()
// header = input.required>()
}
```
Only properties declared with `input()` / `input.required()` are set — other context properties are silently ignored. You can also access the full context via [`injectFlexRenderContext()`](#injectflexrendercontext).
## TemplateRef rendering
You can return a `TemplateRef` from column definitions. The render context is passed as the template's `$implicit` context.
Use `viewChild(...)` to capture template references:
```ts
import { Component, TemplateRef, viewChild } from '@angular/core'
import type {
CellContext,
ColumnDef,
HeaderContext,
} from '@tanstack/angular-table'
@Component({
template: `
{{ context.column.id }}
{{ context.getValue() }}
`,
})
export class AppComponent {
readonly customHeader =
viewChild.required }>>(
'customHeader',
)
readonly customCell =
viewChild.required }>>(
'customCell',
)
readonly columns: ColumnDef[] = [
{
id: 'templated',
header: () => this.customHeader(),
cell: () => this.customCell(),
},
]
}
```
`TemplateRef` rendering uses `createEmbeddedView` with an injector that includes the [DI context tokens](#dependency-injection). For reusable render blocks shared across multiple screens, prefer standalone components over `TemplateRef`.
## Dependency injection
`FlexRender` automatically provides DI tokens when rendering components and templates. These tokens are created in the `#getInjector` method of the renderer, which builds a child `Injector` with the render context properties.
### `injectFlexRenderContext`
[`injectFlexRenderContext()`](../reference/functions/injectFlexRenderContext) returns the full props object passed to `*flexRender`. The return type depends on the column definition slot:
- In a `cell` definition: `CellContext`
- In a `header`/`footer` definition: `HeaderContext`
```ts
import { Component } from '@angular/core'
import {
injectFlexRenderContext,
type CellContext,
} from '@tanstack/angular-table'
@Component({
template: `
{{ context.getValue() }}
`,
})
export class InteractiveCellComponent {
readonly context = injectFlexRenderContext>()
}
```
Internally, the renderer wraps the context in a `Proxy` so that property access always reflects the latest values, even after re-renders.
### Context directives
Three optional directives let you expose table, header, and cell context to **any descendant** in the template — not just components rendered by `*flexRender`.
This eliminates prop drilling: instead of passing data through multiple `input()` layers, any nested component or directive can inject the context directly.
| Directive | Selector | Token | Inject helper |
|---|---|---|---|
| [`TanStackTable`](../reference/functions/injectTableContext) | `[tanStackTable]` | `TanStackTableToken` | `injectTableContext()` |
| [`TanStackTableHeader`](../reference/functions/injectTableHeaderContext) | `[tanStackTableHeader]` | `TanStackTableHeaderToken` | `injectTableHeaderContext()` |
| [`TanStackTableCell`](../reference/functions/injectTableCellContext) | `[tanStackTableCell]` | `TanStackTableCellToken` | `injectTableCellContext()` |
Import them alongside `FlexRender`:
```ts
import {
FlexRender,
TanStackTable,
TanStackTableHeader,
TanStackTableCell,
} from '@tanstack/angular-table'
@Component({
imports: [FlexRender, TanStackTable, TanStackTableHeader, TanStackTableCell],
templateUrl: './app.html',
})
export class AppComponent {}
```
Apply them in the template to establish injection scopes:
```html
@for (headerGroup of table.getHeaderGroups(); track headerGroup.id) {
@for (header of headerGroup.headers; track header.id) {
}
}
@for (row of table.getRowModel().rows; track row.id) {
@for (cell of row.getVisibleCells(); track cell.id) {
}
}
```
Any component nested inside a `[tanStackTableCell]` host can inject the cell context:
```ts
import { Component } from '@angular/core'
import { injectTableCellContext } from '@tanstack/angular-table'
@Component({
template: `
`,
})
export class CellActionsComponent {
readonly cell = injectTableCellContext()
onAction() {
console.log('Cell:', this.cell())
}
}
```
```html
```
Each directive uses Angular's `providers` array to register a factory that reads its own input signal.
This means the token is scoped to the directive's host element and its descendants. Multiple `[tanStackTableCell]` directives on different elements provide independent contexts.
### Automatic token injection in FlexRender
When `FlexRender` renders a component or template, it also provides DI tokens automatically based on the render context shape. In the renderer's `#getInjector` method, if the context object contains `table`, `cell`, or `header` properties, the corresponding `TanStackTableToken`, `TanStackTableCellToken`, or `TanStackTableHeaderToken` tokens are provided in the child injector.
This means that even **without** the context directives, components rendered via `*flexRender` can use `injectTableContext()`, `injectTableCellContext()`, and `injectTableHeaderContext()`. The context directives are only needed for components that live **outside** the `*flexRender` rendering tree (e.g. sibling components in the same `
`).
================================================
FILE: docs/framework/angular/guide/table-composition.md
================================================
---
title: Table Composition (createTableHook)
---
`createTableHook` is a convenience API for creating reusable, type-safe table configurations with pre-bound components. It is inspired by [TanStack Form's `createFormHook`](https://tanstack.com/form/latest/docs/framework/react/guides/form-composition) — a pattern where you define shared infrastructure once and consume it across your application with minimal boilerplate.
> **When to use it:** Use `createTableHook` when you have multiple tables that share the same configuration (features, row models, and reusable components). For a single table, `injectTable` is sufficient.
## Examples
- [Composable Tables](../examples/composable-tables) — Two tables (Users and Products) sharing the same `createTableHook` configuration, with table/cell/header components, sorting, filtering, and pagination.
- [Basic App Table](../examples/basic-app-table) — Minimal example using `createTableHook` with no pre-bound components.
### createTableHook
`createTableHook` centralizes your table configuration into a single factory call. It returns a set of typed functions — `injectAppTable`, `createAppColumnHelper`, and pre-typed injection helpers — that you use instead of the base APIs.
## Setup
Call `createTableHook` with your shared configuration and destructure the returned utilities:
```ts
// table.ts — shared table infrastructure
import {
createTableHook,
tableFeatures,
columnFilteringFeature,
createFilteredRowModel,
createPaginatedRowModel,
createSortedRowModel,
filterFns,
rowPaginationFeature,
rowSortingFeature,
sortFns,
} from '@tanstack/angular-table'
import { PaginationControls, RowCount, TableToolbar } from './components/table-components'
import { TextCell, NumberCell, StatusCell, ProgressCell } from './components/cell-components'
import { SortIndicator, ColumnFilter } from './components/header-components'
export const {
createAppColumnHelper,
injectAppTable,
injectTableContext,
injectTableCellContext,
injectTableHeaderContext,
} = createTableHook({
// Features and row models are shared across all tables
_features: tableFeatures({
columnFilteringFeature,
rowPaginationFeature,
rowSortingFeature,
}),
_rowModels: {
sortedRowModel: createSortedRowModel(sortFns),
filteredRowModel: createFilteredRowModel(filterFns),
paginatedRowModel: createPaginatedRowModel(),
},
// Default table options applied to every table
getRowId: (row) => row.id,
// Pre-bound component registries
tableComponents: {
PaginationControls,
RowCount,
TableToolbar,
},
cellComponents: {
TextCell,
NumberCell,
StatusCell,
ProgressCell,
},
headerComponents: {
SortIndicator,
ColumnFilter,
},
})
```
This single file becomes the source of truth for your application's table infrastructure.
## What `createTableHook` returns
| Export | Description |
|---|---|
| `injectAppTable` | A wrapper around `injectTable` that merges default options and attaches component registries. Returns an `AppAngularTable` with table/cell/header components available directly on the instance. |
| `createAppColumnHelper` | A typed column helper where `cell`, `header`, and `footer` definitions receive enhanced context types with the registered components. |
| `injectTableContext` | Pre-typed `injectTableContext()` bound to your feature set. |
| `injectTableCellContext` | Pre-typed `injectTableCellContext()` bound to your feature set. |
| `injectTableHeaderContext` | Pre-typed `injectTableHeaderContext()` bound to your feature set. |
| `injectFlexRenderCellContext` | Pre-typed `injectFlexRenderContext()` for cell context. |
| `injectFlexRenderHeaderContext` | Pre-typed `injectFlexRenderContext()` for header context. |
## Component registries
`createTableHook` accepts three component registries that map string keys to Angular components or render functions:
### `tableComponents`
Components that need access to the **table instance**. These are attached directly to the `AppAngularTable` object returned by `injectAppTable`, so you can reference them in templates as `table.PaginationControls`, `table.RowCount`, etc.
Use `injectTableContext()` inside these components to access the table:
```ts
@Component({
selector: 'app-pagination-controls',
template: `
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PaginationControls {
readonly table = injectTableContext()
}
```
Render table components via Angular `NgComponentOutlet`:
```html
```
### `cellComponents`
Components that render **cell content**. These are attached to the `Cell` prototype, so they are available in column definitions through the enhanced `AppCellContext`:
```ts
const columnHelper = createAppColumnHelper()
const columns = columnHelper.columns([
columnHelper.accessor('firstName', {
header: 'First Name',
cell: ({ cell }) => cell.TextCell,
}),
columnHelper.accessor('age', {
header: 'Age',
cell: ({ cell }) => cell.NumberCell,
}),
columnHelper.accessor('status', {
header: 'Status',
cell: ({ cell }) => cell.StatusCell,
}),
])
```
Use `injectTableCellContext()` or `injectFlexRenderContext()` inside cell components:
```ts
@Component({
selector: 'span',
template: `{{ cell().getValue() }}`,
})
export class TextCell {
readonly cell = injectTableCellContext()
}
```
### `headerComponents`
Components or render functions that render **header/footer content**. These are attached to the `Header` prototype and available through the enhanced `AppHeaderContext`:
```ts
// Render functions work too — they run in injection context
export function SortIndicator(): string | null {
const header = injectTableHeaderContext()
const sorted = header().column.getIsSorted()
if (!sorted) return null
return sorted === 'asc' ? '🔼' : '🔽'
}
```
Access header components in the template via `table.appHeader(header)`:
```html
@for (_header of headerGroup.headers; track _header.id) {
@let header = table.appHeader(_header);
{{ value }}
}
```
## Using `injectAppTable`
`injectAppTable` is a wrapper around `injectTable`. It merges the default options from `createTableHook` with the per-table options, and returns an `AppAngularTable` — the standard table instance augmented with:
- **Table components** directly on the table object (`table.PaginationControls`, `table.TableToolbar`, etc.)
- **`table.appCell(cell)`** — utility type functions for templates that wraps a `Cell` with the registered `cellComponents`
- **`table.appHeader(header)`** — utility type functions for templates that wraps a `Header` with the registered `headerComponents`
- **`table.appFooter(footer)`** — utility type functions for templates that wraps a `Header` (footer) with the registered `headerComponents`
You do not need to pass `_features` or `_rowModels` — they are inherited from the hook configuration:
```ts
@Component({
selector: 'users-table',
templateUrl: './users-table.html',
imports: [FlexRender, TanStackTable, TanStackTableHeader, TanStackTableCell, NgComponentOutlet],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class UsersTable {
readonly data = signal(makeData(100))
readonly columns = columnHelper.columns([
columnHelper.accessor('firstName', {
header: 'First Name',
cell: ({ cell }) => cell.TextCell,
}),
// ...
])
// No need to specify _features, _rowModels, ... — they come from createTableHook
table = injectAppTable(() => ({
columns: this.columns,
data: this.data(),
}))
}
```
## Using `createAppColumnHelper`
`createAppColumnHelper()` returns a column helper identical to `createColumnHelper` at runtime, but with enhanced types: the `cell`, `header`, and `footer` definition callbacks receive `AppCellContext` / `AppHeaderContext` instead of the base context types.
This means TypeScript knows about your registered components and provides autocompletion:
```ts
const columnHelper = createAppColumnHelper()
columnHelper.accessor('firstName', {
cell: ({ cell }) => {
// ✅ TypeScript knows about TextCell, NumberCell, StatusCell, etc.
return cell.TextCell
},
header: ({ header }) => {
// ✅ TypeScript knows about SortIndicator, ColumnFilter, etc.
return flexRenderComponent(header.SortIndicator)
},
})
```
You can also use `flexRenderComponent(...)` to wrap the component with custom inputs/outputs:
```ts
columnHelper.accessor('firstName', {
cell: ({ cell }) => flexRenderComponent(cell.TextCell),
footer: ({ header }) => flexRenderComponent(header.FooterColumnId),
})
```
## Multiple table configurations
You can call `createTableHook` multiple times to create different table configurations for different parts of your application. Each call returns an independent set of utilities with its own feature set and component registries:
```ts
// admin-table.ts — tables with editing capabilities
export const {
injectAppTable: injectAdminTable,
createAppColumnHelper: createAdminColumnHelper,
} = createTableHook({
_features: tableFeatures({ rowSortingFeature, columnFilteringFeature }),
_rowModels: { /* ... */ },
cellComponents: { EditableCell, DeleteButton },
})
// readonly-table.ts — simpler read-only tables
export const {
injectAppTable: injectReadonlyTable,
createAppColumnHelper: createReadonlyColumnHelper,
} = createTableHook({
_features: tableFeatures({ rowSortingFeature }),
_rowModels: { /* ... */ },
cellComponents: { TextCell, NumberCell },
})
```
## Examples
- [Composable Tables](../examples/composable-tables) — Full example with two tables sharing the same `createTableHook` configuration.
- [Basic App Table](../examples/basic-app-table) — Minimal example with no pre-bound components.
================================================
FILE: docs/framework/angular/guide/table-state.md
================================================
---
title: Table State (Angular) Guide
---
## Table State (Angular) Guide
TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table.
### Accessing Table State
You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API.
```ts
table = injectTable(() => ({
columns: this.columns,
data: this.data(),
//...
}))
someHandler() {
console.log(this.table.store.state) //access the entire internal state
console.log(this.table.store.state.rowSelection) //access just the row selection state
}
```
### Custom Initial State
If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance.
```jsx
table = injectTable(() => ({
columns: this.columns,
data: this.data(),
initialState: {
columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order
columnVisibility: {
id: false //hide the id column by default
},
expanded: true, //expand all rows by default
sorting: [
{
id: 'age',
desc: true //sort by age in descending order by default
}
]
},
//...
}))
```
> **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`.
### Controlled State
If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options.
#### Individual Controlled State
You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis.
In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance.
Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values.
```ts
import {signal} from '@angular/core';
import {SortingState, ColumnFiltersState, PaginationState} from '@tanstack/angular-table'
import {toObservable} from "@angular/core/rxjs-interop";
import {combineLatest, switchMap} from 'rxjs';
class TableComponent {
readonly columnFilters = signal([]) //no default filters
readonly sorting = signal([
{
id: 'age',
desc: true, //sort by age in descending order by default
}
])
readonly pagination = signal({
pageIndex: 0,
pageSize: 15
})
//Use our controlled state values to fetch data
readonly data$ = combineLatest({
filters: toObservable(this.columnFilters),
sorting: toObservable(this.sorting),
pagination: toObservable(this.pagination)
}).pipe(
switchMap(({filters, sorting, pagination}) => fetchData(filters, sorting, pagination))
)
readonly data = toSignal(this.data$);
readonly table = injectTable(() => ({
columns: this.columns,
data: this.data(),
//...
state: {
columnFilters: this.columnFilters(), //pass controlled state back to the table (overrides internal state)
sorting: this.sorting(),
pagination: this.pagination(),
},
onColumnFiltersChange: updater => { //hoist columnFilters state into our own state management
updater instanceof Function
? this.columnFilters.update(updater)
: this.columnFilters.set(updater)
},
onSortingChange: updater => {
updater instanceof Function
? this.sorting.update(updater)
: this.sorting.set(updater)
},
onPaginationChange: updater => {
updater instanceof Function
? this.pagination.update(updater)
: this.pagination.set(updater)
},
}))
}
//...
```
#### Fully Controlled State
Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a component tree, like `columnSizingInfo` state`, might cause bad performance issues.
A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use a constructor in a special way as shown below.
```ts
class TableComponent {
// create an empty table state, we'll override it later
readonly state = signal({} as TableState);
// create a table instance with default state values
readonly table = injectTable(() => ({
columns: this.columns,
data: this.data(),
// our fully controlled state overrides the internal state
state: this.state(),
onStateChange: updater => {
// any state changes will be pushed up to our own state management
this.state.set(
updater instanceof Function ? updater(this.state()) : updater
)
}
}))
constructor() {
// set the initial table state
this.state.set({
// populate the initial state with all of the default state values
// from the table instance
...this.table.initialState,
pagination: {
pageIndex: 0,
pageSize: 15, // optionally customize the initial pagination state.
},
})
}
}
```
### On State Change Callbacks
So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about these using these options that you should be aware of.
#### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**.
Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value.
```ts
class TableComponent {
sorting = signal([])
table = injectTable(() => ({
columns: this.columns,
data: this.data(),
//...
state: {
sorting: this.sorting(), // required because we are using `onSortingChange`
},
onSortingChange: updater => { // makes the `state.sorting` controlled
updater instanceof Function
? this.sorting.update(updater)
: this.sorting.set(updater)
}
}))
}
```
#### 2. **Updaters can either be raw values or callback functions**.
The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value.
What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value.
This is why you will see the `updater instanceof Function ? this.state.update(updater) : this.state.set(updater)` pattern in the examples above. This pattern checks if the updater is a function, and if it is, it calls the function with the previous state value to get the new state value, or the signal will require `signal.update` to be called with the updater instead of `signal.set`.
### State Types
All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling.
```ts
import {injectTable, type SortingState} from '@tanstack/angular-table'
class TableComponent {
readonly sorting = signal([
{
id: 'age', // you should get autocomplete for the `id` and `desc` properties
desc: true,
}
])
}
```
================================================
FILE: docs/framework/angular/reference/classes/FlexRenderCell.md
================================================
---
id: FlexRenderCell
title: FlexRenderCell
---
# Class: FlexRenderCell\
Defined in: [helpers/flexRenderCell.ts:62](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L62)
Simplified directive wrapper of `*flexRender`.
Use this utility component to render headers, cells, or footers with custom markup.
Only one prop (`cell`, `header`, or `footer`) may be passed based on the used selector.
## Examples
```html
{{cell}}
{{header}}
{{footer}}
```
This replaces calling `*flexRender` directly like this:
```html
{{cell}}
{{header}}
{{footer}}
```
Can be imported through FlexRenderCell or [FlexRender](../variables/FlexRender.md) import,
which the latter is preferred.
```ts
import {FlexRender} from '@tanstack/angular-table
@Component({
// ...
imports: [
FlexRender
]
})
```
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
## Constructors
### Constructor
```ts
new FlexRenderCell(): FlexRenderCell;
```
Defined in: [helpers/flexRenderCell.ts:118](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L118)
#### Returns
`FlexRenderCell`\<`TFeatures`, `TData`, `TValue`\>
## Properties
### cell
```ts
readonly cell: InputSignal | undefined>;
```
Defined in: [helpers/flexRenderCell.ts:67](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L67)
***
### footer
```ts
readonly footer: InputSignal | undefined>;
```
Defined in: [helpers/flexRenderCell.ts:75](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L75)
***
### header
```ts
readonly header: InputSignal | undefined>;
```
Defined in: [helpers/flexRenderCell.ts:71](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/flexRenderCell.ts#L71)
================================================
FILE: docs/framework/angular/reference/classes/FlexRenderComponentInstance.md
================================================
---
id: FlexRenderComponentInstance
title: FlexRenderComponentInstance
---
# Class: FlexRenderComponentInstance\
Defined in: [flex-render/flexRenderComponent.ts:259](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L259)
Wrapper class for a component that will be used as content for [FlexRenderDirective](FlexRenderDirective.md)
Prefer [flexRenderComponent](../functions/flexRenderComponent.md) helper for better type-safety
## Type Parameters
### TComponent
`TComponent` = `any`
## Implements
- [`FlexRenderComponent`](../interfaces/FlexRenderComponent.md)\<`TComponent`\>
## Constructors
### Constructor
```ts
new FlexRenderComponentInstance(
component,
inputs?,
injector?,
outputs?,
directives?,
bindings?): FlexRenderComponentInstance;
```
Defined in: [flex-render/flexRenderComponent.ts:266](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L266)
#### Parameters
##### component
`Type`\<`TComponent`\>
##### inputs?
`Inputs`\<`TComponent`\>
##### injector?
`Injector`
##### outputs?
`Outputs`\<`TComponent`\>
##### directives?
(`Type`\<`unknown`\> \| `DirectiveWithBindings`\<`unknown`\>)[]
##### bindings?
`Binding`[]
#### Returns
`FlexRenderComponentInstance`\<`TComponent`\>
## Properties
### allowedInputNames
```ts
readonly allowedInputNames: string[] = [];
```
Defined in: [flex-render/flexRenderComponent.ts:263](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L263)
List of allowed input names.
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`allowedInputNames`](../interfaces/FlexRenderComponent.md#allowedinputnames)
***
### allowedOutputNames
```ts
readonly allowedOutputNames: string[] = [];
```
Defined in: [flex-render/flexRenderComponent.ts:264](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L264)
List of allowed output names.
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`allowedOutputNames`](../interfaces/FlexRenderComponent.md#allowedoutputnames)
***
### bindings?
```ts
readonly optional bindings: Binding[];
```
Defined in: [flex-render/flexRenderComponent.ts:272](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L272)
Bindings to apply to the root component
#### See
FlexRenderOptions#bindings
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`bindings`](../interfaces/FlexRenderComponent.md#bindings)
***
### component
```ts
readonly component: Type;
```
Defined in: [flex-render/flexRenderComponent.ts:267](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L267)
The component type
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`component`](../interfaces/FlexRenderComponent.md#component)
***
### directives?
```ts
readonly optional directives: (Type | DirectiveWithBindings)[];
```
Defined in: [flex-render/flexRenderComponent.ts:271](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L271)
Directives that should be applied to the component.
#### See
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`directives`](../interfaces/FlexRenderComponent.md#directives)
***
### injector?
```ts
readonly optional injector: Injector;
```
Defined in: [flex-render/flexRenderComponent.ts:269](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L269)
Optional Injector that will be used when rendering the component.
#### See
FlexRenderOptions#injector
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`injector`](../interfaces/FlexRenderComponent.md#injector)
***
### inputs?
```ts
readonly optional inputs: Inputs;
```
Defined in: [flex-render/flexRenderComponent.ts:268](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L268)
Component instance inputs. Set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput))
#### See
FlexRenderOptions#inputs
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`inputs`](../interfaces/FlexRenderComponent.md#inputs)
***
### mirror
```ts
readonly mirror: ComponentMirror;
```
Defined in: [flex-render/flexRenderComponent.ts:262](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L262)
Reflected metadata about the component.
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`mirror`](../interfaces/FlexRenderComponent.md#mirror)
***
### outputs?
```ts
readonly optional outputs: Outputs;
```
Defined in: [flex-render/flexRenderComponent.ts:270](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L270)
Component instance outputs. Subscribed via OutputEmitterRef#subscribe
#### See
FlexRenderOptions#outputs
#### Implementation of
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md).[`outputs`](../interfaces/FlexRenderComponent.md#outputs)
================================================
FILE: docs/framework/angular/reference/classes/FlexRenderDirective.md
================================================
---
id: FlexRenderDirective
title: FlexRenderDirective
---
# Class: FlexRenderDirective\
Defined in: [flexRender.ts:84](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L84)
Use this utility directive to render headers, cells, or footers with custom markup.
Note: If you are rendering cell, header, or footer without custom context or other props,
you can use the [FlexRenderCell](FlexRenderCell.md) directive as shorthand instead .
## Example
```ts
import {FlexRender} from '@tanstack/angular-table';
@Component({
imports: [FlexRender],
template: `
{{cell}}
{{header}}
{{footer}}
`,
})
class App {
}
```
Can be imported through FlexRenderDirective or [FlexRender](../variables/FlexRender.md) import,
which the latter is preferred.
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TRowData
`TRowData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
### TProps
`TProps` *extends*
\| `NonNullable`\<`unknown`\>
\| `CellContext`\<`TFeatures`, `TRowData`, `TValue`\>
\| `HeaderContext`\<`TFeatures`, `TRowData`, `TValue`\>
## Constructors
### Constructor
```ts
new FlexRenderDirective(): FlexRenderDirective;
```
Defined in: [flexRender.ts:109](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L109)
#### Returns
`FlexRenderDirective`\<`TFeatures`, `TRowData`, `TValue`, `TProps`\>
## Properties
### content
```ts
readonly content: InputSignal>;
```
Defined in: [flexRender.ts:93](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L93)
***
### injector
```ts
readonly injector: InputSignal;
```
Defined in: [flexRender.ts:102](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L102)
***
### props
```ts
readonly props: InputSignal;
```
Defined in: [flexRender.ts:98](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flexRender.ts#L98)
================================================
FILE: docs/framework/angular/reference/classes/TanStackTable.md
================================================
---
id: TanStackTable
title: TanStackTable
---
# Class: TanStackTable\
Defined in: [helpers/table.ts:59](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L59)
Provides a TanStack Table instance (`AngularTable`) in Angular DI.
The table can be injected by:
- any descendant of an element using `[tanStackTable]="..."`
- any component instantiated by `*flexRender` when the render props contains `table`
## Example
```html
```
```ts
@Component({
selector: 'app-pagination',
template: `
`,
})
export class PaginationComponent {
readonly table = injectTableContext()
prev() {
this.table().previousPage()
}
next() {
this.table().nextPage()
}
}
```
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TSelected
`TSelected` *extends* `object` = `TableState`\<`TFeatures`\>
## Constructors
### Constructor
```ts
new TanStackTable(): TanStackTable;
```
#### Returns
`TanStackTable`\<`TFeatures`, `TData`, `TSelected`\>
## Properties
### table
```ts
readonly table: InputSignal>;
```
Defined in: [helpers/table.ts:69](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L69)
The current TanStack Table instance.
Provided as a required signal input so DI consumers always read the latest value.
================================================
FILE: docs/framework/angular/reference/classes/TanStackTableCell.md
================================================
---
id: TanStackTableCell
title: TanStackTableCell
---
# Class: TanStackTableCell\
Defined in: [helpers/cell.ts:76](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L76)
Provides a TanStack Table `Cell` instance in Angular DI.
The cell can be injected by:
- any descendant of an element using `[tanStackTableCell]="..."`
- any component instantiated by `*flexRender` when the render props contains `cell`
## Examples
Inject from the nearest `[tanStackTableCell]`:
```html
```
```ts
@Component({
selector: 'app-cell-actions',
template: `{{ cell().id }}`,
})
export class CellActionsComponent {
readonly cell = injectTableCellContext()
}
```
Inject inside a component rendered via `flexRender`:
```ts
@Component({
selector: 'app-price-cell',
template: `{{ cell().getValue() }}`,
})
export class PriceCellComponent {
readonly cell = injectTableCellContext()
}
```
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
## Implements
- [`TanStackTableCellContext`](../interfaces/TanStackTableCellContext.md)\<`TFeatures`, `TData`, `TValue`\>
## Constructors
### Constructor
```ts
new TanStackTableCell(): TanStackTableCell;
```
#### Returns
`TanStackTableCell`\<`TFeatures`, `TData`, `TValue`\>
## Properties
### cell
```ts
readonly cell: InputSignal>;
```
Defined in: [helpers/cell.ts:86](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L86)
The current TanStack Table cell.
Provided as a required signal input so DI consumers always read the latest value.
#### Implementation of
[`TanStackTableCellContext`](../interfaces/TanStackTableCellContext.md).[`cell`](../interfaces/TanStackTableCellContext.md#cell)
================================================
FILE: docs/framework/angular/reference/classes/TanStackTableHeader.md
================================================
---
id: TanStackTableHeader
title: TanStackTableHeader
---
# Class: TanStackTableHeader\
Defined in: [helpers/header.ts:71](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L71)
Provides a TanStack Table `Header` instance in Angular DI.
The header can be injected by:
- any descendant of an element using `[tanStackTableHeader]="..."`
- any component instantiated by `*flexRender` when the render props contains `header`
## Example
```html
```
```ts
@Component({
selector: 'app-sort-indicator',
template: `
`,
})
export class SortIndicatorComponent {
readonly header = injectTableHeaderContext()
toggle() {
this.header().column.toggleSorting()
}
}
```
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
## Implements
- [`TanStackTableHeaderContext`](../interfaces/TanStackTableHeaderContext.md)\<`TFeatures`, `TData`, `TValue`\>
## Constructors
### Constructor
```ts
new TanStackTableHeader(): TanStackTableHeader;
```
#### Returns
`TanStackTableHeader`\<`TFeatures`, `TData`, `TValue`\>
## Properties
### header
```ts
readonly header: InputSignal>;
```
Defined in: [helpers/header.ts:81](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L81)
The current TanStack Table header.
Provided as a required signal input so DI consumers always read the latest value.
#### Implementation of
[`TanStackTableHeaderContext`](../interfaces/TanStackTableHeaderContext.md).[`header`](../interfaces/TanStackTableHeaderContext.md#header)
================================================
FILE: docs/framework/angular/reference/functions/createTableHook.md
================================================
---
id: createTableHook
title: createTableHook
---
# Function: createTableHook()
```ts
function createTableHook(__namedParameters): CreateTableHookResult;
```
Defined in: [helpers/createTableHook.ts:352](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L352)
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TTableComponents
`TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### TCellComponents
`TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### THeaderComponents
`THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
## Parameters
### \_\_namedParameters
[`CreateTableContextOptions`](../type-aliases/CreateTableContextOptions.md)\<`TFeatures`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\>
## Returns
[`CreateTableHookResult`](../type-aliases/CreateTableHookResult.md)\<`TFeatures`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\>
================================================
FILE: docs/framework/angular/reference/functions/flexRenderComponent.md
================================================
---
id: flexRenderComponent
title: flexRenderComponent
---
# Function: flexRenderComponent()
```ts
function flexRenderComponent(component, options?): FlexRenderComponent;
```
Defined in: [flex-render/flexRenderComponent.ts:150](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L150)
Helper function to create a [FlexRenderComponent](../interfaces/FlexRenderComponent.md) instance, with better type-safety.
## Type Parameters
### TComponent
`TComponent` = `any`
## Parameters
### component
`Type`\<`TComponent`\>
### options?
`FlexRenderOptions`\<`Inputs`\<`TComponent`\>, `Outputs`\<`TComponent`\>\>
## Returns
[`FlexRenderComponent`](../interfaces/FlexRenderComponent.md)\<`TComponent`\>
## Example
```ts
import {flexRenderComponent} from '@tanstack/angular-table'
import {inputBinding, outputBinding} from '@angular/core';
const columns = [
{
cell: ({ row }) => {
return flexRenderComponent(MyComponent, {
inputs: { value: mySignalValue() },
outputs: { valueChange: (val) => {} }
// or using angular native createComponent#binding api
bindings: [
inputBinding('value', mySignalValue),
outputBinding('valueChange', value => {
console.log("my value changed to", value)
})
]
})
},
},
]
```
================================================
FILE: docs/framework/angular/reference/functions/injectFlexRenderContext.md
================================================
---
id: injectFlexRenderContext
title: injectFlexRenderContext
---
# Function: injectFlexRenderContext()
```ts
function injectFlexRenderContext(): T;
```
Defined in: [flex-render/context.ts:12](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/context.ts#L12)
Inject the flex render context props.
Can be used in components rendered via FlexRender directives.
## Type Parameters
### T
`T` *extends* `object`
## Returns
`T`
================================================
FILE: docs/framework/angular/reference/functions/injectTable.md
================================================
---
id: injectTable
title: injectTable
---
# Function: injectTable()
```ts
function injectTable(options, selector): AngularTable;
```
Defined in: [injectTable.ts:95](https://github.com/TanStack/table/blob/main/packages/angular-table/src/injectTable.ts#L95)
Creates and returns an Angular-reactive table instance.
The initializer is intentionally re-evaluated whenever any signal read inside it changes.
This is how the adapter keeps the table in sync with Angular's reactivity model.
Because of that behavior, keep expensive/static values (for example `columns`, feature setup, row models)
as stable references outside the initializer, and only read reactive state (`data()`, pagination/filter/sorting signals, etc.)
inside it.
The returned table is also signal-reactive: table state and table APIs are wired for Angular signals, so you can safely consume table methods inside `computed(...)` and `effect(...)`.
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TSelected
`TSelected` = `TableState`\<`TFeatures`\>
## Parameters
### options
() => `TableOptions`\<`TFeatures`, `TData`\>
### selector
(`state`) => `TSelected`
## Returns
[`AngularTable`](../type-aliases/AngularTable.md)\<`TFeatures`, `TData`, `TSelected`\>
An Angular-reactive TanStack Table instance.
## Example
1. Register the table features you need
```ts
// Register only the features you need
import {tableFeatures, rowPaginationFeature} from '@tanstack/angular-table';
const _features = tableFeatures({
rowPaginationFeature,
// ...all other features you need
})
// Use all table core features
import {stockFeatures} from '@tanstack/angular-table';
const _features = tableFeatures(stockFeatures);
```
2. Prepare the table columns
```ts
import {ColumnDef} from '@tanstack/angular-table';
type MyData = {}
const columns: ColumnDef[] = [
// ...column definitions
]
// or using createColumnHelper
import {createColumnHelper} from '@tanstack/angular-table';
const columnHelper = createColumnHelper();
const columns = columnHelper.columns([
columnHelper.accessor(...),
// ...other columns
])
```
3. Create the table instance with `injectTable`
```ts
const table = injectTable(() => {
// ...table options,
_features,
columns: columns,
data: myDataSignal(),
})
```
================================================
FILE: docs/framework/angular/reference/functions/injectTableCellContext.md
================================================
---
id: injectTableCellContext
title: injectTableCellContext
---
# Function: injectTableCellContext()
```ts
function injectTableCellContext(): Signal>;
```
Defined in: [helpers/cell.ts:98](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L98)
Injects the current TanStack Table cell signal.
Available when:
- there is a nearest `[tanStackTableCell]` directive in the DI tree, or
- the caller is rendered via `*flexRender` with render props containing `cell`
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `unknown`
## Returns
`Signal`\<`Cell`\<`TFeatures`, `TData`, `TValue`\>\>
================================================
FILE: docs/framework/angular/reference/functions/injectTableContext.md
================================================
---
id: injectTableContext
title: injectTableContext
---
# Function: injectTableContext()
```ts
function injectTableContext(): Signal>;
```
Defined in: [helpers/table.ts:81](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L81)
Injects the current TanStack Table instance signal.
Available when:
- there is a nearest `[tanStackTable]` directive in the DI tree, or
- the caller is rendered via `*flexRender` with render props containing `table`
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TSelected
`TSelected` *extends* `object` = `TableState`\<`TFeatures`\>
## Returns
`Signal`\<[`AngularTable`](../type-aliases/AngularTable.md)\<`TFeatures`, `TData`, `TSelected`\>\>
================================================
FILE: docs/framework/angular/reference/functions/injectTableHeaderContext.md
================================================
---
id: injectTableHeaderContext
title: injectTableHeaderContext
---
# Function: injectTableHeaderContext()
```ts
function injectTableHeaderContext(): Signal>;
```
Defined in: [helpers/header.ts:93](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L93)
Injects the current TanStack Table header signal.
Available when:
- there is a nearest `[tanStackTableHeader]` directive in the DI tree, or
- the caller is rendered via `*flexRender` with render props containing `header`
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `unknown`
## Returns
`Signal`\<`Header`\<`TFeatures`, `TData`, `TValue`\>\>
================================================
FILE: docs/framework/angular/reference/index.md
================================================
---
id: "@tanstack/angular-table"
title: "@tanstack/angular-table"
---
# @tanstack/angular-table
## Classes
- [FlexRenderCell](classes/FlexRenderCell.md)
- [FlexRenderComponentInstance](classes/FlexRenderComponentInstance.md)
- [FlexRenderDirective](classes/FlexRenderDirective.md)
- [TanStackTable](classes/TanStackTable.md)
- [TanStackTableCell](classes/TanStackTableCell.md)
- [TanStackTableHeader](classes/TanStackTableHeader.md)
## Interfaces
- [AngularReactivityFlags](interfaces/AngularReactivityFlags.md)
- [FlexRenderComponent](interfaces/FlexRenderComponent.md)
- [TanStackTableCellContext](interfaces/TanStackTableCellContext.md)
- [TanStackTableHeaderContext](interfaces/TanStackTableHeaderContext.md)
## Type Aliases
- [AngularTable](type-aliases/AngularTable.md)
- [AppAngularTable](type-aliases/AppAngularTable.md)
- [AppCellContext](type-aliases/AppCellContext.md)
- [AppColumnHelper](type-aliases/AppColumnHelper.md)
- [AppHeaderContext](type-aliases/AppHeaderContext.md)
- [CreateTableContextOptions](type-aliases/CreateTableContextOptions.md)
- [CreateTableHookResult](type-aliases/CreateTableHookResult.md)
- [FlexRenderComponentProps](type-aliases/FlexRenderComponentProps.md)
- [FlexRenderContent](type-aliases/FlexRenderContent.md)
- [FlexRenderInputContent](type-aliases/FlexRenderInputContent.md)
## Variables
- [FlexRender](variables/FlexRender.md)
- [TanStackTableCellToken](variables/TanStackTableCellToken.md)
- [TanStackTableHeaderToken](variables/TanStackTableHeaderToken.md)
- [TanStackTableToken](variables/TanStackTableToken.md)
## Functions
- [createTableHook](functions/createTableHook.md)
- [flexRenderComponent](functions/flexRenderComponent.md)
- [injectFlexRenderContext](functions/injectFlexRenderContext.md)
- [injectTable](functions/injectTable.md)
- [injectTableCellContext](functions/injectTableCellContext.md)
- [injectTableContext](functions/injectTableContext.md)
- [injectTableHeaderContext](functions/injectTableHeaderContext.md)
================================================
FILE: docs/framework/angular/reference/interfaces/AngularReactivityFlags.md
================================================
---
id: AngularReactivityFlags
title: AngularReactivityFlags
---
# Interface: AngularReactivityFlags
Defined in: [angularReactivityFeature.ts:55](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L55)
Fine-grained configuration for Angular reactivity.
Each key controls whether prototype methods/getters on the corresponding TanStack Table
objects are wrapped with signal-aware access.
- `true` enables wrapping using the default skip rules.
- `false` disables wrapping entirely for that object type.
- a function allows customizing the skip rules (see SkipPropertyFn).
## Example
```ts
const table = injectTable(() => {
// ...table options,
reactivity: {
// fine-grained control over which table objects have reactive properties,
// and which properties are wrapped
header: true,
column: true,
row: true,
cell: true,
}
})
```
## Properties
### cell
```ts
cell: boolean | SkipPropertyFn;
```
Defined in: [angularReactivityFeature.ts:63](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L63)
Controls reactive wrapping for `Cell` instances.
***
### column
```ts
column: boolean | SkipPropertyFn;
```
Defined in: [angularReactivityFeature.ts:59](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L59)
Controls reactive wrapping for `Column` instances.
***
### header
```ts
header: boolean | SkipPropertyFn;
```
Defined in: [angularReactivityFeature.ts:57](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L57)
Controls reactive wrapping for `Header` instances.
***
### row
```ts
row: boolean | SkipPropertyFn;
```
Defined in: [angularReactivityFeature.ts:61](https://github.com/TanStack/table/blob/main/packages/angular-table/src/angularReactivityFeature.ts#L61)
Controls reactive wrapping for `Row` instances.
================================================
FILE: docs/framework/angular/reference/interfaces/FlexRenderComponent.md
================================================
---
id: FlexRenderComponent
title: FlexRenderComponent
---
# Interface: FlexRenderComponent\
Defined in: [flex-render/flexRenderComponent.ts:205](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L205)
Wrapper interface for a component that will be used as content for [FlexRenderDirective](../classes/FlexRenderDirective.md).
Can be created using [flexRenderComponent](../functions/flexRenderComponent.md) helper.
## Example
```ts
import {flexRenderComponent} from '@tanstack/angular-table'
// Usage in cell/header/footer definition
const columns = [
{
cell: ({ row }) => {
return flexRenderComponent(MyComponent, {
inputs: { value: mySignalValue() },
outputs: { valueChange: (val) => {} }
// or using angular createComponent#bindings api
bindings: [
inputBinding('value', mySignalValue),
outputBinding('valueChange', value => {
console.log("my value changed to", value)
})
]
})
},
},
]
import {input, output} from '@angular/core';
@Component({
selector: 'my-component',
})
class MyComponent {
readonly value = input(0);
readonly valueChange = output();
}
```
## Type Parameters
### TComponent
`TComponent` = `any`
## Properties
### allowedInputNames
```ts
readonly allowedInputNames: string[];
```
Defined in: [flex-render/flexRenderComponent.ts:217](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L217)
List of allowed input names.
***
### allowedOutputNames
```ts
readonly allowedOutputNames: string[];
```
Defined in: [flex-render/flexRenderComponent.ts:221](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L221)
List of allowed output names.
***
### bindings?
```ts
optional bindings: Binding[];
```
Defined in: [flex-render/flexRenderComponent.ts:245](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L245)
Bindings to apply to the root component
#### See
FlexRenderOptions#bindings
***
### component
```ts
readonly component: Type;
```
Defined in: [flex-render/flexRenderComponent.ts:209](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L209)
The component type
***
### directives?
```ts
optional directives: (Type | DirectiveWithBindings)[];
```
Defined in: [flex-render/flexRenderComponent.ts:251](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L251)
Directives that should be applied to the component.
#### See
***
### injector?
```ts
readonly optional injector: Injector;
```
Defined in: [flex-render/flexRenderComponent.ts:239](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L239)
Optional Injector that will be used when rendering the component.
#### See
FlexRenderOptions#injector
***
### inputs?
```ts
readonly optional inputs: Inputs;
```
Defined in: [flex-render/flexRenderComponent.ts:233](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L233)
Component instance inputs. Set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput))
#### See
FlexRenderOptions#inputs
***
### mirror
```ts
readonly mirror: ComponentMirror;
```
Defined in: [flex-render/flexRenderComponent.ts:213](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L213)
Reflected metadata about the component.
***
### outputs?
```ts
readonly optional outputs: Outputs;
```
Defined in: [flex-render/flexRenderComponent.ts:227](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/flexRenderComponent.ts#L227)
Component instance outputs. Subscribed via OutputEmitterRef#subscribe
#### See
FlexRenderOptions#outputs
================================================
FILE: docs/framework/angular/reference/interfaces/TanStackTableCellContext.md
================================================
---
id: TanStackTableCellContext
title: TanStackTableCellContext
---
# Interface: TanStackTableCellContext\
Defined in: [helpers/cell.ts:11](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L11)
DI context shape for a TanStack Table cell.
This exists to make the current `Cell` injectable by any nested component/directive
without having to pass it through inputs/props manually.
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
## Properties
### cell
```ts
cell: Signal>;
```
Defined in: [helpers/cell.ts:17](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L17)
Signal that returns the current cell instance.
================================================
FILE: docs/framework/angular/reference/interfaces/TanStackTableHeaderContext.md
================================================
---
id: TanStackTableHeaderContext
title: TanStackTableHeaderContext
---
# Interface: TanStackTableHeaderContext\
Defined in: [helpers/header.ts:11](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L11)
DI context shape for a TanStack Table header.
This exists to make the current `Header` injectable by any nested component/directive
without passing it through inputs/props.
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
## Properties
### header
```ts
header: Signal>;
```
Defined in: [helpers/header.ts:17](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L17)
Signal that returns the current header instance.
================================================
FILE: docs/framework/angular/reference/type-aliases/AngularTable.md
================================================
---
id: AngularTable
title: AngularTable
---
# Type Alias: AngularTable\
```ts
type AngularTable = Table & object;
```
Defined in: [injectTable.ts:21](https://github.com/TanStack/table/blob/main/packages/angular-table/src/injectTable.ts#L21)
## Type Declaration
### state
```ts
readonly state: Signal>;
```
The selected state from the table store, based on the selector provided.
### Subscribe()
```ts
Subscribe: (props) => Signal>;
```
Subscribe to changes in the table store with a custom selector.
#### Type Parameters
##### TSubSelected
`TSubSelected` = \{
\}
#### Parameters
##### props
###### equal?
`ValueEqualityFn`\<`TSubSelected`\>
###### selector
(`state`) => `TSubSelected`
#### Returns
`Signal`\<`Readonly`\<`TSubSelected`\>\>
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TSelected
`TSelected` = `TableState`\<`TFeatures`\>
================================================
FILE: docs/framework/angular/reference/type-aliases/AppAngularTable.md
================================================
---
id: AppAngularTable
title: AppAngularTable
---
# Type Alias: AppAngularTable\
```ts
type AppAngularTable = AngularTable & NoInfer & object;
```
Defined in: [helpers/createTableHook.ts:243](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L243)
Extended table API returned by useAppTable with all App wrapper components
## Type Declaration
### appCell()
```ts
appCell: (cell) => Cell & NoInfer;
```
#### Type Parameters
##### TValue
`TValue`
#### Parameters
##### cell
`Cell`\<`TFeatures`, `TData`, `TValue`\>
#### Returns
`Cell`\<`TFeatures`, `TData`, `TValue`\> & `NoInfer`\<`TCellComponents`\>
### appFooter()
```ts
appFooter: (footer) => Header & NoInfer;
```
#### Type Parameters
##### TValue
`TValue`
#### Parameters
##### footer
`Header`\<`TFeatures`, `TData`, `TValue`\>
#### Returns
`Header`\<`TFeatures`, `TData`, `TValue`\> & `NoInfer`\<`THeaderComponents`\>
### appHeader()
```ts
appHeader: (header) => Header & NoInfer;
```
#### Type Parameters
##### TValue
`TValue`
#### Parameters
##### header
`Header`\<`TFeatures`, `TData`, `TValue`\>
#### Returns
`Header`\<`TFeatures`, `TData`, `TValue`\> & `NoInfer`\<`THeaderComponents`\>
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TSelected
`TSelected`
### TTableComponents
`TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### TCellComponents
`TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### THeaderComponents
`THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
================================================
FILE: docs/framework/angular/reference/type-aliases/AppCellContext.md
================================================
---
id: AppCellContext
title: AppCellContext
---
# Type Alias: AppCellContext\
```ts
type AppCellContext = object;
```
Defined in: [helpers/createTableHook.ts:47](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L47)
Enhanced CellContext with pre-bound cell components.
The `cell` property includes the registered cellComponents.
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
### TCellComponents
`TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
## Properties
### cell
```ts
cell: Cell & TCellComponents & object;
```
Defined in: [helpers/createTableHook.ts:53](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L53)
#### Type Declaration
##### FlexRender()
```ts
FlexRender: () => unknown;
```
###### Returns
`unknown`
***
### column
```ts
column: Column;
```
Defined in: [helpers/createTableHook.ts:55](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L55)
***
### getValue
```ts
getValue: CellContext["getValue"];
```
Defined in: [helpers/createTableHook.ts:56](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L56)
***
### renderValue
```ts
renderValue: CellContext["renderValue"];
```
Defined in: [helpers/createTableHook.ts:57](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L57)
***
### row
```ts
row: Row;
```
Defined in: [helpers/createTableHook.ts:58](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L58)
***
### table
```ts
table: Table;
```
Defined in: [helpers/createTableHook.ts:59](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L59)
================================================
FILE: docs/framework/angular/reference/type-aliases/AppColumnHelper.md
================================================
---
id: AppColumnHelper
title: AppColumnHelper
---
# Type Alias: AppColumnHelper\
```ts
type AppColumnHelper = object;
```
Defined in: [helpers/createTableHook.ts:168](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L168)
Enhanced column helper with pre-bound components in cell/header/footer contexts.
This enables TypeScript to know about the registered components when defining columns.
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TCellComponents
`TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### THeaderComponents
`THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
## Properties
### accessor()
```ts
accessor: (accessor, column) => TAccessor extends AccessorFn ? AccessorFnColumnDef : AccessorKeyColumnDef;
```
Defined in: [helpers/createTableHook.ts:178](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L178)
Creates a data column definition with an accessor key or function.
The cell, header, and footer contexts include pre-bound components.
#### Type Parameters
##### TAccessor
`TAccessor` *extends* `AccessorFn`\<`TData`\> \| `DeepKeys`\<`TData`\>
##### TValue
`TValue` *extends* `TAccessor` *extends* `AccessorFn`\<`TData`, infer TReturn\> ? `TReturn` : `TAccessor` *extends* `DeepKeys`\<`TData`\> ? `DeepValue`\<`TData`, `TAccessor`\> : `never`
#### Parameters
##### accessor
`TAccessor`
##### column
`TAccessor` *extends* `AccessorFn`\<`TData`\> ? `AppColumnDefBase`\<`TFeatures`, `TData`, `TValue`, `TCellComponents`, `THeaderComponents`\> & `object` : `AppColumnDefBase`\<`TFeatures`, `TData`, `TValue`, `TCellComponents`, `THeaderComponents`\>
#### Returns
`TAccessor` *extends* `AccessorFn`\<`TData`\> ? `AccessorFnColumnDef`\<`TFeatures`, `TData`, `TValue`\> : `AccessorKeyColumnDef`\<`TFeatures`, `TData`, `TValue`\>
***
### columns()
```ts
columns: (columns) => ColumnDef[] & [...TColumns];
```
Defined in: [helpers/createTableHook.ts:209](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L209)
Wraps an array of column definitions to preserve each column's individual TValue type.
#### Type Parameters
##### TColumns
`TColumns` *extends* `ReadonlyArray`\<`ColumnDef`\<`TFeatures`, `TData`, `any`\>\>
#### Parameters
##### columns
\[`...TColumns`\]
#### Returns
`ColumnDef`\<`TFeatures`, `TData`, `any`\>[] & \[`...TColumns`\]
***
### display()
```ts
display: (column) => DisplayColumnDef;
```
Defined in: [helpers/createTableHook.ts:217](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L217)
Creates a display column definition for non-data columns.
The cell, header, and footer contexts include pre-bound components.
#### Parameters
##### column
`AppDisplayColumnDef`\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\>
#### Returns
`DisplayColumnDef`\<`TFeatures`, `TData`, `unknown`\>
***
### group()
```ts
group: (column) => GroupColumnDef;
```
Defined in: [helpers/createTableHook.ts:230](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L230)
Creates a group column definition with nested child columns.
The cell, header, and footer contexts include pre-bound components.
#### Parameters
##### column
`AppGroupColumnDef`\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\>
#### Returns
`GroupColumnDef`\<`TFeatures`, `TData`, `unknown`\>
================================================
FILE: docs/framework/angular/reference/type-aliases/AppHeaderContext.md
================================================
---
id: AppHeaderContext
title: AppHeaderContext
---
# Type Alias: AppHeaderContext\
```ts
type AppHeaderContext = object;
```
Defined in: [helpers/createTableHook.ts:66](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L66)
Enhanced HeaderContext with pre-bound header components.
The `header` property includes the registered headerComponents.
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TData
`TData` *extends* `RowData`
### TValue
`TValue` *extends* `CellData`
### THeaderComponents
`THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
## Properties
### column
```ts
column: Column;
```
Defined in: [helpers/createTableHook.ts:72](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L72)
***
### header
```ts
header: Header & THeaderComponents & object;
```
Defined in: [helpers/createTableHook.ts:73](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L73)
#### Type Declaration
##### FlexRender()
```ts
FlexRender: () => unknown;
```
###### Returns
`unknown`
***
### table
```ts
table: Table;
```
Defined in: [helpers/createTableHook.ts:75](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L75)
================================================
FILE: docs/framework/angular/reference/type-aliases/CreateTableContextOptions.md
================================================
---
id: CreateTableContextOptions
title: CreateTableContextOptions
---
# Type Alias: CreateTableContextOptions\
```ts
type CreateTableContextOptions = Omit, "columns" | "data" | "store" | "state" | "initialState"> & object;
```
Defined in: [helpers/createTableHook.ts:273](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L273)
Options for creating a table hook with pre-bound components and default table options.
Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'.
## Type Declaration
### cellComponents?
```ts
optional cellComponents: TCellComponents;
```
Cell-level components that need access to the cell instance.
These are available on the cell object passed to AppCell's children.
Use `useCellContext()` inside these components.
#### Example
```ts
{ TextCell, NumberCell, DateCell, CurrencyCell }
```
### headerComponents?
```ts
optional headerComponents: THeaderComponents;
```
Header-level components that need access to the header instance.
These are available on the header object passed to AppHeader/AppFooter's children.
Use `useHeaderContext()` inside these components.
#### Example
```ts
{ SortIndicator, ColumnFilter, ResizeHandle }
```
### tableComponents?
```ts
optional tableComponents: TTableComponents;
```
Table-level components that need access to the table instance.
These are available directly on the table object returned by useAppTable.
Use `useTableContext()` inside these components.
#### Example
```ts
{ PaginationControls, GlobalFilter, RowCount }
```
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TTableComponents
`TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### TCellComponents
`TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### THeaderComponents
`THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
================================================
FILE: docs/framework/angular/reference/type-aliases/CreateTableHookResult.md
================================================
---
id: CreateTableHookResult
title: CreateTableHookResult
---
# Type Alias: CreateTableHookResult\
```ts
type CreateTableHookResult = object;
```
Defined in: [helpers/createTableHook.ts:305](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L305)
## Type Parameters
### TFeatures
`TFeatures` *extends* `TableFeatures`
### TTableComponents
`TTableComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### TCellComponents
`TCellComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
### THeaderComponents
`THeaderComponents` *extends* `Record`\<`string`, `RenderableComponent`\>
## Properties
### createAppColumnHelper()
```ts
createAppColumnHelper: () => AppColumnHelper;
```
Defined in: [helpers/createTableHook.ts:311](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L311)
#### Type Parameters
##### TData
`TData` *extends* `RowData`
#### Returns
[`AppColumnHelper`](AppColumnHelper.md)\<`TFeatures`, `TData`, `TCellComponents`, `THeaderComponents`\>
***
### injectAppTable()
```ts
injectAppTable: (tableOptions, selector?) => AppAngularTable;
```
Defined in: [helpers/createTableHook.ts:336](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L336)
#### Type Parameters
##### TData
`TData` *extends* `RowData`
##### TSelected
`TSelected` = `TableState`\<`TFeatures`\>
#### Parameters
##### tableOptions
() => `Omit`\<`TableOptions`\<`TFeatures`, `TData`\>, `"_features"` \| `"_rowModels"`\>
##### selector?
(`state`) => `TSelected`
#### Returns
[`AppAngularTable`](AppAngularTable.md)\<`TFeatures`, `TData`, `TSelected`, `TTableComponents`, `TCellComponents`, `THeaderComponents`\>
***
### injectFlexRenderCellContext()
```ts
injectFlexRenderCellContext: () => CellContext;
```
Defined in: [helpers/createTableHook.ts:332](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L332)
#### Type Parameters
##### TData
`TData` *extends* `RowData`
##### TValue
`TValue` *extends* `CellData`
#### Returns
`CellContext`\<`TFeatures`, `TData`, `TValue`\>
***
### injectFlexRenderHeaderContext()
```ts
injectFlexRenderHeaderContext: () => HeaderContext;
```
Defined in: [helpers/createTableHook.ts:328](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L328)
#### Type Parameters
##### TData
`TData` *extends* `RowData`
##### TValue
`TValue` *extends* `CellData`
#### Returns
`HeaderContext`\<`TFeatures`, `TData`, `TValue`\>
***
### injectTableCellContext()
```ts
injectTableCellContext: () => Signal>;
```
Defined in: [helpers/createTableHook.ts:324](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L324)
#### Type Parameters
##### TValue
`TValue` *extends* `CellData` = `CellData`
##### TRowData
`TRowData` *extends* `RowData` = `RowData`
#### Returns
`Signal`\<`Cell`\<`TFeatures`, `TRowData`, `TValue`\>\>
***
### injectTableContext()
```ts
injectTableContext: () => Signal>;
```
Defined in: [helpers/createTableHook.ts:317](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L317)
#### Type Parameters
##### TData
`TData` *extends* `RowData` = `RowData`
#### Returns
`Signal`\<[`AngularTable`](AngularTable.md)\<`TFeatures`, `TData`\>\>
***
### injectTableHeaderContext()
```ts
injectTableHeaderContext: () => Signal>;
```
Defined in: [helpers/createTableHook.ts:320](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/createTableHook.ts#L320)
#### Type Parameters
##### TValue
`TValue` *extends* `CellData` = `CellData`
##### TRowData
`TRowData` *extends* `RowData` = `RowData`
#### Returns
`Signal`\<`Header`\<`TFeatures`, `TRowData`, `TValue`\>\>
================================================
FILE: docs/framework/angular/reference/type-aliases/FlexRenderComponentProps.md
================================================
---
id: FlexRenderComponentProps
title: FlexRenderComponentProps
---
# Type Alias: FlexRenderComponentProps
```ts
type FlexRenderComponentProps = InjectionToken<{
}>;
```
Defined in: [flex-render/context.ts:3](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/context.ts#L3)
================================================
FILE: docs/framework/angular/reference/type-aliases/FlexRenderContent.md
================================================
---
id: FlexRenderContent
title: FlexRenderContent
---
# Type Alias: FlexRenderContent\
```ts
type FlexRenderContent =
| string
| number
| Type
| FlexRenderComponent
| TemplateRef<{
$implicit: TProps;
}>
| null
| Record
| undefined;
```
Defined in: [flex-render/renderer.ts:40](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/renderer.ts#L40)
Content supported by the `flexRender` directive when declaring
a table column header/cell.
## Type Parameters
### TProps
`TProps` *extends* `NonNullable`\<`unknown`\>
================================================
FILE: docs/framework/angular/reference/type-aliases/FlexRenderInputContent.md
================================================
---
id: FlexRenderInputContent
title: FlexRenderInputContent
---
# Type Alias: FlexRenderInputContent\
```ts
type FlexRenderInputContent =
| number
| string
| (props) => FlexRenderContent
| null
| undefined;
```
Defined in: [flex-render/renderer.ts:53](https://github.com/TanStack/table/blob/main/packages/angular-table/src/flex-render/renderer.ts#L53)
Input content supported by the `flexRender` directives.
## Type Parameters
### TProps
`TProps` *extends* `NonNullable`\<`unknown`\>
================================================
FILE: docs/framework/angular/reference/variables/FlexRender.md
================================================
---
id: FlexRender
title: FlexRender
---
# Variable: FlexRender
```ts
const FlexRender: readonly [typeof FlexRenderDirective, typeof FlexRenderCell];
```
Defined in: [index.ts:25](https://github.com/TanStack/table/blob/main/packages/angular-table/src/index.ts#L25)
Constant helper to import FlexRender directives.
You should prefer to use this constant over importing the directives separately,
as it ensures you always have the correct set of directives over library updates.
## See
[FlexRenderDirective](../classes/FlexRenderDirective.md) and [FlexRenderCell](../classes/FlexRenderCell.md) for more details on the directives included in this export.
================================================
FILE: docs/framework/angular/reference/variables/TanStackTableCellToken.md
================================================
---
id: TanStackTableCellToken
title: TanStackTableCellToken
---
# Variable: TanStackTableCellToken
```ts
const TanStackTableCellToken: InjectionToken>;
```
Defined in: [helpers/cell.ts:25](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/cell.ts#L25)
Injection token that provides access to the current cell.
This token is provided by the [TanStackTableCell](../classes/TanStackTableCell.md) directive.
================================================
FILE: docs/framework/angular/reference/variables/TanStackTableHeaderToken.md
================================================
---
id: TanStackTableHeaderToken
title: TanStackTableHeaderToken
---
# Variable: TanStackTableHeaderToken
```ts
const TanStackTableHeaderToken: InjectionToken>;
```
Defined in: [helpers/header.ts:25](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/header.ts#L25)
Injection token that provides access to the current header.
This token is provided by the [TanStackTableHeader](../classes/TanStackTableHeader.md) directive.
================================================
FILE: docs/framework/angular/reference/variables/TanStackTableToken.md
================================================
---
id: TanStackTableToken
title: TanStackTableToken
---
# Variable: TanStackTableToken
```ts
const TanStackTableToken: InjectionToken>;
```
Defined in: [helpers/table.ts:11](https://github.com/TanStack/table/blob/main/packages/angular-table/src/helpers/table.ts#L11)
Injection token that provides access to the current [AngularTable](../type-aliases/AngularTable.md) instance.
This token is provided by the [TanStackTable](../classes/TanStackTable.md) directive.
================================================
FILE: docs/framework/lit/guide/table-state.md
================================================
---
title: Table State (Lit) Guide
---
## Table State (Lit) Guide
TanStack Table has a simple underlying internal state management system to store and manage the state of the table. It also lets you selectively pull out any state that you need to manage in your own state management. This guide will walk you through the different ways in which you can interact with and manage the state of the table.
### Accessing Table State
You do not need to set up anything special in order for the table state to work. If you pass nothing into either `state`, `initialState`, or any of the `on[State]Change` table options, the table will manage its own state internally. You can access any part of this internal state by using the `table.store.state` table instance API.
```ts
private tableController = new TableController(this);
render() {
const table = this.tableController.table({
columns,
data,
...
})
console.log(table.store.state) //access the entire internal state
console.log(table.store.state.rowSelection) //access just the row selection state
// ...
}
```
### Custom Initial State
If all you need to do for certain states is customize their initial default values, you still do not need to manage any of the state yourself. You can simply set values in the `initialState` option of the table instance.
```ts
render() {
const table = this.tableController.table({
columns,
data,
initialState: {
columnOrder: ['age', 'firstName', 'lastName'], //customize the initial column order
columnVisibility: {
id: false //hide the id column by default
},
expanded: true, //expand all rows by default
sorting: [
{
id: 'age',
desc: true //sort by age in descending order by default
}
]
},
})
return html`...`;
}
```
> **Note**: Only specify each particular state in either `initialState` or `state`, but not both. If you pass in a particular state value to both `initialState` and `state`, the initialized state in `state` will take overwrite any corresponding value in `initialState`.
### Controlled State
If you need easy access to the table state in other areas of your application, TanStack Table makes it easy to control and manage any or all of the table state in your own state management system. You can do this by passing in your own state and state management functions to the `state` and `on[State]Change` table options.
#### Individual Controlled State
You can control just the state that you need easy access to. You do NOT have to control all of the table state if you do not need to. It is recommended to only control the state that you need on a case-by-case basis.
In order to control a particular state, you need to both pass in the corresponding `state` value and the `on[State]Change` function to the table instance.
Let's take filtering, sorting, and pagination as an example in a "manual" server-side data fetching scenario. You can store the filtering, sorting, and pagination state in your own state management, but leave out any other state like column order, column visibility, etc. if your API does not care about those values.
```jsx
import {html} from "lit";
@customElement('my-component')
class MyComponent extends LitElement {
@state()
private _sorting: SortingState = []
render() {
const table = this.tableController.table({
columns,
data,
state: {
sorting: this._sorting,
},
onSortingChange: updaterOrValue => {
if (typeof updaterOrValue === 'function') {
this._sorting = updaterOrValue(this._sorting)
} else {
this._sorting = updaterOrValue
}
},
getSortedRowModel: createSortedRowModel(sortFns),
getCoreRowModel: createCoreRowModel(),
})
return html`...`
}
}
//...
```
#### Fully Controlled State
Alternatively, you can control the entire table state with the `onStateChange` table option. It will hoist out the entire table state into your own state management system. Be careful with this approach, as you might find that raising some frequently changing state values up a component tree, like `columnSizingInfo` state`, might cause bad performance issues.
A couple of more tricks may be needed to make this work. If you use the `onStateChange` table option, the initial values of the `state` must be populated with all of the relevant state values for all of the features that you want to use. You can either manually type out all of the initial state values, or use the `table.setOptions` API in a special way as shown below.
```ts
private tableController = new TableController(this);
@state()
private _tableState;
render() {
const table = this.tableController.table({
columns,
data,
getCoreRowModel: createCoreRowModel(),
getSortedRowModel: createSortedRowModel(sortFns)
})
const state = { ...table.initialState, ...this.tableState };
table.setOptions(prev => ({
...prev,
state,
onStateChange: updater => {
this.tableState =
updater instanceof Function ? updater(state) : updater //any state changes will be pushed up to our own state management
},
}))
return html`...`;
}
```
### On State Change Callbacks
So far, we have seen the `on[State]Change` and `onStateChange` table options work to "hoist" the table state changes into our own state management. However, there are a few things about these using these options that you should be aware of.
#### 1. **State Change Callbacks MUST have their corresponding state value in the `state` option**.
Specifying an `on[State]Change` callback tells the table instance that this will be a controlled state. If you do not specify the corresponding `state` value, that state will be "frozen" with its initial value.
```jsx
@state()
private _sorting = [];
//...
render() {
const table = this.tableController.table({
columns,
data,
state: {
sorting: this._sorting,
},
onSortingChange: updaterOrValue => {
if (typeof updaterOrValue === 'function') {
this._sorting = updaterOrValue(this._sorting)
} else {
this._sorting = updaterOrValue
}
},
getSortedRowModel: createSortedRowModel(sortFns),
getCoreRowModel: createCoreRowModel(),
})
return html`...`;
}
```
#### 2. **Updaters can either be raw values or callback functions**.
The `on[State]Change` and `onStateChange` callbacks work exactly like the `setState` functions in React. The updater values can either be a new state value or a callback function that takes the previous state value and returns the new state value.
What implications does this have? It means that if you want to add in some extra logic in any of the `on[State]Change` callbacks, you can do so, but you need to check whether or not the new incoming updater value is a function or value.
This is why you will see the `updater instanceof Function ? updater(state.value) : updater` pattern in the examples above. This pattern checks if the updater is a function, and if it is, it calls the function with the previous state value to get the new state value.
### State Types
All complex states in TanStack Table have their own TypeScript types that you can import and use. This can be handy for ensuring that you are using the correct data structures and properties for the state values that you are controlling.
```tsx
import { TableController, type SortingState } from '@tanstack/lit-table'
//...
@state()
private _sorting: SortingState = [
{
id: 'age', //you should get autocomplete for the `id` and `desc` properties
desc: true,
}
]
```
================================================
FILE: docs/framework/lit/lit-table.md
================================================
---
title: Lit Table
---
The `@tanstack/lit-table` adapter is a wrapper around the core table logic. Most of it's job is related to managing state the "lit" way, providing types and the rendering implementation of cell/header/footer templates.
## Exports
`@tanstack/lit-table` re-exports all of `@tanstack/table-core`'s APIs and the following:
### `TableController`
Is a reactive controller that provides a `table` API that takes an `options` object and returns a table instance.
```ts
import { TableController } from '@tanstack/lit-table'
@customElement('my-table-element')
class MyTableElement extends LitElement {
private tableController = new TableController(this)
protected render() {
const table = this.tableController.table(options)
// ...render your table
}
}
```
### `flexRender`
A utility function for rendering cell/header/footer templates with dynamic values.
Example:
```jsx
import { flexRender } from '@tanstack/lit-table'
//...
return html`
${table
.getRowModel()
.rows.slice(0, 10)
.map(
row => html`