How do I programatically show "ripple effect" with MUI?

All we need is an easy explanation of the problem, so here it is.

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>
))}

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

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>
);

Live Demo

How do I programatically show "ripple effect" with MUI?

Related answers

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply