Skip to content

Commit c42ece3

Browse files
feat(cdk/table): add element offsets to sticky styler state (#21886)
1 parent 3a50c41 commit c42ece3

File tree

4 files changed

+92
-36
lines changed

4 files changed

+92
-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
@@ -190,12 +190,11 @@ export class StickyStyler {
190190
const stickyCellHeights: (number|undefined)[] = [];
191191
const elementsToStick: HTMLElement[][] = [];
192192
for (let rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) {
193-
stickyOffsets[rowIndex] = stickyOffset;
194-
195193
if (!states[rowIndex]) {
196194
continue;
197195
}
198196

197+
stickyOffsets[rowIndex] = stickyOffset;
199198
const row = rows[rowIndex];
200199
elementsToStick[rowIndex] = this._isNativeHtmlTable ?
201200
Array.from(row.children) as HTMLElement[] : [row];
@@ -224,10 +223,10 @@ export class StickyStyler {
224223

225224
if (position === 'top') {
226225
this._positionListener?.stickyHeaderRowsUpdated(
227-
{sizes: stickyCellHeights, elements: elementsToStick});
226+
{sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick});
228227
} else {
229228
this._positionListener?.stickyFooterRowsUpdated(
230-
{sizes: stickyCellHeights, elements: elementsToStick});
229+
{sizes: stickyCellHeights, offsets: stickyOffsets, elements: elementsToStick});
231230
}
232231
});
233232
}

src/cdk/table/table.spec.ts

+84-32
Original file line numberDiff line numberDiff line change
@@ -922,18 +922,26 @@ 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(
933+
{sizes: [], offsets: [], elements: []});
928934
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
929935
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
930936

