React animation inline styling - css

I am practicing React inline animation styling. I have made one toggle button, when user press button first time, I want pop up animated card from left to right. when user press button 2nd time it will close the card from right to left. I want to learn how the animation work inline react styling. Unfortunately I am unable to do that. Seems like React inline styling, transitions and translate does not work to me. This is the animation I want to do it. I shared my code in code-sandbox.
This is my code
import { useState } from "react";
export default function App() {
const [toggle, setToggle] = useState(false);
return (
<>
<button onClick={(): void => setToggle(!toggle)}>toogle button</button>
{toggle && (
<div
style={{
display: "flex",
zIndex: 1,
marginLeft: 170,
background: "red",
width: 200,
height: 300,
opacity: 1,
backgroundColor: "tomato",
transition: "opacity 5s"
}}
>
<p style={{ margin: "0px" }}>animation</p>
</div>
)}
</>
);
}

I don't think that this is a good idea, but here is one solution.
You can control everything.
import "./styles.css";
import { useState } from "react";
export default function App() {
const transitions = ["linear", "ease", "ease-in", "ease-out", "ease-in-out"];
const [opacity, setOpacity] = useState(0);
const [right, setRight] = useState(40);
const speed = 0.5;
return (
<>
<button
onClick={() => {
setOpacity(opacity ? 0 : 1);
setRight(prev => prev === 40 ? 20 : 40);
}}
>
toogle button
</button>
<div
style={{
display: "flex",
zIndex: 1,
marginLeft: 170,
background: "red",
width: 200,
height: 300,
opacity,
backgroundColor: "tomato",
transition: `all ${transitions[1]} ${speed}s`,
transform: `translateX(-${right}%)`
}}
>
<p style={{ margin: "0px" }}>animation</p>
</div>
)
</>
);
}

You could use the inlined styles, but you cannot achieve the desired behavior without the use of CSS or a third party library doing the animations for you.
I would recommend to check out this: https://www.w3schools.com/css/css3_animations.asp
Another problem that I see:
You are displaying the content only as soon as the "toggle" property is true, but for animations you need to have different states in your markup in order to transition to different states of animation.
E.g.
<div className="opening">
<div className="opened">
<div className="closing">
<div className="closed"> (or removed from DOM)
Then you can apply the CSS #keyframes to all different stages using the corresponding CSS selectors.
Or if you don't want to dig into CSS yourself. You can use e.g. this library to do the job: https://react-spring.dev/

Related

Dynamically drawing multiple borders with MUI

I am using React 17 and MUI 5.6. I have a component that needs to add new borders to the parent container based on user input. I found some non-MUI CSS tutorials for achieving what I want, but their borders are statically coded in CSS and not added on user demand.
Here's a working sandbox for one border. Would appreciate any help on how to support multiple borders.
This should help to solve your problem. Here is the working code, user can decide color with buttons but you can implement same solution also with dropdown options. https://codesandbox.io/embed/wonderful-worker-g8fzyi?fontsize=14&hidenavigation=1&theme=dark
import { Box } from "#mui/material";
import Button from "#mui/material/Button";
import { useState } from "react";
import "./styles.css";
export default function App() {
const [colors, setColors] = useState([]);
const [pixel, setPixel] = useState(6);
const addColor = async (color) => {
setPixel(pixel + 2);
let randomColor = `0 0 0 ${pixel}px ${color}`;
setColors([...colors, randomColor]);
};
return (
<div
style={{
width: "100vw",
height: "100vh",
display: "flex",
justifyContent: "center",
alignItems: "center",
flexDirection: "column"
}}
>
<Box
sx={{
width: "50%",
height: "20%",
border: 3,
boxShadow: colors.join(",")
}}
></Box>
<div style={{ marginTop: 100 }}>
<Button onClick={() => addColor("#FFFF00")}>Yellow</Button>
<Button onClick={() => addColor("#FF002B")}>Red</Button>
<Button onClick={() => addColor("#0000FF")}>Blue</Button>
<Button onClick={() => addColor("#2BFF00")}>Green</Button>
</div>
</div>
);
}

Material UI Button Hover Not Working Absolute Position

I have a div with a button and another div in it. The button is normally hidden and the inner div has a bunch of graphs and text. In certain circumstances, I want to blur the inner div and have the button float on top in the middle of the blurred out section, kind of like you see on medium or news sites when asking for subscriptions (although I removed the logic for the example). The way I'm doing it is using absolute positioning for the button, but when I do that, all of the hover functionality just flat out isn't working on the button. It doesn't change the background color of the button or change the cursorI'm using material UI and react. Here is a code sample ->
const useStyles = makeStyles((theme) => ({
blur: {
filter: "blur(7px)",
},
relativePos: {
position: "relative",
},
absolutePos: {
position: "absolute",
top: "50%",
left: "50%",
},
floatingBtn: {
"&:hover": {
cursor: "pointer",
backgroundColor: "red",
},
},
});
// some other stuff
<div className={classes.relativePos}>
<Button
variant="contained"
color="primary"
className={`${classes.absolutePos} ${classes.floatingBtn}`}
>
Button Text
</Button>
<div className={classes.blur}>
{/* Blurred Inner Div Stuff */}
</div>
</div>
I'd love suggestions on either 1) how to get this implementation working OR 2) a better implementation NOT using absolute positioning, if there's a better, more modern approach.
There are two solutions:
use zIndex on the button that is greater than the blurred inner div
Move the button under your blurred inner div
I would prefer the 2nd approach as you don't need to know the zIndex of other elements
const useStyles = makeStyles((theme) => ({
blur: {
filter: "blur(7px)"
},
relativePos: {
position: "relative"
},
absolutePos: {
position: "absolute",
top: "50%",
left: "50%"
// zIndex: 1000 <- Add The zIndex here if you want 1st approach
},
floatingBtn: {
"&:hover": {
cursor: "pointer",
backgroundColor: "red"
}
},
// This is temp button to just toggle the absolute button
tempButton: { margin: "30px 0" }
}));
export default function App() {
const classes = useStyles();
const [showButton, setShowButton] = useState(false);
return (
<div className={classes.relativePos}>
{/* Your graphs area */}
<div className={classes.blur}>This is graphs area</div>
{/* Your absolute button with hover effect */}
{/* you can add it at the bottom and then no need to use zIndex */}
{showButton && (
<button className={`${classes.absolutePos} ${classes.floatingBtn}`}>
Button
</button>
)}
{/* Temp button to show/hide the absolute button, you should have ur own logic */}
<button
className={classes.tempButton}
onClick={() => setShowButton(!showButton)}
>
Click me to show/Hide the button
</button>
</div>
);
}
working example: codesandbox
BTW If you remove filter: "blur(7px)" from the blur class then the hover should work without changing anything in your code. I have no idea why (-_-)

Material-UI style buttons on the right

How do you align buttons on the right using Material-UI's makeStyles function?
I have tried using CSS's margin-right: 0 tag, but there is an error using '-' with makeStyles.
I renamed it as 'marginRight' and it still does not work. Also mr: 0 is not valid either. (Using Material-UI's spacing).
The code is trying to make the UI similar to stackOverflow's title layout.
import React from 'react';
import { makeStyles } from "#material-ui/core/styles";
import { Box, Button } from "#material-ui/core";
const style = makeStyles({
titleItemRight: {
color: 'white',
backgroundColor: 'blue',
top: '50%',
height: 30,
align: 'right',
position: 'relative',
transform: 'translateY(-50%)',
}
});
const App = () => {
const classes = style();
return (
<div>
<Box className={classes.titleBar}>
<Button variant='text' className={classes.titleItemRight}>Sign In</Button>
</Box>
</div>
);
};
Change,
align: 'right'
To,
float: 'right'
So the code would look like,
import React from "react";
import { makeStyles } from "#material-ui/core/styles";
import { Box, Button } from "#material-ui/core";
const style = makeStyles({
titleItemRight: {
color: "white",
backgroundColor: "blue",
top: "50%",
height: 30,
float: "right",
position: "relative",
transform: "translateY(-50%)"
}
});
const App = () => {
const classes = style();
return (
<div>
<Box className={classes.titleBar}>
<Button variant="text" className={classes.titleItemRight}>
Sign In
</Button>
</Box>
</div>
);
};
Working Codesandbox
I'd suggest using a flexbox for this or just using the AppBar provided already by material ui
https://material-ui.com/components/app-bar/#app-bar
if you'd still like to use Box, just edit the titleBar styles this way and add a spacer element to seperate elements to far right or far left
const style = makeStyles({
titleBar: {
display: 'flex',
width:'100%',
flexFlow: 'row',
},
spacer: {
flex: '1 1 auto'
}
});
and then your component
<Box className={classes.titleBar}>
<LogoHere/>
<div className={classes.spacer}/>
<Button variant="text">
Sign In
</Button>
</Box>

How To Transition React Elements That Already Have An Animation

I need some help merging an animation and a transition that occur at different times using react-spring.
When the component is mounted using useSpring I make the component appear, but I would like it so that when the button child is removed the container transitions smoothly upwards. Theres more details in the example.
https://codesandbox.io/s/naughty-dawn-r0e5x
PLEASE HELP :)
I created a solution. There is a new Spring animation mainly for the button, but we can use part of it for the original div. In this case the maxHeight property. So this way you can combine the animations.
import ReactDOM from "react-dom";
import React, { useState } from "react";
import { useSpring, animated } from "react-spring";
function WelcomeMessage() {
const [isStarted, setIsStarted] = useState(false);
const animation1 = useSpring({
right: "1%",
opacity: 1,
from: { right: "-20%", opacity: 0 },
delay: 300
});
const animation2 = useSpring({
opacity: isStarted ? 0 : 1,
maxHeight: isStarted ? 150 : 250,
transform: `translateY(${isStarted ? "-50px" : "0px"})`
});
return (
<animated.div
style={{
backgroundColor: "pink",
position: "fixed",
top: "2%",
right: "1%",
cursor: "default",
borderRadius: 5,
width: "90%",
maxWidth: 400,
...animation1,
maxHeight: animation2.maxHeight
}}
>
<div style={{ padding: "15px 25px" }}>
<span>
This is a toaster notification component. When you click the following
button it should disappear and the pink container's bottom section
should transition upwards when it decreases in height.
</span>
<br />
<br />
{
<animated.button
style={{ width: "100%", fontSize: 48, ...animation2 }}
onClick={() => {
setIsStarted(true);
}}
>
Get Started
</animated.button>
}
</div>
</animated.div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<WelcomeMessage />, rootElement);
Here is the example: https://codesandbox.io/s/green-star-nzfj8
Is this answer your question?

How to enlarge the SVG icon in material-ui iconButtons?

Has anyone build webpages using react.js and the Material UI library? How should I resize the icon size? It is a svg icon.
I just built an "create new" component, which is a piece of material paper with a content add button on the top. Here is the code.
import React from 'react';
import Paper from 'material-ui/lib/paper';
import ContentAdd from 'material-ui/lib/svg-icons/content/add';
import IconButton from 'material-ui/lib/icon-button';
const styleForPaper = {
width: '96vw',
height: '20vh',
margin: 20,
textAlign: 'center',
display: 'inline-block',
};
const styleForButton = {
'marginTop': '7vh',
};
const PaperToAddNewWidgets = () => (
<div>
<Paper style={styleForPaper} zDepth={2}>
<IconButton
style={styleForButton}
touch={true}
tooltip="Add New Widget">
<ContentAdd/>
</IconButton>
</Paper>
</div>
);
export default PaperToAddNewWidgets;
It looks OK (make sure you are viewing it at full size), but the icon is too small. Then I opened the chrome dev tool, and saw the following html code.
<div style="background-color:#ffffff;transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;box-sizing:border-box;font-family:Roboto, sans-serif;-webkit-tap-highlight-color:rgba(0,0,0,0);box-shadow:0 3px 10px rgba(0,0,0,0.16),
0 3px 10px rgba(0,0,0,0.23);border-radius:2px;width:96vw;height:20vh;margin:20px;text-align:center;display:inline-block;mui-prepared:;" data-reactid=".0.2.0.1.0"><button style="border:10px;background:none;box-sizing:border-box;display:inline-block;font:inherit;font-family:Roboto, sans-serif;tap-highlight-color:rgba(0, 0, 0, 0);cursor:pointer;text-decoration:none;outline:none;transform:translate3d(0, 0, 0);position:relative;transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;padding:12px;width:48px;height:48px;font-size:0;margin-top:7vh;mui-prepared:;-webkit-appearance:button;" tabindex="0" type="button" data-reactid=".0.2.0.1.0.0"><div data-reactid=".0.2.0.1.0.0.0"><span style="height:100%;width:100%;position:absolute;top:0;left:0;overflow:hidden;mui-prepared:;" data-reactid=".0.2.0.1.0.0.0.0"></span><div style="position: absolute; font-family: Roboto, sans-serif; font-size: 14px; line-height: 32px; padding: 0px 16px; z-index: 3000; color: rgb(255, 255, 255); overflow: hidden; top: -10000px; border-radius: 2px; opacity: 0; left: -44px; transition: top 0ms cubic-bezier(0.23, 1, 0.32, 1) 450ms, transform 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms, opacity 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; box-sizing: border-box; -webkit-user-select: none;" data-reactid=".0.2.0.1.0.0.0.1:0"><div style="position: absolute; left: 50%; top: 0px; transform: translate(-50%, -50%); border-radius: 50%; transition: width 0ms cubic-bezier(0.23, 1, 0.32, 1) 450ms, height 0ms cubic-bezier(0.23, 1, 0.32, 1) 450ms, backgroundColor 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms; width: 0px; height: 0px; background-color: transparent;" data-reactid=".0.2.0.1.0.0.0.1:0.0"></div><span style="position:relative;white-space:nowrap;mui-prepared:;" data-reactid=".0.2.0.1.0.0.0.1:0.1">Add New Widget</span></div><svg style="display:inline-block;height:24px;width:24px;transition:all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;fill:rgba(0, 0, 0, 0.87);mui-prepared:;-webkit-user-select:none;" viewBox="0 0 24 24" data-reactid=".0.2.0.1.0.0.0.1:2:$/=10"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z" data-reactid=".0.2.0.1.0.0.0.1:2:$/=10.0"></path></svg></div></button></div>
Using chrome dev tool, I revised the svg icon size and the viewbox property of svg and made the icon larger in browser. But I am not sure how I can resize the icon size in my code. If I write a CSS file to revise the svg it will be problematic if there are more than one svg elements.
do this
<SomeIcon className="svg_icons"/>
.svg_icons {
transform: scale(1.8);
}
just use scale :D it works
Note: iconStyle prop is no longer supported on IconButton Material UI making this answer obsolete
You have to set the size of the icon in the iconStyle prop in <IconButton>. Example below from the material-ui docs.
From my experience, if you set just the height or the width, nothing happens--only seems to work when you set height & width to the same value.
import React from 'react';
import IconButton from 'material-ui/IconButton';
import ActionHome from 'material-ui/svg-icons/action/home';
const styles = {
largeIcon: {
width: 60,
height: 60,
},
};
const IconButtonExampleSize = () => (
<div>
<IconButton
iconStyle={styles.largeIcon}
>
<ActionHome />
</IconButton>
</div>
);
No. Most of the other answers are unsatisfactory and are poor practice, at least in 2021. This answer is literally answered in the documentation here and doesn't require any CSS hacks to get working.
In MUI, the Button and IconButton components are just essentially wrappers that nest the child Icon element in an <a> or <Link> (react-router) element. They don't have any intrinsic control over the size. Thus, to increase the button size, just increase the size of the Icon child of IconButton using the fontSize property. This will automatically make the button larger.
For instance, to make the IconButton below larger:
<IconButton>
<Icon />
</IconButton>
We just increase the size of the Icon child directly.
<IconButton>
<Icon fontSize="large" />
</IconButton>
However, this is largest size you can specify with the fontSize property. To go even larger, we must configure the CSS font-size property manually.
<IconButton>
<Icon style={{ fontSize: 60 }} />
</IconButton>
Simple as.
EDIT: Apparently, for whatever reason, Button components have a size property that allows their size to be controlled, but IconButton components don't. I'm not sure why MUI is so inconsistent...
I faced the same issue while using the last React version (which is today v16.13.1) and Material-ui (which is today v4.9.14).
How I solved it?
By simply adding this style to the icon button
MyIconButton: {
'& svg': {
fontSize: theSizeIWant
}
}
Complete example
import React from "react";
import { makeStyles } from '#material-ui/core/styles';
import IconButton from '#material-ui/core/IconButton';
import DeleteIcon from '#material-ui/icons/Delete';
const useStyles = makeStyles((theme) => ({
deleteIcon1: {
'& svg': {
fontSize: 25
}
},
deleteIcon2: {
'& svg': {
fontSize: 50
}
},
deleteIcon3: {
'& svg': {
fontSize: 75
}
},
deleteIcon4: {
'& svg': {
fontSize: 100
}
}
}));
export default function App() {
const classes = useStyles();
return (
<div className="App">
<h1>fontSize: 25</h1>
<IconButton className={classes.deleteIcon1}>
<DeleteIcon />
</IconButton>
<h1>fontSize: 50</h1>
<IconButton className={classes.deleteIcon2}>
<DeleteIcon />
</IconButton>
<h1>fontSize: 75</h1>
<IconButton className={classes.deleteIcon3}>
<DeleteIcon />
</IconButton>
<h1>fontSize: 100</h1>
<IconButton className={classes.deleteIcon4}>
<DeleteIcon />
</IconButton>
</div>
);
}
and the result will be:
Live running code
I created this codesandbox.
Hope this helps!
With the latest version of material-ui (3.1.0), you can change padding of IconButton and fontSize of SvgIcon to update the looks.
const styles = theme => ({
smallButton: {
padding: 6
},
largeButton: {
padding: 24
},
largeIcon: {
fontSize: "3em"
},
input: {
display: "none"
}
});
function IconButtons(props) {
const { classes } = props;
return (
<div>
<IconButton className={classes.smallButton} aria-label="Delete">
<DeleteIcon fontSize="small" />
</IconButton>
<IconButton aria-label="Delete">
<DeleteIcon fontSize="large" />
</IconButton>
<IconButton className={classes.largeButton} aria-label="Delete">
<DeleteIcon className={classes.largeIcon} />
</IconButton>
</div>
);
}
Live demo
You could just use the fontSize attribute on the child node of IconButton element, that is, in your case - ContentAdd node.
<IconButton
style={styleForButton}
touch={true}
tooltip="Add New Widget">
<ContentAdd fontSize="large" />
</IconButton>
There are 4 options available - inherit, default, small and large.
Source - https://material-ui.com/api/icon/#props
When you need that for your global project you might add a new variant to your MUI theme.
components: {
MuiSvgIcon: {
variants: [
{
props: { fontSize: 'huge' },
style: {
fontSize: '5rem',
},
},
],
},
}
In order to get it worked for TS, you might need to extend the module declarations:
declare module '#mui/material/SvgIcon' {
interface SvgIconPropsSizeOverrides {
huge: true;
}
}
usage:
<HomeIcon fontSize="huge" />
I also wrote a little post on dev.to
this worked for me
fontSize="large"
<Badge badgeContent={4} color="primary" >
<CameraAltIcon fontSize="large" />
</Badge>
look Props --> fontSize
https://material-ui.com/api/icon/
For the current version of MUI (v5.8.5) there is a fontSize prop on the icons with different set sizes of 'small', 'medium', 'large' so you could do something like:
<HomeIcon fontSize="small" />
If one of those set sizes doesn't fit your needs there is also the option to use 'inherit' if you'd like it to match the font size of the container it is in and not have its own separate size.
Lastly, you could use the sx property which MUI places on all its components and in there it will accept the fontSize property which allows you to set the size directly to the icon. For instance:
<WhatshotIcon sx={{ fontSize: 140 }} />
https://mui.com/material-ui/icons/#size
There are two ways of enlarging the svg, one is to override the style with iconStyle, the other is to edit the code found in https://github.com/callemall/material-ui/blob/master/src/SvgIcon/SvgIcon.js
Note: ContentAdd imports from SvgIcon
const mergedStyles = Object.assign({
..
height: 24, // <-- change default height
width: 24, // <-- change default width
..
}, style);
return (
<svg
{...other}
..
style={prepareStyles(mergedStyles)}
..
>
I am using IconStyle prop to change the size of svg icon.
<IconButton
tooltip="Add New Group"
tooltipPosition="top-center"
style={{padding: 0, height: 0}}
iconStyle={{height: 31, width: 48}}
onClick={e => this.openNewList()}
disabled={!this.state.newAvailable}>
<ActionHome />
</IconButton>
There is always simple things to do
give an classname to your material ui icon
And go to your css file and give
height:40px !important and width 40px !impoetant
If className={ classes.classname } , fontSize : '40px' , size= 'large' etc not working then try it inline styling, you can give your height and width size as per required
<OpenInNewIcon style={{ height: '18px', width: '18px' }} />
I hope it will work,
Resize using
fontSize
<Box sx={{ fontSize: '2rem' }}>
<CloseIcon sx={{ fill: 'white', fontSize: 'inherit', mt: 0.375 }} />
</Box>
width orheight
<Box sx={{ width: '15vw' }}>
<CloseIcon sx={{ fill: 'white', width: '100%', height: '100%', mt: 0.375 }} />
</Box>
assuming you using Sass:
.divWithTargetSVG {
.MuiSvgIcon-root {
font-size: Xrem/px;
}
}
This is how I solved my problem with the SVG icon size. I also needed to be smaller when I hit the 768 media query break point.
import { withStyles } from '#material-ui/core/styles';
import { TextField, IconButton } from '#material-ui/core';
import CloseIcon from '#material-ui/icons/Close';
const StyledCloseIcon = withStyles(theme => ({
root: {
fontSize: 35,
[theme.breakpoints.down('768')]: {
fontSize: 19,
}
},
}))(CloseIcon);
use it here like this:
<StyledTextField
size='small'
fullWidth
id="standard-bare"
variant="outlined"
InputProps={{ endAdornment: (<IconButton size='small'><StyledCloseIcon /></IconButton>), }} />
Hope it helps someone. Cheers!

Resources