diff --git a/docs/pages/x/api/data-grid/data-grid-premium.json b/docs/pages/x/api/data-grid/data-grid-premium.json
index 90e048ac17a97..2bf7739699c5a 100644
--- a/docs/pages/x/api/data-grid/data-grid-premium.json
+++ b/docs/pages/x/api/data-grid/data-grid-premium.json
@@ -782,6 +782,12 @@
"description": "Styles applied to the empty cell element.",
"isGlobal": false
},
+ {
+ "key": "cellOffsetLeft",
+ "className": "MuiDataGridPremium-cellOffsetLeft",
+ "description": "",
+ "isGlobal": false
+ },
{
"key": "cellSkeleton",
"className": "MuiDataGridPremium-cellSkeleton",
diff --git a/docs/pages/x/api/data-grid/data-grid-pro.json b/docs/pages/x/api/data-grid/data-grid-pro.json
index 7b3e2e89f0d4b..0dbb6bdc4e055 100644
--- a/docs/pages/x/api/data-grid/data-grid-pro.json
+++ b/docs/pages/x/api/data-grid/data-grid-pro.json
@@ -721,6 +721,12 @@
"description": "Styles applied to the empty cell element.",
"isGlobal": false
},
+ {
+ "key": "cellOffsetLeft",
+ "className": "MuiDataGridPro-cellOffsetLeft",
+ "description": "",
+ "isGlobal": false
+ },
{
"key": "cellSkeleton",
"className": "MuiDataGridPro-cellSkeleton",
diff --git a/docs/pages/x/api/data-grid/data-grid.json b/docs/pages/x/api/data-grid/data-grid.json
index 35526160a411b..7d2e0cc1683fa 100644
--- a/docs/pages/x/api/data-grid/data-grid.json
+++ b/docs/pages/x/api/data-grid/data-grid.json
@@ -606,6 +606,12 @@
"description": "Styles applied to the empty cell element.",
"isGlobal": false
},
+ {
+ "key": "cellOffsetLeft",
+ "className": "MuiDataGrid-cellOffsetLeft",
+ "description": "",
+ "isGlobal": false
+ },
{
"key": "cellSkeleton",
"className": "MuiDataGrid-cellSkeleton",
diff --git a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json
index 1cff481853a86..c03719bd0757a 100644
--- a/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json
+++ b/docs/translations/api-docs/data-grid/data-grid-premium/data-grid-premium.json
@@ -763,6 +763,7 @@
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the empty cell element"
},
+ "cellOffsetLeft": { "description": "" },
"cellSkeleton": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the skeleton cell element"
diff --git a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json
index 80d95b46ddb16..bf41dede0b1df 100644
--- a/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json
+++ b/docs/translations/api-docs/data-grid/data-grid-pro/data-grid-pro.json
@@ -705,6 +705,7 @@
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the empty cell element"
},
+ "cellOffsetLeft": { "description": "" },
"cellSkeleton": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the skeleton cell element"
diff --git a/docs/translations/api-docs/data-grid/data-grid/data-grid.json b/docs/translations/api-docs/data-grid/data-grid/data-grid.json
index e39db6e5df53a..3e905560a3a95 100644
--- a/docs/translations/api-docs/data-grid/data-grid/data-grid.json
+++ b/docs/translations/api-docs/data-grid/data-grid/data-grid.json
@@ -571,6 +571,7 @@
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the empty cell element"
},
+ "cellOffsetLeft": { "description": "" },
"cellSkeleton": {
"description": "Styles applied to {{nodeName}}.",
"nodeName": "the skeleton cell element"
diff --git a/packages/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx
index a84c1f5378f08..1d686619688f0 100644
--- a/packages/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx
+++ b/packages/x-data-grid-pro/src/tests/rows.DataGridPro.test.tsx
@@ -4,6 +4,7 @@ import { spy } from 'sinon';
import { expect } from 'chai';
import {
$,
+ $$,
grid,
getCell,
getRow,
@@ -450,7 +451,7 @@ describe(' - Rows', () => {
virtualScroller.scrollTop = 10e6; // scroll to the bottom
act(() => virtualScroller.dispatchEvent(new Event('scroll')));
- const lastCell = $('[role="row"]:last-child [role="gridcell"]:first-child')!;
+ const lastCell = $$('[role="row"]:last-child [role="gridcell"]')[0];
expect(lastCell).to.have.text('995');
expect(renderingZone.children.length).to.equal(
Math.floor((height - 1) / rowHeight) + rowBuffer,
@@ -486,11 +487,13 @@ describe(' - Rows', () => {
/>,
);
const firstRow = getRow(0);
- expect(firstRow.children).to.have.length(Math.floor(width / columnWidth) + columnBuffer);
+ expect($$(firstRow, '[role="gridcell"]')).to.have.length(
+ Math.floor(width / columnWidth) + columnBuffer,
+ );
const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!;
virtualScroller.scrollLeft = 301;
act(() => virtualScroller.dispatchEvent(new Event('scroll')));
- expect(firstRow.children).to.have.length(
+ expect($$(firstRow, '[role="gridcell"]')).to.have.length(
columnBuffer + 1 + Math.floor(width / columnWidth) + columnBuffer,
);
});
@@ -517,15 +520,14 @@ describe(' - Rows', () => {
render(
,
);
- const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!;
- const renderingZone = document.querySelector('.MuiDataGrid-virtualScrollerRenderZone')!;
- let firstRow = renderingZone.querySelector('[role="row"]:first-child')!;
- let firstColumn = firstRow.firstChild!;
+ const virtualScroller = grid('virtualScroller')!;
+ const renderingZone = grid('virtualScrollerRenderZone')!;
+ const firstRow = $(renderingZone, '[role="row"]:first-child')!;
+ let firstColumn = $$(firstRow, '[role="gridcell"]')[0];
expect(firstColumn).to.have.attr('data-colindex', '0');
virtualScroller.scrollLeft = columnThreshold * columnWidth;
act(() => virtualScroller.dispatchEvent(new Event('scroll')));
- firstRow = renderingZone.querySelector('[role="row"]:first-child')!;
- firstColumn = firstRow.firstChild!;
+ firstColumn = $(renderingZone, '[role="row"] > [role="gridcell"]')!;
expect(firstColumn).to.have.attr('data-colindex', '3');
});
@@ -546,16 +548,14 @@ describe(' - Rows', () => {
act(() => virtualScroller.dispatchEvent(new Event('scroll')));
const dimensions = apiRef.current.state.dimensions;
- const lastCell = document.querySelector(
- '[role="row"]:last-child [role="gridcell"]:first-child',
- )!;
+ const lastCell = $$('[role="row"]:last-child [role="gridcell"]')[0];
expect(lastCell).to.have.text('31');
expect(virtualScroller.scrollHeight).to.equal(
dimensions.headerHeight + nbRows * rowHeight + dimensions.scrollbarSize,
);
});
- it('should not virtualized the last page if smaller than viewport', () => {
+ it('should not virtualize the last page if smaller than viewport', () => {
render(
- Rows', () => {
height={500}
/>,
);
- const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!;
+ const virtualScroller = grid('virtualScroller')!;
virtualScroller.scrollTop = 10e6; // scroll to the bottom
virtualScroller.dispatchEvent(new Event('scroll'));
- const lastCell = document.querySelector(
- '[role="row"]:last-child [role="gridcell"]:first-child',
- )!;
+ const lastCell = $$('[role="row"]:last-child [role="gridcell"]')[0];
expect(lastCell).to.have.text('99');
expect(virtualScroller.scrollTop).to.equal(0);
expect(virtualScroller.scrollHeight).to.equal(virtualScroller.clientHeight);
- expect(
- document.querySelector('.MuiDataGrid-virtualScrollerRenderZone')!.children,
- ).to.have.length(4);
+ expect(grid('virtualScrollerRenderZone')!.children).to.have.length(4);
});
it('should paginate small dataset in auto page-size #1492', () => {
@@ -585,18 +581,14 @@ describe(' - Rows', () => {
);
const virtualScroller = document.querySelector('.MuiDataGrid-virtualScroller')!;
- const lastCell = document.querySelector(
- '[role="row"]:last-child [role="gridcell"]:first-child',
- )!;
+ const lastCell = $$('[role="row"]:last-child [role="gridcell"]')[0];
expect(lastCell).to.have.text('6');
const rows = document.querySelectorAll('.MuiDataGrid-row[role="row"]')!;
expect(rows.length).to.equal(7);
expect(virtualScroller.scrollTop).to.equal(0);
expect(virtualScroller.scrollHeight).to.equal(virtualScroller.clientHeight);
- expect(
- document.querySelector('.MuiDataGrid-virtualScrollerRenderZone')!.children,
- ).to.have.length(7);
+ expect(grid('virtualScrollerRenderZone')!.children).to.have.length(7);
});
});
diff --git a/packages/x-data-grid/src/components/GridRow.tsx b/packages/x-data-grid/src/components/GridRow.tsx
index 457218861b733..3e5ab5adc2ae1 100644
--- a/packages/x-data-grid/src/components/GridRow.tsx
+++ b/packages/x-data-grid/src/components/GridRow.tsx
@@ -91,8 +91,6 @@ const useUtilityClasses = (ownerState: OwnerState) => {
isLastVisible && 'row--lastVisible',
rowHeight === 'auto' && 'row--dynamicHeight',
],
- pinnedLeft: ['pinnedLeft'],
- pinnedRight: ['pinnedRight'],
};
return composeClasses(slots, getDataGridUtilityClass, classes);
@@ -517,6 +515,7 @@ const GridRow = React.forwardRef(function GridRow(
{...other}
>
{leftCells}
+
{cells}
{emptyCellWidth > 0 && }
{rightCells.length > 0 && }
diff --git a/packages/x-data-grid/src/components/GridScrollbarFillerCell.tsx b/packages/x-data-grid/src/components/GridScrollbarFillerCell.tsx
index 8be0cf5eb44b5..188a9d78c13bc 100644
--- a/packages/x-data-grid/src/components/GridScrollbarFillerCell.tsx
+++ b/packages/x-data-grid/src/components/GridScrollbarFillerCell.tsx
@@ -23,9 +23,6 @@ const Style = styled('div')({
position: 'sticky',
right: 0,
},
- [`&:not(.${classes.header}):not(.${classes.pinnedRight})`]: {
- transform: 'translate3d(var(--DataGrid-offsetLeft), 0, 0)',
- },
});
function GridScrollbarFillerCell({
diff --git a/packages/x-data-grid/src/components/containers/GridRootStyles.ts b/packages/x-data-grid/src/components/containers/GridRootStyles.ts
index efa21da4ebae6..b5f81dbc7b7c2 100644
--- a/packages/x-data-grid/src/components/containers/GridRootStyles.ts
+++ b/packages/x-data-grid/src/components/containers/GridRootStyles.ts
@@ -572,8 +572,10 @@ export const GridRootStyles = styled('div', {
},
},
},
- [`& .${c.cell}:not(.${c['cell--pinnedLeft']}):not(.${c['cell--pinnedRight']})`]: {
- transform: 'translate3d(var(--DataGrid-offsetLeft), 0, 0)',
+ [`& .${c.cellOffsetLeft}`]: {
+ flex: '0 0 auto',
+ display: 'inline-block',
+ width: 'var(--DataGrid-offsetLeft)',
},
[`& .${c.columnHeaderDraggableContainer}`]: {
display: 'flex',
diff --git a/packages/x-data-grid/src/constants/gridClasses.ts b/packages/x-data-grid/src/constants/gridClasses.ts
index a54196c2cf97b..f83194a44d634 100644
--- a/packages/x-data-grid/src/constants/gridClasses.ts
+++ b/packages/x-data-grid/src/constants/gridClasses.ts
@@ -112,6 +112,11 @@ export interface GridClasses {
* Styles applied to the skeleton cell element.
*/
cellSkeleton: string;
+ /**
+ * @ignore - do not document.
+ * Styles applied to the left offset cell element.
+ */
+ cellOffsetLeft: string;
/**
* Styles applied to the selection checkbox element.
*/
@@ -634,6 +639,7 @@ export const gridClasses = generateUtilityClasses('MuiDataGrid', [
'cellCheckbox',
'cellEmpty',
'cellSkeleton',
+ 'cellOffsetLeft',
'checkboxInput',
'columnHeader--alignCenter',
'columnHeader--alignLeft',
diff --git a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx
index f84849ac0f60a..7718470f4155b 100644
--- a/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx
+++ b/packages/x-data-grid/src/hooks/features/virtualization/useGridVirtualScroller.tsx
@@ -65,7 +65,6 @@ export const useGridVirtualScroller = () => {
const gridRootRef = apiRef.current.rootElementRef;
const mainRef = apiRef.current.mainElementRef;
const scrollerRef = apiRef.current.virtualScrollerRef;
- const renderZoneRef = React.useRef(null);
const scrollbarVerticalRef = React.useRef(null);
const scrollbarHorizontalRef = React.useRef(null);
const contentHeight = dimensions.contentSize.height;
@@ -343,6 +342,16 @@ export const useGridVirtualScroller = () => {
for (let i = 0; i < renderedRows.length; i += 1) {
const { id, model } = renderedRows[i];
+
+ const rowIndexInPage = (currentPage?.range?.firstRowIndex || 0) + firstRowToRender + i;
+ let index = rowIndexOffset + rowIndexInPage;
+ if (isRowWithFocusedCellNotInRange && cellFocus?.id === id) {
+ index = indexOfRowWithFocusedCell;
+ isRowWithFocusedCellRendered = true;
+ } else if (isRowWithFocusedCellRendered) {
+ index -= 1;
+ }
+
const isRowNotVisible = isRowWithFocusedCellNotInRange && cellFocus!.id === id;
const baseRowHeight = !apiRef.current.rowHasAutoHeight(id)
@@ -358,7 +367,7 @@ export const useGridVirtualScroller = () => {
let isFirstVisible = false;
if (params.position === undefined) {
- isFirstVisible = i === 0;
+ isFirstVisible = rowIndexInPage === 0;
}
let isLastVisible = false;
@@ -394,14 +403,6 @@ export const useGridVirtualScroller = () => {
tabbableCell = cellParams.cellMode === 'view' ? cellTabIndex.field : null;
}
- let index = rowIndexOffset + (currentPage?.range?.firstRowIndex || 0) + firstRowToRender + i;
- if (isRowWithFocusedCellNotInRange && cellFocus?.id === id) {
- index = indexOfRowWithFocusedCell;
- isRowWithFocusedCellRendered = true;
- } else if (isRowWithFocusedCellRendered) {
- index -= 1;
- }
-
rows.push(
{
style: contentSize,
role: 'presentation',
}),
- getRenderZoneProps: () => ({ ref: renderZoneRef, role: 'rowgroup' }),
+ getRenderZoneProps: () => ({ role: 'rowgroup' }),
getScrollbarVerticalProps: () => ({ ref: scrollbarVerticalRef, role: 'presentation' }),
getScrollbarHorizontalProps: () => ({ ref: scrollbarHorizontalRef, role: 'presentation' }),
};