Reputation: 631
This question is specific to usage of the Material UI React component library. I've created a functioning Code Sandbox example, available this link. I am using the Data Grid component, and the default behavior of the Filter button (GridToolbarFilterButton
) is such that it shows a Badge over the button's icon. This is not default behavior of the Columns button (GridToolbarColumnsButton
), but I've managed to add and achieve the same functionality.
One thing that I am having trouble with is getting the same animation / transition to happen them the badge becomes visible or invisible. On the Filter button, you can see that the badge has an animation where it seems to grow into view, and then shrink out of view. On the Columns button, it just immediately appears or disappears. I've spent some time trying to look at the Material UI source code to see if I can piece it together, but it feels just a little bit out of my reach at the moment.
Any thoughts on how I might be able to mimic that same animation for the Columns button? Happy to provide additional information. I've included a GIF animation of the Code Sandbox I provided, hopefully this will be a helpful visualize of differing animations between the badge appearing/disappearing on both buttons. Based on this pull request on the MUI-X project, it seems that perhaps the MUI team might be doing something related to this in the relatively near future.
Upvotes: 2
Views: 67
Reputation: 6044
The grow/shrink animation of the badge works when the class MuiBadge-invisible
is removed or added to the Badge element.
Why this animation is not working for the Badge on the columns button?
It is not working because when the columnVisibilityModel
changes, the whole toolbar section is getting re-rendered. So when the hidden columns count is more than 1, then the Badge element is re-rendered without the class MuiBadge-invisible
. So the transition from invisible to visible is not happening.
Solution:
Solution is we need to mimic the class transition by following these steps:
Check this working CodeSandbox link. I've updated this section of the code in the CodeSandbox.
function MyButton({ prevCount, currentCount }) {
const [count, setCount] = useState(prevCount);
useEffect(() => {
setTimeout(() => {
setCount(currentCount);
}, 50);
}, [currentCount]);
return (
<Badge color="primary" badgeContent={count}>
<GridColumnIcon />
</Badge>
);
}
export default function App() {
const [columnVisibilityModel, setColumnVisibilityModel] = useState(
Object.fromEntries(columns.map((column) => [column.field, true]))
);
const [prevCount, setPrevCount] = useState(0);
const [currentCount, setCurrentCount] = useState(0);
useEffect(() => {
setPrevCount(currentCount);
setCurrentCount(
Object.entries(columnVisibilityModel).filter(
([key, value]) => value === false
).length
);
}, [columnVisibilityModel]);
return (
<DataGridPro
rows={rows}
columns={columns}
columnVisibilityModel={columnVisibilityModel}
onColumnVisibilityModelChange={(newModel) =>
setColumnVisibilityModel(newModel)
}
slots={{
toolbar: () => {
return (
<GridToolbarContainer>
<GridToolbarColumnsButton
startIcon={
<MyButton prevCount={prevCount} currentCount={currentCount} />
}
/>
<GridToolbarFilterButton />
</GridToolbarContainer>
);
},
}}
/>
);
}
And this is how it looks:
Upvotes: 1