Skip to content

Commit

Permalink
[DataGrid] Don't select the row when clicking on an item in the `acti…
Browse files Browse the repository at this point in the history
…ons` column type (#2862)
  • Loading branch information
m4theushw authored Oct 18, 2021
1 parent 7ee2a2c commit d30f09b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ const GridActionsCell = (props: GridActionsCellProps) => {
throw new Error('MUI: Missing the `getActions` property in the `GridColDef`.');
}

const showMenu = () => setOpen(true);
const showMenu = (event: React.MouseEvent) => {
event.stopPropagation();
setOpen(true);
};

const hideMenu = () => setOpen(false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,26 @@ export type GridActionsCellItemProps = {
);

const GridActionsCellItem = (props: GridActionsCellItemProps) => {
const { label, icon, showInMenu, ...other } = props;
const { label, icon, showInMenu, onClick, ...other } = props;

const handleClick = (event: any) => {
event.stopPropagation();

if (onClick) {
onClick(event);
}
};

if (!showInMenu) {
return (
<IconButton size="small" aria-label={label} {...(other as any)}>
<IconButton size="small" aria-label={label} {...(other as any)} onClick={handleClick}>
{React.cloneElement(icon!, { fontSize: 'small' })}
</IconButton>
);
}

return (
<MenuItem {...(other as any)}>
<MenuItem {...(other as any)} onClick={onClick}>
{icon && <ListItemIcon>{icon}</ListItemIcon>}
{label}
</MenuItem>
Expand Down
103 changes: 55 additions & 48 deletions packages/grid/data-grid/src/tests/rows.DataGrid.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,30 @@ describe('<DataGrid /> - Rows', () => {
});

describe('columnType: actions', () => {
const TestCase = ({ getActions }: { getActions?: () => JSX.Element[] }) => {
return (
<div style={{ width: 300, height: 300 }}>
<DataGrid
{...baselineProps}
rows={[{ id: 1 }]}
columns={[
{
field: 'actions',
type: 'actions',
getActions,
},
]}
/>
</div>
);
};

it('should throw an error if getActions is missing', function test() {
if (!isJSDOM) {
this.skip();
}
expect(() => {
render(
<div style={{ width: 300, height: 300 }}>
<DataGrid
{...baselineProps}
rows={[{ id: 1 }]}
columns={[{ field: 'actions', type: 'actions' }]}
/>
</div>,
);
render(<TestCase />);
}) // @ts-expect-error need to migrate helpers to TypeScript
.toErrorDev([
'MUI: Missing the `getActions` property in the `GridColDef`.',
Expand All @@ -153,61 +163,58 @@ describe('<DataGrid /> - Rows', () => {

it('should call getActions with the row params', () => {
const getActions = stub().returns([]);
render(
<div style={{ width: 300, height: 300 }}>
<DataGrid
{...baselineProps}
rows={[{ id: 1 }]}
columns={[{ field: 'actions', type: 'actions', getActions }]}
/>
</div>,
);
render(<TestCase getActions={getActions} />);
expect(getActions.args[0][0].id).to.equal(1);
expect(getActions.args[0][0].row).to.deep.equal({ id: 1 });
});

it('should always show the actions not marked as showInMenu', () => {
render(
<div style={{ width: 300, height: 300 }}>
<DataGrid
{...baselineProps}
rows={[{ id: 1 }]}
columns={[
{
field: 'actions',
type: 'actions',
getActions: () => [
<GridActionsCellItem icon={<span />} label="delete" />,
<GridActionsCellItem label="print" showInMenu />,
],
},
]}
/>
</div>,
<TestCase
getActions={() => [
<GridActionsCellItem icon={<span />} label="delete" />,
<GridActionsCellItem label="print" showInMenu />,
]}
/>,
);
expect(screen.queryByRole('button', { name: 'delete' })).not.to.equal(null);
expect(screen.queryByText('print')).to.equal(null);
});

it('should show in a menu the actions marked as showInMenu', async () => {
render(<TestCase getActions={() => [<GridActionsCellItem label="print" showInMenu />]} />);
expect(screen.queryByText('print')).to.equal(null);
fireEvent.click(screen.getByRole('button', { name: 'more' }));
await waitFor(() => expect(screen.queryByText('print')).not.to.equal(null));
});

it('should not select the row when clicking in an action', () => {
render(
<div style={{ width: 300, height: 300 }}>
<DataGrid
{...baselineProps}
rows={[{ id: 1 }]}
columns={[
{
field: 'actions',
type: 'actions',
getActions: () => [<GridActionsCellItem label="print" showInMenu />],
},
]}
/>
</div>,
<TestCase getActions={() => [<GridActionsCellItem icon={<span />} label="print" />]} />,
);
expect(screen.queryByText('print')).to.equal(null);
expect(getRow(0).className).not.to.contain('Mui-selected');
fireEvent.click(screen.getByRole('button', { name: 'print' }));
expect(getRow(0).className).not.to.contain('Mui-selected');
});

it('should not select the row when clicking in a menu action', async () => {
render(
<TestCase
getActions={() => [<GridActionsCellItem icon={<span />} label="print" showInMenu />]}
/>,
);
expect(getRow(0).className).not.to.contain('Mui-selected');
fireEvent.click(screen.getByRole('button', { name: 'more' }));
await waitFor(() => expect(screen.queryByText('print')).not.to.equal(null));
fireEvent.click(screen.queryByText('print'));
expect(getRow(0).className).not.to.contain('Mui-selected');
});

it('should not select the row when opening the menu', () => {
render(<TestCase getActions={() => [<GridActionsCellItem label="print" showInMenu />]} />);
expect(getRow(0).className).not.to.contain('Mui-selected');
fireEvent.click(screen.getByRole('button', { name: 'more' }));
expect(getRow(0).className).not.to.contain('Mui-selected');
});
});
});

0 comments on commit d30f09b

Please sign in to comment.