export default class SlidingTabs { /** * @param {HTMLElement} containerElement - The main container element with the `data-sliding-tabs-container` attribute. */ constructor(containerElement) { this.container = containerElement; this.indicator = this.container.querySelector('[data-tab-indicator]'); this.tabs = this.container.querySelectorAll('[data-tab-item]'); // Find the initially active tab and store it as the component's state this.activeTab = this.container.querySelector('.tab-active'); if (!this.indicator || this.tabs.length === 0) { console.error('SlidingTabs component is missing required elements (indicator or items).', this.container); return; } this.init(); } init() { // Set initial indicator position if (this.activeTab) { // Use a small delay to ensure layout is fully calculated setTimeout(() => this.updateIndicator(this.activeTab), 50); } // Bind all necessary event listeners this.bindEvents(); } updateIndicator(targetTab) { if (!targetTab) return; const containerRect = this.container.getBoundingClientRect(); const targetRect = targetTab.getBoundingClientRect(); const left = targetRect.left - containerRect.left; const width = targetRect.width; this.indicator.style.left = `${left}px`; this.indicator.style.width = `${width}px`; } bindEvents() { this.tabs.forEach(tab => { // On click, update the active state tab.addEventListener('click', (e) => { // e.preventDefault(); // Uncomment if using tags for SPA routing if (this.activeTab) { this.activeTab.classList.remove('tab-active'); } tab.classList.add('tab-active'); this.activeTab = tab; // Update the component's state this.updateIndicator(this.activeTab); }); // On hover, preview the indicator position tab.addEventListener('mouseenter', () => { this.updateIndicator(tab); }); }); // When the mouse leaves the entire container, reset indicator to the active tab this.container.addEventListener('mouseleave', () => { this.updateIndicator(this.activeTab); }); } } // ---- Auto-Initialization Logic ---- // This is the "bootstrapper". It finds all components on the page and brings them to life. document.addEventListener('DOMContentLoaded', () => { const allTabContainers = document.querySelectorAll('[data-sliding-tabs-container]'); allTabContainers.forEach(container => { new SlidingTabs(container); }); });