From ba6c7a1a947eb38691838a025e9b3602934f4508 Mon Sep 17 00:00:00 2001 From: Rom Grk Date: Mon, 8 Jul 2024 22:31:24 -0400 Subject: [PATCH] [DataGridPro] Keep bottom pinned row at the bottom (#13313) --- .../tests/clipboard.DataGridPremium.test.tsx | 34 +++++++------- .../src/tests/pagination.DataGridPro.test.tsx | 6 ++- .../src/components/base/GridOverlays.tsx | 3 +- .../virtualization/GridVirtualScroller.tsx | 2 +- .../GridVirtualScrollerFiller.tsx | 26 ++++++++--- .../virtualization/useGridVirtualScroller.tsx | 15 ++----- .../x-data-grid/src/tests/DataGrid.test.tsx | 28 ++++++------ .../src/tests/layout.DataGrid.test.tsx | 4 +- .../src/tests/pagination.DataGrid.test.tsx | 14 +++--- test/karma.conf.js | 2 +- .../data-grid/DataGridPinnedBottomRow.js | 44 +++++++++++++++++++ 11 files changed, 120 insertions(+), 58 deletions(-) create mode 100644 test/regressions/data-grid/DataGridPinnedBottomRow.js diff --git a/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx b/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx index 1be69796afdd..22cd738034d8 100644 --- a/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx +++ b/packages/x-data-grid-premium/src/tests/clipboard.DataGridPremium.test.tsx @@ -119,12 +119,14 @@ describe(' - Clipboard', () => { { id: 2, brand: 'Puma' }, ]; render( - , +
+ +
, ); const cell = getCell(0, 0); @@ -143,15 +145,17 @@ describe(' - Clipboard', () => { it('should not escape double quotes when copying multiple cells to clipboard', () => { render( - , +
+ +
, ); const cell = getCell(0, 0); diff --git a/packages/x-data-grid-pro/src/tests/pagination.DataGridPro.test.tsx b/packages/x-data-grid-pro/src/tests/pagination.DataGridPro.test.tsx index 0f9a0952b616..5561eb1afc5e 100644 --- a/packages/x-data-grid-pro/src/tests/pagination.DataGridPro.test.tsx +++ b/packages/x-data-grid-pro/src/tests/pagination.DataGridPro.test.tsx @@ -105,7 +105,11 @@ describe(' - Pagination', () => { it('should log an error if rowCount is used with client-side pagination', () => { expect(() => { - render(); + render( +
+ +
, + ); }).toErrorDev([ 'MUI X: Usage of the `rowCount` prop with client side pagination (`paginationMode="client"`) has no effect. `rowCount` is only meant to be used with `paginationMode="server"`.', ]); diff --git a/packages/x-data-grid/src/components/base/GridOverlays.tsx b/packages/x-data-grid/src/components/base/GridOverlays.tsx index fc64a9c3d759..169763a4633c 100644 --- a/packages/x-data-grid/src/components/base/GridOverlays.tsx +++ b/packages/x-data-grid/src/components/base/GridOverlays.tsx @@ -69,7 +69,8 @@ function GridOverlayWrapper(props: React.PropsWithChildren) { let height: React.CSSProperties['height'] = dimensions.viewportOuterSize.height - - dimensions.headersTotalHeight - + dimensions.topContainerHeight - + dimensions.bottomContainerHeight - (dimensions.hasScrollX ? dimensions.scrollbarSize : 0); if ((rootProps.autoHeight && currentPage.rows.length === 0) || height === 0) { diff --git a/packages/x-data-grid/src/components/virtualization/GridVirtualScroller.tsx b/packages/x-data-grid/src/components/virtualization/GridVirtualScroller.tsx index 42c2c2bf443a..5afc96f930fc 100644 --- a/packages/x-data-grid/src/components/virtualization/GridVirtualScroller.tsx +++ b/packages/x-data-grid/src/components/virtualization/GridVirtualScroller.tsx @@ -106,7 +106,7 @@ function GridVirtualScroller(props: GridVirtualScrollerProps) { - {rows.length > 0 && } + diff --git a/packages/x-data-grid/src/components/virtualization/GridVirtualScrollerFiller.tsx b/packages/x-data-grid/src/components/virtualization/GridVirtualScrollerFiller.tsx index eeaafcdd67ad..718a449a6ee5 100644 --- a/packages/x-data-grid/src/components/virtualization/GridVirtualScrollerFiller.tsx +++ b/packages/x-data-grid/src/components/virtualization/GridVirtualScrollerFiller.tsx @@ -17,24 +17,29 @@ const Pinned = styled('div')({ position: 'sticky', height: '100%', boxSizing: 'border-box', - borderTop: '1px solid var(--DataGrid-rowBorderColor)', + borderTop: '1px solid var(--rowBorderColor)', backgroundColor: 'var(--DataGrid-pinnedBackground)', }); const PinnedLeft = styled(Pinned)({ left: 0, - borderRight: '1px solid var(--DataGrid-rowBorderColor)', + borderRight: '1px solid var(--rowBorderColor)', }); const PinnedRight = styled(Pinned)({ right: 0, - borderLeft: '1px solid var(--DataGrid-rowBorderColor)', + borderLeft: '1px solid var(--rowBorderColor)', }); const Main = styled('div')({ flexGrow: 1, - borderTop: '1px solid var(--DataGrid-rowBorderColor)', + borderTop: '1px solid var(--rowBorderColor)', }); -function GridVirtualScrollerFiller() { +type Props = { + /** The number of rows */ + rowsLength: number; +}; + +function GridVirtualScrollerFiller({ rowsLength }: Props) { const apiRef = useGridApiContext(); const { viewportOuterSize, @@ -54,7 +59,16 @@ function GridVirtualScrollerFiller() { } return ( - + {leftPinnedWidth > 0 && ( { ); const contentSize = React.useMemo(() => { - // In cases where the columns exceed the available width, - // the horizontal scrollbar should be shown even when there're no rows. - // Keeping 1px as minimum height ensures that the scrollbar will visible if necessary. - const height = Math.max(contentHeight, 1); - const size: React.CSSProperties = { width: needsHorizontalScrollbar ? columnsTotalWidth : 'auto', - height, + height: contentHeight, }; - if (rootProps.autoHeight) { - if (currentPage.rows.length === 0) { - size.height = getMinimalContentHeight(apiRef); // Give room to show the overlay when there no rows. - } else { - size.height = contentHeight; - } + if (rootProps.autoHeight && currentPage.rows.length === 0) { + size.height = getMinimalContentHeight(apiRef); // Give room to show the overlay when there no rows. } return size; diff --git a/packages/x-data-grid/src/tests/DataGrid.test.tsx b/packages/x-data-grid/src/tests/DataGrid.test.tsx index f058407dc45f..cef9fe12cf3a 100644 --- a/packages/x-data-grid/src/tests/DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/DataGrid.test.tsx @@ -76,19 +76,21 @@ describe('', () => { ]; expect(() => { render( - - ).reduce((acc, key) => { - // @ts-ignore - acc[key] = undefined; - return acc; - }, {})} - rows={rows} - columns={columns} - />, +
+ + ).reduce((acc, key) => { + // @ts-ignore + acc[key] = undefined; + return acc; + }, {})} + rows={rows} + columns={columns} + /> +
, ); }).not.toErrorDev(); }); diff --git a/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx b/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx index 28a32fe53aa0..4f003a354866 100644 --- a/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx +++ b/packages/x-data-grid/src/tests/layout.DataGrid.test.tsx @@ -1174,7 +1174,7 @@ describe(' - Layout & warnings', () => { } render( -
+
, ); @@ -1213,7 +1213,7 @@ describe(' - Layout & warnings', () => { } render( -
+
- Pagination', () => { ]; expect(() => { const { setProps } = render( - , +
+ +
, ); setProps({ rows: rows.slice(0, 2) }); }).not.to.throw(); diff --git a/test/karma.conf.js b/test/karma.conf.js index 483d8e8ca368..3da8db12d540 100644 --- a/test/karma.conf.js +++ b/test/karma.conf.js @@ -3,7 +3,7 @@ const webpack = require('webpack'); const CI = Boolean(process.env.CI); -process.env.CHROME_BIN = chromium.executablePath(); +process.env.CHROME_BIN ||= chromium.executablePath(); // Karma configuration module.exports = function setKarmaConfig(config) { diff --git a/test/regressions/data-grid/DataGridPinnedBottomRow.js b/test/regressions/data-grid/DataGridPinnedBottomRow.js new file mode 100644 index 000000000000..1b3d5c71c9f5 --- /dev/null +++ b/test/regressions/data-grid/DataGridPinnedBottomRow.js @@ -0,0 +1,44 @@ +import * as React from 'react'; +import { DataGridPro } from '@mui/x-data-grid-pro'; +import { + randomCity, + randomEmail, + randomId, + randomInt, + randomTraderName, + randomUserName, +} from '@mui/x-data-grid-generator'; + +const columns = [ + { field: 'name', headerName: 'Name', width: 150 }, + { field: 'city', headerName: 'City', width: 150 }, + { field: 'username', headerName: 'Username' }, + { field: 'email', headerName: 'Email', width: 200 }, + { field: 'age', type: 'number', headerName: 'Age' }, +]; + +const rows = []; + +function getRow() { + return { + id: randomId(), + name: randomTraderName(), + city: randomCity(), + username: randomUserName(), + email: randomEmail(), + age: randomInt(10, 80), + }; +} + +const pinnedRows = { + top: [getRow()], + bottom: [getRow()], +}; + +export default function RowPinning() { + return ( +
+ +
+ ); +}