@taiga-ui/addon-table 4.52.0-canary.2c75afa → 4.52.0-canary.2d877cf

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.
Files changed (34) hide show
  1. package/README.md +2 -2
  2. package/components/reorder/reorder.component.d.ts +6 -9
  3. package/components/reorder/reorder.options.d.ts +1 -3
  4. package/components/table/directives/cell.directive.d.ts +2 -2
  5. package/components/table/directives/direction-order.directive.d.ts +5 -3
  6. package/components/table/directives/head.directive.d.ts +2 -2
  7. package/components/table/directives/resized.directive.d.ts +2 -1
  8. package/components/table/directives/sort-by.directive.d.ts +10 -6
  9. package/components/table/directives/sortable.directive.d.ts +5 -7
  10. package/components/table/directives/table.directive.d.ts +14 -10
  11. package/components/table/pipes/table-sort.pipe.d.ts +4 -4
  12. package/components/table/table-expand/table-expand.component.d.ts +4 -6
  13. package/components/table/table.options.d.ts +1 -3
  14. package/components/table/tbody/tbody.component.d.ts +5 -8
  15. package/components/table/td/td.component.d.ts +3 -2
  16. package/components/table/th/th.component.d.ts +7 -7
  17. package/components/table/th-group/th-group.component.d.ts +4 -7
  18. package/components/table/tr/tr.component.d.ts +2 -0
  19. package/components/table-pagination/table-pagination.component.d.ts +11 -14
  20. package/components/table-pagination/table-pagination.options.d.ts +1 -3
  21. package/directives/table-control/checkbox-row.directive.d.ts +2 -2
  22. package/directives/table-filters/generic-filter.directive.d.ts +2 -1
  23. package/directives/table-filters/table-filter.directive.d.ts +3 -3
  24. package/fesm2022/taiga-ui-addon-table-components-reorder.mjs +33 -46
  25. package/fesm2022/taiga-ui-addon-table-components-reorder.mjs.map +1 -1
  26. package/fesm2022/taiga-ui-addon-table-components-table-pagination.mjs +35 -59
  27. package/fesm2022/taiga-ui-addon-table-components-table-pagination.mjs.map +1 -1
  28. package/fesm2022/taiga-ui-addon-table-components-table.mjs +180 -261
  29. package/fesm2022/taiga-ui-addon-table-components-table.mjs.map +1 -1
  30. package/fesm2022/taiga-ui-addon-table-directives-table-control.mjs +18 -18
  31. package/fesm2022/taiga-ui-addon-table-directives-table-control.mjs.map +1 -1
  32. package/fesm2022/taiga-ui-addon-table-directives-table-filters.mjs +23 -28
  33. package/fesm2022/taiga-ui-addon-table-directives-table-filters.mjs.map +1 -1
  34. package/package.json +5 -5
@@ -1,17 +1,18 @@
1
1
  import * as i0 from '@angular/core';
2
- import { ChangeDetectionStrategy, ViewEncapsulation, Component, inject, TemplateRef, Input, Directive, InjectionToken, ChangeDetectorRef, EventEmitter, signal, Output, forwardRef, ContentChildren, Pipe, SkipSelf, PLATFORM_ID, computed, ViewChild, ContentChild } from '@angular/core';
3
- import { map, distinctUntilChanged, catchError, EMPTY, combineLatest, debounceTime, Subject, switchMap, takeUntil, delay, filter, timer, of, ReplaySubject, startWith } from 'rxjs';
4
- import { tuiProvideOptions, tuiWithStyles, tuiProvide, tuiDefaultSort, tuiPure } from '@taiga-ui/cdk/utils/miscellaneous';
2
+ import { ChangeDetectionStrategy, ViewEncapsulation, Component, input, inject, TemplateRef, Directive, ChangeDetectorRef, output, signal, Input, effect, forwardRef, untracked, computed, contentChildren, Pipe, SkipSelf, viewChild, PLATFORM_ID, model, contentChild } from '@angular/core';
3
+ import { toSignal, outputToObservable, outputFromObservable, takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
4
+ import { tuiWithStyles, tuiSetSignal, tuiDefaultSort, tuiPure } from '@taiga-ui/cdk/utils/miscellaneous';
5
+ import { map, distinctUntilChanged, catchError, EMPTY, combineLatest, debounceTime, Subject, switchMap, takeUntil, delay, filter, timer, of, ReplaySubject } from 'rxjs';
6
+ import { tuiCreateOptions, tuiProvide } from '@taiga-ui/cdk/utils/di';
5
7
  import { IntersectionObserverService, WA_INTERSECTION_THRESHOLD, WA_INTERSECTION_ROOT_MARGIN } from '@ng-web-apis/intersection-observer';
6
8
  import { tuiButtonOptionsProvider } from '@taiga-ui/core/components/button';
7
9
  import { TUI_TEXTFIELD_OPTIONS, TuiTextfieldComponent } from '@taiga-ui/core/components/textfield';
8
10
  import { tuiBadgeOptionsProvider } from '@taiga-ui/kit/components/badge';
9
11
  import { tuiChipOptionsProvider } from '@taiga-ui/kit/components/chip';
10
12
  import { tuiProgressOptionsProvider } from '@taiga-ui/kit/components/progress';
11
- import { toSignal, takeUntilDestroyed } from '@angular/core/rxjs-interop';
12
- import { tuiWatch, tuiTypedFromEvent, tuiPreventDefault, tuiZoneOptimized, tuiQueryListChanges } from '@taiga-ui/cdk/observables';
13
+ import { tuiWatch, tuiTypedFromEvent, tuiPreventDefault, tuiZoneOptimized } from '@taiga-ui/cdk/observables';
13
14
  import { DOCUMENT, AsyncPipe, NgTemplateOutlet, isPlatformServer } from '@angular/common';
14
- import { EMPTY_CLIENT_RECT, EMPTY_QUERY } from '@taiga-ui/cdk/constants';
15
+ import { EMPTY_CLIENT_RECT } from '@taiga-ui/cdk/constants';
15
16
  import { tuiInjectElement } from '@taiga-ui/cdk/utils/dom';
16
17
  import { coerceBooleanProperty } from '@angular/cdk/coercion';
17
18
  import { TuiIcon } from '@taiga-ui/core/components/icon';
@@ -24,30 +25,28 @@ import { ResizeObserverService } from '@ng-web-apis/resize-observer';
24
25
  import { TuiControl } from '@taiga-ui/cdk/classes';
25
26
 
26
27
  class TuiTableCaption {
27
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableCaption, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
28
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableCaption, isStandalone: true, selector: "caption[tuiCaption]", ngImport: i0, template: '<ng-content/>', isInline: true, styles: ["caption[tuiCaption]{caption-side:bottom;text-align:start;padding:.75rem 0;color:var(--tui-text-secondary)}caption[tuiCaption]>*:not(:first-child){margin-inline-start:.5rem}caption[tuiCaption] tui-pagination:not(:first-child),caption[tuiCaption] tui-pager:not(:first-child){display:inline-flex;vertical-align:middle}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
28
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableCaption, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
29
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: TuiTableCaption, isStandalone: true, selector: "caption[tuiCaption]", ngImport: i0, template: '<ng-content/>', isInline: true, styles: ["caption[tuiCaption]{caption-side:bottom;text-align:start;padding:.75rem 0;color:var(--tui-text-secondary)}caption[tuiCaption]>*:not(:first-child){margin-inline-start:.5rem}caption[tuiCaption] tui-pagination:not(:first-child),caption[tuiCaption] tui-pager:not(:first-child){display:inline-flex;vertical-align:middle}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
29
30
  }
30
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableCaption, decorators: [{
31
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableCaption, decorators: [{
31
32
  type: Component,
32
33
  args: [{ selector: 'caption[tuiCaption]', template: '<ng-content/>', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, styles: ["caption[tuiCaption]{caption-side:bottom;text-align:start;padding:.75rem 0;color:var(--tui-text-secondary)}caption[tuiCaption]>*:not(:first-child){margin-inline-start:.5rem}caption[tuiCaption] tui-pagination:not(:first-child),caption[tuiCaption] tui-pager:not(:first-child){display:inline-flex;vertical-align:middle}\n"] }]
33
34
  }] });
34
35
 
35
36
  class TuiTableCell {
36
37
  constructor() {
37
- this.tuiCell = '';
38
+ this.tuiCell = input('');
38
39
  this.template = inject((TemplateRef));
39
40
  }
40
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableCell, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
41
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableCell, isStandalone: true, selector: "ng-template[tuiCell]", inputs: { tuiCell: "tuiCell" }, ngImport: i0 }); }
41
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableCell, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
42
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.17", type: TuiTableCell, isStandalone: true, selector: "ng-template[tuiCell]", inputs: { tuiCell: { classPropertyName: "tuiCell", publicName: "tuiCell", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
42
43
  }
43
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableCell, decorators: [{
44
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableCell, decorators: [{
44
45
  type: Directive,
45
46
  args: [{
46
47
  selector: 'ng-template[tuiCell]',
47
48
  }]
48
- }], propDecorators: { tuiCell: [{
49
- type: Input
50
- }] } });
49
+ }] });
51
50
 
52
51
  const TuiSortDirection = {
53
52
  Asc: 1,
@@ -66,20 +65,15 @@ const TUI_TABLE_DEFAULT_OPTIONS = {
66
65
  off: '@tui.chevrons-up-down',
67
66
  },
68
67
  };
69
- const TUI_TABLE_OPTIONS = new InjectionToken(ngDevMode ? 'TUI_TABLE_OPTIONS' : '', {
70
- factory: () => TUI_TABLE_DEFAULT_OPTIONS,
71
- });
72
- function tuiTableOptionsProvider(options) {
73
- return tuiProvideOptions(TUI_TABLE_OPTIONS, options, TUI_TABLE_DEFAULT_OPTIONS);
74
- }
68
+ const [TUI_TABLE_OPTIONS, tuiTableOptionsProvider] = tuiCreateOptions(TUI_TABLE_DEFAULT_OPTIONS);
75
69
 
76
70
  // TODO: Consider making universal and moving to CDK
77
71
  class TuiStuck {
78
72
  constructor() {
79
73
  this.stuck = toSignal(inject(IntersectionObserverService).pipe(map((entries) => (entries[entries.length - 1]?.intersectionRatio ?? 0) < 1), distinctUntilChanged(), tuiWatch(), catchError(() => EMPTY)));
80
74
  }
81
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiStuck, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
82
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiStuck, isStandalone: true, selector: "tui-stuck:never", host: { properties: { "class._stuck": "stuck()" } }, providers: [
75
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiStuck, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
76
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.17", type: TuiStuck, isStandalone: true, selector: "tui-stuck:never", host: { properties: { "class._stuck": "stuck()" } }, providers: [
83
77
  IntersectionObserverService,
84
78
  {
85
79
  provide: WA_INTERSECTION_THRESHOLD,
@@ -87,7 +81,7 @@ class TuiStuck {
87
81
  },
88
82
  ], ngImport: i0 }); }
