Skip to content

Commit

Permalink
feat(cdk/table): add element offsets to sticky styler state
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelJamesParsons committed Feb 12, 2021
1 parent 70ff528 commit 3bd1b2f
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 36 deletions.
2 changes: 2 additions & 0 deletions src/cdk/table/sticky-position-listener.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@ export const STICKY_POSITIONING_LISTENER =
new InjectionToken<StickyPositioningListener>('CDK_SPL');

export type StickySize = number|null|undefined;
export type StickyOffset = number|null|undefined;

export interface StickyUpdate {
elements?: ReadonlyArray<HTMLElement[]|undefined>;
offsets?: StickyOffset[];
sizes: StickySize[];
}

Expand Down
7 changes: 3 additions & 4 deletions src/cdk/table/sticky-styler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,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];
Expand Down Expand Up @@ -228,10 +227,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});
}
});
}
Expand Down
94 changes: 62 additions & 32 deletions src/cdk/table/table.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -922,18 +922,23 @@ 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: []});

component.stickyHeaders = [];
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: []});
}));
Expand All @@ -949,13 +954,14 @@ 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: []});
Expand All @@ -965,8 +971,8 @@ 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: []});
}));
Expand Down Expand Up @@ -1010,8 +1016,8 @@ 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,
Expand All @@ -1028,8 +1034,8 @@ 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: []});
}));
Expand Down Expand Up @@ -1063,8 +1069,8 @@ 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: [
Expand All @@ -1080,8 +1086,8 @@ 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: []});
}));
Expand Down Expand Up @@ -1169,10 +1175,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({
Expand All @@ -1193,8 +1201,8 @@ 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: []});
}));
Expand Down Expand Up @@ -1235,9 +1243,14 @@ 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: []});

Expand All @@ -1246,8 +1259,8 @@ 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: []});
}));
Expand All @@ -1268,13 +1281,18 @@ 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: []});
Expand All @@ -1285,8 +1303,8 @@ 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: []});
}));
Expand Down Expand Up @@ -1339,8 +1357,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,
Expand All @@ -1356,8 +1376,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: []});
}));
Expand Down Expand Up @@ -1391,8 +1413,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: [
Expand All @@ -1408,8 +1432,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: []});
}));
Expand Down Expand Up @@ -1464,10 +1490,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({
Expand All @@ -1488,8 +1516,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: []});
}));
Expand Down
3 changes: 3 additions & 0 deletions tools/public_api_guard/cdk/table.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ export declare const STICKY_POSITIONING_LISTENER: InjectionToken<StickyPositioni

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

export declare type StickyOffset = number | null | undefined;

export interface StickyPositioningListener {
stickyColumnsUpdated(update: StickyUpdate): void;
stickyEndColumnsUpdated(update: StickyUpdate): void;
Expand Down Expand Up @@ -360,6 +362,7 @@ export declare class StickyStyler {

export interface StickyUpdate {
elements?: ReadonlyArray<HTMLElement[] | undefined>;
offsets?: StickyOffset[];
sizes: StickySize[];
}

Expand Down

0 comments on commit 3bd1b2f

Please sign in to comment.