Skip to content

Commit 31fd4cf

Browse files
committed
fix(cdk/table): measuring sticky row too early
Fixes that after #28356 the table rows were measured too early which caused multiple sticky rows not to work as expected.
1 parent 244bed4 commit 31fd4cf

File tree

1 file changed

+37
-36
lines changed

1 file changed

+37
-36
lines changed

src/cdk/table/sticky-styler.ts

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,18 @@ export class StickyStyler {
120120
return;
121121
}
122122

123-
const firstRow = rows[0];
124-
const numCells = firstRow.children.length;
125-
const cellWidths: number[] = this._getCellWidths(firstRow, recalculateCellWidths);
123+
// Coalesce with sticky row updates (and potentially other changes like column resize).
124+
this._coalescedStyleScheduler.schedule(() => {
125+
const firstRow = rows[0];
126+
const numCells = firstRow.children.length;
127+
const cellWidths: number[] = this._getCellWidths(firstRow, recalculateCellWidths);
126128

127-
const startPositions = this._getStickyStartColumnPositions(cellWidths, stickyStartStates);
128-
const endPositions = this._getStickyEndColumnPositions(cellWidths, stickyEndStates);
129+
const startPositions = this._getStickyStartColumnPositions(cellWidths, stickyStartStates);
130+
const endPositions = this._getStickyEndColumnPositions(cellWidths, stickyEndStates);
129131

130-
const lastStickyStart = stickyStartStates.lastIndexOf(true);
131-
const firstStickyEnd = stickyEndStates.indexOf(true);
132+
const lastStickyStart = stickyStartStates.lastIndexOf(true);
133+
const firstStickyEnd = stickyEndStates.indexOf(true);
132134

133-
// Coalesce with sticky row updates (and potentially other changes like column resize).
134-
this._coalescedStyleScheduler.schedule(() => {
135135
const isRtl = this.direction === 'rtl';
136136
const start = isRtl ? 'right' : 'left';
137137
const end = isRtl ? 'left' : 'right';
@@ -188,37 +188,38 @@ export class StickyStyler {
188188
return;
189189
}
190190

191-
// If positioning the rows to the bottom, reverse their order when evaluating the sticky
192-
// position such that the last row stuck will be "bottom: 0px" and so on. Note that the
193-
// sticky states need to be reversed as well.
194-
const rows = position === 'bottom' ? rowsToStick.slice().reverse() : rowsToStick;
195-
const states = position === 'bottom' ? stickyStates.slice().reverse() : stickyStates;
196-
197-
// Measure row heights all at once before adding sticky styles to reduce layout thrashing.
198-
const stickyOffsets: number[] = [];
199-
const stickyCellHeights: (number | undefined)[] = [];
200-
const elementsToStick: HTMLElement[][] = [];
201-
for (let rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) {
202-
if (!states[rowIndex]) {
203-
continue;
204-
}
191+
// Coalesce with other sticky row updates (top/bottom), sticky columns updates
192+
// (and potentially other changes like column resize).
193+
this._coalescedStyleScheduler.schedule(() => {
194+
// If positioning the rows to the bottom, reverse their order when evaluating the sticky
195+
// position such that the last row stuck will be "bottom: 0px" and so on. Note that the
196+
// sticky states need to be reversed as well.
197+
const rows = position === 'bottom' ? rowsToStick.slice().reverse() : rowsToStick;
198+
const states = position === 'bottom' ? stickyStates.slice().reverse() : stickyStates;
199+
200+
// Measure row heights all at once before adding sticky styles to reduce layout thrashing.
201+
const stickyOffsets: number[] = [];
202+
const stickyCellHeights: (number | undefined)[] = [];
203+
const elementsToStick: HTMLElement[][] = [];
204+
205+
for (let rowIndex = 0, stickyOffset = 0; rowIndex < rows.length; rowIndex++) {
206+
if (!states[rowIndex]) {
207+
continue;
208+
}
205209

206-
stickyOffsets[rowIndex] = stickyOffset;
207-
const row = rows[rowIndex];
208-
elementsToStick[rowIndex] = this._isNativeHtmlTable
209-
? (Array.from(row.children) as HTMLElement[])
210-
: [row];
210+
stickyOffsets[rowIndex] = stickyOffset;
211+
const row = rows[rowIndex];
212+
elementsToStick[rowIndex] = this._isNativeHtmlTable
213+
? (Array.from(row.children) as HTMLElement[])
214+
: [row];
211215

212-
const height = row.getBoundingClientRect().height;
213-
stickyOffset += height;
214-
stickyCellHeights[rowIndex] = height;
215-
}
216+
const height = row.getBoundingClientRect().height;
217+
stickyOffset += height;
218+
stickyCellHeights[rowIndex] = height;
219+
}
216220

217-
const borderedRowIndex = states.lastIndexOf(true);
221+
const borderedRowIndex = states.lastIndexOf(true);
218222

219-
// Coalesce with other sticky row updates (top/bottom), sticky columns updates
220-
// (and potentially other changes like column resize).
221-
this._coalescedStyleScheduler.schedule(() => {
222223
for (let rowIndex = 0; rowIndex < rows.length; rowIndex++) {
223224
if (!states[rowIndex]) {
224225
continue;

0 commit comments

Comments
 (0)