Created
November 24, 2024 09:35
-
-
Save michael-andreuzza/a32204317dd85346ff715982d45cb9e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
import Wrapper from "@/components/fundations/containers/Wrapper.astro"; | |
import Text from "@/components/fundations/elements/Text.astro"; | |
--- | |
<section> | |
<Wrapper variant="base" class="pt-12"> | |
<div class="flex flex-col space-y-6"> | |
<!-- Tabs --> | |
<div class="flex space-x-1 relative"> | |
<!-- Bubble Effect --> | |
<div | |
id="bubble" | |
class="absolute top-0 left-0 z-0 rounded-full pointer-events-none transition-all duration-300 ease-out" | |
style="width: 0; height: 0; transform: translateX(0);" | |
> | |
</div> | |
<!-- Tab Buttons --> | |
<button | |
data-tab | |
data-target="tab-world" | |
class="relative z-10 outline outline-inset outline-zinc-200 px-3 py-1.5 text-sm font-medium text-black hover:text-white transition-colors duration-300 rounded-full" | |
> | |
World | |
</button> | |
<button | |
data-tab | |
data-target="tab-ny" | |
class="relative z-10 outline outline-inset outline-zinc-200 px-3 py-1.5 text-sm font-medium text-black hover:text-white transition-colors duration-300 rounded-full" | |
> | |
N.Y. | |
</button> | |
<button | |
data-tab | |
data-target="tab-business" | |
class="relative z-10 outline outline-inset outline-zinc-200 px-3 py-1.5 text-sm font-medium text-black hover:text-white transition-colors duration-300 rounded-full" | |
> | |
Business | |
</button> | |
<button | |
data-tab | |
data-target="tab-arts" | |
class="relative z-10 outline outline-inset outline-zinc-200 px-3 py-1.5 text-sm font-medium text-black hover:text-white transition-colors duration-300 rounded-full" | |
> | |
Arts | |
</button> | |
<button | |
data-tab | |
data-target="tab-science" | |
class="relative z-10 outline outline-inset outline-zinc-200 px-3 py-1.5 text-sm font-medium text-black hover:text-white transition-colors duration-300 rounded-full" | |
> | |
Science | |
</button> | |
</div> | |
<!-- Tab Panels --> | |
<div class="relative"> | |
<div | |
id="tab-world" | |
data-panel | |
class="absolute top-0 left-0 w-full opacity-0 transition-all duration-300 ease-out" | |
> | |
<Text>Content for World.</Text> | |
</div> | |
<div | |
id="tab-ny" | |
data-panel | |
class="absolute top-0 left-0 w-full opacity-0 transition-all duration-300 ease-out" | |
> | |
<Text>Content for N.Y.</Text> | |
</div> | |
<div | |
id="tab-business" | |
data-panel | |
class="absolute top-0 left-0 w-full opacity-0 transition-all duration-300 ease-out" | |
> | |
<Text>Content for Business.</Text> | |
</div> | |
<div | |
id="tab-arts" | |
data-panel | |
class="absolute top-0 left-0 w-full opacity-0 transition-all duration-300 ease-out" | |
> | |
<Text>Content for Arts.</Text> | |
</div> | |
<div | |
id="tab-science" | |
data-panel | |
class="absolute top-0 left-0 w-full opacity-0 transition-all duration-300 ease-out" | |
> | |
<Text>Content for Science.</Text> | |
</div> | |
</div> | |
</div> | |
</Wrapper> | |
</section> | |
<script type="module"> | |
document.addEventListener("DOMContentLoaded", () => { | |
const tabs = document.querySelectorAll("[data-tab]"); | |
const panels = document.querySelectorAll("[data-panel]"); | |
const bubble = document.querySelector("#bubble"); | |
let activePanel = null; | |
function updateBubblePosition(tab) { | |
const rect = tab.getBoundingClientRect(); | |
const parentRect = tab.parentElement.getBoundingClientRect(); | |
const translateX = rect.left - parentRect.left; | |
requestAnimationFrame(() => { | |
bubble.style.transform = `translateX(${translateX}px)`; | |
bubble.style.width = `${rect.width}px`; | |
bubble.style.height = `${rect.height}px`; | |
}); | |
} | |
function switchTab(tab) { | |
tabs.forEach((t) => t.classList.remove("text-white")); | |
tab.classList.add("text-white"); | |
updateBubblePosition(tab); | |
const targetPanel = document.getElementById(tab.dataset.target); | |
if (activePanel) { | |
activePanel.style.opacity = "0"; | |
activePanel.style.transform = "translateY(10px)"; | |
} | |
setTimeout(() => { | |
panels.forEach((panel) => { | |
panel.style.display = "none"; | |
}); | |
targetPanel.style.display = "block"; | |
requestAnimationFrame(() => { | |
targetPanel.style.opacity = "1"; | |
targetPanel.style.transform = "translateY(0)"; | |
}); | |
activePanel = targetPanel; | |
}, 300); | |
} | |
tabs.forEach((tab) => { | |
tab.addEventListener("click", () => switchTab(tab)); | |
}); | |
// Initialize the first tab and panel as active | |
switchTab(tabs[0]); | |
}); | |
</script> | |
<style> | |
#bubble { | |
background: white; | |
mix-blend-mode: difference; | |
} | |
[data-panel] { | |
transition: | |
opacity 0.3s ease-out, | |
transform 0.3s ease-out; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment