Animation react Does not reset - reactjs

I am working on animation in React app. I need animation starts working after hover off the button, the animation only works one time and after that for next time hover off the button does not make animation works.
I used
setTimeout(()=> {
e.target.classList.add(classes.hide);
}, 1);
to reset time to works again but it does not work out.
#keyframes rotate-before {
0% { right:0px; top:0px;}
25% { right:40px; top:0px;}
50% {bottom:10px; top:178px;right:40px;}
}
.content {
position: absolute;
inset: 30px;
z-index: 3;
display: flex;
flex-direction:column;
align-items: center;
justify-content: center;
}
.content:hover .button{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
visibility:visible;
position: relative;
}
.hover{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
visibility:visible;
position: relative;
animation: rotate-before 0.5s linear;
animation-iteration-count: 1;
}
.content .button{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
position: relative;
visibility:hidden;
}
.hide{
padding: .8rem .1rem;
background-color: #00092C;
border:none;
border-radius: 50%;
cursor: pointer;
color: #fff;
position: relative;
visibility:hidden;
}
.content img {
position: absolute;
width: 100%;
height:100%;
object-fit: cover;
}
import "./App.css";
import { AnimatePresence, motion, useTransform } from "framer-motion/dist/framer-motion";
import classes from "./components/anm.module.css";
function App() {
const [isHovered, setHovered] = useState(false);
const change = (e) => {
e.target.classList.add(classes.hover);
setTimeout(()=> {
e.target.classList.add(classes.hide);
}, 1);
};
return (
<div className={classes.box}>
<div className={classes.content}>
<img
src="https://budgetreno.ca/wp-content/uploads/Pylon-25_compressed-thegem-portfolio-metro.jpg"
alt=""
/>
<motion.div className="square" onHoverEnd={change} whileHover={{}}>
<button id="test" className={classes.button}>
Follow
</button>
</motion.div>
</div>
</div>
);
}
export default App;

Related

Hamburger menu logic not working properly in React

I have set up the logic for Hamburger menu in Navbar.jsx but when I press the hamburger button it just transitions to X button and doesn't display links menu. How do I display the menu and what would be your approach to animating the transition between hamburger and X icon. Here is my code:
import React from 'react'
import './Navbar.css'
import { useState } from 'react'
import { FaSearch } from 'react-icons/fa'
import { NavLink } from 'react-router-dom'
import { GiHamburgerMenu } from 'react-icons/gi'
import { AiOutlineClose } from 'react-icons/ai'
function Navbar() {
const [toggleMenu, setToggleMenu] = useState(false)
const [toggleSearch, setSearchWindow] = useState(false)
return (
<div className='mka__navbar'>
<div className='mka__navbar-links'>
<div className='mka__navbar-links_container'>
<p><NavLink to='/'>HOME</NavLink></p>
<p><NavLink to='/fahrzeugangebote'>FAHRZEUGANGEBOTE</NavLink></p>
<p><NavLink to='/finanzierung'>FINANZIERUNG</NavLink></p>
<p><NavLink to='/fahrzeugankauf'>FAHRZEUGANKAUF</NavLink></p>
<p><NavLink to='/galerie'>GALERIE</NavLink></p>
<p><NavLink to='/kontakt'>KONTAKT</NavLink></p>
<div className='mka__search_column'>
<p><i><FaSearch onClick={() => setSearchWindow(!toggleSearch)} /></i></p>
{
toggleSearch ?
<div className='mka__search-div'>
< input type="text" value="Suche..."/>
</div>
: null
}
</div>
</div>
{
toggleMenu
? <AiOutlineClose color="#fff" className='mka___hamburger-menu' size={27} onClick={() => setToggleMenu(false)} />
: <GiHamburgerMenu size={27} className='mka___hamburger-menu' color="#fff" onClick={() => setToggleMenu(true)} />
}
{
<div className='mka__navbar-menu-margins'>
<div className='mka__navbar-menu_container'>
<div className='mka__navbar-menu_container-links'>
<p><NavLink to='/'>HOME</NavLink></p>
<p><NavLink to='/fahrzeugangebote'>FAHRZEUGANGEBOTE</NavLink></p>
<p><NavLink to='/finanzierung'>FINANZIERUNG</NavLink></p>
<p><NavLink to='/fahrzeugankauf'>FAHRZEUGANKAUF</NavLink></p>
<p><NavLink to='/galerie'>GALERIE</NavLink></p>
<p><NavLink to='/kontakt'>KONTAKT</NavLink></p>
</div>
</div>
</div> && toggleMenu
}
</div>
</div>
);
}
export default Navbar;
And here is my CSS code for the same component:
/* Navbar links */
.mka__navbar {
display: flex;
padding: 2rem;
}
.mka__navbar-links {
flex: 1;
display: flex;
justify-content: end;
align-items: center;
}
.mka__navbar-links_container {
display: flex;
flex-direction: row;
}
.mka__navbar-links_container p {
color: #fff;
font-size: 14px;
line-height: 66px;
text-transform: uppercase;
font-weight: 400;
font-family: var(--font-family);
transition: padding .25s linear;
padding: 0 0.5rem;
cursor: pointer;
}
.mka__navbar-links_container p > a:link {
color: #fff;
}
.mka__navbar-links_container p > a:hover {
transition: 0.5s;
color: #db2d2e;
}
.mka__navbar-links_container p > i:hover {
transition: 0.5s;
color: #db2d2e;
}
.mka__navbar-links_container p > a.active {
color: #db2d2e;
}
/* Hamburger menu */
.mka__navbar-menu_container-links {
color: #fff;
font-size: 14px;
line-height: 66px;
text-transform: uppercase;
font-weight: 400;
font-family: var(--font-family);
padding: 0 1.5rem;
cursor: pointer;
width: 100%;
}
/* Search */
.mka__search-div {
background: #0e0e0ed1;
display: block;
padding: 15px;
width: 327px;
z-index: 888;
border-radius: 0;
border-top: 5px solid #db2d2e;
position: absolute;
margin-left: auto;
margin-right: auto;
left: 26rem;
right: 0;
top: 9rem;
}
input {
border: 1px solid #fff;
background: #0f1215;
color: gray;
padding: 12px;
width: 290px;
}
.mka__search_column {
display: flex;
flex-direction: column;
}
/* Media Queries */
#media (min-width: 992px){
.mka__navbar-links {
justify-content: center;
}
.mka__navbar-menu_container-links {
display: none;
}
.mka___hamburger-menu {
display: none;
}
}
#media (max-width: 992px){
.mka__navbar-links_container {
display: none;
}
.mka__navbar-menu_container {
background-color: #0f1215;
width: 100%;
margin-top: 0.5rem;
border-radius: 5px;
}
.mka__navbar-menu-margins {
margin-left: auto;
margin-right: auto;
padding-left: 15px;
padding-right: 15px;
width: 100%;
margin-top: 40px;
}
}
#media (min-width: 1200px){
.mka__navbar-links_container p {
padding: 0 1rem;
}
}
#media (max-width: 1200px){
.mka__search-div {
left: 21rem;
}
}
I created a hamburger menu which you can toggle it with X icon. and also implemented the drawer transition. the link is here https://codesandbox.io/s/great-hugle-oy5s8b?file=/src/App.js
hope it can help you.

Is it possible to use the same React component with different CSS, using css modules?

I found the React CSS modules usefull, but having problem when I tried to reuse the same component with a little modified css I stuck. For example I created Neon glowing button, but now need to change only the width of the Button and some additional small changes in the css.
The only option I see is component without css and for every different case need to rewrite the whole css. Is there a smarter way?
import React from "react";
import styles from "./index.module.css";
import { Link } from "react-router-dom";
const GlowingButton = ({ title, path }) => {
return (
<div className={styles.buttonWrapper}>
<Link className={styles.button} to={path}>
<button className={styles["glow-on-hover"]}>{title}</button>
</Link>
</div>
);
};
export default GlowingButton;
And here is index.module.css
.buttonWrapper {
margin: 0px;
padding: 0px;
display: flex;
justify-content: center;
align-items: center;
background: transparent;
font-family: "consolas";
}
.button {
margin: 0;
padding: 0;
width: 80%;
height: 8vh;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
background: #100f;
text-decoration: none;
}
.glow-on-hover {
width: 400px;
height: 50px;
border: none;
outline: none;
color: #fff;
background: #111;
cursor: pointer;
position: relative;
z-index: 0;
border-radius: 10px;
}
.glow-on-hover:before {
content: "";
background: linear-gradient(
45deg,
#ff0000,
#ff7300,
#fffb00,
#48ff00,
#00ffd5,
#002bff,
#7a00ff,
#ff00c8,
#ff0000
);
position: absolute;
top: -2px;
left: -2px;
background-size: 400%;
z-index: -1;
filter: blur(5px);
width: calc(100% + 4px);
height: calc(100% + 4px);
animation: glowing 20s linear infinite;
opacity: 0;
transition: opacity 0.3s ease-in-out;
border-radius: 10px;
}
.glow-on-hover:active {
color: #000;
}
.glow-on-hover:active:after {
background: transparent;
}
.glow-on-hover:hover:before {
opacity: 1;
}
.glow-on-hover:after {
z-index: -1;
content: "";
position: absolute;
width: 100%;
height: 100%;
background: #111;
left: 0;
top: 0;
border-radius: 10px;
}
#keyframes glowing {
0% {
background-position: 0 0;
}
50% {
background-position: 400% 0;
}
100% {
background-position: 0 0;
}
}

