Autoplay Tabs by Fancy Bricks

Autoplay stops when the tabs or panel are hovered over and resumes when the hover exits the items. Autoplay is blocked when the user navigates with the keyboard to improve accessibility.

I am a heading

Here goes your text ... Select any part of your text to access the formatting toolbar.

I am a button

I am a heading

Here goes your text ... Select any part of your text to access the formatting toolbar.

I am a heading

Here goes your text ... Select any part of your text to access the formatting toolbar.

<script>
document.addEventListener('DOMContentLoaded', () => {

    const FBautoplayTime = 5; // Set autoplay time in secounds

    // Seleccionar todos los conjuntos de tabs
    const tabsSets = document.querySelectorAll('[fb-tabs]');
  


    tabsSets.forEach(tabsSet => {
        const tabs = tabsSet.querySelectorAll('[fb-tabs-btn]');
        const panels = tabsSet.querySelectorAll('[fb-tabs-panel]');
        const tabsMenu = tabsSet.querySelector('[fb-tabs-menu]');
        const tabsTitle = tabsSet.querySelector('[fb-tabs-title]');
        const isVertical = tabsSet.hasAttribute('fb-vertical');
            
      // Añadir la variable CSS --fb-progress-time al estilo de [fb-tabs]
        tabsSet.style.setProperty('--fb-progress-time', `${FBautoplayTime}s`);

        // Asignar aria-label del menú de tabs con el texto del título
        if (tabsMenu && tabsTitle) {
            tabsMenu.setAttribute('aria-label', tabsTitle.textContent.trim());
        }

        // Asignar aria-controls a los tabs y aria-label a los paneles
        if (tabs.length === panels.length) {
            tabs.forEach((tab, index) => {
                const panelId = panels[index].id;
                const tabText = tab.textContent.trim();
                if (panelId && tabText) {
                    tab.setAttribute('aria-controls', panelId);
                    panels[index].setAttribute('aria-label', tabText);
                }
                tab.setAttribute('aria-selected', tab.classList.contains('brx-open'));
                tab.setAttribute('tabindex', tab.classList.contains('brx-open') ? '0' : '-1');
            });
        }

        // Configurar el MutationObserver
        const observer = new MutationObserver((mutations) => {
            mutations.forEach((mutation) => {
                if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                    const targetTab = mutation.target;
                    targetTab.setAttribute('aria-selected', targetTab.classList.contains('brx-open'));
                    targetTab.setAttribute('tabindex', targetTab.classList.contains('brx-open') ? '0' : '-1');
                }
            });
        });

        // Observar cada tab para cambios en la clase
        tabs.forEach((tab) => {
            observer.observe(tab, { attributes: true });
        });

        let currentTabIndex = 0;
        let autoplayInterval = null;
        let hoverTimeout = null;
        let isHovered = false;
        let manualSelection = false;

        const startAutoplay = () => {
            autoplayInterval = setInterval(() => {
                if (!manualSelection && !isHovered) {
                    const nextIndex = (currentTabIndex + 1) % tabs.length;
                    activateTab(nextIndex);
                }
            }, FBautoplayTime*1000); // Usar la constante para el tiempo del autoplay
        };

        const resetAutoplay = (index) => {
            clearInterval(autoplayInterval);
            activateTab(index);
            manualSelection = true;

            tabs.forEach((tab, idx) => {
                tab.setAttribute('aria-selected', idx === currentTabIndex);
                tab.setAttribute('tabindex', idx === currentTabIndex ? '0' : '-1');
                panels[idx].classList.toggle('brx-open', idx === currentTabIndex);
            });

            setTimeout(() => {
                manualSelection = false;
            }, 100);
        };

        const activateTab = (index) => {
            tabs[currentTabIndex].classList.remove('brx-open');
            panels[currentTabIndex].classList.remove('brx-open');

            currentTabIndex = index;

            tabs[currentTabIndex].classList.add('brx-open');
            panels[currentTabIndex].classList.add('brx-open');

            tabs.forEach((tab, idx) => {
                tab.setAttribute('aria-selected', idx === currentTabIndex);
                tab.setAttribute('tabindex', idx === currentTabIndex ? '0' : '-1');
            });
        };

        startAutoplay();

        const handleHoverStart = () => {
            isHovered = true;
            tabsSet.classList.add('fb-tab-progress');
            clearInterval(autoplayInterval);
        };

        const handleHoverEnd = () => {
            isHovered = false;
            tabsSet.classList.remove('fb-tab-progress');
            if (!manualSelection) {
                startAutoplay();
            }
        };

        // Añadir manejadores de clic y hover para tabs
        tabs.forEach((tab, index) => {
            tab.addEventListener('click', () => {
                resetAutoplay(index);
            });

            tab.addEventListener('focus', () => {
                handleHoverStart();
            });

            tab.addEventListener('mouseenter', () => {
                handleHoverStart();
            });

            tab.addEventListener('mouseleave', () => {
                handleHoverEnd();
            });

            tab.addEventListener('keydown', (event) => {
                if (event.key === 'Enter' || event.key === ' ') {
                    event.preventDefault();
                    resetAutoplay(index);
                }
            });
        });

        // Añadir manejadores de hover para paneles
        panels.forEach((panel) => {
            panel.addEventListener('mouseenter', () => {
                handleHoverStart();
            });

            panel.addEventListener('mouseleave', () => {
                handleHoverEnd();
            });
        });

        // Manejo de eventos de teclado para navegación entre tabs
        tabsSet.addEventListener('keydown', (event) => {
            const currentTab = tabs[currentTabIndex];

            if (event.key === 'ArrowRight' || (isVertical && event.key === 'ArrowDown')) {
                event.preventDefault();
                const nextIndex = (currentTabIndex + 1) % tabs.length;
                resetAutoplay(nextIndex);
                tabs[nextIndex].focus();
            } else if (event.key === 'ArrowLeft' || (isVertical && event.key === 'ArrowUp')) {
                event.preventDefault();
                const nextIndex = currentTabIndex === 0 ? tabs.length - 1 : currentTabIndex - 1;
                resetAutoplay(nextIndex);
                tabs[nextIndex].focus();
            } else if (event.key === 'Home') {
                event.preventDefault();
                resetAutoplay(0);
                tabs[0].focus();
            } else if (event.key === 'End') {
                event.preventDefault();
                resetAutoplay(tabs.length - 1);
                tabs[tabs.length - 1].focus();
            }
        });
    });
  

});
</script>