add popout animation
This commit is contained in:
parent
fe187034c8
commit
d981716f21
1 changed files with 85 additions and 13 deletions
|
@ -109,7 +109,7 @@ import pages from "../../data/pages.json";
|
|||
{
|
||||
pages.map((page) =>
|
||||
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">
|
||||
<a
|
||||
href={page.path}
|
||||
|
@ -136,7 +136,7 @@ import pages from "../../data/pages.json";
|
|||
</svg>
|
||||
</button>
|
||||
</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) => (
|
||||
<a
|
||||
href={subpage.path}
|
||||
|
@ -173,17 +173,60 @@ import pages from "../../data/pages.json";
|
|||
|
||||
.mobile-dropdown-content {
|
||||
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 {
|
||||
max-height: 500px;
|
||||
transition: max-height 0.5s ease-in;
|
||||
max-height: none;
|
||||
opacity: 1;
|
||||
pointer-events: all;
|
||||
transition: all 0.3s ease-in;
|
||||
}
|
||||
|
||||
.dropdown-icon.rotated {
|
||||
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>
|
||||
|
||||
<script>
|
||||
|
@ -226,20 +269,49 @@ import pages from "../../data/pages.json";
|
|||
dropdownToggles.forEach((toggle) => {
|
||||
toggle.addEventListener("click", (e) => {
|
||||
e.stopPropagation();
|
||||
const container = toggle.closest(".dropdown-container");
|
||||
const content = toggle.parentElement
|
||||
?.nextElementSibling as HTMLElement;
|
||||
const icon = toggle.querySelector(".dropdown-icon");
|
||||
|
||||
// Toggle aria-expanded
|
||||
const isExpanded = toggle.getAttribute("aria-expanded") === "true";
|
||||
toggle.setAttribute("aria-expanded", (!isExpanded).toString());
|
||||
|
||||
// Toggle content visibility
|
||||
if (content) {
|
||||
content.classList.toggle("hidden");
|
||||
content.classList.toggle("show");
|
||||
icon?.classList.toggle("rotated");
|
||||
// If clicking an already active dropdown, close it and restore interactions
|
||||
if (isExpanded) {
|
||||
container?.classList.remove("active");
|
||||
mobileMenu?.classList.remove("has-active-dropdown");
|
||||
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");
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue