@tanstack/angular-table
Version:
Headless UI for building powerful tables & datagrids for Angular.
780 lines (767 loc) • 35 kB
TypeScript
import * as i0 from '@angular/core';
import { Type, ComponentMirror, OutputEmitterRef, InputSignal, Injector, createComponent, Binding, TemplateRef, InjectionToken, Signal } from '@angular/core';
import { TableFeatures, RowData, CellData, Cell, Header, CellContext, HeaderContext, Table, TableOptions, Column, Row, IdentifiedColumnDef, AccessorFn, DeepKeys, DeepValue, AccessorFnColumnDef, AccessorKeyColumnDef, ColumnDef, DisplayColumnDef, GroupColumnDef } from '@tanstack/table-core';
export * from '/table-core';
import { Atom, ReadonlyAtom, Store, ReadonlyStore } from '@tanstack/angular-store';
export { shallow } from '/angular-store';
/**
* 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.
*
* @example
* ```html
* <td *flexRenderCell="cell; let cell">{{cell}}</td>
* <th *flexRenderHeader="header; let header">{{header}}</th>
* <th *flexRenderFooter="footer; let footer">{{footer}}</th>
* ```
*
* This replaces calling `*flexRender` directly like this:
* ```html
* <td *flexRender="cell.column.columnDef.cell; props: cell.getContext(); let cell">{{cell}}</td>
* <td *flexRender="header.column.columnDef.header; props: header.getContext(); let header">{{header}}</td>
* <td *flexRender="footer.column.columnDef.footer; props: footer.getContext(); let footer">{{footer}}</td>
* ```
*
* Can be imported through {@link FlexRenderCell} or {@link FlexRender}, with
* the latter preferred.
*
* @example
* ```ts
* import {FlexRender} from '@tanstack/angular-table'
*
* @Component({
* // ...
* imports: [
* FlexRender
* ]
* })
* ```
*/
declare class FlexRenderCell<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData> {
#private;
readonly cell: i0.InputSignal<Cell<TFeatures, TData, TValue> | undefined>;
readonly header: i0.InputSignal<Header<TFeatures, TData, TValue> | undefined>;
readonly footer: i0.InputSignal<Header<TFeatures, TData, TValue> | undefined>;
constructor();
static ɵfac: i0.ɵɵFactoryDeclaration<FlexRenderCell<any, any, any>, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<FlexRenderCell<any, any, any>, "ng-template[flexRenderCell], ng-template[flexRenderFooter], ng-template[flexRenderHeader]", never, { "cell": { "alias": "flexRenderCell"; "required": false; "isSignal": true; }; "header": { "alias": "flexRenderHeader"; "required": false; "isSignal": true; }; "footer": { "alias": "flexRenderFooter"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
}
type CreateComponentOptions = Parameters<typeof createComponent>[1];
type CreateComponentBindings = CreateComponentOptions['bindings'];
type CreateComponentDirectives = CreateComponentOptions['directives'];
interface FlexRenderOptions<TInputs extends Record<string, any>, TOutputs extends Record<string, any>> {
/**
* Native Angular bindings applied at component creation time via `createComponent`.
* Use this option to set inputs, outputs, or two-way bindings at creation time.
* Shouldn't be used together with {@link FlexRenderOptions#inputs} or {@link FlexRenderOptions#outputs} option.
*
* Binding input/outputs at creation time: {@link https://angular.dev/guide/components/programmatic-rendering#binding-inputs-outputs-and-setting-host-directives-at-creation}
*
* Two-way binding: {@link https://angular.dev/api/core/twoWayBinding}
*
* Output binding: {@link https://angular.dev/api/core/outputBinding}
*
* Input binding: {@link https://angular.dev/api/core/inputBinding}
*
* @example
* ```ts
* import {flexRenderComponent} from '@tanstack/angular-table';
* flexRenderComponent(MyComponent, {
* bindings: [
* // Will update `value` input every time `mySignalValue` changes
* inputBinding('value', mySignalValue),
* // Set myProperty to 1 when the component is created
* inputBinding('myProperty', () => 1),
* // Callback called every time `valueChange` output emit
* outputBinding('valueChange', value => {
* console.log("my value changed to", value)
* }),
* // Two-way binding between `value` input and `valueChange` output
* // Useful while using `model` inputs.
* twoWayBinding('value', mySignal)
* ]
* })
* ```
*/
readonly bindings?: Array<Binding>;
/**
* Directives to apply to the component at creation time.
*
* Binding directives at creation time: {@link https://angular.dev/guide/components/programmatic-rendering#binding-inputs-outputs-and-setting-host-directives-at-creation}
*
* Two-way binding: {@link https://angular.dev/api/core/twoWayBinding}
*
* Output binding: {@link https://angular.dev/api/core/outputBinding}
*
* Input binding: {@link https://angular.dev/api/core/inputBinding}
*
* @example
* ```ts
* import {flexRenderComponent} from '@tanstack/angular-table';
* flexRenderComponent(MyComponent, {
* bindings: [
* // ...
* ],
* directives: [
* DirectiveA,
* {
* type: DirectiveB,
* bindings: [
* inputBinding('value', mySignalValue),
* // ...
* ]
* }
* ]
* })
* ```
*/
readonly directives?: CreateComponentDirectives;
/**
* Component instance inputs.
*
* These values are assigned after the component has been created using
* [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput).
*
* Shouldn't be used together with {@link FlexRenderOptions#bindings} option
*/
readonly inputs?: TInputs;
/**
* Component instance outputs.
*
* Outputs are wired imperatively after component creation using {@link OutputEmitterRef#subscribe}.
*
* Shouldn't be used together with {@link FlexRenderOptions#bindings} option
*/
readonly outputs?: TOutputs;
/**
* Optional {@link Injector} that will be used when rendering the component
*/
readonly injector?: Injector;
}
type Inputs<T> = {
[K in keyof T as T[K] extends InputSignal<infer _R> ? K : never]?: T[K] extends InputSignal<infer R> ? R : never;
};
type Outputs<T> = {
[K in keyof T as T[K] extends OutputEmitterRef<infer _R> ? K : never]?: T[K] extends OutputEmitterRef<infer R> ? OutputEmitterRef<R>['emit'] : never;
};
/**
* Helper function to create a {@link FlexRenderComponent} instance, with better type-safety.
*
* @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)
* })
* ]
* })
* },
* },
* ]
* ```
*/
declare function flexRenderComponent<TComponent = any>(component: Type<TComponent>, options?: FlexRenderOptions<Inputs<TComponent>, Outputs<TComponent>>): FlexRenderComponent<TComponent>;
/**
* Wrapper interface for a component that will be used as content for {@link FlexRenderDirective}.
* Can be created using {@link flexRenderComponent} 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<number>();
* }
*
* ```
*/
interface FlexRenderComponent<TComponent = any> {
/**
* The component type
*/
readonly component: Type<TComponent>;
/**
* Reflected metadata about the component.
*/
readonly mirror: ComponentMirror<TComponent>;
/**
* List of allowed input names.
*/
readonly allowedInputNames: Array<string>;
/**
* List of allowed output names.
*/
readonly allowedOutputNames: Array<string>;
/**
* Component instance outputs. Subscribed via {@link OutputEmitterRef#subscribe}
*
* @see {@link FlexRenderOptions#outputs}
*/
readonly outputs?: Outputs<TComponent>;
/**
* Component instance inputs. Set via [componentRef.setInput API](https://angular.dev/api/core/ComponentRef#setInput))
*
* @see {@link FlexRenderOptions#inputs}
*/
readonly inputs?: Inputs<TComponent>;
/**
* Optional {@link Injector} that will be used when rendering the component.
*
* @see {@link FlexRenderOptions#injector}
*/
readonly injector?: Injector;
/**
* Bindings to apply to the root component
*
* @see {@link FlexRenderOptions#bindings}
*/
bindings?: CreateComponentBindings;
/**
* Directives that should be applied to the component.
*
* @see {FlexRenderOptions#directives}
*/
directives?: CreateComponentDirectives;
}
/**
* Wrapper class for a component that will be used as content for {@link FlexRenderDirective}
*
* Prefer {@link flexRenderComponent} helper for better type-safety
*/
declare class FlexRenderComponentInstance<TComponent = any> implements FlexRenderComponent<TComponent> {
readonly component: Type<TComponent>;
readonly inputs?: Inputs<TComponent> | undefined;
readonly injector?: Injector | undefined;
readonly outputs?: Outputs<TComponent> | undefined;
readonly directives?: CreateComponentDirectives;
readonly bindings?: CreateComponentBindings;
readonly mirror: ComponentMirror<TComponent>;
readonly allowedInputNames: Array<string>;
readonly allowedOutputNames: Array<string>;
constructor(component: Type<TComponent>, inputs?: Inputs<TComponent> | undefined, injector?: Injector | undefined, outputs?: Outputs<TComponent> | undefined, directives?: CreateComponentDirectives, bindings?: CreateComponentBindings);
}
/**
* Content supported by the `flexRender` directive when declaring
* a table column header/cell.
*/
type FlexRenderContent<TProps extends NonNullable<unknown>> = string | number | Type<TProps> | FlexRenderComponent<TProps> | TemplateRef<{
$implicit: TProps;
}> | null | Record<any, any> | undefined;
/**
* Input content supported by the `flexRender` directives.
*/
type FlexRenderInputContent<TProps extends NonNullable<unknown>> = number | string | ((props: TProps) => FlexRenderContent<TProps>) | null | undefined;
declare const FlexRenderComponentProps: InjectionToken<{}>;
/**
* Inject the flex render context props.
*
* Can be used in components rendered via FlexRender directives.
*/
declare function injectFlexRenderContext<T extends NonNullable<unknown>>(): T;
/**
* 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 {@link FlexRenderCell} directive as shorthand instead .
*
* @example
* ```ts
* import {FlexRender} from '@tanstack/angular-table';
*
* @Component({
* imports: [FlexRender],
* template: `
* <td
* *flexRender="
* cell.column.columnDef.cell;
* props: cell.getContext();
* let cell"
* >
* {{cell}}
* </td>
*
* <th
* *flexRender="
* header.column.columnDef.header;
* props: header.getContext();
* let header"
* >
* {{header}}
* </td>
*
* <td
* *flexRender="
* footer.column.columnDef.footer;
* props: footer.getContext();
* let footer"
* >
* {{footer}}
* </td>
* `,
* })
* class App {
* }
* ```
*
* Can be imported through {@link FlexRenderDirective} or {@link FlexRender},
* with the latter preferred.
*/
declare class FlexRenderDirective<TFeatures extends TableFeatures, TRowData extends RowData, TValue extends CellData, TProps extends NonNullable<unknown> | CellContext<TFeatures, TRowData, TValue> | HeaderContext<TFeatures, TRowData, TValue>> {
#private;
readonly content: InputSignal<FlexRenderInputContent<TProps>>;
readonly props: InputSignal<TProps>;
readonly injector: InputSignal<Injector>;
constructor();
static ɵfac: i0.ɵɵFactoryDeclaration<FlexRenderDirective<any, any, any, any>, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<FlexRenderDirective<any, any, any, any>, "ng-template[flexRender]", never, { "content": { "alias": "flexRender"; "required": false; "isSignal": true; }; "props": { "alias": "flexRenderProps"; "required": false; "isSignal": true; }; "injector": { "alias": "flexRenderInjector"; "required": false; "isSignal": true; }; }, {}, never, never, true, never>;
}
type SubscribeSource<TValue> = Atom<TValue> | ReadonlyAtom<TValue> | Store<TValue> | ReadonlyStore<TValue>;
type AngularTable<TFeatures extends TableFeatures, TData extends RowData> = Table<TFeatures, TData>;
/**
* 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(...)`.
*
* @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<typeof features, MyData>[] = [
* // ...column definitions
* ]
*
* // or using createColumnHelper
* import {createColumnHelper} from '@tanstack/angular-table';
* const columnHelper = createColumnHelper<typeof features, MyData>();
* 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(),
* })
* ```
*
* @returns An Angular-reactive TanStack Table instance.
*/
declare function injectTable<TFeatures extends TableFeatures, TData extends RowData>(options: () => TableOptions<TFeatures, TData>): AngularTable<TFeatures, TData>;
/**
* 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.
*/
interface TanStackTableCellContext<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData> {
/** Signal that returns the current cell instance. */
cell: Signal<Cell<TFeatures, TData, TValue>>;
}
/**
* Injection token that provides access to the current cell.
*
* This token is provided by the {@link TanStackTableCell} directive.
*/
declare const TanStackTableCellToken: InjectionToken<Signal<Cell<TableFeatures, RowData, unknown>>>;
/**
* 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`
*
* @example
* Inject from the nearest `[tanStackTableCell]`:
* ```html
* <td [tanStackTableCell]="cell">
* <app-cell-actions />
* </td>
* ```
*
* ```ts
* @Component({
* selector: 'app-cell-actions',
* template: `{{ cell().id }}`,
* })
* export class CellActionsComponent {
* readonly cell = injectTableCellContext()
* }
* ```
*
* @example
* Inject inside a component rendered via `flexRender`:
* ```ts
* @Component({
* selector: 'app-price-cell',
* template: `{{ cell().getValue() }}`,
* })
* export class PriceCellComponent {
* readonly cell = injectTableCellContext()
* }
* ```
*/
declare class TanStackTableCell<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData> implements TanStackTableCellContext<TFeatures, TData, TValue> {
/**
* The current TanStack Table cell.
*
* Provided as a required signal input so DI consumers always read the latest value.
*/
readonly cell: i0.InputSignal<Cell<TFeatures, TData, TValue>>;
static ɵfac: i0.ɵɵFactoryDeclaration<TanStackTableCell<any, any, any>, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<TanStackTableCell<any, any, any>, "[tanStackTableCell]", ["cell"], { "cell": { "alias": "tanStackTableCell"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
}
/**
* 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`
*/
declare function injectTableCellContext<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData>(): TanStackTableCellContext<TFeatures, TData, TValue>['cell'];
/**
* 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.
*/
interface TanStackTableHeaderContext<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData> {
/** Signal that returns the current header instance. */
header: Signal<Header<TFeatures, TData, TValue>>;
}
/**
* Injection token that provides access to the current header.
*
* This token is provided by the {@link TanStackTableHeader} directive.
*/
declare const TanStackTableHeaderToken: InjectionToken<Signal<Header<TableFeatures, RowData, unknown>>>;
/**
* 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
* <th [tanStackTableHeader]="header">
* <app-sort-indicator />
* </th>
* ```
*
* ```ts
* @Component({
* selector: 'app-sort-indicator',
* template: `
* <button (click)="toggle()">
* {{ header().column.id }}
* </button>
* `,
* })
* export class SortIndicatorComponent {
* readonly header = injectTableHeaderContext()
*
* toggle() {
* this.header().column.toggleSorting()
* }
* }
* ```
*/
declare class TanStackTableHeader<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData> implements TanStackTableHeaderContext<TFeatures, TData, TValue> {
/**
* The current TanStack Table header.
*
* Provided as a required signal input so DI consumers always read the latest value.
*/
readonly header: i0.InputSignal<Header<TFeatures, TData, TValue>>;
static ɵfac: i0.ɵɵFactoryDeclaration<TanStackTableHeader<any, any, any>, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<TanStackTableHeader<any, any, any>, "[tanStackTableHeader]", ["header"], { "header": { "alias": "tanStackTableHeader"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
}
/**
* 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`
*/
declare function injectTableHeaderContext<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData>(): TanStackTableHeaderContext<TFeatures, TData, TValue>['header'];
/**
* Injection token that provides access to the current {@link AngularTable} instance.
*
* This token is provided by the {@link TanStackTable} directive.
*/
declare const TanStackTableToken: InjectionToken<Signal<AngularTable<TableFeatures, RowData>>>;
/**
* 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
* <div [tanStackTable]="table">
* <app-pagination />
* </div>
* ```
*
* ```ts
* @Component({
* selector: 'app-pagination',
* template: `
* <button (click)="prev()" [disabled]="!table().getCanPreviousPage()">Prev</button>
* <button (click)="next()" [disabled]="!table().getCanNextPage()">Next</button>
* `,
* })
* export class PaginationComponent {
* readonly table = injectTableContext()
*
* prev() {
* this.table().previousPage()
* }
* next() {
* this.table().nextPage()
* }
* }
* ```
*/
declare class TanStackTable<TFeatures extends TableFeatures, TData extends RowData> {
/**
* The current TanStack Table instance.
*
* Provided as a required signal input so DI consumers always read the latest value.
*/
readonly table: i0.InputSignal<AngularTable<TFeatures, TData>>;
static ɵfac: i0.ɵɵFactoryDeclaration<TanStackTable<any, any>, never>;
static ɵdir: i0.ɵɵDirectiveDeclaration<TanStackTable<any, any>, "[tanStackTable]", ["table"], { "table": { "alias": "tanStackTable"; "required": true; "isSignal": true; }; }, {}, never, never, true, never>;
}
/**
* 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`
*/
declare function injectTableContext<TFeatures extends TableFeatures, TData extends RowData>(): Signal<AngularTable<TFeatures, TData>>;
type RenderableComponent = Type<any> | (<T extends NonNullable<unknown>>(props: T) => FlexRenderContent<T>);
/**
* Enhanced CellContext with pre-bound cell components.
* The `cell` property includes the registered cellComponents.
*/
type AppCellContext<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record<string, RenderableComponent>> = {
cell: Cell<TFeatures, TData, TValue> & TCellComponents & {
FlexRender: () => unknown;
};
column: Column<TFeatures, TData, TValue>;
getValue: CellContext<TFeatures, TData, TValue>['getValue'];
renderValue: CellContext<TFeatures, TData, TValue>['renderValue'];
row: Row<TFeatures, TData>;
table: Table<TFeatures, TData>;
};
/**
* Enhanced HeaderContext with pre-bound header components.
* The `header` property includes the registered headerComponents.
*/
type AppHeaderContext<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, THeaderComponents extends Record<string, RenderableComponent>> = {
column: Column<TFeatures, TData, TValue>;
header: Header<TFeatures, TData, TValue> & THeaderComponents & {
FlexRender: () => unknown;
};
table: Table<TFeatures, TData>;
};
/**
* Template type for column definitions that can be a string or a function.
*/
type AppColumnDefTemplate<TProps extends object> = string | ((props: TProps) => any);
/**
* Enhanced column definition base with pre-bound components in cell/header/footer contexts.
*/
type AppColumnDefBase<TFeatures extends TableFeatures, TData extends RowData, TValue extends CellData, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = Omit<IdentifiedColumnDef<TFeatures, TData, TValue>, 'cell' | 'header' | 'footer'> & {
cell?: AppColumnDefTemplate<AppCellContext<TFeatures, TData, TValue, TCellComponents>>;
header?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, TValue, THeaderComponents>>;
footer?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, TValue, THeaderComponents>>;
};
/**
* Enhanced display column definition with pre-bound components.
*/
type AppDisplayColumnDef<TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = Omit<DisplayColumnDef<TFeatures, TData, unknown>, 'cell' | 'header' | 'footer'> & {
cell?: AppColumnDefTemplate<AppCellContext<TFeatures, TData, unknown, TCellComponents>>;
header?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>>;
footer?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>>;
};
/**
* Enhanced group column definition with pre-bound components.
*/
type AppGroupColumnDef<TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = Omit<GroupColumnDef<TFeatures, TData, unknown>, 'cell' | 'header' | 'footer' | 'columns'> & {
cell?: AppColumnDefTemplate<AppCellContext<TFeatures, TData, unknown, TCellComponents>>;
header?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>>;
footer?: AppColumnDefTemplate<AppHeaderContext<TFeatures, TData, unknown, THeaderComponents>>;
columns?: ReadonlyArray<ColumnDef<TFeatures, TData, unknown>>;
};
/**
* 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 AppColumnHelper<TFeatures extends TableFeatures, TData extends RowData, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = {
/**
* Creates a data column definition with an accessor key or function.
* The cell, header, and footer contexts include pre-bound components.
*/
accessor: <TAccessor extends AccessorFn<TData> | DeepKeys<TData>, TValue extends (TAccessor extends AccessorFn<TData, infer TReturn> ? TReturn : TAccessor extends DeepKeys<TData> ? DeepValue<TData, TAccessor> : never)>(accessor: TAccessor, column: TAccessor extends AccessorFn<TData> ? AppColumnDefBase<TFeatures, TData, TValue, TCellComponents, THeaderComponents> & {
id: string;
} : AppColumnDefBase<TFeatures, TData, TValue, TCellComponents, THeaderComponents>) => TAccessor extends AccessorFn<TData> ? AccessorFnColumnDef<TFeatures, TData, TValue> : AccessorKeyColumnDef<TFeatures, TData, TValue>;
/**
* Wraps an array of column definitions to preserve each column's individual TValue type.
*/
columns: <TColumns extends ReadonlyArray<ColumnDef<TFeatures, TData, any>>>(columns: [...TColumns]) => Array<ColumnDef<TFeatures, TData, any>> & [...TColumns];
/**
* Creates a display column definition for non-data columns.
* The cell, header, and footer contexts include pre-bound components.
*/
display: (column: AppDisplayColumnDef<TFeatures, TData, TCellComponents, THeaderComponents>) => DisplayColumnDef<TFeatures, TData, unknown>;
/**
* Creates a group column definition with nested child columns.
* The cell, header, and footer contexts include pre-bound components.
*/
group: (column: AppGroupColumnDef<TFeatures, TData, TCellComponents, THeaderComponents>) => GroupColumnDef<TFeatures, TData, unknown>;
};
/**
* Extended table API returned by useAppTable with all App wrapper components
*/
type AppAngularTable<TFeatures extends TableFeatures, TData extends RowData, TTableComponents extends Record<string, RenderableComponent>, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = AngularTable<TFeatures, TData> & NoInfer<TTableComponents> & {
appCell: <TValue>(cell: Cell<TFeatures, TData, TValue>) => Cell<TFeatures, TData, TValue> & NoInfer<TCellComponents>;
appHeader: <TValue>(header: Header<TFeatures, TData, TValue>) => Header<TFeatures, TData, TValue> & NoInfer<THeaderComponents>;
appFooter: <TValue>(footer: Header<TFeatures, TData, TValue>) => Header<TFeatures, TData, TValue> & NoInfer<THeaderComponents>;
};
/**
* Options for creating a table hook with pre-bound components and default table options.
* Extends all TableOptions except 'columns' | 'data' | 'store' | 'state' | 'initialState'.
*/
type CreateTableContextOptions<TFeatures extends TableFeatures, TTableComponents extends Record<string, RenderableComponent>, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = Omit<TableOptions<TFeatures, any>, 'columns' | 'data' | 'store' | 'state' | 'initialState'> & {
/**
* 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 { PaginationControls, GlobalFilter, RowCount }
*/
tableComponents?: TTableComponents;
/**
* 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 { TextCell, NumberCell, DateCell, CurrencyCell }
*/
cellComponents?: TCellComponents;
/**
* 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 { SortIndicator, ColumnFilter, ResizeHandle }
*/
headerComponents?: THeaderComponents;
};
type CreateTableHookResult<TFeatures extends TableFeatures, TTableComponents extends Record<string, RenderableComponent>, TCellComponents extends Record<string, RenderableComponent>, THeaderComponents extends Record<string, RenderableComponent>> = {
createAppColumnHelper: <TData extends RowData>() => AppColumnHelper<TFeatures, TData, TCellComponents, THeaderComponents>;
injectTableContext: <TData extends RowData = RowData>() => Signal<AngularTable<TFeatures, TData> & TTableComponents>;
injectTableHeaderContext: <TValue extends CellData = CellData, TRowData extends RowData = RowData>() => Signal<Header<TFeatures, TRowData, TValue> & THeaderComponents>;
injectTableCellContext: <TValue extends CellData = CellData, TRowData extends RowData = RowData>() => Signal<Cell<TFeatures, TRowData, TValue> & TCellComponents>;
injectFlexRenderHeaderContext: <TData extends RowData, TValue extends CellData>() => HeaderContext<TFeatures, TData, TValue>;
injectFlexRenderCellContext: <TData extends RowData, TValue extends CellData>() => CellContext<TFeatures, TData, TValue>;
injectAppTable: <TData extends RowData>(tableOptions: () => Omit<TableOptions<TFeatures, TData>, 'features'>) => AppAngularTable<TFeatures, TData, TTableComponents, TCellComponents, THeaderComponents>;
};
/**
* Creates app-scoped Angular table helpers with features, row models, and
* renderable component maps pre-bound.
*
* Use this when an app or design system wants typed `injectAppTable`,
* pre-bound column helpers, and typed table/cell/header context injection
* helpers without repeating the same feature and component generics.
*
* @example
* ```ts
* const { injectAppTable, createAppColumnHelper } = createTableHook({
* features,
* tableComponents: {},
* cellComponents: {},
* headerComponents: {},
* })
* ```
*/
declare function createTableHook<TFeatures extends TableFeatures, const TTableComponents extends Record<string, RenderableComponent>, const TCellComponents extends Record<string, RenderableComponent>, const THeaderComponents extends Record<string, RenderableComponent>>({ tableComponents, cellComponents, headerComponents, ...defaultTableOptions }: CreateTableContextOptions<TFeatures, TTableComponents, TCellComponents, THeaderComponents>): CreateTableHookResult<TFeatures, TTableComponents, TCellComponents, THeaderComponents>;
/**
* 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 {@link FlexRenderDirective} and {@link FlexRenderCell} for more details on the directives included in this export.
*/
declare const FlexRender: readonly [typeof FlexRenderDirective, typeof FlexRenderCell];
export { FlexRender, FlexRenderCell, FlexRenderComponentInstance, FlexRenderComponentProps, FlexRenderDirective, TanStackTable, TanStackTableCell, TanStackTableCellToken, TanStackTableHeader, TanStackTableHeaderToken, TanStackTableToken, createTableHook, flexRenderComponent, injectFlexRenderContext, injectTable, injectTableCellContext, injectTableContext, injectTableHeaderContext };
export type { AngularTable, AppAngularTable, AppCellContext, AppColumnDefBase, AppColumnDefTemplate, AppColumnHelper, AppDisplayColumnDef, AppGroupColumnDef, AppHeaderContext, CreateTableContextOptions, CreateTableHookResult, FlexRenderComponent, FlexRenderContent, FlexRenderInputContent, RenderableComponent, SubscribeSource, TanStackTableCellContext, TanStackTableHeaderContext };