Skip to content

Commit 3bd1b2f

Browse files
feat(cdk/table): add element offsets to sticky styler state
1 parent 70ff528 commit 3bd1b2f

File tree

4 files changed

+70
-36
lines changed

4 files changed

+70
-36
lines changed

src/cdk/table/sticky-position-listener.ts

+2
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ export const STICKY_POSITIONING_LISTENER =
1313
new InjectionToken<StickyPositioningListener>('CDK_SPL');
1414

1515
export type StickySize = number|null|undefined;
16+
export type StickyOffset = number|null|undefined;
1617

1718
export interface StickyUpdate {
1819
elements?: ReadonlyArray<HTMLElement[]|undefined>;
20+
offsets?: StickyOffset[];
1921
sizes: StickySize[];
2022
}
2123

src/cdk/table/sticky-styler.ts

+3-4
Original file line numberDiff line numberDiff line change
@@ -194,12 +194,11 @@ export class StickyStyler {
194194
const stickyCellHeights: (number|undefined)[] = [];
195195
const elementsToStick: HTMLElement[][] = [];
196196
for (let rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) {
197-
stickyOffsets[rowIndex] = stickyOffset;
198-
199197
if (!states[rowIndex]) {
200198
continue;
201199
}
202200

201+
stickyOffsets[rowIndex] = stickyOffset;
203202
const row = rows[rowIndex];
204203
elementsToStick[rowIndex] = this._isNativeHtmlTable ?
205204
Array.from(row.children) as HTMLElement[] : [row];
@@ -228,10 +227,10 @@ export class StickyStyler {
228227

229228
if (position === 'top') {
230229
this._positionListener?.stickyHeaderRowsUpdated(
231-
{sizes: stickyCellHeights, elements: elementsToStick});
230+
{sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick});
232231
} else {
233232
this._positionListener?.stickyFooterRowsUpdated(
234-
{sizes: stickyCellHeights, elements: elementsToStick});
233+
{sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick});
235234
}
236235
});
237236
}

src/cdk/table/table.spec.ts

+62-32
Original file line numberDiff line numberDiff line change
@@ -922,18 +922,23 @@ describe('CdkTable', () => {
922922
undefined,
923923
headerRows[2].getBoundingClientRect().height,
924924
],
925+
offsets: [
926+
0,
927+
undefined,
928+
headerRows[0].getBoundingClientRect().height,
929+
],
925930
elements: [[headerRows[0]], undefined, [headerRows[2]]],
926931
});
927-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
932+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
928933
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
929934
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
930935

