1export default function GDMTabs( 2 navLisSelector, 3 tabPanels, 4 tabPanelsContainer, 5 navUl, 6 addHorizontalNav 7) { 8 9 10 11 const tabsNavUl = document.querySelector(navUl); 12 const tabsNavLis = document.querySelectorAll(navLisSelector); 13 const tabPanelDivs = document.querySelectorAll(tabPanels); 14 15 tabsNavLis[0].classList.add("open-tab"); 16 17 tabPanelDivs[0].classList.add("open-tab"); 18 19 20 // if someone clicks tabsNavLi[i], then open tabPanel[i] 21 tabsNavLis.forEach((li, i) => { 22 li.addEventListener("click", function () { 23 tabsNavLis.forEach((li) => li.classList.remove("open-tab")); 24 25 [...tabPanelDivs].forEach((div) => div.classList.remove("open-tab")); 26 27 tabsNavLis[i].classList.add("open-tab"); 28 29 tabPanelDivs[i].classList.add("open-tab"); 30 }); 31 }); 32 33 34 // Make sure they're all the same height 35 const tabHeights = [...tabPanels].map((panel) => panel.offsetHeight); 36 37 if (tabPanelsContainer) 38 document.querySelector(tabPanelsContainer).style.height = `${Math.max( 39 ...tabHeights 40 )}px`; 41 42 43 // If the page is loaded with a hash tag on the URL, open the corresponding tab 44 [...tabPanelDivs].forEach(tabPanel => { 45 if(tabPanel.id === `${window.location.href.split('#')[1]}-panel`) { 46 47 48 // Change class on tab panels: 49 [...tabPanelDivs].map(tp => tp.classList.remove('open-tab')); 50 tabPanel.classList.add('open-tab'); 51 52 } 53 }); 54 55 [...tabsNavLis].forEach(tab => { 56 57 58 if(tab.id === `${window.location.href.split('#')[1]}-tab`) { 59 60 // Change class on tabs: 61 [...tabsNavLis].map(t => t.classList.remove('open-tab')); 62 tab.classList.add('open-tab'); 63 64 } 65 66 }); 67 68 69 70 // Add a horizontal scroling arrow if the tabs are wider than the screen 71 const createHorizontalNav = () => { 72 73 if(document.querySelector('.tabs-horizontal-nav')) return; 74 75 const scrollingNav = document.createElement("nav"); 76 scrollingNav.classList.add('tabs-horizontal-nav'); 77 tabsNavUl.insertAdjacentElement('afterend', scrollingNav); 78 79 tabsNavUl.parentElement.style.overflow = 'hidden'; 80 81 82 const leftArrow = document.createElement('div'); 83 leftArrow.classList.add('arrow-left'); 84 scrollingNav.insertAdjacentElement('afterbegin', leftArrow); 85 86 const rightArrow = document.createElement('div'); 87 rightArrow.classList.add('arrow-right'); 88 scrollingNav.insertAdjacentElement('beforeend', rightArrow); 89 90 let position = 0; 91 let marginLeft = 0; 92 93 const enableLeftArrow = () => scrollingNav.classList.add("show-left-arrow"); 94 95 const disableLeftArrow = () => scrollingNav.classList.remove("show-left-arrow"); 96 97 const enableRightArrow = () => scrollingNav.classList.add("show-right-arrow"); 98 99 const disableRightArrow = () => scrollingNav.classList.remove("show-right-arrow"); 100 101 // If the right edge is overflowing outside of the right, show the right arrow 102 103 [...tabsNavLis][tabsNavLis.length - 1].getBoundingClientRect().right > 104 tabsNavUl.getBoundingClientRect().right 105 ? enableRightArrow() 106 : disableRightArrow(); 107 108 109 110 scrollingNav.addEventListener("click", (e) => { 111 // If the user clicks left or right, change position state by 1 112 113 if (e.target === leftArrow) position += 1; 114 115 if (e.target === rightArrow) position -= 1; 116 117 // If the left edge is overflowing left show the left arrow 118 119 position < 0 ? enableLeftArrow() : disableLeftArrow(); 120 121 // If the right edge is overflowing outside of the right, show the right arrow 122 123 [...tabsNavLis][tabsNavLis.length - 1].getBoundingClientRect().right > 124 tabsNavUl.getBoundingClientRect().right 125 ? enableRightArrow() 126 : disableRightArrow(); 127 128 if (e.target === rightArrow) 129 marginLeft += 130 tabsNavLis[position === 0 ? 0 : Math.abs(position)].offsetWidth; 131 132 if (e.target === leftArrow) 133 marginLeft -= 134 tabsNavLis[position === 0 ? 0 : Math.abs(position)].offsetWidth; 135 136 tabsNavUl.style.marginLeft = `${position < 0 && "-"}${marginLeft}px`; 137 }); 138 139 } 140 141 if(addHorizontalNav) createHorizontalNav(); 142 143}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.