How to convert from TSX to JSX in this Codesandbox

I am learning React and JavaScript and now I have this CodeSandbox but I can't convert it to JavaScript React I have tried this for the Card Component:
import React, { useState } from "react";
const Card = props => {
const [expanded, setExpanded] = useState(false);
const RenderCard = (className) => {
return (
<div
className={`card ${className}${expanded ? " expanded" : ""}`}
onClick={() => {
setExpanded(!expanded);
}}
>
<div className="image">
<img alt="digger" src={props.image} />
</div>
<div className="info">
<div
className="bg1"
style={{ backgroundImage: "url('" + props.image + "')" }}
/>
<div
className="bg2"
style={{ backgroundImage: "url('" + props.image + "')" }}
/>
<div
className="bg3"
style={{ backgroundImage: "url('" + props.image + "')" }}
/>
<h1>JCB OES System</h1>
<h2>Report Number #1</h2>
<h3>Load lifter work area</h3>
<div className="button">Open</div>
</div>
</div>
);
};
return (
<div className={`card-container${expanded ? " expanded" : ""}`}>
{expanded && <div className="background" />}
{<RenderCard className="card1"/>}
{<RenderCard className="card2"/>}
</div>
);
};
export default Card;
And I show the Card like this. It's very simple, it's just that when I click a card it does not pop up like the CodeSandbox does.
import Card from "./Card";
import "./styles.scss";
const CreateContent = () => {
return (
<div className="app">
<link rel="stylesheet" href="https://use.typekit.net/jli8mqj.css" />
<Card image="https://www.thetimes.co.uk/imageserver/image/methode%2Fsundaytimes%2Fprodmigration%2Fweb%2Fbin%2Fbeae8dfb-0a41-4f8e-b076-ffd68417287b.jpg?crop=1024%2C683%2C0%2C0&resize=685" />
<Card image="https://www.virginexperiencedays.co.uk/content/img/product/large/PJCBRA__01.jpg" />
<Card image="https://www.toyfarmers.co.uk/images/britains-jcb-3cx-backhoe-loader.jpg" />
<Card image="https://seatylive.blob.core.windows.net/eventimages/2019-Aug-20-Tue_18-37-31-969.png" />
</div>
);
};
export default CreateContent;
The styles is the same, with no changes: I understand that the expanded background when set to expanded=true using the hook that the scss style for background should be in effect but all I get is a black screen.
.app {
font-family: sans-serif;
text-align: center;
padding: 4em 0;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
border: 0;
}
.card-container {
font-family: niveau-grotesk, sans-serif !important;
position: relative;
z-index: 0;
&.expanded {
z-index: 3;
#keyframes fade-in {
0% { opacity: 0; }
100% { opacity: 1; }
}
.background {
animation: fade-in .3s ease-out;
z-index: 2;
position: fixed;
background: black;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
}
.card {
margin: 0 auto;
width: 25em;
cursor: pointer;
border-radius: .5em;
box-shadow: 0 50px 100px -20px rgba(50,50,93,.25),
0 30px 60px -30px rgba(0,0,0,.3),
0 -18px 60px -10px rgba(0,0,0,.03);
margin-bottom: 4em;
&.card2 {
transition: .2s ease-out;
position: absolute;
top: 0;
width: 25em;
left: 50%;
z-index: 4;
transform: translateX(-50%);
&.expanded {
width: 40em;
}
}
.image {
img {
display: block;
border-top-left-radius: .5em;
border-top-right-radius: .5em;
width: 100%;
}
}
$button-color: rgb(87, 87, 228);
&:hover {
.info .button {
color: white;
background: $button-color;
}
}
.info {
background: white;
position: relative;
border-bottom-left-radius: .5em;
border-bottom-right-radius: .5em;
overflow: hidden;
padding: .9em 1.2em;
text-align: left;
$darkness: 0;
&:after {
content: '';
position: absolute;
top: -20%;
left: -20%;
right: -20%;
bottom: -20%;
height: 140%;
width: 140%;
// filter: blur(8px);
// -webkit-filter: blur(8px);
background: linear-gradient(to right,
rgba(0, 0, 0, 0.4) 30%,
rgba(0, 0, 0, 0) 100%);
}
.bg1, .bg2 {
position: absolute;
top: -20%;
left: -20%;
right: -20%;
bottom: -20%;
height: 140%;
width: 140%;
z-index: 0;
background-position: center;
background-repeat: no-repeat;
background-size: 100%;
transform: rotate(180deg);
filter: blur(16px);
}
.bg2 {
background-position: bottom;
transform: rotate(0deg);
opacity:0.4;
}
.bg3 {
background-position: top;
transform: rotate(180deg);
opacity:0.4;
}
.button {
transition: .2s ease-out;
text-transform: uppercase;
line-height: 1.2em;
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 1.8em;
z-index: 1;
background: white;
border-radius: 1em;
padding: .4em 1.1em;
font-weight: 600;
color: $button-color;
}
h1, h2, h3 {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
max-width: 13em;
color: white;
position: relative;
z-index: 1;
text-shadow: 1px 1px 1px rgba(0,0,0,0.8);
}
h1 {
line-height: .8em;
letter-spacing: .03em;
font-size: 1.1em;
font-weight: 900;
padding: .1em 0;
}
h2 {
letter-spacing: .02em;
font-size: 1.0em;
font-weight: 400;
padding: .1em 0;
opacity: 0.6;
}
h3 {
letter-spacing: .02em;
font-size: .9em;
font-weight: 400;
padding: .1em 0;
}
}
}
}
What am I missing?
To swap your Code Sandbox from TypeScript to JavaScript you should just need to:
Remove all typescript specific syntax from your ".ts" and ".tsx" files (interfaces, typings, etc)
Change all the file extensions to their JavaScript equivalent i.e. ".ts" -> ".js" and ".tsx" -> ".jsx".
Update the "main" property of the "package.json" file to point to the renamed entry point. i.e. "src/index.jsx".
I created a quick CodeSandbox with this already done.

