javascriptcssreactjsmaterial-uimui-x-data-grid

Custom edit and delete components on row MUI X Data Grid v5 component hovered


I'm using MUI X Data Grid v5 components for the UI library in my React Js app.

I'm creating a custom edit and delete row inside the DataGrid/DataGridPro component.

The specification is to show edit and delete icons for the hovered row but not by adding a new column (not adding an action column). I found the example for a private dashboard here. enter image description here

So if the user decreases the width of the browser, the edit and delete icons wouldn't be hidden instead it would hide the row as seen in the image below. enter image description here enter image description here

I made it here https://codesandbox.io/s/learn-mui-data-grid-hover-row-367vh?file=/demo.js but I found some drawbacks below:

1. The Popper component is rendered on top of the DataGrid component

When our mouse cursor hovered the row that was not fully shown, the Popper component was shown like these images below.

enter image description here enter image description here

I've tried to add the disablePortal={true} prop to the Popper component but it would make the Popper component rendered outside the row like this image below. enter image description here

I also have tried to change the zIndex prop for the column header (became 1000), the row (became 10), and the pagination container (became 1000) of the DataGrid component also changed the zIndex prop of the Popper component (became 100) but still the Popper component was rendered on top of the DataGrid component like this image below. enter image description here

Question 1: What should I do to make the Popper component rendered on the top of the row but still inside the DataGrid component like this image below? enter image description here

2. The Popper component was not sticking to the DataGrid component

If I add a few new columns, the Popper component was sticking on the end of the row like this image below. This was the condition I want.

enter image description here

If we scroll our mouse to the start of the row, the Popper component was not sticking to the end of the row like this image below. This was not the condition I want. enter image description here

Question 2: What should I do to make the Popper component stick to the end of the row regardless of scrolling horizontally our mouse like this image below? enter image description here

Here is the demo https://codesandbox.io/s/learn-mui-data-grid-hover-row-367vh?file=/Demo2.jsx

Or is there any better way to achieve this case? 🤔


Solution

  • Finally, I could make it after learning about these features:

    1. column pinning feature https://mui.com/components/data-grid/columns/#column-pinning to create the edit and delete icons container
    2. componentsProps https://mui.com/components/data-grid/components/#row to control which row is hovered

    Here are the steps:

    1. use componentsProps to control which row is hovered
    componentsProps={{
      row: {
        onMouseEnter: onMouseEnterRow,
        onMouseLeave: onMouseLeaveRow
      }
    }}
    
    1. add actions column and only show the edit and delete icons when the row is hovered
    {
      field: "actions",
      headerName: "",
      width: 120,
      sortable: false,
      disableColumnMenu: true,
      renderCell: (params) => {
        if (hoveredRow === params.id) {
          return (
            <Box
              sx={{
                backgroundColor: "whitesmoke",
                width: "100%",
                height: "100%",
                display: "flex",
                justifyContent: "center",
                alignItems: "center"
              }}
            >
              <IconButton onClick={() => console.log(params.id)}>
                <EditIcon />
              </IconButton>
              <IconButton onClick={() => console.log(params.id)}>
                <DeleteIcon />
              </IconButton>
            </Box>
          );
        } else return null;
      }
    }
    
    1. pin the actions column and change the DataGrid styles
    <DataGridPro
      // some code here ...
      initialState={{ pinnedColumns: { right: ["actions"] } }}
      sx={{
        "& .MuiDataGrid-iconSeparator": {
          display: "none"
        },
        "& .MuiDataGrid-pinnedColumnHeaders": {
          boxShadow: "none",
          backgroundColor: "transparent"
        },
        "& .MuiDataGrid-pinnedColumns": {
          boxShadow: "none",
          backgroundColor: "transparent",
          "& .MuiDataGrid-cell": {
            padding: 0
          }
        },
        "& .MuiDataGrid-row": {
          cursor: "pointer",
          "&:hover": {
            backgroundColor: "whitesmoke"
          },
          "&:first-child": {
            borderTop: "1px solid rgba(224, 224, 224, 1)"
          }
        },
        "& .MuiDataGrid-cell:focus": {
          outline: "none"
        },
        "& .MuiDataGrid-cell:focus-within": {
          outline: "none"
        }
      }}
    />
    

    Here is the demo https://codesandbox.io/s/learn-mui-data-grid-column-pinning-gzgn0?file=/demo.js

    enter image description here