I'm creating a simple hamburger menu and I want to add new className to element when onClick event occurs. This new className should transform the element, but when onClick occurs element dissapears, animation doesn't work. I understand the problem is in classes.line[i] part, but what could be the problem maybe someone can help me here.
link to the example https://repl.it/@RokasSimkus/DelectableFrugalMuse
jsx:
const menu = (props) =>{
let lineArray= ['', '', ''];
let lines= lineArray.map((lineArray, i) => {
return <span key={"classes.line" + i} className={!props.active ? classes.line : classes.line[i]}></span>
});
console.log(props.active);
return(
<>
<div className={!props.active ? classes.hamburger: classes.hamburger}
onClick={props.open}
onMouseOver={props.mouseHover}
onMouseLeave={props.leaveMouseHover}>
{lines}
</div>
</>
)
};
css code:
@media(min-width: 500px){
.hamburger{
display: none;
}
}
.hamburger {
left: 0;
top: 0;
}
.hamburger .line {
display: block;
width: 30px;
height: 2px;
background-color: white;
margin: 8px 0;
transition: all 0.3s ease-in-out;
}
.hamburger:hover {
cursor: pointer;
.line:nth-of-type(1) {
transform: translateX(15px);
width: 40px;
}
}
.hamburger .line1 {
transform: translate(4px, 1px) rotate(45deg);
width: 18px;
}
.hamburger .line2 {
transform: rotate(-45deg);
width: 51px;
}
.hamburger .line3 {
transform: translate(14px, 4px) rotate(45deg);
width: 28px;
transform-origin: bottom right;
}
If I change the line you marked to the following, it works:
return <span key={"classes.line" + i} className={`${classes.line} ${props.active ? `${classes["line" + i]}` : ''}`}></span>
To show anything, your lines need the class .line
. To be in the "active" state, they need to add their respective .lineX
class to add the transform you want to see. As you need both classes at the same time, you need to put both into the className property, which I've done here by putting them together into a string.
I'd suggest to change your CSS and add an active
class to your menu.
The underlying problem is that you need to add multiple classes to your elements at some point. You can do that with string interpolation like I showed above (same would be for adding an active
class to .menu
) or you could use a module like classnames which does a great job concatenating classes. Thus you could write
return <span key={"classes.line" + i} className={classnames(classes.line, props.active && classes["line" + i])}></span>
I'd still suggest to create an active
modifier class on your "root" element of your component, to keep modifiers on the top level and your code a bit more understandable. Here is your modified example.