931937
component.stickyHeaders = [];
932938
fixture.detectChanges();
933939
flushMicrotasks();
934940
expectNoStickyStyles(headerRows);
935-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
936-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
941+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
942+
{sizes: [], offsets: [], elements: []});
943+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
944+
{sizes: [], offsets: [], elements: []});
937945
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
938946
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
939947
}));
@@ -949,13 +957,15 @@ describe('CdkTable', () => {
949957
expectNoStickyStyles([footerRows[1]]);
950958
expectStickyStyles(footerRows[2], '10', {bottom: '0px'});
951959
expectStickyBorderClass(footerRows[2]);
952-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
960+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
961+
{sizes: [], offsets: [], elements: []});
953962
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
954963
sizes: [
955964
footerRows[2].getBoundingClientRect().height,
956965
undefined,
957966
footerRows[0].getBoundingClientRect().height,
958967
],
968+
offsets: [0, undefined, footerRows[0].getBoundingClientRect().height],
959969
elements: [[footerRows[2]], undefined, [footerRows[0]]],
960970
});
961971
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
@@ -965,8 +975,10 @@ describe('CdkTable', () => {
965975
fixture.detectChanges();
966976
flushMicrotasks();
967977
expectNoStickyStyles(footerRows);
968-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
969-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
978+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
979+
{sizes: [], offsets: [], elements: []});
980+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
981+
{sizes: [], offsets: [], elements: []});
970982
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
971983
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
972984
}));
@@ -1010,8 +1022,10 @@ describe('CdkTable', () => {
10101022
expectStickyBorderClass(cells[2], {left: true});
10111023
expectNoStickyStyles([cells[1], cells[3], cells[4], cells[5]]);
10121024
});
1013-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1014-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1025+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1026+
{sizes: [], offsets: [], elements: []});
1027+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1028+
{sizes: [], offsets: [], elements: []});
10151029
expect(component.mostRecentStickyColumnsUpdate).toEqual({
10161030
sizes: [
10171031
getCells(dataRows[0])[0].getBoundingClientRect().width,
@@ -1028,8 +1042,10 @@ describe('CdkTable', () => {
10281042
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
10291043
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
10301044
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1031-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1032-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1045+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1046+
{sizes: [], offsets: [], elements: []});
1047+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1048+
{sizes: [], offsets: [], elements: []});
10331049
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10341050
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
10351051
}));
@@ -1063,8 +1079,10 @@ describe('CdkTable', () => {
10631079
expectStickyBorderClass(cells[3], {right: true});
10641080
expectNoStickyStyles([cells[0], cells[1], cells[2], cells[4]]);
10651081
});
1066-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1067-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1082+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1083+
{sizes: [], offsets: [], elements: []});
1084+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1085+
{sizes: [], offsets: [], elements: []});
10681086
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10691087
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({
10701088
sizes: [
@@ -1080,8 +1098,10 @@ describe('CdkTable', () => {
10801098
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
10811099
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
10821100
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1083-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1084-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1101+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1102+
{sizes: [], offsets: [], elements: []});
1103+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1104+
{sizes: [], offsets: [], elements: []});
10851105
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
10861106
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
10871107
}));
@@ -1169,10 +1189,12 @@ describe('CdkTable', () => {
11691189

11701190
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({
11711191
sizes: [headerRows[0].getBoundingClientRect().height],
1192+
offsets: [0],
11721193
elements: [[headerRows[0]]],
11731194
});
11741195
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
11751196
sizes: [footerRows[2].getBoundingClientRect().height],
1197+
offsets: [0],
11761198
elements: [[footerRows[2]]],
11771199
});
11781200
expect(component.mostRecentStickyColumnsUpdate).toEqual({
@@ -1193,8 +1215,10 @@ describe('CdkTable', () => {
11931215
dataRows.forEach(row => expectNoStickyStyles([row, ...getCells(row)]));
11941216
footerRows.forEach(row => expectNoStickyStyles([row, ...getFooterCells(row)]));
11951217

1196-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1197-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1218+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1219+
{sizes: [], offsets: [], elements: []});
1220+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1221+
{sizes: [], offsets: [], elements: []});
11981222
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
11991223
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12001224
}));
@@ -1235,9 +1259,15 @@ describe('CdkTable', () => {
12351259
undefined,
12361260
headerRows[2].getBoundingClientRect().height,
12371261
],
1262+
offsets: [
1263+
0,
1264+
undefined,
1265+
headerRows[0].getBoundingClientRect().height,
1266+
],
12381267
elements: [getHeaderCells(headerRows[0]), undefined, getHeaderCells(headerRows[2])],
12391268
});
1240-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1269+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1270+
{sizes: [], offsets: [], elements: []});
12411271
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
12421272
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12431273

