I have a hamburger menu in javascript that I'm trying to recreate in React.
Hamburger Menu in Javascript:
function hamburgerMenu() {
const menuIcon = document.querySelector('.hamburger-menu');
const mainNav = document.querySelector('.header-links-container');
const hamLinks = document.querySelectorAll('.header-links a');
//hamburger function
function hamburger (){
menuIcon.classList.toggle('change');
mainNav.classList.toggle('change');
}
//when click on hamburger menu
menuIcon.addEventListener('click', () => {
hamburger();
});
//when click on links, hamburger menu closes
for(var i =0 ; i<hamLinks.length;i ){
hamLinks[i].addEventListener('click',()=>{
hamburger();
});
}
}
hamburgerMenu();
Below I have tried to implement it in React but with this, it seems like it adds the class of .change
but the hamburger menu doesn't open.
const Header = () => {
const [isActive, setActive] = useState(false);
const openHam = () => {
const toggleClass = () => {
setActive(!isActive);
};
toggleClass();
};
const closeMenu = () => {
setActive(false);
};
return (
<div className={`header-links-container ${isActive ? 'change' : null}`} onClick={openHam}>
<div className={`hamburger-menu ${isActive ? 'change' : null}`} onClick={openHam}>
<div className="line line-1"></div>
<div className="line line-2"></div>
<div className="line line-3"></div>
</div>
<div className="header-links">
<a href="/" onClick={closeMenu}>Luxury Suites</a>
<a href="/" onClick={closeMenu}>Exclusive Clubs</a>
<a href="/" onClick={closeMenu}>Contact Us</a>
</div>
</div>
);
};
export default Header;
CSS:
.header-links-container {
width: 200px;
height: 100%;
background-color: #2b2b2b;
position: fixed;
top: 0;
right: -300px;
display: flex;
justify-content: center;
align-items: center;
transition: right .8s cubic-bezier(1, 0, 0, 1);
z-index: 4;
& .hamburger-menu {
width: 35px;
height: 30px;
position: fixed;
top: 10px;
right: 10px;
cursor: pointer;
display: flex;
flex-direction: column;
justify-content: space-around;
& .line {
width: 80%;
height: 3px;
background-color: $yellow;
transition: all 0.8s;
font-size: 1.17em;
}
& .change {
& .line-1 {
transform: rotateZ(-405deg) translate(-8px, 6px);
background-color: #fff;
}
& .line-2 {
opacity: 0;
}
& .line-3 {
transform: rotateZ(405deg) translate(-8px, -6px);
background-color: #fff;
}
}
}
& .header-links {
display: flex;
flex-direction: column;
}
& .change {
right: 0;
}
}
Please any help would be appreciated.
CodePudding user response:
You are using scss nesting in the wrong way. The "change" should be separated from "header-links-container".
Or you can use a more understandable class name like "header-links-container-active". Then nest it like "&-active" in "header-links-container".
Try this:
SCSS:
.header-links-container {
width: 100px;
height: 100%;
background-color: #eee;
position: fixed;
top: 0;
right: 0;
opacity: 0;
display: flex;
justify-content: center;
align-items: center;
z-index: 4;
transition: all 0.5s;
.header-links {
display: flex;
flex-direction: column;
}
}
.change {
opacity: 1;
width: 200px;
}
.hamburger {
position: fixed;
height: 3rem;
width: 3rem;
top: 1rem;
right: 1rem;
cursor: pointer;
text-align: center;
z-index: 100;
&__icon {
position: relative;
margin-top: 1.5rem;
&,
&::before,
&::after {
width: 2rem;
height: 2px;
background-color: #333;
display: inline-block;
}
&::before,
&::after {
content: "";
position: absolute;
left: 0;
transition: all 0.2s;
}
&::before {
top: -0.8rem;
}
&::after {
top: 0.8rem;
}
}
&-active &__icon {
background-color: transparent;
}
&-active &__icon::before {
top: 0;
transform: rotate(135deg);
}
&-active &__icon::after {
top: 0;
transform: rotate(-135deg);
}
}
JS:
const Hamburger = () => {
const [isActive, setActive] = useState(false);
const openHam = () => {
const toggleClass = () => {
setActive(!isActive);
};
toggleClass();
};
const closeMenu = () => {
setActive(false);
};
return (
<>
<div
className={`hamburger ${isActive ? "hamburger-active" : ""}`}
onClick={openHam}
>
<span > </span>
</div>
<div className={`header-links-container ${isActive ? "change" : ""}`}>
<div className="header-links">
<a href="/" onClick={closeMenu}>
Luxury Suites
</a>
<a href="/" onClick={closeMenu}>
Exclusive Clubs
</a>
<a href="/" onClick={closeMenu}>
Contact Us
</a>
</div>
</div>
</>
);
};
export default Hamburger;