89
83
  }
90
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiStuck, decorators: [{
84
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiStuck, decorators: [{
91
85
  type: Directive,
92
86
  args: [{
93
87
  selector: 'tui-stuck:never',
@@ -104,10 +98,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
104
98
 
105
99
  const EMPTY_COMPARATOR = () => 0;
106
100
  class Styles {
107
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: Styles, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
108
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: Styles, isStandalone: true, selector: "ng-component", host: { classAttribute: "tui-table" }, ngImport: i0, template: '', isInline: true, styles: ["table[tuiTable]{border-collapse:separate;border-spacing:0}table[tuiTable] [tuiCell]{padding:0}table[tuiTable] [tuiTitle]{white-space:nowrap}table[tuiTable] [tuiTitle] tui-icon{font-size:1rem}table[tuiTable] [tuiSubtitle]{color:var(--tui-text-secondary)}table[tuiTable] [tuiTh] [tuiCell],table[tuiTable] [tuiTh] [tuiTitle]{font:inherit;color:inherit}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
101
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: Styles, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
102
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: Styles, isStandalone: true, selector: "ng-component", host: { classAttribute: "tui-table" }, ngImport: i0, template: '', isInline: true, styles: ["table[tuiTable]{border-collapse:separate;border-spacing:0}table[tuiTable] [tuiCell]{padding:0}table[tuiTable] [tuiTitle]{white-space:nowrap}table[tuiTable] [tuiTitle] tui-icon{font-size:1rem}table[tuiTable] [tuiSubtitle]{color:var(--tui-text-secondary)}table[tuiTable] [tuiTh] [tuiCell],table[tuiTable] [tuiTh] [tuiTitle]{font:inherit;color:inherit}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
109
103
  }
110
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: Styles, decorators: [{
104
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: Styles, decorators: [{
111
105
  type: Component,
112
106
  args: [{ template: '', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, host: { class: 'tui-table' }, styles: ["table[tuiTable]{border-collapse:separate;border-spacing:0}table[tuiTable] [tuiCell]{padding:0}table[tuiTable] [tuiTitle]{white-space:nowrap}table[tuiTable] [tuiTitle] tui-icon{font-size:1rem}table[tuiTable] [tuiSubtitle]{color:var(--tui-text-secondary)}table[tuiTable] [tuiTh] [tuiCell],table[tuiTable] [tuiTh] [tuiTitle]{font:inherit;color:inherit}\n"] }]
113
107
  }] });
@@ -116,38 +110,41 @@ class TuiTableDirective {
116
110
  this.options = inject(TUI_TABLE_OPTIONS);
117
111
  this.cdr = inject(ChangeDetectorRef);
118
112
  this.nothing = tuiWithStyles(Styles);
119
- this.columns = [];
120
- this.direction = this.options.direction;
113
+ this.columns = input([]);
114
+ this.direction = input(this.options.direction);
121
115
  this.sorter = EMPTY_COMPARATOR;
122
116
  /**
123
117
  * @deprecated: use sortChange
124
118
  */
125
- this.directionChange = new EventEmitter();
119
+ this.directionChange = output();
126
120
  /**
127
121
  * @deprecated: use sortChange
128
122
  */
129
- this.sorterChange = new EventEmitter();
130
- this.sortChange = combineLatest([
131
- this.sorterChange,
132
- this.directionChange,
123
+ this.directionChange$ = outputToObservable(this.directionChange);
124
+ /**
125
+ * @deprecated: use sortChange
126
+ */
127
+ this.sorterChange = output();
128
+ this.sorterChange$ = outputToObservable(this.sorterChange);
129
+ this.sortChange$ = combineLatest([
130
+ this.sorterChange$,
131
+ this.directionChange$,
133
132
  ]).pipe(debounceTime(0), map(([sortComparator, sortDirection]) => ({
134
133
  sortBy: sortComparator,
135
134
  orderBy: sortDirection,
136
135
  sortComparator,
137
136
  sortDirection,
138
137
  })));
138
+ this.sortChange = outputFromObservable(this.sortChange$);
139
139
  this.appearance = signal('table');
140
- this.size = signal(this.options.size);
140
+ this.size = input(this.options.size);
141
141
  this.cleaner = signal(false);
142
142
  // TODO: refactor to signal inputs after Angular update
143
143
  this.change$ = new Subject();
144
144
  }
145
- set sizeSetter(size) {
146
- this.size.set(size);
147
- }
148
145
  updateSorterAndDirection(sorter) {
149
146
  if (this.sorter === sorter) {
150
- this.updateSorter(this.sorter, this.direction === TuiSortDirection.Asc
147
+ this.updateSorter(this.sorter, this.direction() === TuiSortDirection.Asc
151
148
  ? TuiSortDirection.Desc
152
149
  : TuiSortDirection.Asc);
153
150
  }
@@ -163,13 +160,13 @@ class TuiTableDirective {
163
160
  }
164
161
  updateSorter(sorter, direction = TuiSortDirection.Asc) {
165
162
  this.sorter = sorter || EMPTY_COMPARATOR.bind({});
166
- this.direction = direction;
163
+ tuiSetSignal(this.direction, direction);
167
164
  this.sorterChange.emit(sorter);
168
- this.directionChange.emit(this.direction);
165
+ this.directionChange.emit(this.direction());
169
166
  this.change$.next();
170
167
  }
171
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
172
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableDirective, isStandalone: true, selector: "table[tuiTable]", inputs: { columns: "columns", direction: "direction", sorter: "sorter", sizeSetter: ["size", "sizeSetter"] }, outputs: { directionChange: "directionChange", sorterChange: "sorterChange", sortChange: "sortChange" }, host: { properties: { "attr.data-size": "size()" } }, providers: [
168
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
169
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.17", type: TuiTableDirective, isStandalone: true, selector: "table[tuiTable]", inputs: { columns: { classPropertyName: "columns", publicName: "columns", isSignal: true, isRequired: false, transformFunction: null }, direction: { classPropertyName: "direction", publicName: "direction", isSignal: true, isRequired: false, transformFunction: null }, sorter: { classPropertyName: "sorter", publicName: "sorter", isSignal: false, isRequired: false, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { directionChange: "directionChange", sorterChange: "sorterChange", sortChange: "sortChange" }, host: { attributes: { "tuiTable": "" }, properties: { "attr.data-size": "size()" } }, providers: [
173
170
  {
174
171
  provide: WA_INTERSECTION_ROOT_MARGIN,
175
172
  useValue: '10000px 10000px 10000px 0px',
@@ -181,7 +178,7 @@ class TuiTableDirective {
181
178
  tuiProgressOptionsProvider({ size: 's', color: 'var(--tui-text-action)' }),
182
179
  ], usesOnChanges: true, hostDirectives: [{ directive: TuiStuck }], ngImport: i0 }); }
183
180
  }
184
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableDirective, decorators: [{
181
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableDirective, decorators: [{
185
182
  type: Directive,
186
183
  args: [{
187
184
  selector: 'table[tuiTable]',
@@ -198,90 +195,71 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
198
195
  ],
199
196
  hostDirectives: [TuiStuck],
200
197
  host: {
198
+ tuiTable: '',
201
199
  '[attr.data-size]': 'size()',
202
200
  },
203
201
  }]
204
- }], propDecorators: { columns: [{
202
+ }], propDecorators: { sorter: [{
205
203
  type: Input
206
- }], direction: [{
207
- type: Input
208
- }], sorter: [{
209
- type: Input
210
- }], directionChange: [{
211
- type: Output
212
- }], sorterChange: [{
213
- type: Output
214
- }], sortChange: [{
215
- type: Output
216
- }], sizeSetter: [{
217
- type: Input,
218
- args: ['size']
219
204
  }] } });
220
205
 
221
206
  class TuiTableDirectionOrder {
222
207
  constructor() {
223
208
  this.table = inject((TuiTableDirective));
209
+ this.directionOrderChange$ = this.table.directionChange$.pipe(map((dir) => (dir === 1 ? 'asc' : 'desc')));
224
210
  /**
225
211
  * @deprecated: use tuiSortChange
226
212
  */
227
- this.directionOrderChange = this.table.directionChange.pipe(map((dir) => (dir === 1 ? 'asc' : 'desc')));
228
- }
229
- set directionOrder(order) {
230
- this.table.direction =
231
- order === 'asc' ? TuiSortDirection.Asc : TuiSortDirection.Desc;
213
+ this.directionOrderChange = outputFromObservable(this.directionOrderChange$);
214
+ this.directionOrder = input();
215
+ this.setTableDirection = effect((_, order = this.directionOrder()) => {
216
+ tuiSetSignal(this.table.direction, order === 'asc' ? TuiSortDirection.Asc : TuiSortDirection.Desc);
217
+ });
232
218
  }
233
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableDirectionOrder, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
234
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableDirectionOrder, isStandalone: true, selector: "table[tuiTable][tuiDirectionOrder]", inputs: { directionOrder: "directionOrder" }, outputs: { directionOrderChange: "directionOrderChange" }, ngImport: i0 }); }
219
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableDirectionOrder, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
220
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.17", type: TuiTableDirectionOrder, isStandalone: true, selector: "table[tuiTable][tuiDirectionOrder]", inputs: { directionOrder: { classPropertyName: "directionOrder", publicName: "directionOrder", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { directionOrderChange: "directionOrderChange" }, ngImport: i0 }); }
235
221
  }
236
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableDirectionOrder, decorators: [{
222
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableDirectionOrder, decorators: [{
237
223
  type: Directive,
238
224
  args: [{
239
225
  selector: 'table[tuiTable][tuiDirectionOrder]',
240
226
  }]
241
- }], propDecorators: { directionOrderChange: [{
242
- type: Output
243
- }], directionOrder: [{
244
- type: Input
245
- }] } });
227
+ }] });
246
228
 
247
229
  class TuiTableHead {
248
230
  constructor() {
249
- this.tuiHead = '';
231
+ this.tuiHead = input.required();
250
232
  this.template = inject((TemplateRef));
251
233
  }
252
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableHead, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
253
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableHead, isStandalone: true, selector: "[tuiHead]", inputs: { tuiHead: "tuiHead" }, ngImport: i0 }); }
234
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableHead, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
235
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.17", type: TuiTableHead, isStandalone: true, selector: "[tuiHead]", inputs: { tuiHead: { classPropertyName: "tuiHead", publicName: "tuiHead", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0 }); }
254
236
  }
255
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableHead, decorators: [{
237
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableHead, decorators: [{
256
238
  type: Directive,
257
239
  args: [{
258
240
  selector: '[tuiHead]',
259
241
  }]
260
- }], propDecorators: { tuiHead: [{
261
- type: Input,
262
- args: [{ required: true }]
263
- }] } });
242
+ }] });
264
243
 
265
244
  class TuiTableResized {
266
245
  constructor() {
267
246
  this.doc = inject(DOCUMENT);
268
247
  this.el = tuiInjectElement();
269
- this.tuiResized = tuiTypedFromEvent(this.el, 'mousedown').pipe(tuiPreventDefault(), switchMap(() => {
248
+ this.tuiResized$ = tuiTypedFromEvent(this.el, 'mousedown').pipe(tuiPreventDefault(), switchMap(() => {
270
249
  const { width, right } = this.el.closest('th')?.getBoundingClientRect() || EMPTY_CLIENT_RECT;
271
250
  return tuiTypedFromEvent(this.doc, 'mousemove').pipe(distinctUntilChanged(), map(({ clientX }) => width + clientX - right), takeUntil(tuiTypedFromEvent(this.doc, 'mouseup')));
272
251
  }));
252
+ this.tuiResized = outputFromObservable(this.tuiResized$);
273
253
  }
274
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableResized, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
275
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableResized, isStandalone: true, selector: "[tuiResized]", outputs: { tuiResized: "tuiResized" }, ngImport: i0 }); }
254
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableResized, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
255
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.17", type: TuiTableResized, isStandalone: true, selector: "[tuiResized]", outputs: { tuiResized: "tuiResized" }, ngImport: i0 }); }
276
256
  }
277
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableResized, decorators: [{
257
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableResized, decorators: [{
278
258
  type: Directive,
279
259
  args: [{
280
260
  selector: '[tuiResized]',
281
261
  }]
282
- }], propDecorators: { tuiResized: [{
283
- type: Output
284
- }] } });
262
+ }] });
285
263
 
286
264
  /// <reference types="@taiga-ui/tsconfig/ng-dev-mode" />
287
265
  class TuiTableTh {
@@ -290,67 +268,57 @@ class TuiTableTh {
290
268
  this.head = inject(TuiTableHead, {
291
269
  optional: true,
292
270
  });
293
- this.width = null;
271
+ this.width = signal(null);
294
272
  this.table = inject(forwardRef(() => TuiTableDirective), { optional: true });
295
- this.minWidth = -Infinity;
296
- this.maxWidth = Infinity;
273
+ this.minWidth = input(-Infinity);
274
+ this.maxWidth = input(Infinity);
297
275
  this.sorter = this.head
298
276
  ? (a, b) => tuiDefaultSort(a[this.key], b[this.key])
299
277
  : null;
300
- this.resizable = this.options.resizable;
301
- this.sticky = this.options.sticky;
302
- this.requiredSort = this.options.requiredSort;
278
+ this.resizable = input(this.options.resizable);
279
+ this.sticky = input(this.options.sticky);
280
+ this.requiredSort = input(this.options.requiredSort);
303
281
  }
304
282
  get key() {
305
283
  if (!this.head) {
306
284
  throw new TuiTableSortKeyException();
307
285
  }
308
- return this.head.tuiHead;
286
+ return this.head.tuiHead();
309
287
  }
310
288
  get isCurrent() {
311
289
  return !!this.sorter && !!this.table && this.sorter === this.table.sorter;
312
290
  }
313
291
  get icon() {
314
292
  if (this.isCurrent) {
315
- return this.table?.direction === TuiSortDirection.Asc
293
+ return this.table?.direction() === TuiSortDirection.Asc
316
294
  ? this.options.sortIcons.asc
317
295
  : this.options.sortIcons.desc;
318
296
  }
319
297
  return this.options.sortIcons.off;
320
298
  }
321
299
  updateSorterAndDirection() {
322
- const sorter = this.requiredSort ? this.sorter : null;
300
+ const sorter = this.requiredSort() ? this.sorter : null;
323
301
  this.table?.updateSorterAndDirection(this.isCurrentAndDescDirection ? sorter : this.sorter);
324
302
  }
325
303
  onResized(width) {
326
- this.width = Math.min(Math.max(width, this.minWidth), this.maxWidth);
304
+ this.width.set(Math.min(Math.max(width, this.minWidth()), this.maxWidth()));
327
305
  }
328
306
  get isCurrentAndDescDirection() {
329
307
  return (this.sorter === this.table?.sorter &&
330
- this.table?.direction === TuiSortDirection.Desc);
308
+ this.table?.direction() === TuiSortDirection.Desc);
331
309
  }
332
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTh, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
333
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TuiTableTh, isStandalone: true, selector: "th[tuiTh]", inputs: { minWidth: "minWidth", maxWidth: "maxWidth", sorter: "sorter", resizable: "resizable", sticky: "sticky", requiredSort: "requiredSort" }, host: { properties: { "style.min-width.px": "width || minWidth", "style.width.px": "width || minWidth", "style.max-width.px": "width || maxWidth", "class._sticky": "sticky" } }, ngImport: i0, template: "@if (sorter && table) {\n <button\n type=\"button\"\n class=\"t-sort\"\n [class.t-sort_sorted]=\"isCurrent\"\n (click)=\"updateSorterAndDirection()\"\n >\n <ng-container [ngTemplateOutlet]=\"content\" />\n {{ table.change$ | async }}\n <tui-icon\n class=\"t-icon\"\n [icon]=\"icon\"\n />\n </button>\n} @else {\n <ng-container [ngTemplateOutlet]=\"content\" />\n}\n<ng-template #content>\n <ng-content />\n</ng-template>\n@if (resizable) {\n <div\n class=\"t-bar\"\n (tuiResized)=\"onResized($event)\"\n ></div>\n}\n", styles: [":host{transition-property:box-shadow;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:relative;top:0;block-size:var(--tui-height-m);font:var(--tui-font-text-s);text-align:start;font-weight:700;color:var(--tui-text-secondary);background:var(--tui-background-base);cursor:default;padding:0 .75rem;box-sizing:border-box;box-shadow:0 .3125rem #ededed00;border:1px solid var(--tui-border-normal);filter:opacity(1)}@supports (-webkit-hyphens: none){:host{transform:translateZ(0)}}:host:not(:first-child){border-inline-start:none}:host._sticky,:host-context(._stuck) :host._sticky{position:sticky;z-index:30}:host._sticky:first-child,:host-context(._stuck) :host._sticky:first-child{left:0}:host._sticky:after,:host-context(._stuck) :host._sticky:after{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;content:\"\";position:absolute;top:0;left:100%;bottom:0;inline-size:.3125rem;pointer-events:none;background:#edededb3;opacity:0}:host-context(._stuck) :host{z-index:20}:host-context(tr:not(:first-child)){border-block-start:none}:host-context(table[data-size=\"l\"]){block-size:var(--tui-height-l);font:var(--tui-font-text-m);font-weight:700;padding:0 1rem}:host-context(table[data-size=\"s\"]){block-size:var(--tui-height-s);font:var(--tui-font-text-s);font-weight:700;padding:0 .5rem}:host-context(thead[tuiThead]){position:sticky}:host-context(table._stuck)._sticky:after{opacity:1}:host-context(thead[tuiThead]._stuck){box-shadow:0 .3125rem #edededb3}:host-context([tuiTheme=\"dark\"])._sticky:after{background:#3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck){box-shadow:0 .3125rem #3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck):first-child{box-shadow:.0625rem .3125rem #3c3c3ce6}:host-context(table[data-size=\"l\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-l)}:host-context(table[data-size=\"m\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-m)}:host-context(table[data-size=\"s\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-s)}.t-sort{transition-property:color;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;line-height:inherit;text-decoration:none;display:inline-flex;vertical-align:top;flex-direction:inherit;align-items:center;outline:none;font:inherit;text-transform:inherit;color:inherit;cursor:pointer}.t-sort_sorted{color:var(--tui-text-primary)}.t-sort:focus-visible{background:var(--tui-service-selection-background)}.t-sort:hover{color:var(--tui-text-primary)}.t-bar{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:absolute;top:0;bottom:0;right:-1px;inline-size:.1875rem;justify-self:flex-end;border-inline-start:2px solid transparent;background:var(--tui-status-warning);background-clip:content-box;cursor:ew-resize;opacity:0}.t-bar:hover,.t-bar:active{opacity:1}.t-icon:before{font-size:1rem}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TuiIcon, selector: "tui-icon:not([tuiBadge])", inputs: ["background"] }, { kind: "directive", type: TuiTableResized, selector: "[tuiResized]", outputs: ["tuiResized"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
310
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTh, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
311
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: TuiTableTh, isStandalone: true, selector: "th[tuiTh]", inputs: { minWidth: { classPropertyName: "minWidth", publicName: "minWidth", isSignal: true, isRequired: false, transformFunction: null }, maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, sorter: { classPropertyName: "sorter", publicName: "sorter", isSignal: false, isRequired: false, transformFunction: null }, resizable: { classPropertyName: "resizable", publicName: "resizable", isSignal: true, isRequired: false, transformFunction: null }, sticky: { classPropertyName: "sticky", publicName: "sticky", isSignal: true, isRequired: false, transformFunction: null }, requiredSort: { classPropertyName: "requiredSort", publicName: "requiredSort", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "style.min-width.px": "width() || minWidth()", "style.width.px": "width() || minWidth()", "style.max-width.px": "width() || maxWidth()", "class._sticky": "sticky()" } }, ngImport: i0, template: "@if (sorter && table) {\n <button\n type=\"button\"\n class=\"t-sort\"\n [class.t-sort_sorted]=\"isCurrent\"\n (click)=\"updateSorterAndDirection()\"\n >\n <ng-container [ngTemplateOutlet]=\"content\" />\n {{ table.change$ | async }}\n <tui-icon\n class=\"t-icon\"\n [icon]=\"icon\"\n />\n </button>\n} @else {\n <ng-container [ngTemplateOutlet]=\"content\" />\n}\n<ng-template #content>\n <ng-content />\n</ng-template>\n@if (resizable()) {\n <div\n class=\"t-bar\"\n (tuiResized)=\"onResized($event)\"\n ></div>\n}\n", styles: [":host{transition-property:box-shadow;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:relative;top:0;block-size:var(--tui-height-m);font:var(--tui-font-text-s);text-align:start;font-weight:700;color:var(--tui-text-secondary);background:var(--tui-background-base);cursor:default;padding:0 .75rem;box-sizing:border-box;box-shadow:0 .3125rem #ededed00;border:1px solid var(--tui-border-normal);filter:opacity(1)}@supports (-webkit-hyphens: none){:host{transform:translateZ(0)}}:host:not(:first-child){border-inline-start:none}:host._sticky,:host-context(._stuck) :host._sticky{position:sticky;z-index:30}:host._sticky:first-child,:host-context(._stuck) :host._sticky:first-child{left:0}:host._sticky:after,:host-context(._stuck) :host._sticky:after{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;content:\"\";position:absolute;top:0;left:100%;bottom:0;inline-size:.3125rem;pointer-events:none;background:#edededb3;opacity:0}:host-context(._stuck) :host{z-index:20}:host-context(tr:not(:first-child)){border-block-start:none}:host-context(table[data-size=\"l\"]){block-size:var(--tui-height-l);font:var(--tui-font-text-m);font-weight:700;padding:0 1rem}:host-context(table[data-size=\"s\"]){block-size:var(--tui-height-s);font:var(--tui-font-text-s);font-weight:700;padding:0 .5rem}:host-context(thead[tuiThead]){position:sticky}:host-context(table._stuck)._sticky:after{opacity:1}:host-context(thead[tuiThead]._stuck){box-shadow:0 .3125rem #edededb3}:host-context([tuiTheme=\"dark\"])._sticky:after{background:#3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck){box-shadow:0 .3125rem #3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck):first-child{box-shadow:.0625rem .3125rem #3c3c3ce6}:host-context(table[data-size=\"l\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-l)}:host-context(table[data-size=\"m\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-m)}:host-context(table[data-size=\"s\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-s)}.t-sort{transition-property:color;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;line-height:inherit;text-decoration:none;display:inline-flex;vertical-align:top;flex-direction:inherit;align-items:center;outline:none;font:inherit;text-transform:inherit;color:inherit;cursor:pointer}.t-sort_sorted{color:var(--tui-text-primary)}.t-sort:focus-visible{background:var(--tui-service-selection-background)}.t-sort:hover{color:var(--tui-text-primary)}.t-bar{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:absolute;top:0;bottom:0;right:-1px;inline-size:.1875rem;justify-self:flex-end;border-inline-start:2px solid transparent;background:var(--tui-status-warning);background-clip:content-box;cursor:ew-resize;opacity:0}.t-bar:hover,.t-bar:active{opacity:1}.t-icon:before{font-size:1rem}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TuiIcon, selector: "tui-icon:not([tuiBadge])", inputs: ["background"] }, { kind: "directive", type: TuiTableResized, selector: "[tuiResized]", outputs: ["tuiResized"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
334
312
  }
335
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTh, decorators: [{
313
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTh, decorators: [{
336
314
  type: Component,
337
315
  args: [{ selector: 'th[tuiTh]', imports: [AsyncPipe, NgTemplateOutlet, TuiIcon, TuiTableResized], changeDetection: ChangeDetectionStrategy.OnPush, host: {
338
- '[style.min-width.px]': 'width || minWidth',
339
- '[style.width.px]': 'width || minWidth',
340
- '[style.max-width.px]': 'width || maxWidth',
341
- '[class._sticky]': 'sticky',
342
- }, template: "@if (sorter && table) {\n <button\n type=\"button\"\n class=\"t-sort\"\n [class.t-sort_sorted]=\"isCurrent\"\n (click)=\"updateSorterAndDirection()\"\n >\n <ng-container [ngTemplateOutlet]=\"content\" />\n {{ table.change$ | async }}\n <tui-icon\n class=\"t-icon\"\n [icon]=\"icon\"\n />\n </button>\n} @else {\n <ng-container [ngTemplateOutlet]=\"content\" />\n}\n<ng-template #content>\n <ng-content />\n</ng-template>\n@if (resizable) {\n <div\n class=\"t-bar\"\n (tuiResized)=\"onResized($event)\"\n ></div>\n}\n", styles: [":host{transition-property:box-shadow;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:relative;top:0;block-size:var(--tui-height-m);font:var(--tui-font-text-s);text-align:start;font-weight:700;color:var(--tui-text-secondary);background:var(--tui-background-base);cursor:default;padding:0 .75rem;box-sizing:border-box;box-shadow:0 .3125rem #ededed00;border:1px solid var(--tui-border-normal);filter:opacity(1)}@supports (-webkit-hyphens: none){:host{transform:translateZ(0)}}:host:not(:first-child){border-inline-start:none}:host._sticky,:host-context(._stuck) :host._sticky{position:sticky;z-index:30}:host._sticky:first-child,:host-context(._stuck) :host._sticky:first-child{left:0}:host._sticky:after,:host-context(._stuck) :host._sticky:after{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;content:\"\";position:absolute;top:0;left:100%;bottom:0;inline-size:.3125rem;pointer-events:none;background:#edededb3;opacity:0}:host-context(._stuck) :host{z-index:20}:host-context(tr:not(:first-child)){border-block-start:none}:host-context(table[data-size=\"l\"]){block-size:var(--tui-height-l);font:var(--tui-font-text-m);font-weight:700;padding:0 1rem}:host-context(table[data-size=\"s\"]){block-size:var(--tui-height-s);font:var(--tui-font-text-s);font-weight:700;padding:0 .5rem}:host-context(thead[tuiThead]){position:sticky}:host-context(table._stuck)._sticky:after{opacity:1}:host-context(thead[tuiThead]._stuck){box-shadow:0 .3125rem #edededb3}:host-context([tuiTheme=\"dark\"])._sticky:after{background:#3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck){box-shadow:0 .3125rem #3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck):first-child{box-shadow:.0625rem .3125rem #3c3c3ce6}:host-context(table[data-size=\"l\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-l)}:host-context(table[data-size=\"m\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-m)}:host-context(table[data-size=\"s\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-s)}.t-sort{transition-property:color;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;line-height:inherit;text-decoration:none;display:inline-flex;vertical-align:top;flex-direction:inherit;align-items:center;outline:none;font:inherit;text-transform:inherit;color:inherit;cursor:pointer}.t-sort_sorted{color:var(--tui-text-primary)}.t-sort:focus-visible{background:var(--tui-service-selection-background)}.t-sort:hover{color:var(--tui-text-primary)}.t-bar{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:absolute;top:0;bottom:0;right:-1px;inline-size:.1875rem;justify-self:flex-end;border-inline-start:2px solid transparent;background:var(--tui-status-warning);background-clip:content-box;cursor:ew-resize;opacity:0}.t-bar:hover,.t-bar:active{opacity:1}.t-icon:before{font-size:1rem}\n"] }]
343
- }], propDecorators: { minWidth: [{
344
- type: Input
345
- }], maxWidth: [{
346
- type: Input
347
- }], sorter: [{
348
- type: Input
349
- }], resizable: [{
350
- type: Input
351
- }], sticky: [{
352
- type: Input
353
- }], requiredSort: [{
316
+ '[style.min-width.px]': 'width() || minWidth()',
317
+ '[style.width.px]': 'width() || minWidth()',
318
+ '[style.max-width.px]': 'width() || maxWidth()',
319
+ '[class._sticky]': 'sticky()',
320
+ }, template: "@if (sorter && table) {\n <button\n type=\"button\"\n class=\"t-sort\"\n [class.t-sort_sorted]=\"isCurrent\"\n (click)=\"updateSorterAndDirection()\"\n >\n <ng-container [ngTemplateOutlet]=\"content\" />\n {{ table.change$ | async }}\n <tui-icon\n class=\"t-icon\"\n [icon]=\"icon\"\n />\n </button>\n} @else {\n <ng-container [ngTemplateOutlet]=\"content\" />\n}\n<ng-template #content>\n <ng-content />\n</ng-template>\n@if (resizable()) {\n <div\n class=\"t-bar\"\n (tuiResized)=\"onResized($event)\"\n ></div>\n}\n", styles: [":host{transition-property:box-shadow;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:relative;top:0;block-size:var(--tui-height-m);font:var(--tui-font-text-s);text-align:start;font-weight:700;color:var(--tui-text-secondary);background:var(--tui-background-base);cursor:default;padding:0 .75rem;box-sizing:border-box;box-shadow:0 .3125rem #ededed00;border:1px solid var(--tui-border-normal);filter:opacity(1)}@supports (-webkit-hyphens: none){:host{transform:translateZ(0)}}:host:not(:first-child){border-inline-start:none}:host._sticky,:host-context(._stuck) :host._sticky{position:sticky;z-index:30}:host._sticky:first-child,:host-context(._stuck) :host._sticky:first-child{left:0}:host._sticky:after,:host-context(._stuck) :host._sticky:after{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;content:\"\";position:absolute;top:0;left:100%;bottom:0;inline-size:.3125rem;pointer-events:none;background:#edededb3;opacity:0}:host-context(._stuck) :host{z-index:20}:host-context(tr:not(:first-child)){border-block-start:none}:host-context(table[data-size=\"l\"]){block-size:var(--tui-height-l);font:var(--tui-font-text-m);font-weight:700;padding:0 1rem}:host-context(table[data-size=\"s\"]){block-size:var(--tui-height-s);font:var(--tui-font-text-s);font-weight:700;padding:0 .5rem}:host-context(thead[tuiThead]){position:sticky}:host-context(table._stuck)._sticky:after{opacity:1}:host-context(thead[tuiThead]._stuck){box-shadow:0 .3125rem #edededb3}:host-context([tuiTheme=\"dark\"])._sticky:after{background:#3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck){box-shadow:0 .3125rem #3c3c3ce6}:host-context([tuiTheme=\"dark\"] thead[tuiThead]._stuck):first-child{box-shadow:.0625rem .3125rem #3c3c3ce6}:host-context(table[data-size=\"l\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-l)}:host-context(table[data-size=\"m\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-m)}:host-context(table[data-size=\"s\"] thead[tuiThead] tr:nth-child(2)){top:var(--tui-height-s)}.t-sort{transition-property:color;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;line-height:inherit;text-decoration:none;display:inline-flex;vertical-align:top;flex-direction:inherit;align-items:center;outline:none;font:inherit;text-transform:inherit;color:inherit;cursor:pointer}.t-sort_sorted{color:var(--tui-text-primary)}.t-sort:focus-visible{background:var(--tui-service-selection-background)}.t-sort:hover{color:var(--tui-text-primary)}.t-bar{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;position:absolute;top:0;bottom:0;right:-1px;inline-size:.1875rem;justify-self:flex-end;border-inline-start:2px solid transparent;background:var(--tui-status-warning);background-clip:content-box;cursor:ew-resize;opacity:0}.t-bar:hover,.t-bar:active{opacity:1}.t-icon:before{font-size:1rem}\n"] }]
321
+ }], propDecorators: { sorter: [{
354
322
  type: Input
355
323
  }] } });
356
324
  class TuiTableSortKeyException extends Error {
@@ -364,105 +332,90 @@ class TuiTableSortable {
364
332
  this.table = inject((TuiTableDirective));
365
333
  this.th = inject((TuiTableTh));
366
334
  this.sortBy = inject(forwardRef(() => TuiTableSortBy));
367
- this.sorter = () => 0;
335
+ this.sortable = input(undefined, {
336
+ alias: 'tuiSortable',
337
+ transform: coerceBooleanProperty,
338
+ });
339
+ this.setSorter = effect(() => {
340
+ this.th.sorter = this.sortable() ? untracked(this.sorter) : null;
341
+ });
342
+ this.sorter = computed(() => {
343
+ return this.sortable() && this.match ? this.table.sorter : () => 0;
344
+ });
368
345
  }
369
346
  get key() {
370
347
  return this.th.key;
371
348
  }
372
- ngOnChanges() {
373
- if (this.sortable) {
374
- this.sorter = this.match ? this.table.sorter : this.sorter;
375
- this.th.sorter = this.sorter;
376
- }
377
- else {
378
- this.th.sorter = null;
379
- }
380
- }
381
349
  check() {
382
- if (this.match && this.table.sorter !== this.sorter) {
383
- this.table.updateSorter(this.sorter);
350
+ if (this.match && this.table.sorter !== this.sorter()) {
351
+ this.table.updateSorter(this.sorter());
384
352
  }
385
353
  }
386
354
  get match() {
387
- return this.sortBy.tuiSortBy === this.key;
355
+ return untracked(this.sortBy.tuiSortBy) === this.key;
388
356
  }
389
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableSortable, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
390
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "16.1.0", version: "19.2.15", type: TuiTableSortable, isStandalone: true, selector: "th[tuiTh][tuiSortable]", inputs: { sortable: ["tuiSortable", "sortable", coerceBooleanProperty] }, usesOnChanges: true, ngImport: i0 }); }
357
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableSortable, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
358
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.17", type: TuiTableSortable, isStandalone: true, selector: "th[tuiTh][tuiSortable]", inputs: { sortable: { classPropertyName: "sortable", publicName: "tuiSortable", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 }); }
391
359
  }
392
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableSortable, decorators: [{
360
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableSortable, decorators: [{
393
361
  type: Directive,
394
362
  args: [{
395
363
  selector: 'th[tuiTh][tuiSortable]',
396
364
  }]
397
- }], propDecorators: { sortable: [{
398
- type: Input,
399
- args: [{
400
- alias: 'tuiSortable',
401
- transform: coerceBooleanProperty,
402
- }]
403
- }] } });
365
+ }] });
404
366
 
405
367
  class TuiTableSortBy {
406
368
  constructor() {
407
- this.sortables = EMPTY_QUERY;
369
+ this.sortables = contentChildren(TuiTableSortable, {
370
+ descendants: true,
371
+ });
408
372
  this.table = inject((TuiTableDirective));
409
373
  /**
410
- * @deprecated: use tuiSortChange
374
+ * @deprecated
411
375
  */
412
- this.tuiSortByChange = this.table.sorterChange.pipe(
376
+ this.tuiSortByChange$ = this.table.sorterChange$.pipe(
413
377
  // delay is for getting actual ContentChildren (sortables) https://github.com/angular/angular/issues/38976
414
- delay(0), filter(() => !!this.sortables.length), map((sorter) => this.getKey(sorter)));
415
- this.tuiSortChange = combineLatest([
416
- this.tuiSortByChange,
417
- this.table.directionChange,
378
+ delay(0), filter(() => !!this.sortables().length), map((sorter) => this.getKey(sorter)));
379
+ /**
380
+ * @deprecated: use tuiSortChange
381
+ */
382
+ this.tuiSortByChange = outputFromObservable(this.tuiSortByChange$);
383
+ this.tuiSortChange$ = combineLatest([
384
+ this.tuiSortByChange$,
385
+ this.table.directionChange$,
418
386
  ]).pipe(debounceTime(0), map(([sortKey, sortDirection]) => ({
419
387
  sortBy: sortKey,
420
388
  orderBy: sortDirection,
421
389
  sortKey,
422
390
  sortDirection,
423
391
  })));
424
- this.tuiSortBy = null;
425
- }
426
- set sortBy(sortBy) {
427
- this.tuiSortBy = sortBy;
428
- this.checkSortables();
429
- }
430
- checkSortables() {
431
- this.sortables.forEach((s) => s.check());
392
+ this.tuiSortChange = outputFromObservable(this.tuiSortChange$);
393
+ this.tuiSortBy = input(null);
394
+ this.checkSortables = effect((_, __ = this.tuiSortBy()) => untracked(this.sortables).forEach((s) => s.check()));
432
395
  }
433
396
  getKey(sorter) {
434
- return this.sortables.find((s) => s.sorter === sorter)?.key || null;
397
+ return this.sortables().find((s) => s.sorter() === sorter)?.key || null;
435
398
  }
436
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableSortBy, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
437
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableSortBy, isStandalone: true, selector: "table[tuiTable][tuiSortBy]", inputs: { sortBy: ["tuiSortBy", "sortBy"] }, outputs: { tuiSortByChange: "tuiSortByChange", tuiSortChange: "tuiSortChange" }, queries: [{ propertyName: "sortables", predicate: TuiTableSortable, descendants: true }], ngImport: i0 }); }
399
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableSortBy, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
400
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.2.17", type: TuiTableSortBy, isStandalone: true, selector: "table[tuiTable][tuiSortBy]", inputs: { tuiSortBy: { classPropertyName: "tuiSortBy", publicName: "tuiSortBy", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { tuiSortByChange: "tuiSortByChange", tuiSortChange: "tuiSortChange" }, queries: [{ propertyName: "sortables", predicate: TuiTableSortable, descendants: true, isSignal: true }], ngImport: i0 }); }
438
401
  }
439
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableSortBy, decorators: [{
402
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableSortBy, decorators: [{
440
403
  type: Directive,
441
404
  args: [{
442
405
  selector: 'table[tuiTable][tuiSortBy]',
443
406
  }]
444
- }], propDecorators: { sortables: [{
445
- type: ContentChildren,
446
- args: [TuiTableSortable, { descendants: true }]
447
- }], tuiSortByChange: [{
448
- type: Output
449
- }], tuiSortChange: [{
450
- type: Output
451
- }], sortBy: [{
452
- type: Input,
453
- args: ['tuiSortBy']
454
- }] } });
407
+ }] });
455
408
 
456
409
  class TuiTableThead {
457
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableThead, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
458
- static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableThead, isStandalone: true, selector: "thead[tuiThead]", providers: [
410
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableThead, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
411
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.17", type: TuiTableThead, isStandalone: true, selector: "thead[tuiThead]", providers: [
459
412
  {
460
413
  provide: WA_INTERSECTION_ROOT_MARGIN,
461
414
  useValue: '0px 10000px 10000px 10000px',
462
415
  },
463
416
  ], hostDirectives: [{ directive: TuiStuck }], ngImport: i0 }); }
464
417
  }
465
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableThead, decorators: [{
418
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableThead, decorators: [{
466
419
  type: Directive,
467
420
  args: [{
468
421
  selector: 'thead[tuiThead]',
@@ -481,18 +434,18 @@ class TuiTableSortPipe {
481
434
  this.table = inject((TuiTableDirective));
482
435
  }
483
436
  transform(data) {
484
- return this.sort(data ?? [], this.table.sorter, this.table.direction);
437
+ return this.sort(data ?? [], this.table.sorter, this.table.direction());
485
438
  }
486
439
  sort(data, sorter, direction) {
487
440
  return [...data].sort((a, b) => direction * sorter(a, b));
488
441
  }
489
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableSortPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
490
- static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.15", ngImport: i0, type: TuiTableSortPipe, isStandalone: true, name: "tuiTableSort", pure: false }); }
442
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableSortPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
443
+ static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.2.17", ngImport: i0, type: TuiTableSortPipe, isStandalone: true, name: "tuiTableSort", pure: false }); }
491
444
  }
492
445
  __decorate([
493
446
  tuiPure
494
447
  ], TuiTableSortPipe.prototype, "sort", null);
495
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableSortPipe, decorators: [{
448
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableSortPipe, decorators: [{
496
449
  type: Pipe,
497
450
  args: [{
498
451
  name: 'tuiTableSort',
@@ -516,40 +469,35 @@ const TUI_TABLE_PROVIDER = [
516
469
 
517
470
  class TuiTableExpand {
518
471
  constructor() {
472
+ this.content = viewChild('content');
519
473
  this.el = tuiInjectElement();
520
474
  this.server = isPlatformServer(inject(PLATFORM_ID));
521
475
  this.transitioning = signal(false);
522
- this.contentHeight = computed((_ = this.expanded()) => this.update());
476
+ this.contentHeight = computed((_ = this.expanded()) => this.update(this.content()));
523
477
  this.visible$ = new Subject();
524
478
  this.sub = this.visible$
525
479
  .pipe(switchMap((v) => (v ? timer(500).pipe(map(() => v)) : of(v))), takeUntilDestroyed())
526
480
  .subscribe((visible) => this.el.classList.toggle('_visible', visible));
527
- this.expandedChange = new EventEmitter();
528
- this.expanded = signal(inject(TUI_TABLE_OPTIONS).open);
529
- }
530
- set expandedSetter(open) {
531
- this.expanded.set(open);
532
- this.transitioning.set(true);
481
+ this.expanded = model(inject(TUI_TABLE_OPTIONS).open);
482
+ this.transitioningEffect = effect((_, __ = this.expanded()) => this.transitioning.set(true));
533
483
  }
534
484
  toggle() {
535
485
  this.expanded.set(!this.expanded());
536
- this.transitioning.set(true);
537
- this.expandedChange.emit(this.expanded());
538
486
  }
539
- update() {
540
- if (!this.content || this.server) {
487
+ update(content) {
488
+ if (!content || this.server) {
541
489
  return 0;
542
490
  }
543
- const el = this.content.nativeElement;
491
+ const el = content.nativeElement;
544
492
  el.style.setProperty('display', 'block');
545
493
  const height = el.getBoundingClientRect().height;
546
494
  el.style.removeProperty('display');
547
495
  return height;
548
496
  }
549
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableExpand, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
550
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableExpand, isStandalone: true, selector: "tui-table-expand", inputs: { expandedSetter: ["expanded", "expandedSetter"] }, outputs: { expandedChange: "expandedChange" }, host: { attributes: { "ngSkipHydration": "true" }, listeners: { "tuiPresentChange": "visible$.next($event)" } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, static: true }], hostDirectives: [{ directive: i1.TuiPresent, outputs: ["tuiPresentChange", "tuiPresentChange"] }], ngImport: i0, template: "<div\n #content\n class=\"t-content\"\n [class.t-content_open]=\"expanded() && !transitioning()\"\n>\n <ng-content />\n</div>\n\n<div\n class=\"t-filler\"\n [class.t-filler_open]=\"expanded()\"\n [style.--t-height.px]=\"contentHeight()\"\n (animationcancel)=\"transitioning.set(false)\"\n (animationend)=\"transitioning.set(false)\"\n (animationstart)=\"transitioning.set(true)\"\n></div>\n", styles: ["@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes open{0%{block-size:0}to{block-size:var(--t-height)}}@keyframes close{0%{block-size:var(--t-height)}to{block-size:0}}:host{display:contents}:host:not(._visible){--tui-duration: 0ms}.t-content{display:none}.t-content_open{display:contents}.t-content_open ::ng-deep tr{animation:fade-in var(--tui-duration)}.t-filler{animation:close calc(var(--tui-duration) + 1ms)}.t-filler_open{animation:open calc(var(--tui-duration) + 1ms)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
497
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableExpand, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
498
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.17", type: TuiTableExpand, isStandalone: true, selector: "tui-table-expand", inputs: { expanded: { classPropertyName: "expanded", publicName: "expanded", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { expanded: "expandedChange" }, host: { attributes: { "ngSkipHydration": "true" }, listeners: { "tuiPresentChange": "visible$.next($event)" } }, viewQueries: [{ propertyName: "content", first: true, predicate: ["content"], descendants: true, isSignal: true }], hostDirectives: [{ directive: i1.TuiPresent, outputs: ["tuiPresentChange", "tuiPresentChange"] }], ngImport: i0, template: "<div\n #content\n class=\"t-content\"\n [class.t-content_open]=\"expanded() && !transitioning()\"\n>\n <ng-content />\n</div>\n\n<div\n class=\"t-filler\"\n [class.t-filler_open]=\"expanded()\"\n [style.--t-height.px]=\"contentHeight()\"\n (animationcancel)=\"transitioning.set(false)\"\n (animationend)=\"transitioning.set(false)\"\n (animationstart)=\"transitioning.set(true)\"\n></div>\n", styles: ["@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes open{0%{block-size:0}to{block-size:var(--t-height)}}@keyframes close{0%{block-size:var(--t-height)}to{block-size:0}}:host{display:contents}:host:not(._visible){--tui-duration: 0ms}.t-content{display:none}.t-content_open{display:contents}.t-content_open ::ng-deep tr{animation:fade-in var(--tui-duration)}.t-filler{animation:close calc(var(--tui-duration) + 1ms)}.t-filler_open{animation:open calc(var(--tui-duration) + 1ms)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
551
499
  }
552
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableExpand, decorators: [{
500
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableExpand, decorators: [{
553
501
  type: Component,
554
502
  args: [{ selector: 'tui-table-expand', changeDetection: ChangeDetectionStrategy.OnPush, hostDirectives: [
555
503
  {
@@ -560,116 +508,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImpo
560
508
  ngSkipHydration: 'true',
561
509
  '(tuiPresentChange)': 'visible$.next($event)',
562
510
  }, template: "<div\n #content\n class=\"t-content\"\n [class.t-content_open]=\"expanded() && !transitioning()\"\n>\n <ng-content />\n</div>\n\n<div\n class=\"t-filler\"\n [class.t-filler_open]=\"expanded()\"\n [style.--t-height.px]=\"contentHeight()\"\n (animationcancel)=\"transitioning.set(false)\"\n (animationend)=\"transitioning.set(false)\"\n (animationstart)=\"transitioning.set(true)\"\n></div>\n", styles: ["@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes open{0%{block-size:0}to{block-size:var(--t-height)}}@keyframes close{0%{block-size:var(--t-height)}to{block-size:0}}:host{display:contents}:host:not(._visible){--tui-duration: 0ms}.t-content{display:none}.t-content_open{display:contents}.t-content_open ::ng-deep tr{animation:fade-in var(--tui-duration)}.t-filler{animation:close calc(var(--tui-duration) + 1ms)}.t-filler_open{animation:open calc(var(--tui-duration) + 1ms)}\n"] }]
563
- }], propDecorators: { content: [{
564
- type: ViewChild,
565
- args: ['content', { static: true }]
566
- }], expandedChange: [{
567
- type: Output
568
- }], expandedSetter: [{
569
- type: Input,
570
- args: ['expanded']
571
- }] } });
511
+ }] });
572
512
 
573
513
  class TuiTableTd {
574
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTd, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
575
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.15", type: TuiTableTd, isStandalone: true, selector: "th[tuiTd], td[tuiTd]", host: { properties: { "class._editable": "control || textfield" } }, queries: [{ propertyName: "control", first: true, predicate: TuiControl, descendants: true }, { propertyName: "textfield", first: true, predicate: TuiTextfieldComponent, descendants: true }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{position:relative;text-align:start;background:var(--tui-background-base);border:1px solid var(--tui-border-normal);border-block-start:none;box-sizing:border-box;filter:opacity(1)}@supports (-webkit-hyphens: none){:host{transform:translateZ(0)}}:host:first-child{left:0}:host:not(:first-child){border-inline-start:none}:host._editable:focus-within{z-index:1}:host._editable{padding:0!important;vertical-align:top}:host(th){position:sticky;z-index:1}:host(th):after{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;content:\"\";position:absolute;top:0;bottom:0;left:100%;inline-size:.3125rem;pointer-events:none;background:#edededb3;opacity:0}:host(th):focus-within:not(:disabled){z-index:11}:host-context([tuiTheme=\"dark\"]):after{background:#3c3c3ce6}:host-context(table._stuck){z-index:10}:host-context(table._stuck):last-of-type:after{opacity:1}:host-context(table[data-size=\"l\"]){block-size:var(--tui-height-l);font:var(--tui-font-text-m);padding:1rem}:host-context(table[data-size=\"m\"]){block-size:var(--tui-height-m);font:var(--tui-font-text-s);padding:.75rem}:host-context(table[data-size=\"s\"]){block-size:var(--tui-height-s);font:var(--tui-font-text-s);padding:.25rem .5rem}:host(td):focus-within{z-index:1}:host(td):not(:focus-within){z-index:0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
514
+ constructor() {
515
+ this.control = contentChild((TuiControl));
516
+ this.textfield = contentChild((TuiTextfieldComponent));
517
+ }
518
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTd, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
519
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.2.17", type: TuiTableTd, isStandalone: true, selector: "th[tuiTd], td[tuiTd]", host: { properties: { "class._editable": "control() || textfield()" } }, queries: [{ propertyName: "control", first: true, predicate: (TuiControl), descendants: true, isSignal: true }, { propertyName: "textfield", first: true, predicate: (TuiTextfieldComponent), descendants: true, isSignal: true }], ngImport: i0, template: '<ng-content />', isInline: true, styles: [":host{position:relative;text-align:start;background:var(--tui-background-base);border:1px solid var(--tui-border-normal);border-block-start:none;box-sizing:border-box;filter:opacity(1)}@supports (-webkit-hyphens: none){:host{transform:translateZ(0)}}:host:first-child{left:0}:host:not(:first-child){border-inline-start:none}:host._editable:focus-within{z-index:1}:host._editable{padding:0!important;vertical-align:top}:host(th){position:sticky;z-index:1}:host(th):after{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;content:\"\";position:absolute;top:0;bottom:0;left:100%;inline-size:.3125rem;pointer-events:none;background:#edededb3;opacity:0}:host(th):focus-within:not(:disabled){z-index:11}:host-context([tuiTheme=\"dark\"]):after{background:#3c3c3ce6}:host-context(table._stuck){z-index:10}:host-context(table._stuck):last-of-type:after{opacity:1}:host-context(table[data-size=\"l\"]){block-size:var(--tui-height-l);font:var(--tui-font-text-m);padding:1rem}:host-context(table[data-size=\"m\"]){block-size:var(--tui-height-m);font:var(--tui-font-text-s);padding:.75rem}:host-context(table[data-size=\"s\"]){block-size:var(--tui-height-s);font:var(--tui-font-text-s);padding:.25rem .5rem}:host(td):focus-within{z-index:1}:host(td):not(:focus-within){z-index:0}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
576
520
  }
577
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTd, decorators: [{
521
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTd, decorators: [{
578
522
  type: Component,
579
523
  args: [{ selector: 'th[tuiTd], td[tuiTd]', template: '<ng-content />', changeDetection: ChangeDetectionStrategy.OnPush, host: {
580
- '[class._editable]': 'control || textfield',
524
+ '[class._editable]': 'control() || textfield()',
581
525
  }, styles: [":host{position:relative;text-align:start;background:var(--tui-background-base);border:1px solid var(--tui-border-normal);border-block-start:none;box-sizing:border-box;filter:opacity(1)}@supports (-webkit-hyphens: none){:host{transform:translateZ(0)}}:host:first-child{left:0}:host:not(:first-child){border-inline-start:none}:host._editable:focus-within{z-index:1}:host._editable{padding:0!important;vertical-align:top}:host(th){position:sticky;z-index:1}:host(th):after{transition-property:opacity;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;content:\"\";position:absolute;top:0;bottom:0;left:100%;inline-size:.3125rem;pointer-events:none;background:#edededb3;opacity:0}:host(th):focus-within:not(:disabled){z-index:11}:host-context([tuiTheme=\"dark\"]):after{background:#3c3c3ce6}:host-context(table._stuck){z-index:10}:host-context(table._stuck):last-of-type:after{opacity:1}:host-context(table[data-size=\"l\"]){block-size:var(--tui-height-l);font:var(--tui-font-text-m);padding:1rem}:host-context(table[data-size=\"m\"]){block-size:var(--tui-height-m);font:var(--tui-font-text-s);padding:.75rem}:host-context(table[data-size=\"s\"]){block-size:var(--tui-height-s);font:var(--tui-font-text-s);padding:.25rem .5rem}:host(td):focus-within{z-index:1}:host(td):not(:focus-within){z-index:0}\n"] }]
582
- }], propDecorators: { control: [{
583
- type: ContentChild,
584
- args: [TuiControl]
585
- }], textfield: [{
586
- type: ContentChild,
587
- args: [TuiTextfieldComponent]
588
- }] } });
526
+ }] });
589
527
 
590
528
  class TuiTableTr {
591
529
  constructor() {
592
- this.cells = EMPTY_QUERY;
530
+ this.cells = contentChildren(forwardRef(() => TuiTableCell));
593
531
  this.body = inject(forwardRef(() => TuiTableTbody));
594
532
  this.contentReady$ = new ReplaySubject(1);
533
+ this.rows$ = toObservable(this.body.rows);
534
+ this.contentCells$ = toObservable(this.cells);
595
535
  this.table = inject(forwardRef(() => TuiTableDirective));
596
536
  this.height = toSignal(inject(ResizeObserverService, { self: true }).pipe(map(([entry]) => entry?.contentRect.height ?? 0), distinctUntilChanged(), tuiZoneOptimized()), { initialValue: 0 });
597
- this.cells$ = this.contentReady$.pipe(switchMap(() => tuiQueryListChanges(this.cells)), map((cells) => cells.reduce((record, item) => ({ ...record, [item.tuiCell]: item }), {})));
598
- this.item$ = this.contentReady$.pipe(switchMap(() => tuiQueryListChanges(this.body.rows)), map((rows) => this.body.data[rows.findIndex((row) => row === this)]));
537
+ this.cells$ = this.contentReady$.pipe(switchMap(() => this.contentCells$), map((cells) => cells.reduce((record, item) => ({ ...record, [item.tuiCell()]: item }), {})));
538
+ this.item$ = this.contentReady$.pipe(switchMap(() => this.rows$), map((rows) => this.body.data()[rows.findIndex((row) => row === this)]));
599
539
  }
600
540
  ngAfterContentInit() {
601
541
  Promise.resolve().then(() => this.contentReady$.next(true));
602
542
  }
603
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTr, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
604
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TuiTableTr, isStandalone: true, selector: "tr[tuiTr]", host: { properties: { "style.--t-row-height.px": "height()" } }, providers: [TUI_TABLE_PROVIDER, ResizeObserverService], queries: [{ propertyName: "cells", predicate: i0.forwardRef(() => TuiTableCell) }], ngImport: i0, template: "@if (cells$ | async; as items) {\n @for (key of table.columns; track key) {\n <ng-container [ngTemplateOutlet]=\"(items[key] && items[key].template) || plain\">\n <ng-template #plain>\n @if (item$ | async; as item) {\n <td tuiTd>\n {{ item[key] }}\n </td>\n }\n </ng-template>\n </ng-container>\n }\n} @else {\n <td></td>\n}\n<ng-content />\n", dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TuiTableTd, selector: "th[tuiTd], td[tuiTd]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
543
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTr, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
544
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: TuiTableTr, isStandalone: true, selector: "tr[tuiTr]", host: { properties: { "style.--t-row-height.px": "height()" } }, providers: [TUI_TABLE_PROVIDER, ResizeObserverService], queries: [{ propertyName: "cells", predicate: i0.forwardRef(() => TuiTableCell), isSignal: true }], ngImport: i0, template: "@if (cells$ | async; as items) {\n @for (key of table.columns(); track key) {\n <ng-container [ngTemplateOutlet]=\"(items[key] && items[key].template) || plain\">\n <ng-template #plain>\n @if (item$ | async; as item) {\n <td tuiTd>\n {{ item[key] }}\n </td>\n }\n </ng-template>\n </ng-container>\n }\n} @else {\n <td></td>\n}\n<ng-content />\n", dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TuiTableTd, selector: "th[tuiTd], td[tuiTd]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
605
545
  }
606
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTr, decorators: [{
546
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTr, decorators: [{
607
547
  type: Component,
608
548
  args: [{ selector: 'tr[tuiTr]', imports: [AsyncPipe, NgTemplateOutlet, TuiTableTd], changeDetection: ChangeDetectionStrategy.OnPush, providers: [TUI_TABLE_PROVIDER, ResizeObserverService], host: {
609
549
  '[style.--t-row-height.px]': 'height()',
610
- }, template: "@if (cells$ | async; as items) {\n @for (key of table.columns; track key) {\n <ng-container [ngTemplateOutlet]=\"(items[key] && items[key].template) || plain\">\n <ng-template #plain>\n @if (item$ | async; as item) {\n <td tuiTd>\n {{ item[key] }}\n </td>\n }\n </ng-template>\n </ng-container>\n }\n} @else {\n <td></td>\n}\n<ng-content />\n" }]
611
- }], propDecorators: { cells: [{
612
- type: ContentChildren,
613
- args: [forwardRef(() => TuiTableCell)]
614
- }] } });
550
+ }, template: "@if (cells$ | async; as items) {\n @for (key of table.columns(); track key) {\n <ng-container [ngTemplateOutlet]=\"(items[key] && items[key].template) || plain\">\n <ng-template #plain>\n @if (item$ | async; as item) {\n <td tuiTd>\n {{ item[key] }}\n </td>\n }\n </ng-template>\n </ng-container>\n }\n} @else {\n <td></td>\n}\n<ng-content />\n" }]
551
+ }] });
615
552
 
616
553
  class TuiTableTbody {
617
554
  constructor() {
618
555
  this.options = inject(TUI_TABLE_OPTIONS);
619
556
  this.table = inject(forwardRef(() => TuiTableDirective));
620
- this.rows = EMPTY_QUERY;
621
- this.data = [];
557
+ this.rows = contentChildren(forwardRef(() => TuiTableTr));
558
+ this.data = input([]);
622
559
  /** @deprecated: drop in v5.0, use TuiTableExpand */
623
- this.open = this.options.open;
560
+ this.heading = input();
624
561
  /** @deprecated: drop in v5.0, use TuiTableExpand */
625
- this.openChange = new EventEmitter();
562
+ this.open = model(this.options.open);
626
563
  /** @deprecated: drop in v5.0, use TuiTableExpand */
627
564
  this.onClick = () => {
628
- this.open = !this.open;
629
- this.openChange.emit(this.open);
565
+ this.open.set(!this.open());
630
566
  };
631
567
  }
632
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTbody, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
633
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TuiTableTbody, isStandalone: true, selector: "tbody[tuiTbody]", inputs: { data: "data", heading: "heading", open: "open" }, outputs: { openChange: "openChange" }, providers: TUI_TABLE_PROVIDER, queries: [{ propertyName: "rows", predicate: i0.forwardRef(() => TuiTableTr) }], ngImport: i0, template: "@if (heading) {\n <tr>\n <th\n class=\"t-heading\"\n [colSpan]=\"table.columns.length\"\n >\n <button\n type=\"button\"\n class=\"t-expand\"\n (click)=\"onClick()\"\n >\n <span class=\"t-name\">\n <ng-container *polymorpheusOutlet=\"heading as text\">\n {{ text }}\n </ng-container>\n </span>\n <tui-icon\n class=\"t-chevron\"\n [tuiChevron]=\"open\"\n />\n </button>\n </th>\n </tr>\n}\n@if (open) {\n <ng-content />\n}\n", styles: [":host{border-color:var(--tui-border-normal)}:host tr{border-color:inherit}.t-expand{-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;font:inherit;line-height:inherit;text-decoration:none;display:flex;inline-size:100%;block-size:100%;align-items:center;box-sizing:border-box;outline:none;font-weight:700;cursor:pointer;border-color:inherit}.t-expand:focus-visible .t-name{background:var(--tui-service-selection-background)}.t-expand:before,.t-expand:after{content:\"\";position:sticky;block-size:100%;border-inline-start:1px solid;border-color:inherit}.t-expand:before{left:0}.t-expand:after{right:0}.t-heading{transition-property:background;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;block-size:var(--tui-height-m);font:var(--tui-font-text-s);padding:0;background:var(--tui-background-neutral-1);border-block-end:1px solid var(--tui-border-normal);border-color:inherit}.t-heading:hover{background:var(--tui-background-neutral-1-hover)}:host-context(table[data-size=\"l\"]) .t-heading{font:var(--tui-font-text-m);block-size:var(--tui-height-l)}.t-name{position:sticky;left:.75rem;display:inline-block}:host-context(table[data-size=\"l\"]) .t-name{left:1rem}.t-chevron{position:sticky;right:.75rem;margin:0 .6875rem 0 auto}\n"], dependencies: [{ kind: "directive", type: PolymorpheusOutlet, selector: "[polymorpheusOutlet]", inputs: ["polymorpheusOutlet", "polymorpheusOutletContext"] }, { kind: "directive", type: TuiChevron, selector: "[tuiChevron]", inputs: ["tuiChevron"] }, { kind: "component", type: TuiIcon, selector: "tui-icon:not([tuiBadge])", inputs: ["background"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
568
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTbody, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
569
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: TuiTableTbody, isStandalone: true, selector: "tbody[tuiTbody]", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, open: { classPropertyName: "open", publicName: "open", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { open: "openChange" }, providers: TUI_TABLE_PROVIDER, queries: [{ propertyName: "rows", predicate: i0.forwardRef(() => TuiTableTr), isSignal: true }], ngImport: i0, template: "@if (heading()) {\n <tr>\n <th\n class=\"t-heading\"\n [colSpan]=\"table.columns().length\"\n >\n <button\n type=\"button\"\n class=\"t-expand\"\n (click)=\"onClick()\"\n >\n <span class=\"t-name\">\n <ng-container *polymorpheusOutlet=\"heading() as text\">\n {{ text }}\n </ng-container>\n </span>\n <tui-icon\n class=\"t-chevron\"\n [tuiChevron]=\"open()\"\n />\n </button>\n </th>\n </tr>\n}\n@if (open()) {\n <ng-content />\n}\n", styles: [":host{border-color:var(--tui-border-normal)}:host tr{border-color:inherit}.t-expand{-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;font:inherit;line-height:inherit;text-decoration:none;display:flex;inline-size:100%;block-size:100%;align-items:center;box-sizing:border-box;outline:none;font-weight:700;cursor:pointer;border-color:inherit}.t-expand:focus-visible .t-name{background:var(--tui-service-selection-background)}.t-expand:before,.t-expand:after{content:\"\";position:sticky;block-size:100%;border-inline-start:1px solid;border-color:inherit}.t-expand:before{left:0}.t-expand:after{right:0}.t-heading{transition-property:background;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;block-size:var(--tui-height-m);font:var(--tui-font-text-s);padding:0;background:var(--tui-background-neutral-1);border-block-end:1px solid var(--tui-border-normal);border-color:inherit}.t-heading:hover{background:var(--tui-background-neutral-1-hover)}:host-context(table[data-size=\"l\"]) .t-heading{font:var(--tui-font-text-m);block-size:var(--tui-height-l)}.t-name{position:sticky;left:.75rem;display:inline-block}:host-context(table[data-size=\"l\"]) .t-name{left:1rem}.t-chevron{position:sticky;right:.75rem;margin:0 .6875rem 0 auto}\n"], dependencies: [{ kind: "directive", type: PolymorpheusOutlet, selector: "[polymorpheusOutlet]", inputs: ["polymorpheusOutlet", "polymorpheusOutletContext"] }, { kind: "directive", type: TuiChevron, selector: "[tuiChevron]", inputs: ["tuiChevron"] }, { kind: "component", type: TuiIcon, selector: "tui-icon:not([tuiBadge])", inputs: ["background"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
634
570
  }
635
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableTbody, decorators: [{
571
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableTbody, decorators: [{
636
572
  type: Component,
637
- args: [{ selector: 'tbody[tuiTbody]', imports: [PolymorpheusOutlet, TuiChevron, TuiIcon], changeDetection: ChangeDetectionStrategy.OnPush, providers: TUI_TABLE_PROVIDER, template: "@if (heading) {\n <tr>\n <th\n class=\"t-heading\"\n [colSpan]=\"table.columns.length\"\n >\n <button\n type=\"button\"\n class=\"t-expand\"\n (click)=\"onClick()\"\n >\n <span class=\"t-name\">\n <ng-container *polymorpheusOutlet=\"heading as text\">\n {{ text }}\n </ng-container>\n </span>\n <tui-icon\n class=\"t-chevron\"\n [tuiChevron]=\"open\"\n />\n </button>\n </th>\n </tr>\n}\n@if (open) {\n <ng-content />\n}\n", styles: [":host{border-color:var(--tui-border-normal)}:host tr{border-color:inherit}.t-expand{-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;font:inherit;line-height:inherit;text-decoration:none;display:flex;inline-size:100%;block-size:100%;align-items:center;box-sizing:border-box;outline:none;font-weight:700;cursor:pointer;border-color:inherit}.t-expand:focus-visible .t-name{background:var(--tui-service-selection-background)}.t-expand:before,.t-expand:after{content:\"\";position:sticky;block-size:100%;border-inline-start:1px solid;border-color:inherit}.t-expand:before{left:0}.t-expand:after{right:0}.t-heading{transition-property:background;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;block-size:var(--tui-height-m);font:var(--tui-font-text-s);padding:0;background:var(--tui-background-neutral-1);border-block-end:1px solid var(--tui-border-normal);border-color:inherit}.t-heading:hover{background:var(--tui-background-neutral-1-hover)}:host-context(table[data-size=\"l\"]) .t-heading{font:var(--tui-font-text-m);block-size:var(--tui-height-l)}.t-name{position:sticky;left:.75rem;display:inline-block}:host-context(table[data-size=\"l\"]) .t-name{left:1rem}.t-chevron{position:sticky;right:.75rem;margin:0 .6875rem 0 auto}\n"] }]
638
- }], propDecorators: { rows: [{
639
- type: ContentChildren,
640
- args: [forwardRef(() => TuiTableTr)]
641
- }], data: [{
642
- type: Input
643
- }], heading: [{
644
- type: Input
645
- }], open: [{
646
- type: Input
647
- }], openChange: [{
648
- type: Output
649
- }] } });
573
+ args: [{ selector: 'tbody[tuiTbody]', imports: [PolymorpheusOutlet, TuiChevron, TuiIcon], changeDetection: ChangeDetectionStrategy.OnPush, providers: TUI_TABLE_PROVIDER, template: "@if (heading()) {\n <tr>\n <th\n class=\"t-heading\"\n [colSpan]=\"table.columns().length\"\n >\n <button\n type=\"button\"\n class=\"t-expand\"\n (click)=\"onClick()\"\n >\n <span class=\"t-name\">\n <ng-container *polymorpheusOutlet=\"heading() as text\">\n {{ text }}\n </ng-container>\n </span>\n <tui-icon\n class=\"t-chevron\"\n [tuiChevron]=\"open()\"\n />\n </button>\n </th>\n </tr>\n}\n@if (open()) {\n <ng-content />\n}\n", styles: [":host{border-color:var(--tui-border-normal)}:host tr{border-color:inherit}.t-expand{-webkit-appearance:none;appearance:none;padding:0;border:0;background:none;font:inherit;line-height:inherit;text-decoration:none;display:flex;inline-size:100%;block-size:100%;align-items:center;box-sizing:border-box;outline:none;font-weight:700;cursor:pointer;border-color:inherit}.t-expand:focus-visible .t-name{background:var(--tui-service-selection-background)}.t-expand:before,.t-expand:after{content:\"\";position:sticky;block-size:100%;border-inline-start:1px solid;border-color:inherit}.t-expand:before{left:0}.t-expand:after{right:0}.t-heading{transition-property:background;transition-duration:var(--tui-duration, .3s);transition-timing-function:ease-in-out;block-size:var(--tui-height-m);font:var(--tui-font-text-s);padding:0;background:var(--tui-background-neutral-1);border-block-end:1px solid var(--tui-border-normal);border-color:inherit}.t-heading:hover{background:var(--tui-background-neutral-1-hover)}:host-context(table[data-size=\"l\"]) .t-heading{font:var(--tui-font-text-m);block-size:var(--tui-height-l)}.t-name{position:sticky;left:.75rem;display:inline-block}:host-context(table[data-size=\"l\"]) .t-name{left:1rem}.t-chevron{position:sticky;right:.75rem;margin:0 .6875rem 0 auto}\n"] }]
574
+ }] });
650
575
 
651
576
  class TuiTableThGroup {
652
577
  constructor() {
653
- this.heads = EMPTY_QUERY;
654
- this.heads$ = null;
578
+ this.th = contentChild(forwardRef(() => TuiTableTh));
579
+ this.heads = contentChildren(forwardRef(() => TuiTableHead));
580
+ this.computedHeads = computed(() => {
581
+ return this.heads().reduce((record, item) => ({ ...record, [item.tuiHead()]: item }), {});
582
+ });
655
583
  this.table = inject(forwardRef(() => TuiTableDirective));
656
584
  }
657
- ngAfterContentInit() {
658
- this.heads$ = this.heads.changes.pipe(startWith(null), map(() => this.heads.reduce((record, item) => ({ ...record, [item.tuiHead]: item }), {})));
659
- }
660
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableThGroup, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
661
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: TuiTableThGroup, isStandalone: true, selector: "tr[tuiThGroup]", providers: [TUI_TABLE_PROVIDER], queries: [{ propertyName: "th", first: true, predicate: i0.forwardRef(() => TuiTableTh), descendants: true }, { propertyName: "heads", predicate: i0.forwardRef(() => TuiTableHead) }], ngImport: i0, template: "<ng-content />\n@if (heads$ | async; as headings) {\n @for (key of table.columns; track key) {\n <ng-container\n [ngTemplateOutlet]=\"headings?.[key]?.template || plain\"\n [ngTemplateOutletContext]=\"{$implicit: key}\"\n />\n }\n <ng-template\n #plain\n let-key\n >\n @if (!th && !heads.length) {\n <th tuiTh>\n {{ key.toString() }}\n </th>\n }\n </ng-template>\n}\n", dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TuiTableTh, selector: "th[tuiTh]", inputs: ["minWidth", "maxWidth", "sorter", "resizable", "sticky", "requiredSort"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
585
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableThGroup, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
586
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: TuiTableThGroup, isStandalone: true, selector: "tr[tuiThGroup]", providers: [TUI_TABLE_PROVIDER], queries: [{ propertyName: "th", first: true, predicate: i0.forwardRef(() => TuiTableTh), descendants: true, isSignal: true }, { propertyName: "heads", predicate: i0.forwardRef(() => TuiTableHead), isSignal: true }], ngImport: i0, template: "<ng-content />\n@if (computedHeads(); as headings) {\n @for (key of table.columns(); track key) {\n <ng-container\n [ngTemplateOutlet]=\"headings?.[key]?.template || plain\"\n [ngTemplateOutletContext]=\"{$implicit: key}\"\n />\n }\n <ng-template\n #plain\n let-key\n >\n @if (!th() && !heads().length) {\n <th tuiTh>\n {{ key.toString() }}\n </th>\n }\n </ng-template>\n}\n", dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: TuiTableTh, selector: "th[tuiTh]", inputs: ["minWidth", "maxWidth", "sorter", "resizable", "sticky", "requiredSort"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
662
587
  }
663
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: TuiTableThGroup, decorators: [{
588
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: TuiTableThGroup, decorators: [{
664
589
  type: Component,
665
- args: [{ selector: 'tr[tuiThGroup]', imports: [AsyncPipe, NgTemplateOutlet, TuiTableTh], changeDetection: ChangeDetectionStrategy.OnPush, providers: [TUI_TABLE_PROVIDER], template: "<ng-content />\n@if (heads$ | async; as headings) {\n @for (key of table.columns; track key) {\n <ng-container\n [ngTemplateOutlet]=\"headings?.[key]?.template || plain\"\n [ngTemplateOutletContext]=\"{$implicit: key}\"\n />\n }\n <ng-template\n #plain\n let-key\n >\n @if (!th && !heads.length) {\n <th tuiTh>\n {{ key.toString() }}\n </th>\n }\n </ng-template>\n}\n" }]
666
- }], propDecorators: { th: [{
667
- type: ContentChild,
668
- args: [forwardRef(() => TuiTableTh)]
669
- }], heads: [{
670
- type: ContentChildren,
671
- args: [forwardRef(() => TuiTableHead)]
672
- }] } });
590
+ args: [{ selector: 'tr[tuiThGroup]', imports: [NgTemplateOutlet, TuiTableTh], changeDetection: ChangeDetectionStrategy.OnPush, providers: [TUI_TABLE_PROVIDER], template: "<ng-content />\n@if (computedHeads(); as headings) {\n @for (key of table.columns(); track key) {\n <ng-container\n [ngTemplateOutlet]=\"headings?.[key]?.template || plain\"\n [ngTemplateOutletContext]=\"{$implicit: key}\"\n />\n }\n <ng-template\n #plain\n let-key\n >\n @if (!th() && !heads().length) {\n <th tuiTh>\n {{ key.toString() }}\n </th>\n }\n </ng-template>\n}\n" }]
591
+ }] });
673
592
 
674
593
  const TuiTable = [
675
594
  TuiTableDirective,