@@ -1246,8 +1276,10 @@ describe('CdkTable', () => {
12461276
flushMicrotasks();
12471277
expectNoStickyStyles(headerRows); // No sticky styles on rows for native table
12481278
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
1249-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1250-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1279+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1280+
{sizes: [], offsets: [], elements: []});
1281+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1282+
{sizes: [], offsets: [], elements: []});
12511283
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
12521284
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12531285
}));
@@ -1268,13 +1300,19 @@ describe('CdkTable', () => {
12681300
});
12691301
expectNoStickyStyles(getFooterCells(footerRows[1]));
12701302
expectNoStickyStyles(footerRows); // No sticky styles on rows for native table
1271-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1303+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1304+
{sizes: [], offsets: [], elements: []});
12721305
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
12731306
sizes: [
12741307
footerRows[2].getBoundingClientRect().height,
12751308
undefined,
12761309
footerRows[0].getBoundingClientRect().height,
12771310
],
1311+
offsets: [
1312+
0,
1313+
undefined,
1314+
footerRows[2].getBoundingClientRect().height,
1315+
],
12781316
elements: [getFooterCells(footerRows[2]), undefined, getFooterCells(footerRows[0])],
12791317
});
12801318
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
@@ -1285,8 +1323,10 @@ describe('CdkTable', () => {
12851323
flushMicrotasks();
12861324
expectNoStickyStyles(footerRows); // No sticky styles on rows for native table
12871325
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1288-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1289-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1326+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1327+
{sizes: [], offsets: [], elements: []});
1328+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1329+
{sizes: [], offsets: [], elements: []});
12901330
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
12911331
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
12921332
}));
@@ -1339,8 +1379,10 @@ describe('CdkTable', () => {
13391379
expectStickyBorderClass(cells[2], {left: true});
13401380
expectNoStickyStyles([cells[1], cells[3], cells[4], cells[5]]);
13411381
});
1342-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1343-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1382+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1383+
{sizes: [], offsets: [], elements: []});
1384+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1385+
{sizes: [], offsets: [], elements: []});
13441386
expect(component.mostRecentStickyColumnsUpdate).toEqual({
13451387
sizes: [
13461388
getCells(dataRows[0])[0].getBoundingClientRect().width,
@@ -1356,8 +1398,10 @@ describe('CdkTable', () => {
13561398
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
13571399
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
13581400
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1359-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1360-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1401+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1402+
{sizes: [], offsets: [], elements: []});
1403+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1404+
{sizes: [], offsets: [], elements: []});
13611405
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
13621406
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
13631407
}));
@@ -1391,8 +1435,10 @@ describe('CdkTable', () => {
13911435
expectStickyBorderClass(cells[3], {right: true});
13921436
expectNoStickyStyles([cells[0], cells[1], cells[2], cells[4]]);
13931437
});
1394-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1395-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1438+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1439+
{sizes: [], offsets: [], elements: []});
1440+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1441+
{sizes: [], offsets: [], elements: []});
13961442
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
13971443
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({
13981444
sizes: [
@@ -1408,8 +1454,10 @@ describe('CdkTable', () => {
14081454
headerRows.forEach(row => expectNoStickyStyles(getHeaderCells(row)));
14091455
dataRows.forEach(row => expectNoStickyStyles(getCells(row)));
14101456
footerRows.forEach(row => expectNoStickyStyles(getFooterCells(row)));
1411-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1412-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1457+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1458+
{sizes: [], offsets: [], elements: []});
1459+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1460+
{sizes: [], offsets: [], elements: []});
14131461
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
14141462
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
14151463
}));
@@ -1464,10 +1512,12 @@ describe('CdkTable', () => {
14641512

14651513
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({
14661514
sizes: [headerRows[0].getBoundingClientRect().height],
1515+
offsets: [0],
14671516
elements: [getHeaderCells(headerRows[0])],
14681517
});
14691518
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({
14701519
sizes: [footerRows[2].getBoundingClientRect().height],
1520+
offsets: [0],
14711521
elements: [getFooterCells(footerRows[2])],
14721522
});
14731523
expect(component.mostRecentStickyColumnsUpdate).toEqual({
@@ -1488,8 +1538,10 @@ describe('CdkTable', () => {
14881538
dataRows.forEach(row => expectNoStickyStyles([row, ...getCells(row)]));
14891539
footerRows.forEach(row => expectNoStickyStyles([row, ...getFooterCells(row)]));
14901540

1491-
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual({sizes: [], elements: []});
1492-
expect(component.mostRecentStickyFooterRowsUpdate).toEqual({sizes: [], elements: []});
1541+
expect(component.mostRecentStickyHeaderRowsUpdate).toEqual(
1542+
{sizes: [], offsets: [], elements: []});
1543+
expect(component.mostRecentStickyFooterRowsUpdate).toEqual(
1544+
{sizes: [], offsets: [], elements: []});
14931545
expect(component.mostRecentStickyColumnsUpdate).toEqual({sizes: []});
14941546
expect(component.mostRecentStickyEndColumnsUpdate).toEqual({sizes: []});
14951547
}));

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;
@@ -359,6 +361,7 @@ export declare class StickyStyler {
359361

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

0 commit comments

Comments
 (0)