-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Expand file tree
/
Copy pathflexRender.ts
More file actions
124 lines (115 loc) · 2.71 KB
/
flexRender.ts
File metadata and controls
124 lines (115 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import {
DestroyRef,
Directive,
Injector,
InputSignal,
TemplateRef,
ViewContainerRef,
inject,
input,
} from '@angular/core'
import {
FlexRenderInputContent,
FlexViewRenderer,
} from './flex-render/renderer'
import type {
CellContext,
CellData,
HeaderContext,
RowData,
TableFeatures,
} from '@tanstack/table-core'
export {
injectFlexRenderContext,
type FlexRenderComponentProps,
} from './flex-render/context'
export type {
FlexRenderInputContent,
FlexRenderContent,
} from './flex-render/renderer'
/**
* 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} import,
* which the latter is preferred.
*/
@Directive({
selector: 'ng-template[flexRender]',
})
export class FlexRenderDirective<
TFeatures extends TableFeatures,
TRowData extends RowData,
TValue extends CellData,
TProps extends
| NonNullable<unknown>
| CellContext<TFeatures, TRowData, TValue>
| HeaderContext<TFeatures, TRowData, TValue>,
> {
readonly content: InputSignal<FlexRenderInputContent<TProps>> = input(
undefined as FlexRenderInputContent<TProps>,
{ alias: 'flexRender' },
)
readonly props = input<TProps>({} as TProps, {
alias: 'flexRenderProps',
})
readonly injector = input(inject(Injector), {
alias: 'flexRenderInjector',
})
readonly #viewContainerRef = inject(ViewContainerRef)
readonly #templateRef = inject(TemplateRef)
constructor() {
const renderer = new FlexViewRenderer({
content: this.content,
props: this.props,
injector: this.injector,
templateRef: this.#templateRef,
viewContainerRef: this.#viewContainerRef,
})
renderer.mount()
inject(DestroyRef).onDestroy(() => {
renderer.destroy()
})
}
}