How do i make my Navbar overlap the rest of the page?

I want my navbar to be fixed and stay above the rest of the page as i scroll down, but whenever i add the 'position: fixed;' function on the css page it disappears.
Here is the code for the navbar in JS and Css...
import Logo from '../../Images/mmt-white.png';
import './Navbar.css';
const Navbar = props => (
<header className="Navbar">
<nav className="Navbar__navigation">
<div></div>
<div className='Navbar__logo'><img src={Logo}/></div>
<div className='spacer '/>
<div className="Navbar_navigation-items">
<ul>
<li>Home</li>
<li>Servicos</li>
<li>Depoimentos</li>
<li>Começando</li>
<li>Contacte-nos</li>
</ul>
</div>
<div className="Navbar_navigation_items_acessar">
<ul>
<li>Acessar</li>
</ul>
</div>
</nav>
</header>
);
export default Navbar;
And here is my app.js where i import all the pages and the navbar on top off them...
import Navbar from './components/NavBar/Navbar';
import Home from "./components/pages/HomePage/Home";
import Comecando from "./components/pages/Comecando/Comecando";
import Depoimentos from "./components/pages/Depoimentos/Depoimentos";
import Sac from "./components/pages/SAC/Sac";
import Servicos from "./components/pages/Servicos/Servicos";
import './App.css';
function App () {
return(
<div className='App'>
<div>
<Navbar/>
</div>
<Home/>
<Servicos/>
<Comecando/>
<Depoimentos/>
<Sac/>
</div>
);
}
export default App;
and here is the css
.NavbarItems {
background: linear-gradient(90deg,rgb(49,56,64)0%,rgba(49, 56, 64, 1) 100%);
height: 10vh;
display: flex;
justify-content: center;
align-items: center;
font-size: 1,2rem;
left: 0;
position: fixed;
top: 0;
z-index: 1;
position: relative;
}
.sticky {
position: fixed;
top: 0;
width: 100%;
}
.navbar-logo{
position: absolute;
top: 0;
left: 0;
transform: translate(15%, 10%);
}
.fa-react{
margin-left: 0.5rem;
font-size: 1,6rem;
}
.nav-menu {
display: grid;
grid-template-columns: repeat(6, auto);
grid-gap: 10px;
transform: translate(8%, 0%);
list-style: none;
margin-left: 10vh;
text-align: center;
width: 80vw;
justify-content: end;
padding-left: 10vh;
margin-right: 1rem;
font-size: 10px;
}
.nav-links {
color:#edf0f1;
margin-top: 2rem;
padding-right: 2rem;
padding: 0;
text-decoration: none;
font-size: 22px;
font-family: monospace;
text-transform: uppercase;
}
.nav-links:hover{
border-radius: 4px;
transition: all 0.2s ease0;
color: #0088a9;
}
.fa-bars{
color: #ffffff;
}
button{
margin-left: 10vh;
right: 0;
padding: 9px 25px;
background-color: rgba(0, 136, 169, 1);
border: none;
border-radius: 50px;
cursor: pointer;
transition: all 0.3s ease 0s;
font-family: "Montserrat", sans-serif;
font-weight: 500;
color: #edf0f1;
font-size: 17px;
text-decoration: none;
}
.menu-icon{
display: none;
}
.nav-links-mobile{
color: transparent;
}
You may want to add the following to your NavBar class in your NavBar.css file to add the positional properties like so:
left: 0;
position: fixed;
top: 0;
z-index: 1; // increase this value if you have other elements at varying levels of elevation
Or you may want to add the following to your NavBar class in your NavBar.css file instead of position: fixed (it depends on the behavior you're looking for):
position: sticky;
top: 0; // vertical position you'd like the element to stick to
z-index: 1; // increase this value if you have other elements at varying levels of elevation

How to Use Classes in Styled-Component

I am new to styled-component. I want to convert custom CSS to Styled-Component. I have already used className in React File.
App.js
<div className="left-menus">
{menus.map(item => {
return (
<Link to={item.name} name={item.name} key={item.name}
className={this.state.activeMenu === item.name ? 'menu active' : 'menu' }
onClick={() => this.setState({ activeMenu: item.name })}
>
<Icon name={item.icon} size="large"/>
<span>{item.name}</span>
</Link>
)
})}
</div>
App.css
.left-menus {
position: fixed;
width: 200px;
padding-right: 0 !important;
background-color: #fff;
height: 100%;
margin-top: 20px;
top: 47px;
font-size: 12px !important;
border-right: 2px solid #e8e8ec; }
.left-menus .menu {
color: #4a4a4a;
width: 100%;
display: block;
cursor: pointer;
text-transform: capitalize !important;
padding: 15px 10px 15px 18px; }
.left-menus .menu .angle.down.icon,
.left-menus .menu .angle.up.icon {
right: 10px;
position: absolute; }
.left-menus .menu .icon:first-child {
margin-right: 10px; }
.left-menus .menu.active {
border-right: 4px solid #3cbfc8;
background-color: #f8f8f8; }
.left-menus .sub-menu-container .sub-menu {
display: none;
height: 0;
transition: 0.3s all ease; }
.left-menus .sub-menu-container.active .sub-menu {
display: block;
height: 100%;
text-transform: capitalize;
transition: 0.3s all ease; }
.left-menus .sub-menu-container.active .sub-menu a {
color: #4a4a4a; }
.left-menus .sub-menu-container.active .sub-menu .icon {
margin: 10px 10px 0 10px; }
CSS with a class selector will only match elements that are members of a class.
To give a styled component that class, you need to do it when you instantiate it.
For example:
const MyStyledComponent = styled.div`
background: red;
`;
const myFunctionComponent = () => {
const myClass = "left-menus";
return(
<div>
Here is MyStyledComponent
<MyStyledComponent className={myClass}>
Example
</MyStyledComponent>
</div>
);
}
If you have an existing stylesheet you want to apply, it is likely that styled components are not the right tool for the job.

Resources