UNPKG

basecoat-css

Version:

Tailwind CSS for Basecoat components

75 lines (63 loc) 2.38 kB
(() => { const initTabs = (tabsComponent) => { const tablist = tabsComponent.querySelector('[role="tablist"]'); if (!tablist) return; const tabs = Array.from(tablist.querySelectorAll('[role="tab"]')); const panels = tabs.map(tab => document.getElementById(tab.getAttribute('aria-controls'))).filter(Boolean); const selectTab = (tabToSelect) => { tabs.forEach((tab, index) => { tab.setAttribute('aria-selected', 'false'); tab.setAttribute('tabindex', '-1'); if (panels[index]) panels[index].hidden = true; }); tabToSelect.setAttribute('aria-selected', 'true'); tabToSelect.setAttribute('tabindex', '0'); const activePanel = document.getElementById(tabToSelect.getAttribute('aria-controls')); if (activePanel) activePanel.hidden = false; }; tablist.addEventListener('click', (event) => { const clickedTab = event.target.closest('[role="tab"]'); if (clickedTab) selectTab(clickedTab); }); tablist.addEventListener('keydown', (event) => { const currentTab = event.target; if (!tabs.includes(currentTab)) return; let nextTab; const currentIndex = tabs.indexOf(currentTab); switch (event.key) { case 'ArrowRight': nextTab = tabs[(currentIndex + 1) % tabs.length]; break; case 'ArrowLeft': nextTab = tabs[(currentIndex - 1 + tabs.length) % tabs.length]; break; case 'Home': nextTab = tabs[0]; break; case 'End': nextTab = tabs[tabs.length - 1]; break; default: return; } event.preventDefault(); selectTab(nextTab); nextTab.focus(); }); tabsComponent.dataset.tabsInitialized = true; }; document.querySelectorAll('.tabs:not([data-tabs-initialized])').forEach(initTabs); const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { mutation.addedNodes.forEach((node) => { if (node.nodeType === Node.ELEMENT_NODE) { if (node.matches('.tabs:not([data-tabs-initialized])')) { initTabs(node); } node.querySelectorAll('.tabs:not([data-tabs-initialized])').forEach(initTabs); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })();