Skip to content

Commit e251b44

Browse files
committed
fix(cdk/table): Measure column width for sticky columns after new data has rendered.
1 parent a801603 commit e251b44

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

src/cdk/table/table.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import {
4040
IterableChangeRecord,
4141
IterableDiffer,
4242
IterableDiffers,
43+
NgZone,
4344
OnDestroy,
4445
OnInit,
4546
Optional,
@@ -60,7 +61,7 @@ import {
6061
Subject,
6162
Subscription,
6263
} from 'rxjs';
63-
import {takeUntil} from 'rxjs/operators';
64+
import {take, takeUntil} from 'rxjs/operators';
6465
import {CdkColumnDef} from './cell';
6566
import {_CoalescedStyleScheduler, _COALESCED_STYLE_SCHEDULER} from './coalesced-style-scheduler';
6667
import {
@@ -525,6 +526,12 @@ export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDes
525526
@SkipSelf()
526527
@Inject(STICKY_POSITIONING_LISTENER)
527528
protected readonly _stickyPositioningListener: StickyPositioningListener,
529+
/**
530+
* @deprecated `_ngZone` parameter to become required.
531+
* @breaking-change 14.0.0
532+
*/
533+
@Optional()
534+
protected readonly _ngZone: NgZone,
528535
) {
529536
if (!role) {
530537
this._elementRef.nativeElement.setAttribute('role', 'table');
@@ -666,7 +673,16 @@ export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDes
666673
});
667674

668675
this._updateNoDataRow();
669-
this.updateStickyColumnStyles();
676+
677+
// Allow the new row data to render before measuring it.
678+
// @breaking-change 14.0.0 Remove fallback once _ngZone is required.
679+
if (this._ngZone) {
680+
this._ngZone.onStable.pipe(take(1)).subscribe(() => {
681+
this.updateStickyColumnStyles();
682+
});
683+
} else {
684+
this.updateStickyColumnStyles();
685+
}
670686

671687
this.contentChanged.next();
672688
}

src/material/table/table.spec.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,6 +300,7 @@ describe('MatTable', () => {
300300
// Change filter to a_1, should match one row
301301
dataSource.filter = 'a_1';
302302
fixture.detectChanges();
303+
303304
expect(dataSource.filteredData.length).toBe(1);
304305
expect(dataSource.filteredData[0]).toBe(dataSource.data[0]);
305306
expectTableToMatchContent(tableElement, [
@@ -378,6 +379,7 @@ describe('MatTable', () => {
378379
// column plus the first character of the second column.
379380
dataSource.filter = '1b';
380381
fixture.detectChanges();
382+
381383
expect(dataSource.filteredData.length).toBe(0);
382384
expectTableToMatchContent(tableElement, [
383385
['Column A', 'Column B', 'Column C'],
@@ -523,6 +525,7 @@ describe('MatTable', () => {
523525
}
524526
fixture.detectChanges();
525527
flushMicrotasks(); // Resolve promise that updates paginator's length
528+
526529
expectTableToMatchContent(tableElement, [
527530
['Column A', 'Column B', 'Column C'],
528531
['a_1', 'b_1', 'c_1'],
@@ -536,6 +539,7 @@ describe('MatTable', () => {
536539
// Navigate to the next page
537540
component.paginator.nextPage();
538541
fixture.detectChanges();
542+
539543
expectTableToMatchContent(tableElement, [
540544
['Column A', 'Column B', 'Column C'],
541545
['a_6', 'b_6', 'c_6'],

tools/public_api_guard/cdk/table.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,8 @@ export class CdkRowDef<T> extends BaseRowDef {
297297
// @public
298298
export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDestroy, OnInit {
299299
constructor(_differs: IterableDiffers, _changeDetectorRef: ChangeDetectorRef, _elementRef: ElementRef, role: string, _dir: Directionality, _document: any, _platform: Platform, _viewRepeater: _ViewRepeater<T, RenderRow<T>, RowContext<T>>, _coalescedStyleScheduler: _CoalescedStyleScheduler, _viewportRuler: ViewportRuler,
300-
_stickyPositioningListener: StickyPositioningListener);
300+
_stickyPositioningListener: StickyPositioningListener,
301+
_ngZone: NgZone);
301302
addColumnDef(columnDef: CdkColumnDef): void;
302303
addFooterRowDef(footerRowDef: CdkFooterRowDef): void;
303304
addHeaderRowDef(headerRowDef: CdkHeaderRowDef): void;
@@ -344,6 +345,8 @@ export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDes
344345
ngOnDestroy(): void;
345346
// (undocumented)
346347
ngOnInit(): void;
348+
// @deprecated (undocumented)
349+
protected readonly _ngZone: NgZone;
347350
_noDataRow: CdkNoDataRow;
348351
// (undocumented)
349352
_noDataRowOutlet: NoDataRowOutlet;
@@ -372,7 +375,7 @@ export class CdkTable<T> implements AfterContentChecked, CollectionViewer, OnDes
372375
// (undocumented)
373376
static ɵcmp: i0.ɵɵComponentDeclaration<CdkTable<any>, "cdk-table, table[cdk-table]", ["cdkTable"], { "trackBy": "trackBy"; "dataSource": "dataSource"; "multiTemplateDataRows": "multiTemplateDataRows"; "fixedLayout": "fixedLayout"; }, { "contentChanged": "contentChanged"; }, ["_noDataRow", "_contentColumnDefs", "_contentRowDefs", "_contentHeaderRowDefs", "_contentFooterRowDefs"], ["caption", "colgroup, col"]>;
374377
// (undocumented)
375-
static ɵfac: i0.ɵɵFactoryDeclaration<CdkTable<any>, [null, null, null, { attribute: "role"; }, { optional: true; }, null, null, null, null, null, { optional: true; skipSelf: true; }]>;
378+
static ɵfac: i0.ɵɵFactoryDeclaration<CdkTable<any>, [null, null, null, { attribute: "role"; }, { optional: true; }, null, null, null, null, null, { optional: true; skipSelf: true; }, { optional: true; }]>;
376379
}
377380

378381
// @public (undocumented)

0 commit comments

Comments
 (0)