add popout animation

This commit is contained in:
chark1es 2025-02-08 06:08:40 -08:00
parent fe187034c8
commit d981716f21

View file

@ -109,7 +109,7 @@ import pages from "../../data/pages.json";
{ {
pages.map((page) => pages.map((page) =>
page.subpages ? ( page.subpages ? (
<div class="w-full max-w-md space-y-4"> <div class="w-full max-w-md space-y-4 relative dropdown-container">
<div class="flex gap-2"> <div class="flex gap-2">
<a <a
href={page.path} href={page.path}
@ -136,7 +136,7 @@ import pages from "../../data/pages.json";
</svg> </svg>
</button> </button>
</div> </div>
<div class="mobile-dropdown-content hidden mt-2 space-y-2 pl-4"> <div class="mobile-dropdown-content hidden mt-2 space-y-2 pl-4 absolute w-full">
{page.subpages.map((subpage) => ( {page.subpages.map((subpage) => (
<a <a
href={subpage.path} href={subpage.path}
@ -173,17 +173,60 @@ import pages from "../../data/pages.json";
.mobile-dropdown-content { .mobile-dropdown-content {
max-height: 0; max-height: 0;
transition: max-height 0.3s ease-out; opacity: 0;
pointer-events: none;
transition: all 0.3s ease-out;
z-index: 30;
} }
.mobile-dropdown-content.show { .mobile-dropdown-content.show {
max-height: 500px; max-height: none;
transition: max-height 0.5s ease-in; opacity: 1;
pointer-events: all;
transition: all 0.3s ease-in;
} }
.dropdown-icon.rotated { .dropdown-icon.rotated {
transform: rotate(180deg); transform: rotate(180deg);
} }
/* Add styles for focus effect */
.dropdown-container {
transition: all 0.3s ease;
position: relative;
}
.dropdown-container.active {
transform: scale(1.02);
z-index: 25;
}
.dropdown-container.active .mobile-dropdown-toggle,
.dropdown-container.active > div > a {
position: relative;
z-index: 25;
pointer-events: all;
}
.dropdown-container.active::after {
content: "";
position: fixed;
inset: 0;
background: transparent;
z-index: 15;
pointer-events: none;
}
#mobile-menu.has-active-dropdown > div > *:not(.dropdown-container.active) {
opacity: 0.3;
transform: scale(0.98);
transition: all 0.3s ease;
pointer-events: none;
}
#mobile-menu.has-active-dropdown .dropdown-container.active {
pointer-events: all;
}
</style> </style>
<script> <script>
@ -226,20 +269,49 @@ import pages from "../../data/pages.json";
dropdownToggles.forEach((toggle) => { dropdownToggles.forEach((toggle) => {
toggle.addEventListener("click", (e) => { toggle.addEventListener("click", (e) => {
e.stopPropagation(); e.stopPropagation();
const container = toggle.closest(".dropdown-container");
const content = toggle.parentElement const content = toggle.parentElement
?.nextElementSibling as HTMLElement; ?.nextElementSibling as HTMLElement;
const icon = toggle.querySelector(".dropdown-icon"); const icon = toggle.querySelector(".dropdown-icon");
// Toggle aria-expanded
const isExpanded = toggle.getAttribute("aria-expanded") === "true"; const isExpanded = toggle.getAttribute("aria-expanded") === "true";
toggle.setAttribute("aria-expanded", (!isExpanded).toString());
// Toggle content visibility // If clicking an already active dropdown, close it and restore interactions
if (content) { if (isExpanded) {
content.classList.toggle("hidden"); container?.classList.remove("active");
content.classList.toggle("show"); mobileMenu?.classList.remove("has-active-dropdown");
icon?.classList.toggle("rotated"); content?.classList.add("hidden");
content?.classList.remove("show");
icon?.classList.remove("rotated");
toggle.setAttribute("aria-expanded", "false");
return;
} }
// Remove active state from all dropdowns first
document.querySelectorAll(".dropdown-container").forEach((el) => {
el.classList.remove("active");
const dropdownContent = el.querySelector(
".mobile-dropdown-content"
);
const dropdownToggle = el.querySelector(
".mobile-dropdown-toggle"
);
const dropdownIcon =
dropdownToggle?.querySelector(".dropdown-icon");
dropdownContent?.classList.add("hidden");
dropdownContent?.classList.remove("show");
dropdownIcon?.classList.remove("rotated");
dropdownToggle?.setAttribute("aria-expanded", "false");
});
mobileMenu?.classList.remove("has-active-dropdown");
// Activate the clicked dropdown
container?.classList.add("active");
mobileMenu?.classList.add("has-active-dropdown");
content?.classList.remove("hidden");
content?.classList.add("show");
icon?.classList.add("rotated");
toggle.setAttribute("aria-expanded", "true");
}); });
}); });