diff --git a/src/cdk/table/sticky-position-listener.ts b/src/cdk/table/sticky-position-listener.ts index c604c86f3788..906d1272e125 100644 --- a/src/cdk/table/sticky-position-listener.ts +++ b/src/cdk/table/sticky-position-listener.ts @@ -13,9 +13,11 @@ export const STICKY_POSITIONING_LISTENER = new InjectionToken('CDK_SPL'); export type StickySize = number|null|undefined; +export type StickyOffset = number|null|undefined; export interface StickyUpdate { elements?: ReadonlyArray; + offsets?: StickyOffset[]; sizes: StickySize[]; } diff --git a/src/cdk/table/sticky-styler.ts b/src/cdk/table/sticky-styler.ts index 11179c5845ff..c1ed66a84904 100644 --- a/src/cdk/table/sticky-styler.ts +++ b/src/cdk/table/sticky-styler.ts @@ -190,12 +190,11 @@ export class StickyStyler { const stickyCellHeights: (number|undefined)[] = []; const elementsToStick: HTMLElement[][] = []; for (let rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) { - stickyOffsets[rowIndex] = stickyOffset; - if (!states[rowIndex]) { continue; } + stickyOffsets[rowIndex] = stickyOffset; const row = rows[rowIndex]; elementsToStick[rowIndex] = this._isNativeHtmlTable ? Array.from(row.children) as HTMLElement[] : [row]; @@ -224,10 +223,10 @@ export class StickyStyler { if (position === 'top') { this._positionListener?.stickyHeaderRowsUpdated( - {sizes: stickyCellHeights, elements: elementsToStick}); + {sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick}); } else { this._positionListener?.stickyFooterRowsUpdated( - {sizes: stickyCellHeights, elements: elementsToStick}); + {sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick}); } }); } diff --git a/src/cdk/table/table.spec.ts b/src/cdk/table/table.spec.ts index b890db97151d..6e5d8d806c33 100644 --- a/src/cdk/table/table.spec.ts +++ b/src/cdk/table/table.spec.ts @@ -922,9 +922,15 @@ describe('CdkTable', () => { undefined, headerRows[2].getBoundingClientRect().height, ], + offsets: [ + 0, + undefined, + headerRows[0].getBoundingClientRect().height, + ], elements: [[headerRows[0]], undefined, [headerRows[2]]], }); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); @@ -932,8 +938,10 @@ describe('CdkTable', () => { fixture.detectChanges(); flushMicrotasks(); expectNoStickyStyles(headerRows); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -949,13 +957,15 @@ describe('CdkTable', () => { expectNoStickyStyles([footerRows[1]]); expectStickyStyles(footerRows[2], '10', {bottom: '0px'}); expectStickyBorderClass(footerRows[2]); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyFooterRowsUpdate).toEqual({ sizes: [ footerRows[2].getBoundingClientRect().height, undefined, footerRows[0].getBoundingClientRect().height, ], + offsets: [0, undefined, footerRows[0].getBoundingClientRect().height], elements: [[footerRows[2]], undefined, [footerRows[0]]], }); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); @@ -965,8 +975,10 @@ describe('CdkTable', () => { fixture.detectChanges(); flushMicrotasks(); expectNoStickyStyles(footerRows); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1010,8 +1022,10 @@ describe('CdkTable', () => { expectStickyBorderClass(cells[2], {left: true}); expectNoStickyStyles([cells[1], cells[3], cells[4], cells[5]]); }); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({ sizes: [ getCells(dataRows[0])[0].getBoundingClientRect().width, @@ -1028,8 +1042,10 @@ describe('CdkTable', () => { headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row))); dataRows.forEach(row => expectNoStickyStyles(getCells(row))); footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row))); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1063,8 +1079,10 @@ describe('CdkTable', () => { expectStickyBorderClass(cells[3], {right: true}); expectNoStickyStyles([cells[0], cells[1], cells[2], cells[4]]); }); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({ sizes: [ @@ -1080,8 +1098,10 @@ describe('CdkTable', () => { headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row))); dataRows.forEach(row => expectNoStickyStyles(getCells(row))); footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row))); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1169,10 +1189,12 @@ describe('CdkTable', () => { expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({ sizes: [headerRows[0].getBoundingClientRect().height], + offsets: [0], elements: [[headerRows[0]]], }); expect(component.mostRecentStickyFooterRowsUpdate).toEqual({ sizes: [footerRows[2].getBoundingClientRect().height], + offsets: [0], elements: [[footerRows[2]]], }); expect(component.mostRecentStickyColumnsUpdate).toEqual({ @@ -1193,8 +1215,10 @@ describe('CdkTable', () => { dataRows.forEach(row => expectNoStickyStyles([row, ...getCells(row)])); footerRows.forEach(row => expectNoStickyStyles([row, ...getFooterCells(row)])); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1235,9 +1259,15 @@ describe('CdkTable', () => { undefined, headerRows[2].getBoundingClientRect().height, ], + offsets: [ + 0, + undefined, + headerRows[0].getBoundingClientRect().height, + ], elements: [getHeaderCells(headerRows[0]), undefined, getHeaderCells(headerRows[2])], }); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); @@ -1246,8 +1276,10 @@ describe('CdkTable', () => { flushMicrotasks(); expectNoStickyStyles(headerRows); // No sticky styles on rows for native table headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row))); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1268,13 +1300,19 @@ describe('CdkTable', () => { }); expectNoStickyStyles(getFooterCells(footerRows[1])); expectNoStickyStyles(footerRows); // No sticky styles on rows for native table - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyFooterRowsUpdate).toEqual({ sizes: [ footerRows[2].getBoundingClientRect().height, undefined, footerRows[0].getBoundingClientRect().height, ], + offsets: [ + 0, + undefined, + footerRows[2].getBoundingClientRect().height, + ], elements: [getFooterCells(footerRows[2]), undefined, getFooterCells(footerRows[0])], }); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); @@ -1285,8 +1323,10 @@ describe('CdkTable', () => { flushMicrotasks(); expectNoStickyStyles(footerRows); // No sticky styles on rows for native table footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row))); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1339,8 +1379,10 @@ describe('CdkTable', () => { expectStickyBorderClass(cells[2], {left: true}); expectNoStickyStyles([cells[1], cells[3], cells[4], cells[5]]); }); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({ sizes: [ getCells(dataRows[0])[0].getBoundingClientRect().width, @@ -1356,8 +1398,10 @@ describe('CdkTable', () => { headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row))); dataRows.forEach(row => expectNoStickyStyles(getCells(row))); footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row))); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1391,8 +1435,10 @@ describe('CdkTable', () => { expectStickyBorderClass(cells[3], {right: true}); expectNoStickyStyles([cells[0], cells[1], cells[2], cells[4]]); }); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({ sizes: [ @@ -1408,8 +1454,10 @@ describe('CdkTable', () => { headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row))); dataRows.forEach(row => expectNoStickyStyles(getCells(row))); footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row))); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); @@ -1464,10 +1512,12 @@ describe('CdkTable', () => { expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({ sizes: [headerRows[0].getBoundingClientRect().height], + offsets: [0], elements: [getHeaderCells(headerRows[0])], }); expect(component.mostRecentStickyFooterRowsUpdate).toEqual({ sizes: [footerRows[2].getBoundingClientRect().height], + offsets: [0], elements: [getFooterCells(footerRows[2])], }); expect(component.mostRecentStickyColumnsUpdate).toEqual({ @@ -1488,8 +1538,10 @@ describe('CdkTable', () => { dataRows.forEach(row => expectNoStickyStyles([row, ...getCells(row)])); footerRows.forEach(row => expectNoStickyStyles([row, ...getFooterCells(row)])); - expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []}); - expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []}); + expect(component.mostRecentStickyHeaderRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); + expect(component.mostRecentStickyFooterRowsUpdate).toEqual( + {sizes: [], offsets: [], elements: []}); expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []}); expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []}); })); diff --git a/tools/public_api_guard/cdk/table.d.ts b/tools/public_api_guard/cdk/table.d.ts index a4b602c8cda0..bd591429fce9 100644 --- a/tools/public_api_guard/cdk/table.d.ts +++ b/tools/public_api_guard/cdk/table.d.ts @@ -333,6 +333,8 @@ export declare const STICKY_POSITIONING_LISTENER: InjectionToken; + offsets?: StickyOffset[]; sizes: StickySize[]; }