Essentially, I'm trying to have a component hide and show on click, which is pretty standard in react but I was using the state (isOpen) simply like this {isOpen && <ProjectCard/> } to open and close but if I want to animate the Project card in any way it all goes to hell. I have understood that the isOpen + ternary block any kinda div or ref I wanna pass to ProjectCard. I've been able to have it open with ease in but not close, and I'm a little discouraged at the moment.
Any insight will be welcomed. there's not lots of info online and chat gpt well doesn't help either haha
here is my code
import { useState, useEffect } from "react";
import { useGSAP } from "@gsap/react";
import gsap from "gsap";
import { useRef } from "react";
export const Tabs = () => {
const tabs = useRef();
const [isOpen, setIsOpen] = useState(false);
const openPdfInNewTab = () => {
const pdfUrl = "src/assets/Resume.pdf";
window.open(pdfUrl, "_blank");
};
const handleClick = () => {
if (isOpen) {
gsap.to(".projects", {
y: "100%",
duration: 1,
ease: "power1.inOut",
// onComplete: () => {
// // Set display to 'none' when the closing animation is complete
// document.querySelector(".project-card").style.display = "none";
// },
});
console.log("here");
setIsOpen(false);
} else {
gsap.fromTo(
".projects",
{ y: "150%" },
{ y: "0%", duration: 1, ease: "power1.inOut" }
);
setIsOpen(true);
}
};
// animation on load
useGSAP(
() => {
gsap.from(".tab", {
x: 150,
ease: "power1.inOut",
delay: 2.5,
});
},
{ scope: tabs }
);
useGSAP(
() => {
gsap.utils.toArray(".tab").forEach((tab) => {
const initialWidth = tab.classList.contains("project-tab")
? "80px"
: "100px";
const hoverWidth = tab.classList.contains("project-tab")
? "100px"
: "120px";
gsap.set(tab, { width: initialWidth, textAlign: "left" });
tab.addEventListener("mouseenter", () => {
gsap.to(tab, { width: hoverWidth });
});
tab.addEventListener("mouseleave", () => {
gsap.to(tab, { width: initialWidth });
});
});
},
{ scope: tabs }
);
const handleEscape = (event) => {
if (event.key === "Escape") {
setIsOpen(false);
}
};
// const handleOutsideClick = (event) => {
// const projectsContainer = document.querySelector(".projects");
// if (projectsContainer && !projectsContainer.contains(event.target)) {
// setIsOpen(false);
// }
// };
useEffect(() => {
document.addEventListener("keydown", handleEscape);
// document.addEventListener("mousedown", handleOutsideClick);
return () => {
document.removeEventListener("keydown", handleEscape);
// document.removeEventListener("mousedown", handleOutsideClick);
};
}, []);
return (
<div ref={tabs} className="tabs-container">
<div className="tab project-tab" onClick={handleClick}>
Projects
</div>
<div className="tab resume-tab" onClick={openPdfInNewTab}>
Resume
</div>
<div className={`projects ${isOpen ? "open" : ""}`}>
{/* <div className="project-card"> */}
<h1>Projects</h1>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
{/* </div> */}
</div>
</div>
);
};
I was testing lots of stuff. so I have lots of weirdness, but essentially I also have animations on the tabs ( which work with no problem)
What I'm trying to achieve is basically a react/gsap problem is using the gsap hook to create and ease in and easeout when I click to show the projects, I've ultimately extracted the content of my ProjectCard component to test things, eventually ill add it back to the div. but i would also like it to ease out on the outside click and on the escape key . the outside click was causing me so much trouble because it counts the tab click also as an outside click and it would just glitch open and close
i also made my css apply on isOpen, ive tested so many things at this point. ANY INSIGHTS WILL HELP
thank you and if more details need to be added let me know