Is it possible to use the touch ripple effect of MUI on a div?
Asked Answered
L

3

15

I have read different answers of similar questions, but they are all old and don't seem to work in the latest version of MUI.

I need to apply the touch ripple effect on a div, but I can't use a button or a ButtonBase element because there is another button inside it.

Thanks in advance for the reply.

Leporid answered 22/4, 2021 at 11:20 Comment(1)
The TouchRipple component uses a div, so there's no problem in using it to wrap a button element.Infatuate
R
17

Yes, you can use TouchRipple to emulate the ripple effect. This component is undocumented, but you can see how it's used in the ButtonBase and learn to use it yourself.

First, you need to pass a ref to TouchRipple and call ref.current.start(e) or ref.current.stop(e) when you want to start or stop the effect respectively.

e is the event object. When you call start(e), it needs the mouse or touch position (from mousedown or touchstart event) to know where to start the ripple effect (Source). You can override this behavior by setting center props to true, which makes the ripple effect always start at the middle.

Below is the minimum working example to get you started:

function App() {
  const rippleRef = React.useRef(null);
  const onRippleStart = (e) => {
    rippleRef.current.start(e);
  };
  const onRippleStop = (e) => {
    rippleRef.current.stop(e);
  };

  return (
    <div
      onMouseDown={onRippleStart}
      onMouseUp={onRippleStop}
      style={{
        display: "inline-block",
        padding: 8,
        position: "relative",
        border: "black solid 1px"
      }}
    >
      Button
      <TouchRipple ref={rippleRef} center={false} />
    </div>
  );
}

Live Demo

Edit 66888248/how-do-i-programatically-show-ripple-effect-with-material-ui

Ripplet answered 22/4, 2021 at 12:2 Comment(1)
Wow! Thanks a ton.Rill
P
19

You Can Use ButtonBase API

With ButtonBase API you can pass component prop as div or any component you want

For Eg.

import { ButtonBase, Typography } from "@mui/material";

const App = () => {
  return (
    <ButtonBase component="div">
        <Typography fontSize="1.2rem">Hello, I'm a div with MUI Ripple Effect!</Typography>
    </ButtonBase>
  )
}

export default App;
Phillada answered 24/2, 2022 at 9:25 Comment(2)
Worked on my endSpecify
I know this is obvious out of context, but you may want to check your theme for something like this inside components: ` MuiButtonBase: { defaultProps: { disableRipple: true, }, }, ` … in which case you'll need to overwrite this one time use with disableRipple={false} prop to ButtonBase.Parrisch
R
17

Yes, you can use TouchRipple to emulate the ripple effect. This component is undocumented, but you can see how it's used in the ButtonBase and learn to use it yourself.

First, you need to pass a ref to TouchRipple and call ref.current.start(e) or ref.current.stop(e) when you want to start or stop the effect respectively.

e is the event object. When you call start(e), it needs the mouse or touch position (from mousedown or touchstart event) to know where to start the ripple effect (Source). You can override this behavior by setting center props to true, which makes the ripple effect always start at the middle.

Below is the minimum working example to get you started:

function App() {
  const rippleRef = React.useRef(null);
  const onRippleStart = (e) => {
    rippleRef.current.start(e);
  };
  const onRippleStop = (e) => {
    rippleRef.current.stop(e);
  };

  return (
    <div
      onMouseDown={onRippleStart}
      onMouseUp={onRippleStop}
      style={{
        display: "inline-block",
        padding: 8,
        position: "relative",
        border: "black solid 1px"
      }}
    >
      Button
      <TouchRipple ref={rippleRef} center={false} />
    </div>
  );
}

Live Demo

Edit 66888248/how-do-i-programatically-show-ripple-effect-with-material-ui

Ripplet answered 22/4, 2021 at 12:2 Comment(1)
Wow! Thanks a ton.Rill
M
1

The top answer here is great but I think it can be done better since MUI provides a hook that simplifies the things.

You can implement it by the following way:

import TouchRipple from '@mui/material/ButtonBase/TouchRipple';
import useTouchRipple from '@mui/material/useTouchRipple';
import { Collapse, Divider, Paper, useTheme } from '@mui/material';
import React from 'react';

const App = () => {
  const rippleRef = React.useRef(null);
  const { getRippleHandlers } = useTouchRipple({
    disabled: false,
    focusVisible: false,
    rippleRef,
  });

  return (
    <div
      style={{
        position: "relative",
      }}
      {...getRippleHandlers()}
    >
      <TouchRipple ref={rippleRef} center={false} />

      <Typography>Button</Typography>
    </div>
  );
}

I also noticed that if you don't provide position: relative then it ripple effect will be on the whole screen instead of the component you're trying to do so.

Moniquemonism answered 1/4 at 7:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.