In the MUI DataGrid, by clicking the options menu on any header column, you can access the column visibility panel.
But I haven't found a way to display this panel from outside the Grid. The idea was to have a button that, when clicked, could display the panel. Even if it remains with its position inside the Grid
This would avoid having to build a component for this purpose.
I'm not sure if I missed it in the docs, but it doesn't look like you can control the visibility of the default MUI 'Column Visibility Panel' with the Grid API like you can with the Filter Panel.
However, you can provide your own columnVisibilityModel to the DataGrid which will dictate which columns are visible in the grid. This will let you control the visibility of each column from outside the grid, but you will have to create your own Column Visibility Panel.
Here is a code sandbox example: https://codesandbox.io/s/mui-5-forked-zj4glu?file=/src/ArrowPopper.tsx
Code:
import * as React from "react";
import { Box, Button, FormControlLabel, Popper, Switch } from "@mui/material";
import { DataGrid, GridColDef, GridValueGetterParams } from "@mui/x-data-grid";
const columns: GridColDef[] = [
{ field: "id", headerName: "ID", width: 90 },
{
field: "firstName",
headerName: "First name",
width: 150,
editable: true
},
{
field: "lastName",
headerName: "Last name",
width: 150,
editable: true
},
{
field: "age",
headerName: "Age",
type: "number",
width: 110,
editable: true
},
{
field: "fullName",
headerName: "Full name",
description: "This column has a value getter and is not sortable.",
sortable: false,
width: 160,
valueGetter: (params: GridValueGetterParams) =>
`${params.row.firstName || ""} ${params.row.lastName || ""}`
}
];
const rows = [
{ id: 1, lastName: "Snow", firstName: "Jon", age: 35 },
{ id: 2, lastName: "Lannister", firstName: "Cersei", age: 42 },
{ id: 3, lastName: "Lannister", firstName: "Jaime", age: 45 },
{ id: 4, lastName: "Stark", firstName: "Arya", age: 16 },
{ id: 5, lastName: "Targaryen", firstName: "Daenerys", age: null },
{ id: 6, lastName: "Melisandre", firstName: null, age: 150 },
{ id: 7, lastName: "Clifford", firstName: "Ferrara", age: 44 },
{ id: 8, lastName: "Frances", firstName: "Rossini", age: 36 },
{ id: 9, lastName: "Roxie", firstName: "Harvey", age: 65 }
];
export default function DataGridDemo() {
const [columnVisibility, setColumnVisibility] = React.useState({
id: true,
firstName: true,
lastName: true,
age: true,
fullName: true
});
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const toggleColumnVisibility = (e) => {
setColumnVisibility((prev) => ({
...prev,
[e.target.name]: e.target.checked
}));
};
const handleClick = (event: React.MouseEvent<HTMLElement>) => {
setAnchorEl(anchorEl ? null : event.currentTarget);
};
const open = Boolean(anchorEl);
return (
<Box sx={{ height: 400, width: "100%" }}>
<Button
onClick={handleClick}
variant="contained"
sx={{
mb: 2
}}
>
Show Column Visibility
</Button>
<DataGrid
rows={rows}
columns={columns}
pageSize={5}
rowsPerPageOptions={[5]}
checkboxSelection
disableSelectionOnClick
columnVisibilityModel={columnVisibility}
/>
<Popper open={open} anchorEl={anchorEl}>
<Box
sx={{
display: "flex",
flexDirection: "column",
backgroundColor: "white"
}}
>
{columns.map((c) => (
<FormControlLabel
key={c.field}
label={c.headerName}
control={
<Switch
name={c.field}
checked={columnVisibility[c.field]}
onChange={toggleColumnVisibility}
/>
}
/>
))}
</Box>
</Popper>
</Box>
);
}