Basically the title. I want to manually show the ripple effect on my collection of MUI's Buttons - the ripple effect works when I click the button, but I can't find a way to show the ripple effect programmatically.
Do I need to disable the MUI's ripple effect and then make my own ripple effect function, that I can attach to onClick
?
{this.buttons.map((button) => (
<React.Fragment key={button.name}>
{button.render ? (
<div className="col-3">
<Button
autoFocus={true}
className="w-100 p-3"
variant="contained"
color="primary"
classes={{root: classes.button}}
disableElevation
onClick={() => {updateState(button.onClick(text))}}
>
{button.keyCode}
</Button>
</div>
) : (<></>)}
</React.Fragment>
))}
Button
uses ButtonBase
which uses TouchRipple
under the hood. Here is a snippet of ButtonBase
definition:
function ButtonBase(props) {
// ...
return (
<ButtonBaseRoot>
{children}
<TouchRipple ref={rippleRef} center={centerRipple} {...TouchRippleProps} />
</ButtonBaseRoot>
)
}
There is no API to trigger the ripple manually. It's handled internally inside the button, so in order to do that, you need to create and control your own ripple component provided by MUI:
import TouchRipple from '@mui/material/ButtonBase/TouchRipple';
const rippleRef = React.useRef(null);
const buttonRef = React.useRef(null);
const triggerRipple = () => {
const container = buttonRef.current;
const rect = container.getBoundingClientRect();
rippleRef.current.start(
{
clientX: rect.left + rect.width / 2,
clientY: rect.top + rect.height / 2,
},
// when center is true, the ripple doesn't travel to the border of the container
{ center: false },
);
setTimeout(() => rippleRef.current.stop({}), 320);
};
return (
<div>
<Button onClick={triggerRipple}>start ripple</Button>
<Box display="flex" justifyContent="center" m={10}>
<Button
variant="contained"
color="primary"
ref={buttonRef}
sx={{ display: 'relative' }}
>
My little ripple
<TouchRipple ref={rippleRef} center />
</Button>
</Box>
</div>
);