UNPKG

@tanstack/angular-table

Version:

Headless UI for building powerful tables & datagrids for Angular.

780 lines (767 loc) 35 kB
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 '@tanstack/table-core'; import { Atom, ReadonlyAtom, Store, ReadonlyStore } from '@tanstack/angular-store'; export { shallow } from '@tanstack/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 };