Skip to content

Commit

Permalink
[DataGrid] Fix group header resize (#12863)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrew Cherniavskii <andrew.cherniavskii@gmail.com>
  • Loading branch information
arminmeh and cherniavskii committed Apr 23, 2024
1 parent 06ba75a commit b93315a
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
findRightPinnedCellsBeforeCol,
getFieldFromHeaderElem,
findHeaderElementFromField,
getFieldsFromGroupHeaderElem,
findGroupHeaderElementsFromField,
findGridHeader,
findGridCells,
Expand Down Expand Up @@ -428,6 +429,24 @@ export const useGridColumnResize = (
if (refs.colDef) {
apiRef.current.setColumnWidth(refs.colDef.field, refs.colDef.width!);
logger.debug(`Updating col ${refs.colDef.field} with new width: ${refs.colDef.width}`);

const columnsState = gridColumnsStateSelector(apiRef.current.state);
refs.groupHeaderElements!.forEach((element) => {
const fields = getFieldsFromGroupHeaderElem(element);
const div = element as HTMLDivElement;

const newWidth = fields.reduce((acc, field) => {
if (columnsState.columnVisibilityModel[field] !== false) {
return acc + columnsState.lookup[field].computedWidth;
}
return acc;
}, 0);
const finalWidth: `${number}px` = `${newWidth}px`;

div.style.width = finalWidth;
div.style.minWidth = finalWidth;
div.style.maxWidth = finalWidth;
});
}

stopResizeEventTimeout.start(0, () => {
Expand Down
5 changes: 5 additions & 0 deletions packages/x-data-grid/src/utils/domUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ export function findHeaderElementFromField(elem: Element, field: string): HTMLDi
return elem.querySelector(`[data-field="${field}"]`)!;
}

export function getFieldsFromGroupHeaderElem(colCellEl: Element): string[] {
const fieldsString = colCellEl.getAttribute('data-fields');
return fieldsString?.startsWith('|-') ? fieldsString!.slice(2, -2).split('-|-') : [];
}

export function findGroupHeaderElementsFromField(elem: Element, field: string): Element[] {
return Array.from(elem.querySelectorAll<HTMLDivElement>(`[data-fields*="|-${field}-|"]`) ?? []);
}
Expand Down
35 changes: 35 additions & 0 deletions test/e2e/fixtures/DataGrid/ResizeWithFlex.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as React from 'react';
import { DataGrid } from '@mui/x-data-grid';

const columns = [
{ field: 'column1', flex: 1 },
{ field: 'column2', flex: 1 },
{ field: 'column3', flex: 1 },
{ field: 'column4', flex: 0 },
{ field: 'column5', flex: 0 },
];

const columnGroupingModel = [
{
groupId: 'group1',
children: [
{ field: 'column1' },
{
groupId: 'group1.1',
children: [{ field: 'column2' }, { field: 'column3' }, { field: 'column4' }],
},
],
},
{
groupId: 'group2',
children: [{ field: 'column5' }],
},
];

export default function ResizeWithFlex() {
return (
<div style={{ width: 700, height: 300 }}>
<DataGrid columns={columns} rows={[]} columnGroupingModel={columnGroupingModel} />
</div>
);
}
49 changes: 49 additions & 0 deletions test/e2e/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
BrowserContextOptions,
BrowserType,
WebError,
Locator,
} from '@playwright/test';
import { pickersTextFieldClasses } from '@mui/x-date-pickers/PickersTextField';
import { pickersSectionListClasses } from '@mui/x-date-pickers/PickersSectionList';
Expand Down Expand Up @@ -538,6 +539,54 @@ async function initializeEnvironment(
await sleep(200);
expect(thrownError).to.equal(null);
});

// https://github.com/mui/mui-x/issues/12290
it('should properly set the width of a group header if the resize happened in a group with fluid columns', async () => {
await renderFixture('DataGrid/ResizeWithFlex');

const headers = await page.locator('.MuiDataGrid-columnHeaders > div').all();
const columnHeader = headers.pop()!;

const columns = columnHeader.locator('.MuiDataGrid-columnHeader');
const separators = await columnHeader
.locator('.MuiDataGrid-columnSeparator--resizable')
.all();

const moveSeparator = async (separator: Locator) => {
const boundingBox = (await separator?.boundingBox())!;
const x = boundingBox.x + boundingBox.width / 2;
const y = boundingBox.y + boundingBox.height / 2;

await page.mouse.move(x, y, { steps: 5 });
await page.mouse.down();
await page.mouse.move(x - 20, y, { steps: 5 });
await page.mouse.up();
};

await moveSeparator(separators[0]);
await moveSeparator(separators[1]);

const groupHeaderWidth = await headers[0]
.locator('.MuiDataGrid-columnHeader--filledGroup')
.first()
.evaluate((node) => node.clientWidth);
const subGroupHeaderWidth = await headers[1]
.locator('.MuiDataGrid-columnHeader--filledGroup')
.first()
.evaluate((node) => node.clientWidth);

const groupHeaderColumnsTotalWidth = await columns.evaluateAll((elements) =>
// last column is not part of the group
elements.slice(0, -1).reduce((acc, element) => acc + element.clientWidth, 0),
);
const subGroupHeaderColumnsTotalWidth = await columns.evaluateAll((elements) =>
// first and last columns are not part of the sub-group
elements.slice(1, -1).reduce((acc, element) => acc + element.clientWidth, 0),
);

expect(groupHeaderWidth).to.equal(groupHeaderColumnsTotalWidth);
expect(subGroupHeaderWidth).to.equal(subGroupHeaderColumnsTotalWidth);
});
});

describe('<DatePicker />', () => {
Expand Down

0 comments on commit b93315a

Please sign in to comment.