931936
component.stickyHeaders = [];
932937
fixture.detectChanges();
933938
flushMicrotasks();
934939
expectNoStickyStyles(headerRows);
935-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
936-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
940+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
941+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
937942
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
938943
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
939944
}));
@@ -949,13 +954,14 @@ describe('CdkTable', () => {
949954
expectNoStickyStyles([footerRows[1]]);
950955
expectStickyStyles(footerRows[2], '10', {bottom: '0px'});
951956
expectStickyBorderClass(footerRows[2]);
952-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
957+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
953958
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
954959
sizes: [
955960
footerRows[2].getBoundingClientRect().height,
956961
undefined,
957962
footerRows[0].getBoundingClientRect().height,
958963
],
964+
offsets: [0, undefined, footerRows[0].getBoundingClientRect().height],
959965
elements: [[footerRows[2]], undefined, [footerRows[0]]],
960966
});
961967
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
@@ -965,8 +971,8 @@ describe('CdkTable', () => {
965971
fixture.detectChanges();
966972
flushMicrotasks();
967973
expectNoStickyStyles(footerRows);
968-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
969-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
974+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
975+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
970976
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
971977
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
972978
}));
@@ -1010,8 +1016,8 @@ describe('CdkTable', () => {
10101016
expectStickyBorderClass(cells[2], {left: true});
10111017
expectNoStickyStyles([cells[1], cells[3], cells[4], cells[5]]);
10121018
});
1013-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1014-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1019+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
1020+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
10151021
expect(component.mostRecentStickyColumnsUpdate).toEqual({
10161022
sizes: [
10171023
getCells(dataRows[0])[0].getBoundingClientRect().width,
@@ -1028,8 +1034,8 @@ describe('CdkTable', () => {
10281034
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
10291035
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
10301036
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1031-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1032-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1037+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
1038+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
10331039
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10341040
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
10351041
}));
@@ -1063,8 +1069,8 @@ describe('CdkTable', () => {
10631069
expectStickyBorderClass(cells[3], {right: true});
10641070
expectNoStickyStyles([cells[0], cells[1], cells[2], cells[4]]);
10651071
});
1066-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1067-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1072+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
1073+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
10681074
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10691075
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({
10701076
sizes: [
@@ -1080,8 +1086,8 @@ describe('CdkTable', () => {
10801086
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
10811087
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
10821088
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1083-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1084-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1089+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
1090+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
10851091
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10861092
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
10871093
}));
@@ -1169,10 +1175,12 @@ describe('CdkTable', () => {
11691175

11701176
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({
11711177
sizes: [headerRows[0].getBoundingClientRect().height],
1178+
offsets: [0],
11721179
elements: [[headerRows[0]]],
11731180
});
11741181
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
11751182
sizes: [footerRows[2].getBoundingClientRect().height],
1183+
offsets: [0],
11761184
elements: [[footerRows[2]]],
11771185
});
11781186
expect(component.mostRecentStickyColumnsUpdate).toEqual({
@@ -1193,8 +1201,8 @@ describe('CdkTable', () => {
11931201
dataRows.forEach(row => expectNoStickyStyles([row, ...getCells(row)]));
11941202
footerRows.forEach(row => expectNoStickyStyles([row, ...getFooterCells(row)]));
11951203

1196-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1197-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1204+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
1205+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
11981206
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
11991207
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12001208
}));
@@ -1235,9 +1243,14 @@ describe('CdkTable', () => {
12351243
undefined,
12361244
headerRows[2].getBoundingClientRect().height,
12371245
],
1246+
offsets: [
1247+
0,
1248+
undefined,
1249+
headerRows[0].getBoundingClientRect().height,
1250+
],
12381251
elements: [getHeaderCells(headerRows[0]), undefined, getHeaderCells(headerRows[2])],
12391252
});
1240-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1253+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
12411254
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
12421255
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12431256

@@ -1246,8 +1259,8 @@ describe('CdkTable', () => {
12461259
flushMicrotasks();
12471260
expectNoStickyStyles(headerRows); // No sticky styles on rows for native table
12481261
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
1249-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1250-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1262+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
1263+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
12511264
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
12521265
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12531266
}));
@@ -1268,13 +1281,18 @@ describe('CdkTable', () => {
12681281
});
12691282
expectNoStickyStyles(getFooterCells(footerRows[1]));
12701283
expectNoStickyStyles(footerRows); // No sticky styles on rows for native table
1271-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1284+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
12721285
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
12731286
sizes: [
12741287
footerRows[2].getBoundingClientRect().height,
12751288
undefined,
12761289
footerRows[0].getBoundingClientRect().height,
12771290
],
1291+
offsets: [
1292+
0,
1293+
undefined,
1294+
footerRows[2].getBoundingClientRect().height,
1295+
],
12781296
elements: [getFooterCells(footerRows[2]), undefined, getFooterCells(footerRows[0])],
12791297
});
12801298
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
@@ -1285,8 +1303,8 @@ describe('CdkTable', () => {
12851303
flushMicrotasks();
12861304
expectNoStickyStyles(footerRows); // No sticky styles on rows for native table
12871305
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1288-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1289-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1306+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
1307+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], offsets: [], elements: []});
12901308
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
12911309
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12921310
}));
@@ -1339,8 +1357,10 @@ describe('CdkTable', () => {
13391357
expectStickyBorderClass(cells[2], {left: true});
13401358
expectNoStickyStyles([cells[1], cells[3], cells[4], cells[5]]);
13411359
});
1342-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1343-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1360+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1361+
{sizes: [], offsets: [], elements: []});
1362+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1363+
{sizes: [], offsets: [], elements: []});
13441364
expect(component.mostRecentStickyColumnsUpdate).toEqual({
13451365
sizes: [
13461366
getCells(dataRows[0])[0].getBoundingClientRect().width,
@@ -1356,8 +1376,10 @@ describe('CdkTable', () => {
13561376
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
13571377
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
13581378
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1359-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1360-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1379+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1380+
{sizes: [], offsets: [], elements: []});
1381+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1382+
{sizes: [], offsets: [], elements: []});
13611383
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
13621384
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
13631385
}));
@@ -1391,8 +1413,10 @@ describe('CdkTable', () => {
13911413
expectStickyBorderClass(cells[3], {right: true});
13921414
expectNoStickyStyles([cells[0], cells[1], cells[2], cells[4]]);
13931415
});
1394-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1395-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1416+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1417+
{sizes: [], offsets: [], elements: []});
1418+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1419+
{sizes: [], offsets: [], elements: []});
13961420
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
13971421
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({
13981422
sizes: [
@@ -1408,8 +1432,10 @@ describe('CdkTable', () => {
14081432
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
14091433
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
14101434
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1411-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1412-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1435+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1436+
{sizes: [], offsets: [], elements: []});
1437+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1438+
{sizes: [], offsets: [], elements: []});
14131439
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
14141440
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
14151441
}));
@@ -1464,10 +1490,12 @@ describe('CdkTable', () => {
14641490

14651491
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({
14661492
sizes: [headerRows[0].getBoundingClientRect().height],
1493+
offsets: [0],
14671494
elements: [getHeaderCells(headerRows[0])],
14681495
});
14691496
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
14701497
sizes: [footerRows[2].getBoundingClientRect().height],
1498+
offsets: [0],
14711499
elements: [getFooterCells(footerRows[2])],
14721500
});
14731501
expect(component.mostRecentStickyColumnsUpdate).toEqual({
@@ -1488,8 +1516,10 @@ describe('CdkTable', () => {
14881516
dataRows.forEach(row => expectNoStickyStyles([row, ...getCells(row)]));
14891517
footerRows.forEach(row => expectNoStickyStyles([row, ...getFooterCells(row)]));
14901518

1491-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1492-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1519+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1520+
{sizes: [], offsets: [], elements: []});
1521+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1522+
{sizes: [], offsets: [], elements: []});
14931523
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
14941524
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
14951525
}));

tools/public_api_guard/cdk/table.d.ts

+3
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,8 @@ export declare const STICKY_POSITIONING_LISTENER: InjectionToken<StickyPositioni
333333

334334
export declare type StickyDirection = 'top' | 'bottom' | 'left' | 'right';
335335

336+
export declare type StickyOffset = number | null | undefined;
337+
336338
export interface StickyPositioningListener {
337339
stickyColumnsUpdated(update: StickyUpdate): void;
338340
stickyEndColumnsUpdated(update: StickyUpdate): void;
@@ -360,6 +362,7 @@ export declare class StickyStyler {
360362

361363
export interface StickyUpdate {
362364
elements?: ReadonlyArray<HTMLElement[] | undefined>;
365+
offsets?: StickyOffset[];
363366
sizes: StickySize[];
364367
}
365368

0 commit comments

Comments
 (0)