Reputation: 2528
Is there a way I can add ripple effect to Material UI Card
component on click.
And I would also like to know, is it possible to make ripple effect to come on top of the content of Card component, rather that it showing as background.
Upvotes: 30
Views: 28823
Reputation: 3716
You can get the benefit of the component
prop, use the <ButtonBase>
component to get the ripple effect.
Create a React HOC or simply copy this code into a new file:
import React, { forwardRef } from 'react'
import { ButtonBase } from '@mui/material'
export default function WithTouchRipple(OriginalComponent) {
return (props) => {
const Wrapper = !props.component
? ButtonBase
: forwardRef((ButtonBaseProps, ref) => <ButtonBase component={props.component} {...ButtonBaseProps} ref={ref} />)
return <OriginalComponent {...props} component={Wrapper} />
}
}
Then use it as follows on any component you like:
import { Chip, Card, Stack } from '@mui/material'
import WithTouchRipple from '../WithTouchRipple'
const RippleChip = WithTouchRipple(Chip)
const RippleCard = WithTouchRipple(Card)
const RippleStack = WithTouchRipple(Stack)
<RippleChip component={Link} to={`/users/${id}`} {...chipProps} />
<RippleStack>...</RippleStack>
<RippleCard>...</RippleCard>
If you want the ripple effect to appear on the <Card>
component, there is a built-in component for that called <CardActionArea>
, and you can use it as follows:
<Card>
<CardActionArea>
<CardContent>
{...}
</CardContent>
</CardActionArea>
</Card>
Upvotes: 3
Reputation: 1476
component
attributecomponent
attribute as the desired component you want it to be. That is, for this use-case;
import ButtonBase from '@material-ui/core/ButtonBase';
...
<Card component = {ButtonBase}>
<CardContent>
...
</CardContent>
</Card>
If you have issues with height or width of the card, add the sx
attribute;
<Card component={ButtonBase} sx={{height:'100%', width:'100%'}}>
...
</Card>
If ButtonBase messes up all other buttons on the page, it's better to use just the Button;
import Button from '@mui/material/Button';
...
<Card component = {Button}>
<CardContent>
...
</CardContent>
</Card>
Upvotes: 1
Reputation: 81520
The most idiomatic way to add the ripple effect when clicking the Card
is using the CardActionArea
. This component inherits the props of ButtonBase
. It also changes the Card
background color when hovered and focused (unlike ButtonBase
):
<Card>
<CardActionArea>
<CardContent>
{...}
</CardContent>
</CardActionArea>
</Card>
Upvotes: 8
Reputation: 383
You can customize by wrapping with Grid and props container
import { Button } from "@material-ui/core";
function ImageCard(props){
return (
<Button style={{ padding: 0, borderRadius: "16px" }}>
{/*my custom component you can use any component even material ui component also*/}
<img
src={yourImageUrl}
alt="img"
style={{
height: 200,
width: 400,
borderRadius: "16px",//optional
}}
/>
</Button>
);
}
Upvotes: 1
Reputation: 1006
I can see this question was not answered, so I'll provide an up-to-date solution (writing this as material-ui
is v. 0.18.7 (stable):
You need to import the ripple higher-order comp. (HOC) as:
import TouchRipple from '@material-ui/core/ButtonBase/TouchRipple';
Then you can wrap any component of you choice with TouchRipple
, like:
<TouchRipple>
<div>
MY RIPPLING DIV
</div>
</TouchRipple>
Or, if you need a CSS class-based apporach, you can use materialize lib -> https://react-materialize.github.io/#/
In that case, it's as simple as adding a value to waves
prop on a material-ui Button
, like:
<Button waves='light'>EDIT ME<Icon left>save</Icon></Button>
Upvotes: 14
Reputation: 360
I noticed that TouchRipple has been moved out of the internal
directory.
It's now available in the ButtonBase folder.
Here is how I was able to add ripple effect by using the ButtonBase component -
Basically, you wrap your component, let's say <Card>
inside the <ButtonBase>
like so, and the ButtonBase
takes care of the TouchRipple
setting up for you -
<ButtonBase>
<Card>
....
</Card>
</ButtonBase>
Here is a Codesandbox link to working demo.
I know this is not the best way. You could directly use the TouchRipple
/Ripple
component, but I found this way to be very easy to use.
Hope this helps.
Upvotes: 26
Reputation: 6260
The approach taken in @xiaofan2406 never worked for me, not to mention passing height, width and position seems easily breakable and might not be possible when using flexbox.
However I managed to make it work like:
<YourComponent>
<TouchRipple>
{children}
</TouchRipple>
</YourComponent>
Upvotes: 1
Reputation: 3310
The official api doesn't seem to support it.
But this is what I do, when I want to use material-ui
ripple affect:
Use material-ui/internal/TouchRipple
, have a look at its source code
Usage example:
<YourComponent>
<TouchRipple style={style}/>
{children}
</YourComponent>
You need to pass the inline style to specify its height, width and position that matches YourComponent
's height, width and postion
Upvotes: 0