From 182191f92649f1e54310c6e9a4a429925d5b94a9 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Thu, 24 Oct 2024 21:31:54 +0100 Subject: [PATCH 1/9] [data grid] Fix column resizing issues --- .../x-data-grid/src/components/GridRow.tsx | 21 +++---------------- .../components/containers/GridRootStyles.ts | 3 ++- .../columnResize/useGridColumnResize.tsx | 12 ++++++----- 3 files changed, 12 insertions(+), 24 deletions(-) diff --git a/packages/x-data-grid/src/components/GridRow.tsx b/packages/x-data-grid/src/components/GridRow.tsx index 8358424a82a76..de69959b29d95 100644 --- a/packages/x-data-grid/src/components/GridRow.tsx +++ b/packages/x-data-grid/src/components/GridRow.tsx @@ -67,18 +67,8 @@ export interface GridRowProps extends React.HTMLAttributes { [x: string]: any; // Allow custom attributes like data-* and aria-* } -function EmptyCell({ width }: { width: number }) { - if (!width) { - return null; - } - - return ( -
- ); +function EmptyCell() { + return
; } EmptyCell.propTypes = { @@ -454,10 +444,6 @@ const GridRow = React.forwardRef(function GridRow( } : null; - const expandedWidth = - dimensions.viewportOuterSize.width - dimensions.columnsTotalWidth - scrollbarWidth; - const emptyCellWidth = Math.max(0, expandedWidth); - return (
(function GridRow( style={{ width: offsetLeft }} /> {cells} - {emptyCellWidth > 0 && } - {rightCells.length > 0 &&
} + {rightCells} {scrollbarWidth !== 0 && 0} />}
diff --git a/packages/x-data-grid/src/components/containers/GridRootStyles.ts b/packages/x-data-grid/src/components/containers/GridRootStyles.ts index eb1ccdc749965..3f049bf769d59 100644 --- a/packages/x-data-grid/src/components/containers/GridRootStyles.ts +++ b/packages/x-data-grid/src/components/containers/GridRootStyles.ts @@ -564,6 +564,7 @@ export const GridRootStyles = styled('div', { lineHeight: 'inherit', }, [`& .${c.cellEmpty}`]: { + flex: 1, padding: 0, height: 'unset', }, @@ -743,7 +744,7 @@ export const GridRootStyles = styled('div', { }, [`& .${c.filler}`]: { - flex: '1 0 auto', + flex: 1, }, [`& .${c['filler--borderBottom']}`]: { borderBottom: '1px solid var(--DataGrid-rowBorderColor)', diff --git a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx index aa79485f5a4ac..7d166b1509981 100644 --- a/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx +++ b/packages/x-data-grid/src/hooks/features/columnResize/useGridColumnResize.tsx @@ -300,12 +300,14 @@ export const useGridColumnResize = ( const prevWidth = refs.columnHeaderElement!.offsetWidth; const widthDiff = newWidth - prevWidth; const columnWidthDiff = newWidth - refs.initialColWidth; - const newTotalWidth = refs.initialTotalWidth + columnWidthDiff; - apiRef.current.rootElementRef?.current?.style.setProperty( - '--DataGrid-rowWidth', - `${newTotalWidth}px`, - ); + if (columnWidthDiff > 0) { + const newTotalWidth = refs.initialTotalWidth + columnWidthDiff; + apiRef.current.rootElementRef?.current?.style.setProperty( + '--DataGrid-rowWidth', + `${newTotalWidth}px`, + ); + } refs.colDef!.computedWidth = newWidth; refs.colDef!.width = newWidth; From 30c1e6ef0ce913310f286f7e8e8e0fc53cbd31ea Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Thu, 24 Oct 2024 21:40:50 +0100 Subject: [PATCH 2/9] empty cell --- packages/x-data-grid/src/components/GridRow.tsx | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/packages/x-data-grid/src/components/GridRow.tsx b/packages/x-data-grid/src/components/GridRow.tsx index de69959b29d95..18f4e9aef6525 100644 --- a/packages/x-data-grid/src/components/GridRow.tsx +++ b/packages/x-data-grid/src/components/GridRow.tsx @@ -67,18 +67,6 @@ export interface GridRowProps extends React.HTMLAttributes { [x: string]: any; // Allow custom attributes like data-* and aria-* } -function EmptyCell() { - return
; -} - -EmptyCell.propTypes = { - // ----------------------------- Warning -------------------------------- - // | These PropTypes are generated from the TypeScript type definitions | - // | To update them edit the TypeScript types and run "pnpm proptypes" | - // ---------------------------------------------------------------------- - width: PropTypes.number.isRequired, -} as any; - const GridRow = React.forwardRef(function GridRow(props, refProp) { const { selected, @@ -463,7 +451,7 @@ const GridRow = React.forwardRef(function GridRow( style={{ width: offsetLeft }} /> {cells} - +
{rightCells} {scrollbarWidth !== 0 && 0} />}
From 4fec4086d1f85dc1e2fea483c965cb22b30c36a7 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Mon, 28 Oct 2024 15:49:46 +0000 Subject: [PATCH 3/9] undo flex change --- .../x-data-grid/src/components/containers/GridRootStyles.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-data-grid/src/components/containers/GridRootStyles.ts b/packages/x-data-grid/src/components/containers/GridRootStyles.ts index 3f049bf769d59..aece7534183e5 100644 --- a/packages/x-data-grid/src/components/containers/GridRootStyles.ts +++ b/packages/x-data-grid/src/components/containers/GridRootStyles.ts @@ -744,7 +744,7 @@ export const GridRootStyles = styled('div', { }, [`& .${c.filler}`]: { - flex: 1, + flex: '1 0 auto', }, [`& .${c['filler--borderBottom']}`]: { borderBottom: '1px solid var(--DataGrid-rowBorderColor)', From 028b3d347758729aa7316aa98923b2b00ec28a90 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Wed, 30 Oct 2024 10:23:34 +0000 Subject: [PATCH 4/9] update test to account for empty cell --- packages/x-data-grid/src/tests/rows.DataGrid.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx index 0952929261989..6b64a6c94883e 100644 --- a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx @@ -750,7 +750,7 @@ describe(' - Rows', () => { width={100} />, ); - expect(document.querySelectorAll('.MuiDataGrid-cell')).to.have.length(2); + expect(document.querySelectorAll('.MuiDataGrid-cell')).to.have.length(3); }); it('should measure rows while scrolling', async () => { From e8befe268dea9167e650994e671e3d88e94223b0 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Wed, 30 Oct 2024 14:47:52 +0000 Subject: [PATCH 5/9] regression tests --- .../src/tests/columns.DataGridPro.test.tsx | 75 ++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/packages/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx index 3d6e0567771d6..29f757c4beb96 100644 --- a/packages/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/columns.DataGridPro.test.tsx @@ -13,7 +13,7 @@ import { GridAutosizeOptions, } from '@mui/x-data-grid-pro'; import { useGridPrivateApiContext } from '@mui/x-data-grid-pro/internals'; -import { getColumnHeaderCell, getCell, microtasks } from 'test/utils/helperFn'; +import { getColumnHeaderCell, getCell, microtasks, getRow } from 'test/utils/helperFn'; const isJSDOM = /jsdom/.test(window.navigator.userAgent); @@ -237,6 +237,79 @@ describe(' - Columns', () => { expect(bottomPinnedRowCell?.getBoundingClientRect().width).to.equal(150); }); + // /~https://github.com/mui/mui-x/issues/12852 + it('should work with right pinned column', () => { + render( + , + ); + + const pinnedHeaderCell = getColumnHeaderCell(1); + const pinnedCell = getCell(1, 1); + const pinnedSeparator = pinnedHeaderCell.querySelector( + `.${gridClasses['columnSeparator--resizable']}`, + )!; + const pinnedRightPosition = pinnedHeaderCell.getBoundingClientRect().right; + + // resize right pinned column to the right + fireEvent.mouseDown(pinnedSeparator, { clientX: 100 }); + fireEvent.mouseMove(pinnedSeparator, { clientX: 150, buttons: 1 }); + + // check that the right pinned column has shrunk and is in the same position + expect(pinnedHeaderCell.getBoundingClientRect().width).to.equal(50); + expect(pinnedCell.getBoundingClientRect().width).to.equal(50); + expect(pinnedHeaderCell.getBoundingClientRect().right).to.equal(pinnedRightPosition); + + // release the mouse and check that the right pinned column is still in the same position + fireEvent.mouseUp(pinnedSeparator); + expect(pinnedHeaderCell.getBoundingClientRect().width).to.equal(50); + expect(pinnedCell.getBoundingClientRect().width).to.equal(50); + expect(pinnedHeaderCell.getBoundingClientRect().right).to.equal(pinnedRightPosition); + + // resize the right pinned column to the left + fireEvent.mouseDown(pinnedSeparator, { clientX: 150 }); + fireEvent.mouseMove(pinnedSeparator, { clientX: 50, buttons: 1 }); + + // check that the right pinned column has grown and is in the same position + expect(pinnedHeaderCell.getBoundingClientRect().width).to.equal(150); + expect(pinnedCell.getBoundingClientRect().width).to.equal(150); + expect(pinnedHeaderCell.getBoundingClientRect().right).to.equal(pinnedRightPosition); + + // release the mouse and check that the right pinned column is still in the same position + fireEvent.mouseUp(pinnedSeparator); + expect(pinnedHeaderCell.getBoundingClientRect().width).to.equal(150); + expect(pinnedCell.getBoundingClientRect().width).to.equal(150); + expect(pinnedHeaderCell.getBoundingClientRect().right).to.equal(pinnedRightPosition); + }); + + // /~https://github.com/mui/mui-x/issues/13548 + it('should fill remaining horizontal space in a row with an empty cell', () => { + render(); + + const row = getRow(0); + const rowWidth = row.getBoundingClientRect().width; + const headerCell = getColumnHeaderCell(0); + const separator = headerCell.querySelector(`.${gridClasses['columnSeparator--resizable']}`)!; + const emptyCell = row.querySelector(`.${gridClasses.cellEmpty}`)!; + + // check that empty cell takes up the remaining width in a row + expect(emptyCell.getBoundingClientRect().width).to.equal(rowWidth - 100); + + // check that empty cell takes up the remaining width when the column is resized + fireEvent.mouseDown(separator, { clientX: 100 }); + fireEvent.mouseMove(separator, { clientX: 50, buttons: 1 }); + expect(emptyCell.getBoundingClientRect().width).to.equal(rowWidth - 50); + + // release the mouse and check that the empty cell still takes up the remaining width + fireEvent.mouseUp(separator); + expect(emptyCell.getBoundingClientRect().width).to.equal(rowWidth - 50); + }); + describe('flex resizing', () => { before(function beforeHook() { if (isJSDOM) { From 1f552a5703edbbb4950b58c9a637a3c0044b33b0 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Wed, 30 Oct 2024 15:17:51 +0000 Subject: [PATCH 6/9] Visual regression tests --- .../regressions/data-grid/DataGridBordered.js | 25 +++++++++++++++ .../DataGridPinnedColumnsBordered.js | 31 +++++++++++++++++++ .../data-grid/DataGridPinnedColumnsWithGap.js | 29 +++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 test/regressions/data-grid/DataGridBordered.js create mode 100644 test/regressions/data-grid/DataGridPinnedColumnsBordered.js create mode 100644 test/regressions/data-grid/DataGridPinnedColumnsWithGap.js diff --git a/test/regressions/data-grid/DataGridBordered.js b/test/regressions/data-grid/DataGridBordered.js new file mode 100644 index 0000000000000..d33139e76c6fe --- /dev/null +++ b/test/regressions/data-grid/DataGridBordered.js @@ -0,0 +1,25 @@ +import * as React from 'react'; +import { DataGridPro } from '@mui/x-data-grid-pro'; + +const columns = [ + { field: 'name', headerName: 'Name', width: 160 }, + { field: 'email', headerName: 'Email', width: 200 }, + { field: 'age', headerName: 'Age', type: 'number' }, +]; + +const rows = [ + { + id: 1, + name: 'Test User', + email: 'testuser@mui.com', + age: 40, + }, +]; + +export default function BasicColumnPinning() { + return ( +
+ +
+ ); +} diff --git a/test/regressions/data-grid/DataGridPinnedColumnsBordered.js b/test/regressions/data-grid/DataGridPinnedColumnsBordered.js new file mode 100644 index 0000000000000..60a5f415d6b13 --- /dev/null +++ b/test/regressions/data-grid/DataGridPinnedColumnsBordered.js @@ -0,0 +1,31 @@ +import * as React from 'react'; +import { DataGridPro } from '@mui/x-data-grid-pro'; + +const columns = [ + { field: 'name', headerName: 'Name', width: 160 }, + { field: 'email', headerName: 'Email', width: 200 }, + { field: 'age', headerName: 'Age', type: 'number' }, +]; + +const rows = [ + { + id: 1, + name: 'Test User', + email: 'testuser@mui.com', + age: 40, + }, +]; + +export default function BasicColumnPinning() { + return ( +
+ +
+ ); +} diff --git a/test/regressions/data-grid/DataGridPinnedColumnsWithGap.js b/test/regressions/data-grid/DataGridPinnedColumnsWithGap.js new file mode 100644 index 0000000000000..253093ffbfe13 --- /dev/null +++ b/test/regressions/data-grid/DataGridPinnedColumnsWithGap.js @@ -0,0 +1,29 @@ +import * as React from 'react'; +import { DataGridPro } from '@mui/x-data-grid-pro'; + +const columns = [ + { field: 'name', headerName: 'Name', width: 160 }, + { field: 'email', headerName: 'Email', width: 200 }, + { field: 'age', headerName: 'Age', type: 'number' }, +]; + +const rows = [ + { + id: 1, + name: 'Test User', + email: 'testuser@mui.com', + age: 40, + }, +]; + +export default function BasicColumnPinning() { + return ( +
+ +
+ ); +} From 934afe51bc3de2f06f52715d8690dae6e0b14104 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Wed, 30 Oct 2024 15:38:44 +0000 Subject: [PATCH 7/9] update visual regression tests --- .../regressions/data-grid/DataGridBordered.js | 9 +- .../DataGridPinnedColumnsBordered.js | 9 +- .../DataGridPinnedColumnsScrollbars.js | 134 ++++++++++++++++++ .../data-grid/DataGridPinnedColumnsWithGap.js | 9 +- 4 files changed, 149 insertions(+), 12 deletions(-) create mode 100644 test/regressions/data-grid/DataGridPinnedColumnsScrollbars.js diff --git a/test/regressions/data-grid/DataGridBordered.js b/test/regressions/data-grid/DataGridBordered.js index d33139e76c6fe..b790417a5fc01 100644 --- a/test/regressions/data-grid/DataGridBordered.js +++ b/test/regressions/data-grid/DataGridBordered.js @@ -1,5 +1,6 @@ import * as React from 'react'; import { DataGridPro } from '@mui/x-data-grid-pro'; +import { randomTraderName, randomEmail } from '@mui/x-data-grid-generator'; const columns = [ { field: 'name', headerName: 'Name', width: 160 }, @@ -10,13 +11,13 @@ const columns = [ const rows = [ { id: 1, - name: 'Test User', - email: 'testuser@mui.com', - age: 40, + name: randomTraderName(), + email: randomEmail(), + age: 25, }, ]; -export default function BasicColumnPinning() { +export default function DataGridBordered() { return (
diff --git a/test/regressions/data-grid/DataGridPinnedColumnsBordered.js b/test/regressions/data-grid/DataGridPinnedColumnsBordered.js index 60a5f415d6b13..6fec3acd27857 100644 --- a/test/regressions/data-grid/DataGridPinnedColumnsBordered.js +++ b/test/regressions/data-grid/DataGridPinnedColumnsBordered.js @@ -1,5 +1,6 @@ import * as React from 'react'; import { DataGridPro } from '@mui/x-data-grid-pro'; +import { randomTraderName, randomEmail } from '@mui/x-data-grid-generator'; const columns = [ { field: 'name', headerName: 'Name', width: 160 }, @@ -10,13 +11,13 @@ const columns = [ const rows = [ { id: 1, - name: 'Test User', - email: 'testuser@mui.com', - age: 40, + name: randomTraderName(), + email: randomEmail(), + age: 25, }, ]; -export default function BasicColumnPinning() { +export default function DataGridPinnedColumnsBordered() { return (
[ + } label="Edit" />, + } label="Delete" />, + ], + }, +]; + +const rows = [ + { + id: 1, + name: randomTraderName(), + email: randomEmail(), + age: 25, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 2, + name: randomTraderName(), + email: randomEmail(), + age: 32, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 3, + name: randomTraderName(), + email: randomEmail(), + age: 45, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 4, + name: randomTraderName(), + email: randomEmail(), + age: 28, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 5, + name: randomTraderName(), + email: randomEmail(), + age: 39, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 6, + name: randomTraderName(), + email: randomEmail(), + age: 52, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 7, + name: randomTraderName(), + email: randomEmail(), + age: 33, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 8, + name: randomTraderName(), + email: randomEmail(), + age: 41, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 9, + name: randomTraderName(), + email: randomEmail(), + age: 36, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, + { + id: 10, + name: randomTraderName(), + email: randomEmail(), + age: 29, + dateCreated: randomCreatedDate(), + lastLogin: randomUpdatedDate(), + }, +]; + +export default function DataGridPinnedColumnsScrollbars() { + return ( +
+ +
+ ); +} diff --git a/test/regressions/data-grid/DataGridPinnedColumnsWithGap.js b/test/regressions/data-grid/DataGridPinnedColumnsWithGap.js index 253093ffbfe13..492e054a6e243 100644 --- a/test/regressions/data-grid/DataGridPinnedColumnsWithGap.js +++ b/test/regressions/data-grid/DataGridPinnedColumnsWithGap.js @@ -1,5 +1,6 @@ import * as React from 'react'; import { DataGridPro } from '@mui/x-data-grid-pro'; +import { randomTraderName, randomEmail } from '@mui/x-data-grid-generator'; const columns = [ { field: 'name', headerName: 'Name', width: 160 }, @@ -10,13 +11,13 @@ const columns = [ const rows = [ { id: 1, - name: 'Test User', - email: 'testuser@mui.com', - age: 40, + name: randomTraderName(), + email: randomEmail(), + age: 25, }, ]; -export default function BasicColumnPinning() { +export default function DataGridPinnedColumnsWithGap() { return (
Date: Mon, 4 Nov 2024 16:53:25 +0000 Subject: [PATCH 8/9] Update packages/x-data-grid/src/tests/rows.DataGrid.test.tsx Co-authored-by: Andrew Cherniavskii Signed-off-by: Kenan Yusuf --- packages/x-data-grid/src/tests/rows.DataGrid.test.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx index 6b64a6c94883e..f276858b9ca21 100644 --- a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx @@ -750,7 +750,7 @@ describe(' - Rows', () => { width={100} />, ); - expect(document.querySelectorAll('.MuiDataGrid-cell')).to.have.length(3); + expect($$(`.${gridClasses.cell}:not(.${gridClasses.cellEmpty})`)).to.have.length(2); }); it('should measure rows while scrolling', async () => { From 1da2274ca9fe2b5cfac7c1a0ddf1e08c802ace02 Mon Sep 17 00:00:00 2001 From: Kenan Yusuf Date: Tue, 5 Nov 2024 06:46:09 +0000 Subject: [PATCH 9/9] fix test --- packages/x-data-grid/src/tests/rows.DataGrid.test.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx index f276858b9ca21..4d222603334b4 100644 --- a/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/rows.DataGrid.test.tsx @@ -21,6 +21,7 @@ import { GridRenderCellParams, useGridApiRef, GridApi, + gridClasses, } from '@mui/x-data-grid'; import { getBasicGridData } from '@mui/x-data-grid-generator'; import { @@ -31,6 +32,7 @@ import { getActiveCell, getCell, microtasks, + $$, } from 'test/utils/helperFn'; import { fireUserEvent } from 'test/utils/fireUserEvent'; import Dialog from '@mui/material/Dialog';