Skip to content

Instantly share code, notes, and snippets.

@michael-andreuzza
Created November 24, 2024 09:35
Show Gist options
  • Save michael-andreuzza/a32204317dd85346ff715982d45cb9e4 to your computer and use it in GitHub Desktop.
Save michael-andreuzza/a32204317dd85346ff715982d45cb9e4 to your computer and use it in GitHub Desktop.
---
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