@tanstack/angular-table 9.0.0-alpha.23 → 9.0.0-alpha.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -0
- package/dist/README.md +117 -0
- package/dist/fesm2022/tanstack-angular-table.mjs +206 -189
- package/dist/fesm2022/tanstack-angular-table.mjs.map +1 -1
- package/package.json +3 -3
- package/src/flex-render/renderer.ts +25 -15
- package/src/flex-render/view.ts +45 -3
package/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="./media/header_table.png" alt="TanStack Table">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<br />
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
<a href="https://npmjs.com/package/@tanstack/react-table" target="\_parent">
|
|
9
|
+
<img alt="npm downloads" src="https://img.shields.io/npm/dm/@tanstack/react-table.svg" />
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://github.com/tanstack/table" target="\_parent">
|
|
12
|
+
<img alt="github stars" src="https://img.shields.io/github/stars/tanstack/react-table.svg?style=social&label=Star" />
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://bundlephobia.com/result?p=@tanstack/react-table@latest" target="\_parent">
|
|
15
|
+
<img alt="bundle size" src="https://badgen.net/bundlephobia/minzip/@tanstack/react-table@latest" />
|
|
16
|
+
</a>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div align="center">
|
|
20
|
+
<a href="#badge">
|
|
21
|
+
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
|
|
22
|
+
</a>
|
|
23
|
+
<a href="https://bestofjs.org/projects/tanstack-table"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Ftable%26since=daily" /></a>
|
|
24
|
+
<a href="https://twitter.com/tan_stack"><img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/></a>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
# TanStack Table
|
|
32
|
+
|
|
33
|
+
> [!NOTE]
|
|
34
|
+
> You may know TanStack Table by the adapter names:
|
|
35
|
+
>
|
|
36
|
+
> - [Angular Table](https://tanstack.com/table/alpha/docs/framework/angular/angular-table)
|
|
37
|
+
> - [Lit Table](https://tanstack.com/table/alpha/docs/framework/lit/lit-table)
|
|
38
|
+
> - [React Table](https://tanstack.com/table/alpha/docs/framework/react/react-table)
|
|
39
|
+
> - [Solid Table](https://tanstack.com/table/alpha/docs/framework/solid/solid-table)
|
|
40
|
+
> - [Svelte Table](https://tanstack.com/table/alpha/docs/framework/svelte/svelte-table)
|
|
41
|
+
> - [Vue Table](https://tanstack.com/table/alpha/docs/framework/vue/vue-table)
|
|
42
|
+
|
|
43
|
+
A headless table library for building powerful datagrids with full control over markup, styles, and behavior.
|
|
44
|
+
|
|
45
|
+
- Framework‑agnostic core with bindings for React, Vue & Solid
|
|
46
|
+
- 100% customizable — bring your own UI, components, and styles
|
|
47
|
+
- Sorting, filtering, grouping, aggregation & row selection
|
|
48
|
+
- Lightweight, virtualizable & server‑side friendly
|
|
49
|
+
|
|
50
|
+
### <a href="https://tanstack.com/table">Read the Docs →</a>
|
|
51
|
+
|
|
52
|
+
## Get Involved
|
|
53
|
+
|
|
54
|
+
- We welcome issues and pull requests!
|
|
55
|
+
- Participate in [GitHub discussions](https://github.com/TanStack/table/discussions)
|
|
56
|
+
- Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ)
|
|
57
|
+
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions
|
|
58
|
+
|
|
59
|
+
## Partners
|
|
60
|
+
|
|
61
|
+
<table align="center">
|
|
62
|
+
<tr>
|
|
63
|
+
<td>
|
|
64
|
+
<a href="https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS">
|
|
65
|
+
<picture>
|
|
66
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/coderabbit-dark-CMcuvjEy.svg" height="40" />
|
|
67
|
+
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" />
|
|
68
|
+
<img src="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" alt="CodeRabbit" />
|
|
69
|
+
</picture>
|
|
70
|
+
</a>
|
|
71
|
+
</td>
|
|
72
|
+
<td padding="20">
|
|
73
|
+
<a href="https://www.cloudflare.com?utm_source=tanstack">
|
|
74
|
+
<picture>
|
|
75
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/cloudflare-white-DQDB7UaL.svg" height="60" />
|
|
76
|
+
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" />
|
|
77
|
+
<img src="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" alt="Cloudflare" />
|
|
78
|
+
</picture>
|
|
79
|
+
</a>
|
|
80
|
+
</td>
|
|
81
|
+
<td>
|
|
82
|
+
<a href="https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable" style="display: flex; align-items: center; border: none;">
|
|
83
|
+
<picture>
|
|
84
|
+
<source media="(prefers-color-scheme: dark)" srcset="./media/ag-grid-dark.svg" height="40" />
|
|
85
|
+
<source media="(prefers-color-scheme: light)" srcset="./media/ag-grid-light.svg" height="40" />
|
|
86
|
+
<img src="https://raw.githubusercontent.com/tannerlinsley/files/master/partners/ag-grid.svg" height="60" alt="AG Grid" />
|
|
87
|
+
</picture>
|
|
88
|
+
</a>
|
|
89
|
+
</td>
|
|
90
|
+
</tr>
|
|
91
|
+
</table>
|
|
92
|
+
|
|
93
|
+
<div align="center">
|
|
94
|
+
<img src="./media/partner_logo.svg" alt="Table & you?" height="65">
|
|
95
|
+
<p>
|
|
96
|
+
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.
|
|
97
|
+
</p>
|
|
98
|
+
<a href="mailto:partners@tanstack.com?subject=TanStack Table Partnership"><b>LET'S CHAT</b></a>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
## Explore the TanStack Ecosystem
|
|
102
|
+
|
|
103
|
+
- <a href="https://github.com/tanstack/config"><b>TanStack Config</b></a> – Tooling for JS/TS packages
|
|
104
|
+
- <a href="https://github.com/tanstack/db"><b>TanStack DB</b></a> – Reactive sync client store
|
|
105
|
+
- <a href="https://github.com/tanstack/devtools"><b>TanStack DevTools</b></a> – Unified devtools panel
|
|
106
|
+
- <a href="https://github.com/tanstack/form"><b>TanStack Form</b></a> – Type‑safe form state
|
|
107
|
+
- <a href="https://github.com/tanstack/pacer"><b>TanStack Pacer</b></a> – Debouncing, throttling, batching <br/>
|
|
108
|
+
- <a href="https://github.com/tanstack/query"><b>TanStack Query</b></a> – Async state & caching
|
|
109
|
+
- <a href="https://github.com/tanstack/ranger"><b>TanStack Ranger</b></a> – Range & slider primitives
|
|
110
|
+
- <a href="https://github.com/tanstack/router"><b>TanStack Router</b></a> – Type‑safe routing, caching & URL state
|
|
111
|
+
- <a href="https://github.com/tanstack/router"><b>TanStack Start</b></a> – Full‑stack SSR & streaming
|
|
112
|
+
- <a href="https://github.com/tanstack/store"><b>TanStack Store</b></a> – Reactive data store
|
|
113
|
+
- <a href="https://github.com/tanstack/virtual"><b>TanStack Virtual</b></a> – Virtualized rendering
|
|
114
|
+
|
|
115
|
+
… and more at <a href="https://tanstack.com"><b>TanStack.com »</b></a>
|
|
116
|
+
|
|
117
|
+
<!-- USE THE FORCE LUKE -->
|
package/dist/README.md
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="./media/header_table.png" alt="TanStack Table">
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
<br />
|
|
6
|
+
|
|
7
|
+
<div align="center">
|
|
8
|
+
<a href="https://npmjs.com/package/@tanstack/react-table" target="\_parent">
|
|
9
|
+
<img alt="npm downloads" src="https://img.shields.io/npm/dm/@tanstack/react-table.svg" />
|
|
10
|
+
</a>
|
|
11
|
+
<a href="https://github.com/tanstack/table" target="\_parent">
|
|
12
|
+
<img alt="github stars" src="https://img.shields.io/github/stars/tanstack/react-table.svg?style=social&label=Star" />
|
|
13
|
+
</a>
|
|
14
|
+
<a href="https://bundlephobia.com/result?p=@tanstack/react-table@latest" target="\_parent">
|
|
15
|
+
<img alt="bundle size" src="https://badgen.net/bundlephobia/minzip/@tanstack/react-table@latest" />
|
|
16
|
+
</a>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<div align="center">
|
|
20
|
+
<a href="#badge">
|
|
21
|
+
<img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
|
|
22
|
+
</a>
|
|
23
|
+
<a href="https://bestofjs.org/projects/tanstack-table"><img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Ftable%26since=daily" /></a>
|
|
24
|
+
<a href="https://twitter.com/tan_stack"><img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/></a>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
|
|
28
|
+
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
# TanStack Table
|
|
32
|
+
|
|
33
|
+
> [!NOTE]
|
|
34
|
+
> You may know TanStack Table by the adapter names:
|
|
35
|
+
>
|
|
36
|
+
> - [Angular Table](https://tanstack.com/table/alpha/docs/framework/angular/angular-table)
|
|
37
|
+
> - [Lit Table](https://tanstack.com/table/alpha/docs/framework/lit/lit-table)
|
|
38
|
+
> - [React Table](https://tanstack.com/table/alpha/docs/framework/react/react-table)
|
|
39
|
+
> - [Solid Table](https://tanstack.com/table/alpha/docs/framework/solid/solid-table)
|
|
40
|
+
> - [Svelte Table](https://tanstack.com/table/alpha/docs/framework/svelte/svelte-table)
|
|
41
|
+
> - [Vue Table](https://tanstack.com/table/alpha/docs/framework/vue/vue-table)
|
|
42
|
+
|
|
43
|
+
A headless table library for building powerful datagrids with full control over markup, styles, and behavior.
|
|
44
|
+
|
|
45
|
+
- Framework‑agnostic core with bindings for React, Vue & Solid
|
|
46
|
+
- 100% customizable — bring your own UI, components, and styles
|
|
47
|
+
- Sorting, filtering, grouping, aggregation & row selection
|
|
48
|
+
- Lightweight, virtualizable & server‑side friendly
|
|
49
|
+
|
|
50
|
+
### <a href="https://tanstack.com/table">Read the Docs →</a>
|
|
51
|
+
|
|
52
|
+
## Get Involved
|
|
53
|
+
|
|
54
|
+
- We welcome issues and pull requests!
|
|
55
|
+
- Participate in [GitHub discussions](https://github.com/TanStack/table/discussions)
|
|
56
|
+
- Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ)
|
|
57
|
+
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions
|
|
58
|
+
|
|
59
|
+
## Partners
|
|
60
|
+
|
|
61
|
+
<table align="center">
|
|
62
|
+
<tr>
|
|
63
|
+
<td>
|
|
64
|
+
<a href="https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS">
|
|
65
|
+
<picture>
|
|
66
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/coderabbit-dark-CMcuvjEy.svg" height="40" />
|
|
67
|
+
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" />
|
|
68
|
+
<img src="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" alt="CodeRabbit" />
|
|
69
|
+
</picture>
|
|
70
|
+
</a>
|
|
71
|
+
</td>
|
|
72
|
+
<td padding="20">
|
|
73
|
+
<a href="https://www.cloudflare.com?utm_source=tanstack">
|
|
74
|
+
<picture>
|
|
75
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/cloudflare-white-DQDB7UaL.svg" height="60" />
|
|
76
|
+
<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" />
|
|
77
|
+
<img src="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" alt="Cloudflare" />
|
|
78
|
+
</picture>
|
|
79
|
+
</a>
|
|
80
|
+
</td>
|
|
81
|
+
<td>
|
|
82
|
+
<a href="https://ag-grid.com/react-data-grid/?utm_source=reacttable&utm_campaign=githubreacttable" style="display: flex; align-items: center; border: none;">
|
|
83
|
+
<picture>
|
|
84
|
+
<source media="(prefers-color-scheme: dark)" srcset="./media/ag-grid-dark.svg" height="40" />
|
|
85
|
+
<source media="(prefers-color-scheme: light)" srcset="./media/ag-grid-light.svg" height="40" />
|
|
86
|
+
<img src="https://raw.githubusercontent.com/tannerlinsley/files/master/partners/ag-grid.svg" height="60" alt="AG Grid" />
|
|
87
|
+
</picture>
|
|
88
|
+
</a>
|
|
89
|
+
</td>
|
|
90
|
+
</tr>
|
|
91
|
+
</table>
|
|
92
|
+
|
|
93
|
+
<div align="center">
|
|
94
|
+
<img src="./media/partner_logo.svg" alt="Table & you?" height="65">
|
|
95
|
+
<p>
|
|
96
|
+
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.
|
|
97
|
+
</p>
|
|
98
|
+
<a href="mailto:partners@tanstack.com?subject=TanStack Table Partnership"><b>LET'S CHAT</b></a>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
## Explore the TanStack Ecosystem
|
|
102
|
+
|
|
103
|
+
- <a href="https://github.com/tanstack/config"><b>TanStack Config</b></a> – Tooling for JS/TS packages
|
|
104
|
+
- <a href="https://github.com/tanstack/db"><b>TanStack DB</b></a> – Reactive sync client store
|
|
105
|
+
- <a href="https://github.com/tanstack/devtools"><b>TanStack DevTools</b></a> – Unified devtools panel
|
|
106
|
+
- <a href="https://github.com/tanstack/form"><b>TanStack Form</b></a> – Type‑safe form state
|
|
107
|
+
- <a href="https://github.com/tanstack/pacer"><b>TanStack Pacer</b></a> – Debouncing, throttling, batching <br/>
|
|
108
|
+
- <a href="https://github.com/tanstack/query"><b>TanStack Query</b></a> – Async state & caching
|
|
109
|
+
- <a href="https://github.com/tanstack/ranger"><b>TanStack Ranger</b></a> – Range & slider primitives
|
|
110
|
+
- <a href="https://github.com/tanstack/router"><b>TanStack Router</b></a> – Type‑safe routing, caching & URL state
|
|
111
|
+
- <a href="https://github.com/tanstack/router"><b>TanStack Start</b></a> – Full‑stack SSR & streaming
|
|
112
|
+
- <a href="https://github.com/tanstack/store"><b>TanStack Store</b></a> – Reactive data store
|
|
113
|
+
- <a href="https://github.com/tanstack/virtual"><b>TanStack Virtual</b></a> – Virtualized rendering
|
|
114
|
+
|
|
115
|
+
… and more at <a href="https://tanstack.com"><b>TanStack.com »</b></a>
|
|
116
|
+
|
|
117
|
+
<!-- USE THE FORCE LUKE -->
|
|
@@ -1,88 +1,9 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, input, inject, Directive, reflectComponentType,
|
|
2
|
+
import { InjectionToken, input, inject, Directive, reflectComponentType, Injectable, KeyValueDiffers, ChangeDetectorRef, OutputEmitterRef, TemplateRef, Type, runInInjectionContext, computed, effect, untracked, Injector, ViewContainerRef, DestroyRef, assertInInjectionContext, signal } from '@angular/core';
|
|
3
3
|
import { constructReactivityFeature, constructTable, createColumnHelper } from '@tanstack/table-core';
|
|
4
4
|
export * from '@tanstack/table-core';
|
|
5
5
|
import { injectStore } from '@tanstack/angular-store';
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Injection token that provides access to the current {@link AngularTable} instance.
|
|
9
|
-
*
|
|
10
|
-
* This token is provided by the {@link TanStackTable} directive.
|
|
11
|
-
*/
|
|
12
|
-
const TanStackTableToken = new InjectionToken('[TanStack Table] Table Context');
|
|
13
|
-
/**
|
|
14
|
-
* Provides a TanStack Table instance (`AngularTable`) in Angular DI.
|
|
15
|
-
*
|
|
16
|
-
* The table can be injected by:
|
|
17
|
-
* - any descendant of an element using `[tanStackTable]="..."`
|
|
18
|
-
* - any component instantiated by `*flexRender` when the render props contains `table`
|
|
19
|
-
*
|
|
20
|
-
* @example
|
|
21
|
-
* ```html
|
|
22
|
-
* <div [tanStackTable]="table">
|
|
23
|
-
* <app-pagination />
|
|
24
|
-
* </div>
|
|
25
|
-
* ```
|
|
26
|
-
*
|
|
27
|
-
* ```ts
|
|
28
|
-
* @Component({
|
|
29
|
-
* selector: 'app-pagination',
|
|
30
|
-
* template: `
|
|
31
|
-
* <button (click)="prev()" [disabled]="!table().getCanPreviousPage()">Prev</button>
|
|
32
|
-
* <button (click)="next()" [disabled]="!table().getCanNextPage()">Next</button>
|
|
33
|
-
* `,
|
|
34
|
-
* })
|
|
35
|
-
* export class PaginationComponent {
|
|
36
|
-
* readonly table = injectTableContext()
|
|
37
|
-
*
|
|
38
|
-
* prev() {
|
|
39
|
-
* this.table().previousPage()
|
|
40
|
-
* }
|
|
41
|
-
* next() {
|
|
42
|
-
* this.table().nextPage()
|
|
43
|
-
* }
|
|
44
|
-
* }
|
|
45
|
-
* ```
|
|
46
|
-
*/
|
|
47
|
-
class TanStackTable {
|
|
48
|
-
/**
|
|
49
|
-
* The current TanStack Table instance.
|
|
50
|
-
*
|
|
51
|
-
* Provided as a required signal input so DI consumers always read the latest value.
|
|
52
|
-
*/
|
|
53
|
-
table = input.required({ ...(ngDevMode ? { debugName: "table" } : /* istanbul ignore next */ {}), alias: 'tanStackTable' });
|
|
54
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TanStackTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
55
|
-
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: TanStackTable, isStandalone: true, selector: "[tanStackTable]", inputs: { table: { classPropertyName: "table", publicName: "tanStackTable", isSignal: true, isRequired: true, transformFunction: null } }, providers: [
|
|
56
|
-
{
|
|
57
|
-
provide: TanStackTableToken,
|
|
58
|
-
useFactory: () => inject(TanStackTable).table,
|
|
59
|
-
},
|
|
60
|
-
], exportAs: ["table"], ngImport: i0 });
|
|
61
|
-
}
|
|
62
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TanStackTable, decorators: [{
|
|
63
|
-
type: Directive,
|
|
64
|
-
args: [{
|
|
65
|
-
selector: '[tanStackTable]',
|
|
66
|
-
exportAs: 'table',
|
|
67
|
-
providers: [
|
|
68
|
-
{
|
|
69
|
-
provide: TanStackTableToken,
|
|
70
|
-
useFactory: () => inject(TanStackTable).table,
|
|
71
|
-
},
|
|
72
|
-
],
|
|
73
|
-
}]
|
|
74
|
-
}], propDecorators: { table: [{ type: i0.Input, args: [{ isSignal: true, alias: "tanStackTable", required: true }] }] } });
|
|
75
|
-
/**
|
|
76
|
-
* Injects the current TanStack Table instance signal.
|
|
77
|
-
*
|
|
78
|
-
* Available when:
|
|
79
|
-
* - there is a nearest `[tanStackTable]` directive in the DI tree, or
|
|
80
|
-
* - the caller is rendered via `*flexRender` with render props containing `table`
|
|
81
|
-
*/
|
|
82
|
-
function injectTableContext() {
|
|
83
|
-
return inject(TanStackTableToken);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
7
|
/**
|
|
87
8
|
* Injection token that provides access to the current cell.
|
|
88
9
|
*
|
|
@@ -242,6 +163,85 @@ function injectTableHeaderContext() {
|
|
|
242
163
|
return inject(TanStackTableHeaderToken);
|
|
243
164
|
}
|
|
244
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Injection token that provides access to the current {@link AngularTable} instance.
|
|
168
|
+
*
|
|
169
|
+
* This token is provided by the {@link TanStackTable} directive.
|
|
170
|
+
*/
|
|
171
|
+
const TanStackTableToken = new InjectionToken('[TanStack Table] Table Context');
|
|
172
|
+
/**
|
|
173
|
+
* Provides a TanStack Table instance (`AngularTable`) in Angular DI.
|
|
174
|
+
*
|
|
175
|
+
* The table can be injected by:
|
|
176
|
+
* - any descendant of an element using `[tanStackTable]="..."`
|
|
177
|
+
* - any component instantiated by `*flexRender` when the render props contains `table`
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```html
|
|
181
|
+
* <div [tanStackTable]="table">
|
|
182
|
+
* <app-pagination />
|
|
183
|
+
* </div>
|
|
184
|
+
* ```
|
|
185
|
+
*
|
|
186
|
+
* ```ts
|
|
187
|
+
* @Component({
|
|
188
|
+
* selector: 'app-pagination',
|
|
189
|
+
* template: `
|
|
190
|
+
* <button (click)="prev()" [disabled]="!table().getCanPreviousPage()">Prev</button>
|
|
191
|
+
* <button (click)="next()" [disabled]="!table().getCanNextPage()">Next</button>
|
|
192
|
+
* `,
|
|
193
|
+
* })
|
|
194
|
+
* export class PaginationComponent {
|
|
195
|
+
* readonly table = injectTableContext()
|
|
196
|
+
*
|
|
197
|
+
* prev() {
|
|
198
|
+
* this.table().previousPage()
|
|
199
|
+
* }
|
|
200
|
+
* next() {
|
|
201
|
+
* this.table().nextPage()
|
|
202
|
+
* }
|
|
203
|
+
* }
|
|
204
|
+
* ```
|
|
205
|
+
*/
|
|
206
|
+
class TanStackTable {
|
|
207
|
+
/**
|
|
208
|
+
* The current TanStack Table instance.
|
|
209
|
+
*
|
|
210
|
+
* Provided as a required signal input so DI consumers always read the latest value.
|
|
211
|
+
*/
|
|
212
|
+
table = input.required({ ...(ngDevMode ? { debugName: "table" } : /* istanbul ignore next */ {}), alias: 'tanStackTable' });
|
|
213
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TanStackTable, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
214
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.7", type: TanStackTable, isStandalone: true, selector: "[tanStackTable]", inputs: { table: { classPropertyName: "table", publicName: "tanStackTable", isSignal: true, isRequired: true, transformFunction: null } }, providers: [
|
|
215
|
+
{
|
|
216
|
+
provide: TanStackTableToken,
|
|
217
|
+
useFactory: () => inject(TanStackTable).table,
|
|
218
|
+
},
|
|
219
|
+
], exportAs: ["table"], ngImport: i0 });
|
|
220
|
+
}
|
|
221
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.7", ngImport: i0, type: TanStackTable, decorators: [{
|
|
222
|
+
type: Directive,
|
|
223
|
+
args: [{
|
|
224
|
+
selector: '[tanStackTable]',
|
|
225
|
+
exportAs: 'table',
|
|
226
|
+
providers: [
|
|
227
|
+
{
|
|
228
|
+
provide: TanStackTableToken,
|
|
229
|
+
useFactory: () => inject(TanStackTable).table,
|
|
230
|
+
},
|
|
231
|
+
],
|
|
232
|
+
}]
|
|
233
|
+
}], propDecorators: { table: [{ type: i0.Input, args: [{ isSignal: true, alias: "tanStackTable", required: true }] }] } });
|
|
234
|
+
/**
|
|
235
|
+
* Injects the current TanStack Table instance signal.
|
|
236
|
+
*
|
|
237
|
+
* Available when:
|
|
238
|
+
* - there is a nearest `[tanStackTable]` directive in the DI tree, or
|
|
239
|
+
* - the caller is rendered via `*flexRender` with render props containing `table`
|
|
240
|
+
*/
|
|
241
|
+
function injectTableContext() {
|
|
242
|
+
return inject(TanStackTableToken);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
245
|
const FlexRenderComponentProps = new InjectionToken('[@tanstack/angular-table] Flex render component context props');
|
|
246
246
|
/**
|
|
247
247
|
* Inject the flex render context props.
|
|
@@ -354,112 +354,6 @@ class FlexRenderComponentInstance {
|
|
|
354
354
|
}
|
|
355
355
|
}
|
|
356
356
|
|
|
357
|
-
function mapToFlexRenderTypedContent(content) {
|
|
358
|
-
if (content === null || content === undefined) {
|
|
359
|
-
return { kind: 'null' };
|
|
360
|
-
}
|
|
361
|
-
if (typeof content === 'string' || typeof content === 'number') {
|
|
362
|
-
return { kind: 'primitive', content };
|
|
363
|
-
}
|
|
364
|
-
if (content instanceof FlexRenderComponentInstance) {
|
|
365
|
-
return { kind: 'flexRenderComponent', content };
|
|
366
|
-
}
|
|
367
|
-
else if (content instanceof TemplateRef) {
|
|
368
|
-
return { kind: 'templateRef', content };
|
|
369
|
-
}
|
|
370
|
-
else if (content instanceof Type) {
|
|
371
|
-
return { kind: 'component', content };
|
|
372
|
-
}
|
|
373
|
-
else {
|
|
374
|
-
return { kind: 'primitive', content };
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
class FlexRenderView {
|
|
378
|
-
view;
|
|
379
|
-
#previousContent;
|
|
380
|
-
#content;
|
|
381
|
-
constructor(initialContent, view) {
|
|
382
|
-
this.#content = initialContent;
|
|
383
|
-
this.view = view;
|
|
384
|
-
}
|
|
385
|
-
get previousContent() {
|
|
386
|
-
return this.#previousContent ?? { kind: 'null' };
|
|
387
|
-
}
|
|
388
|
-
get content() {
|
|
389
|
-
return this.#content;
|
|
390
|
-
}
|
|
391
|
-
set content(content) {
|
|
392
|
-
this.#previousContent = this.#content;
|
|
393
|
-
this.#content = content;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
class FlexRenderTemplateView extends FlexRenderView {
|
|
397
|
-
constructor(initialContent, view) {
|
|
398
|
-
super(initialContent, view);
|
|
399
|
-
}
|
|
400
|
-
updateProps(props) {
|
|
401
|
-
this.view.markForCheck();
|
|
402
|
-
}
|
|
403
|
-
dirtyCheck() {
|
|
404
|
-
// Basically a no-op. When the view is created via EmbeddedViewRef, we don't need to do any manual update
|
|
405
|
-
// since this type of content has a proxy as a context, then every time the root component is checked for changes,
|
|
406
|
-
// the property getter will be re-evaluated.
|
|
407
|
-
//
|
|
408
|
-
// If in a future we need to manually mark the view as dirty, just uncomment next line
|
|
409
|
-
// this.view.markForCheck()
|
|
410
|
-
}
|
|
411
|
-
unmount() {
|
|
412
|
-
this.view.destroy();
|
|
413
|
-
}
|
|
414
|
-
onDestroy(callback) {
|
|
415
|
-
this.view.onDestroy(callback);
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
class FlexRenderComponentView extends FlexRenderView {
|
|
419
|
-
constructor(initialContent, view) {
|
|
420
|
-
super(initialContent, view);
|
|
421
|
-
}
|
|
422
|
-
updateProps(props) {
|
|
423
|
-
switch (this.content.kind) {
|
|
424
|
-
case 'component': {
|
|
425
|
-
this.view.setInputs(props);
|
|
426
|
-
break;
|
|
427
|
-
}
|
|
428
|
-
case 'flexRenderComponent': {
|
|
429
|
-
// No-op. When FlexRenderFlags.PropsReferenceChanged is set,
|
|
430
|
-
// FlexRenderComponent will be updated into `dirtyCheck`.
|
|
431
|
-
break;
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
dirtyCheck() {
|
|
436
|
-
switch (this.content.kind) {
|
|
437
|
-
case 'component': {
|
|
438
|
-
// Component context is currently valuated with the cell context. Since it's reference
|
|
439
|
-
// shouldn't change, we force mark the component as dirty in order to re-evaluate function invocation in view.
|
|
440
|
-
// NOTE: this should behave like having a component with ChangeDetectionStrategy.Default
|
|
441
|
-
this.view.markAsDirty();
|
|
442
|
-
break;
|
|
443
|
-
}
|
|
444
|
-
case 'flexRenderComponent': {
|
|
445
|
-
// Given context instance will always have a different reference than the previous one,
|
|
446
|
-
// so instead of recreating the entire view, we will only update the current view
|
|
447
|
-
if (this.view.eqType(this.content.content)) {
|
|
448
|
-
this.view.update(this.content.content);
|
|
449
|
-
}
|
|
450
|
-
this.view.markAsDirty();
|
|
451
|
-
break;
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
unmount() {
|
|
456
|
-
this.view.componentRef.destroy();
|
|
457
|
-
}
|
|
458
|
-
onDestroy(callback) {
|
|
459
|
-
this.view.componentRef.onDestroy(callback);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
357
|
class FlexRenderComponentFactory {
|
|
464
358
|
#viewContainerRef;
|
|
465
359
|
constructor(viewContainerRef) {
|
|
@@ -636,6 +530,128 @@ class FlexRenderComponentOutputManager {
|
|
|
636
530
|
}
|
|
637
531
|
}
|
|
638
532
|
|
|
533
|
+
function mapToFlexRenderTypedContent(content) {
|
|
534
|
+
if (content === null || content === undefined) {
|
|
535
|
+
return { kind: 'null' };
|
|
536
|
+
}
|
|
537
|
+
if (typeof content === 'string' || typeof content === 'number') {
|
|
538
|
+
return { kind: 'primitive', content };
|
|
539
|
+
}
|
|
540
|
+
if (content instanceof FlexRenderComponentInstance) {
|
|
541
|
+
return { kind: 'flexRenderComponent', content };
|
|
542
|
+
}
|
|
543
|
+
else if (content instanceof TemplateRef) {
|
|
544
|
+
return { kind: 'templateRef', content };
|
|
545
|
+
}
|
|
546
|
+
else if (content instanceof Type) {
|
|
547
|
+
return { kind: 'component', content };
|
|
548
|
+
}
|
|
549
|
+
else {
|
|
550
|
+
return { kind: 'primitive', content };
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
class FlexRenderView {
|
|
554
|
+
view;
|
|
555
|
+
#previousContent;
|
|
556
|
+
#content;
|
|
557
|
+
constructor(initialContent, view) {
|
|
558
|
+
this.#content = initialContent;
|
|
559
|
+
this.view = view;
|
|
560
|
+
}
|
|
561
|
+
get previousContent() {
|
|
562
|
+
return this.#previousContent ?? { kind: 'null' };
|
|
563
|
+
}
|
|
564
|
+
get content() {
|
|
565
|
+
return this.#content;
|
|
566
|
+
}
|
|
567
|
+
set content(content) {
|
|
568
|
+
this.#previousContent = this.#content;
|
|
569
|
+
this.#content = content;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
class FlexRenderTemplateView extends FlexRenderView {
|
|
573
|
+
constructor(initialContent, view) {
|
|
574
|
+
super(initialContent, view);
|
|
575
|
+
}
|
|
576
|
+
updateProps(props) {
|
|
577
|
+
this.view.markForCheck();
|
|
578
|
+
}
|
|
579
|
+
dirtyCheck() {
|
|
580
|
+
// Basically a no-op. When the view is created via EmbeddedViewRef, we don't need to do any manual update
|
|
581
|
+
// since this type of content has a proxy as a context, then every time the root component is checked for changes,
|
|
582
|
+
// the property getter will be re-evaluated.
|
|
583
|
+
//
|
|
584
|
+
// If in a future we need to manually mark the view as dirty, just uncomment next line
|
|
585
|
+
// this.view.markForCheck()
|
|
586
|
+
}
|
|
587
|
+
unmount() {
|
|
588
|
+
this.view.destroy();
|
|
589
|
+
}
|
|
590
|
+
onDestroy(callback) {
|
|
591
|
+
this.view.onDestroy(callback);
|
|
592
|
+
}
|
|
593
|
+
eq(compare) {
|
|
594
|
+
return ((this.content.kind === 'primitive' &&
|
|
595
|
+
compare.kind === 'primitive' &&
|
|
596
|
+
this.content.content === compare.content) ||
|
|
597
|
+
(this.content.kind === 'templateRef' &&
|
|
598
|
+
compare.kind === 'templateRef' &&
|
|
599
|
+
this.content.content === compare.content));
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
class FlexRenderComponentView extends FlexRenderView {
|
|
603
|
+
constructor(initialContent, view) {
|
|
604
|
+
super(initialContent, view);
|
|
605
|
+
}
|
|
606
|
+
updateProps(props) {
|
|
607
|
+
switch (this.content.kind) {
|
|
608
|
+
case 'component': {
|
|
609
|
+
this.view.setInputs(props);
|
|
610
|
+
break;
|
|
611
|
+
}
|
|
612
|
+
case 'flexRenderComponent': {
|
|
613
|
+
// No-op. When FlexRenderFlags.PropsReferenceChanged is set,
|
|
614
|
+
// FlexRenderComponent will be updated into `dirtyCheck`.
|
|
615
|
+
break;
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
dirtyCheck() {
|
|
620
|
+
switch (this.content.kind) {
|
|
621
|
+
case 'component': {
|
|
622
|
+
// Component context is currently valuated with the cell context. Since it's reference
|
|
623
|
+
// shouldn't change, we force mark the component as dirty in order to re-evaluate function invocation in view.
|
|
624
|
+
// NOTE: this should behave like having a component with ChangeDetectionStrategy.Default
|
|
625
|
+
this.view.markAsDirty();
|
|
626
|
+
break;
|
|
627
|
+
}
|
|
628
|
+
case 'flexRenderComponent': {
|
|
629
|
+
// Given context instance will always have a different reference than the previous one,
|
|
630
|
+
// so instead of recreating the entire view, we will only update the current view
|
|
631
|
+
if (this.view.eqType(this.content.content)) {
|
|
632
|
+
this.view.update(this.content.content);
|
|
633
|
+
}
|
|
634
|
+
this.view.markAsDirty();
|
|
635
|
+
break;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
unmount() {
|
|
640
|
+
this.view.componentRef.destroy();
|
|
641
|
+
}
|
|
642
|
+
onDestroy(callback) {
|
|
643
|
+
this.view.componentRef.onDestroy(callback);
|
|
644
|
+
}
|
|
645
|
+
eq(compare) {
|
|
646
|
+
return ((this.content.kind === 'component' &&
|
|
647
|
+
compare.kind === 'component' &&
|
|
648
|
+
this.content.content === compare.content) ||
|
|
649
|
+
(this.content.kind === 'flexRenderComponent' &&
|
|
650
|
+
compare.kind === 'flexRenderComponent' &&
|
|
651
|
+
this.content.content.component === compare.content.component));
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
639
655
|
/**
|
|
640
656
|
* Internal view renderer used by Angular TanStack Table to implement `flexRender` directives.
|
|
641
657
|
*
|
|
@@ -766,11 +782,12 @@ class FlexViewRenderer {
|
|
|
766
782
|
this.#renderFlags |= FlexRenderFlags.ContentChanged;
|
|
767
783
|
}
|
|
768
784
|
else {
|
|
769
|
-
this.#renderView.content
|
|
770
|
-
|
|
771
|
-
|
|
785
|
+
const { kind: currentKind } = this.#renderView.content;
|
|
786
|
+
if (latestContent.kind !== currentKind ||
|
|
787
|
+
!this.#renderView.eq(latestContent)) {
|
|
772
788
|
this.#renderFlags |= FlexRenderFlags.ContentChanged;
|
|
773
789
|
}
|
|
790
|
+
this.#renderView.content = latestContent;
|
|
774
791
|
}
|
|
775
792
|
this.#update();
|
|
776
793
|
}
|