From 7b7ff831fdb7984633e77d832cc33ceaea3e4253 Mon Sep 17 00:00:00 2001 From: "Ghislain B." Date: Fri, 23 Aug 2024 00:55:37 -0400 Subject: [PATCH] perf: add new `rowTopOffsetRenderType` grid option to use "transform" (#1050) * feat: add new `rowTopOffsetRenderType` grid option to use "transform" --- cypress/e2e/example-frozen-rows.cy.ts | 84 +++++++++++++------------- cypress/e2e/example-grouping-esm.cy.ts | 50 +++++++-------- examples/example-frozen-rows.html | 11 +++- examples/example-grouping-esm.html | 4 +- examples/example-grouping.html | 2 +- src/models/gridOption.interface.ts | 7 +++ src/slick.grid.ts | 19 +++++- 7 files changed, 104 insertions(+), 73 deletions(-) diff --git a/cypress/e2e/example-frozen-rows.cy.ts b/cypress/e2e/example-frozen-rows.cy.ts index 4887146db..e911ad1ea 100644 --- a/cypress/e2e/example-frozen-rows.cy.ts +++ b/cypress/e2e/example-frozen-rows.cy.ts @@ -22,71 +22,71 @@ describe('Example - Frozen Rows', { retries: 1 }, () => { }); it('should have a frozen grid with 4 containers on page load with 3 columns on the left and 6 columns on the right', () => { - cy.get('[style="top: 0px;"]').should('have.length', 2); // top + bottom - cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 11 * 2); + cy.get('[style="transform: translateY(0px);"]').should('have.length', 2); // top + bottom + cy.get('.grid-canvas-left > [style="transform: translateY(0px);"]').children().should('have.length', 11 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(7)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 49995'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '49995'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(1)').should('contain', 'Task 49995'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(7)').should('contain', '49995'); }); it('should change frozen row and increment by 1 and expect changes to be reflected in the grid', () => { cy.get('input#frozenRow').type('{backspace}7'); cy.get('button#setFrozenRow').click(); - cy.get('[style="top: 0px;"]').should('have.length', 2); // top + bottom - cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 11 * 2); + cy.get('[style="transform: translateY(0px);"]').should('have.length', 2); // top + bottom + cy.get('.grid-canvas-left > [style="transform: translateY(0px);"]').children().should('have.length', 11 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(7)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 49993'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '49993'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(1)').should('contain', 'Task 49993'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(7)').should('contain', '49993'); }); it('should uncheck "frozen bottom rows" and set it', () => { cy.get('input#frozenBottomRows').uncheck(); cy.get('button#setFrozenBottomRows').click(); - cy.get('[style="top: 0px;"]').should('have.length', 2); // top + bottom - cy.get('.grid-canvas-left > [style="top: 0px;"]').children().should('have.length', 11 * 2); + cy.get('[style="transform: translateY(0px);"]').should('have.length', 2); // top + bottom + cy.get('.grid-canvas-left > [style="transform: translateY(0px);"]').children().should('have.length', 11 * 2); // top-left - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 0'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-top.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(1)').should('contain', 'Task 0'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-top.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(7)').should('contain', '0'); // bottom-left - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(0)').should('contain', ''); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(1)').should('contain', 'Task 7'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(2)').should('contain', '5 days'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); - cy.get('.grid-canvas-bottom.grid-canvas-left > [style="top: 0px;"] > .slick-cell:nth(7)').should('contain', '7'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(0)').should('contain', ''); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(1)').should('contain', 'Task 7'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(2)').should('contain', '5 days'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(4)').should('contain', '01/01/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(5)').should('contain', '01/05/2009'); + cy.get('.grid-canvas-bottom.grid-canvas-left > [style="transform: translateY(0px);"] > .slick-cell:nth(7)').should('contain', '7'); }); }); diff --git a/cypress/e2e/example-grouping-esm.cy.ts b/cypress/e2e/example-grouping-esm.cy.ts index 70d20594f..dab3d1763 100644 --- a/cypress/e2e/example-grouping-esm.cy.ts +++ b/cypress/e2e/example-grouping-esm.cy.ts @@ -25,13 +25,13 @@ describe('Example - Grouping & Aggregators (ESM)', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="collapse-all-btn"]').click(); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"] > .slick-cell:nth(0) .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 4}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 1'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 2}px);"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 2'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 3}px);"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 3'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 4}px);"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 4'); }); it('should click on Expand All columns and expect 1st row as grouping title and 2nd row as a regular row', () => { @@ -39,42 +39,42 @@ describe('Example - Grouping & Aggregators (ESM)', { retries: 1 }, () => { cy.get('[data-test="group-duration-sort-value-btn"]').click(); cy.get('[data-test="expand-all-btn"]').click(); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"] > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"] > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(1)`).should('contain', 'Task'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"] > .slick-cell:nth(2)`).should('contain', '0'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(1)`).should('contain', 'Task'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"] > .slick-cell:nth(2)`).should('contain', '0'); }); it('should "Group by Duration then Effort-Driven" and expect 1st row to be expanded, 2nd row to be collapsed and 3rd row to have group totals', () => { cy.get('[data-test="group-duration-effort-btn"]').click(); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: True'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 2}px);"].slick-group-level-1 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 2}px);"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: True'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-0 .slick-cell:nth(2)`).should('contain', 'total: 0'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 3}px);"].slick-group-totals.slick-group-level-0 .slick-cell:nth(2)`).should('contain', 'total: 0'); }); it('should "Group by Duration then Effort-Driven then Percent" and expect fist 2 rows to be expanded, 3rd row to be collapsed then 4th row to have group total', () => { cy.get('[data-test="group-duration-effort-percent-btn"]').click(); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 0}px;"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 0}px);"].slick-group-level-0 > .slick-cell:nth(0) .slick-group-title`).should('contain', 'Duration: 0'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 1}px;"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"].slick-group-level-1 .slick-group-toggle.expanded`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 1}px);"].slick-group-level-1 .slick-group-title`).should('contain', 'Effort-Driven: False'); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-2 .slick-group-toggle.collapsed`).should('have.length', 1); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 2}px;"].slick-group-level-2 .slick-group-title`).contains(/^% Complete: [0-9]/); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 2}px);"].slick-group-level-2 .slick-group-toggle.collapsed`).should('have.length', 1); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 2}px);"].slick-group-level-2 .slick-group-title`).contains(/^% Complete: [0-9]/); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-2 .slick-cell:nth(3)`).contains(/^avg: [0-9]%$/); - cy.get(`[style="top: ${GRID_ROW_HEIGHT * 3}px;"].slick-group-totals.slick-group-level-2`) + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 3}px);"].slick-group-totals.slick-group-level-2 .slick-cell:nth(3)`).contains(/^avg: [0-9]%$/); + cy.get(`[style="transform: translateY(${GRID_ROW_HEIGHT * 3}px);"].slick-group-totals.slick-group-level-2`) .find('.slick-cell:nth(3)').contains('avg: '); }); }); diff --git a/examples/example-frozen-rows.html b/examples/example-frozen-rows.html index e0f7623d7..57f31181a 100644 --- a/examples/example-frozen-rows.html +++ b/examples/example-frozen-rows.html @@ -137,7 +137,16 @@

Demonstrates:

]; var options = { - editable: true, enableAddRow: false, enableCellNavigation: true, asyncEditorLoading: true, forceFitColumns: false, autoEdit: false, topPanelHeight: 25, frozenRow: 5, frozenBottom: true + editable: true, + enableAddRow: false, + enableCellNavigation: true, + asyncEditorLoading: true, + forceFitColumns: false, + autoEdit: false, + topPanelHeight: 25, + frozenRow: 5, + frozenBottom: true, + rowTopOffsetRenderType: 'transform' // defaults: 'top' }; var sortcol = "title"; diff --git a/examples/example-grouping-esm.html b/examples/example-grouping-esm.html index 641e0b9bb..b9e7908da 100644 --- a/examples/example-grouping-esm.html +++ b/examples/example-grouping-esm.html @@ -132,7 +132,9 @@

View Source:

let options = { enableCellNavigation: true, editable: true, - rowHeight: 28 + rowHeight: 28, + // forceSyncScrolling: true, + rowTopOffsetRenderType: 'transform' // defaults: 'top' }; let sortcol = "title"; diff --git a/examples/example-grouping.html b/examples/example-grouping.html index 261a477e8..9e20e4b81 100644 --- a/examples/example-grouping.html +++ b/examples/example-grouping.html @@ -129,7 +129,7 @@

View Source:

var options = { enableCellNavigation: true, - editable: true + editable: true, }; var sortcol = "title"; diff --git a/src/models/gridOption.interface.ts b/src/models/gridOption.interface.ts index 77c7f2d46..fa36c58b9 100644 --- a/src/models/gridOption.interface.ts +++ b/src/models/gridOption.interface.ts @@ -285,6 +285,13 @@ export interface GridOption { /** Defaults to 400, duration to show the row highlight (e.g. after CRUD executions) */ rowHighlightDuration?: number; + /** + * Defaults to "top", what CSS style to we want to use to render each row top offset (we can use "top" or "transform"). + * For example, with a default `rowHeight: 22`, the 2nd row will have a `top` offset of 44px and by default have a CSS style of `top: 44px`. + * NOTE: for perf reasons, the "transform" might become the default in our future major version. + */ + rowTopOffsetRenderType?: 'top' | 'transform'; + /** Optional sanitizer function to use for sanitizing data to avoid XSS attacks */ sanitizer?: (dirtyHtml: string) => string; diff --git a/src/slick.grid.ts b/src/slick.grid.ts index 7b508757b..387477923 100644 --- a/src/slick.grid.ts +++ b/src/slick.grid.ts @@ -287,6 +287,7 @@ export class SlickGrid = Column, O e doPaging: true, autosizeColsMode: GridAutosizeColsMode.LegacyOff, autosizeColPaddingPx: 4, + rowTopOffsetRenderType: 'top', scrollRenderThrottling: 10, autosizeTextAvgToMWidthRatio: 0.75, viewportSwitchToScrollModeWidthPercent: undefined, @@ -3837,7 +3838,7 @@ export class SlickGrid = Column, O e // Rendering / Scrolling protected getRowTop(row: number) { - return this._options.rowHeight! * row - this.offset; + return Math.round(this._options.rowHeight! * row - this.offset); } protected getRowFromPosition(y: number) { @@ -3946,8 +3947,15 @@ export class SlickGrid = Column, O e rowCss += ' ' + metadata.cssClasses; } + const rowDiv = Utils.createDomElement('div', { className: `ui-widget-content ${rowCss}`, role: 'row' }); const frozenRowOffset = this.getFrozenRowOffset(row); - const rowDiv = Utils.createDomElement('div', { className: `ui-widget-content ${rowCss}`, role: 'row', style: { top: `${this.getRowTop(row) - frozenRowOffset}px` } }); + const topOffset = this.getRowTop(row) - frozenRowOffset; + if (this._options.rowTopOffsetRenderType === 'transform') { + rowDiv.style.transform = `translateY(${topOffset}px)`; + } else { + rowDiv.style.top = `${topOffset}px`; // default to `top: {offset}px` + } + let rowDivR: HTMLElement | undefined; divArrayL.push(rowDiv); if (this.hasFrozenColumns()) { @@ -4906,7 +4914,12 @@ export class SlickGrid = Column, O e for (const row in this.rowsCache) { if (this.rowsCache) { const rowNumber = row ? parseInt(row, 10) : 0; - Utils.setStyleSize(this.rowsCache[rowNumber].rowNode![0], 'top', this.getRowTop(rowNumber)); + const rowNode = this.rowsCache[rowNumber].rowNode![0]; + if (this._options.rowTopOffsetRenderType === 'transform') { + rowNode.style.transform = `translateY(${this.getRowTop(rowNumber)}px)`; + } else { + rowNode.style.top = `${this.getRowTop(rowNumber)}px`; // default to `top: {offset}px` + } } } }