From d5c5f34d7d4aba4b663720f789d4dae4cdba87c0 Mon Sep 17 00:00:00 2001 From: Federico Navarrete Date: Sun, 25 Aug 2024 09:57:33 +0200 Subject: [PATCH] Allowed more than one set of tabs at the time --- README.md | 6 +- dist/scrollable-tabs.js | 213 ++++++++++++++++------------------ dist/scrollable-tabs.min.js | 2 +- example/index.html | 101 ++++++++++++---- package-lock.json | 4 +- package.json | 2 +- src/js/scrollable-tabs.js | 213 ++++++++++++++++------------------ src/js/scrollable-tabs.min.js | 2 +- 8 files changed, 284 insertions(+), 259 deletions(-) diff --git a/README.md b/README.md index 61df824..0575df2 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,13 @@ A simple plugin to create scrollable tabs with Bootstrap 5. ## Usage: +## Breaking change from 1.1.0+: + +To allow more than one set of tabs, it required to add a new class to wrap the tabs `tab-wrapper`. It must be added to use it. + ### Install: -- [Download the latest release](https://github.com/SupernovaIC/scrollable-tabs-bootstrap-5/archive/refs/tags/v1.0.9.zip) +- [Download the latest release](https://github.com/SupernovaIC/scrollable-tabs-bootstrap-5/archive/refs/tags/v1.1.0.zip) - Install with [npm](https://www.npmjs.com/): `npm i scrolling-tabs-bootstrap-5` diff --git a/dist/scrollable-tabs.js b/dist/scrollable-tabs.js index 4c1cff3..4299353 100644 --- a/dist/scrollable-tabs.js +++ b/dist/scrollable-tabs.js @@ -1,137 +1,120 @@ //let move = require('move'); - -const scrollBarWidths = 40; -const wrapper = document.getElementsByClassName("wrapper-nav")[0]; -const navLink = document.getElementsByClassName("nav-item nav-link"); -const lastNavLink = navLink[navLink.length - 1]; - -const scrollerRight = document.getElementsByClassName("scroller-right")[0]; -const scrollerLeft = document.getElementsByClassName("scroller-left")[0]; - -const list = document.querySelectorAll(".list"); - -let btnTriggered = false; - -let widthOfList = function() { - let itemsWidth = 0; - - const listLinks = document.querySelectorAll(".list a"); - - listLinks.forEach((el) => { - let itemWidth = getOuterWidth(el); - itemsWidth += itemWidth; +// Function to initialize scrollable tabs for a specific wrapper +function initializeScrollableTabs(wrapper) { + const scrollBarWidths = 40; + const scrollerRight = wrapper.querySelector(".scroller-right"); + const scrollerLeft = wrapper.querySelector(".scroller-left"); + const list = wrapper.querySelector(".list"); + const lastNavLink = list.querySelectorAll(".nav-item.nav-link")[list.querySelectorAll(".nav-item.nav-link").length - 1]; + let btnTriggered = false; + + let widthOfList = function () { + let itemsWidth = 0; + const listLinks = list.querySelectorAll("a"); + + listLinks.forEach((el) => { + let itemWidth = getOuterWidth(el); + itemsWidth += itemWidth; + }); + + return itemsWidth; + }; + + let widthOfHidden = function (w) { + w = (!w) ? 0 : w; + const oW = getOuterWidth(wrapper.querySelector(".wrapper-nav")) - w; + const ww = parseFloat((0 - oW).toFixed(3)); + const hw = (oW - widthOfList() - getLeftPosi()) - scrollBarWidths; + const rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)) - w; + + if (ww > hw) { + return (rp > ww ? rp : ww); + } else { + return (rp > hw ? rp : hw); + } + }; + + let getLeftPosi = () => { + const lp = getOuterLeft(list); + const wrapperLeft = getOuterLeft(wrapper.querySelector(".wrapper-nav")); + + return lp - wrapperLeft; + }; + + let reAdjust = () => { + let rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)); + + if (getOuterWidth(wrapper.querySelector(".wrapper-nav")) < widthOfList() && (rp < 0)) { + scrollerRight.style.display = 'flex'; + unfade(scrollerRight); + } else { + scrollerRight.style.display = 'none'; + } + + if (getLeftPosi() < 0) { + scrollerLeft.style.display = 'flex'; + unfade(scrollerLeft); + } else { + scrollerLeft.style.display = 'none'; + } + + btnTriggered = false; + }; + + scrollerRight.addEventListener("click", () => { + if (btnTriggered) return; + + btnTriggered = true; + + fade(scrollerLeft); + unfade(scrollerRight); + + let wR = getOuterWidth(scrollerRight); + + move(list).add("left", +widthOfHidden(wR), 200).end().then(() => { + reAdjust(); + }); }); - - return itemsWidth; -}; - -let widthOfHidden = function(w) { - const wrapperh = document.getElementsByClassName("wrapper-nav")[0]; - - w = (!w) ? 0 : w; - - oW = getOuterWidth(wrapperh) - w; - - let ww = parseFloat((0 - oW).toFixed(3)); - - let hw = (oW - widthOfList() - getLeftPosi()) - scrollBarWidths; - - let rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)) - w; - - if (ww > hw) { - //return ww; - return (rp > ww ? rp : ww); - } - else { - //return hw; - return (rp > hw ? rp : hw); - } -}; - -let getLeftPosi = function() { - let ww = 0 - getOuterWidth(wrapper); - let lp = getOuterLeft(list[0]); - - if (ww > lp) { - return ww; - } - else { - return lp; - } -}; - -let reAdjust = function() { - let rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)); - - if (getOuterWidth(wrapper) < widthOfList() && (rp < 0)) { - scrollerRight.style.cssText = 'display: flex'; - } - else { - scrollerRight.style.display = 'none'; - } - - if (getLeftPosi() < 0) { - scrollerLeft.style.cssText = 'display: flex'; - } - else { - scrollerLeft.style.display = 'none'; - } - - btnTriggered = false; -} - -window.addEventListener('resize', function(event) { - reAdjust(); -}, true); -scrollerRight.addEventListener("click", function() { - if (btnTriggered) return; + scrollerLeft.addEventListener("click", () => { + if (btnTriggered) return; - btnTriggered = true; + btnTriggered = true; - fade(scrollerLeft); - unfade(scrollerRight); + fade(scrollerRight); + unfade(scrollerLeft); - let wR = getOuterWidth(scrollerRight); + let wL = getOuterWidth(scrollerLeft); - move(document.querySelectorAll(".list")[0]).add("left", +widthOfHidden(wR), 200).end().then(x=> { - reAdjust(); + move(list).add("left", -getLeftPosi() + wL, 200).end().then(() => { + reAdjust(); + }); }); -}); -scrollerLeft.addEventListener("click", function() { - if (btnTriggered) return; - - btnTriggered = true; - - fade(scrollerRight); - unfade(scrollerLeft); - - let wL = getOuterWidth(scrollerLeft); - - move(document.querySelectorAll(".list")[0]).add("left", -getLeftPosi() + wL, 200).end().then(()=> { + window.addEventListener('resize', () => { reAdjust(); - }); -}); + }, true); -let getOuterLeft = function(elem) { - return elem.getBoundingClientRect().left; + reAdjust(); } -let getOuterWidth = function(elem) { - return parseFloat(window.getComputedStyle(elem).width); -} +let getOuterLeft = (elem) => elem.getBoundingClientRect().left; + +let getOuterWidth = (elem) => parseFloat(window.getComputedStyle(elem).width); function fade(elem) { elem.style.display = "none"; - elem.style.transition="opacity 0.6s"; - elem.style.opacity=0; + elem.style.transition = "opacity 0.6s"; + elem.style.opacity = 0; } function unfade(elem) { elem.style.display = "block"; - elem.style.transition="opacity 0.6s"; - elem.style.opacity=1; + elem.style.transition = "opacity 0.6s"; + elem.style.opacity = 1; } -reAdjust(); \ No newline at end of file +// Initialize scrollable tabs for each tab set +document.querySelectorAll('.tab-wrapper').forEach(wrapper => { + initializeScrollableTabs(wrapper); +}); \ No newline at end of file diff --git a/dist/scrollable-tabs.min.js b/dist/scrollable-tabs.min.js index 1d8a208..1db8a26 100644 --- a/dist/scrollable-tabs.min.js +++ b/dist/scrollable-tabs.min.js @@ -1 +1 @@ -const scrollBarWidths=40,wrapper=document.getElementsByClassName("wrapper-nav")[0],navLink=document.getElementsByClassName("nav-item nav-link"),lastNavLink=navLink[navLink.length-1],scrollerRight=document.getElementsByClassName("scroller-right")[0],scrollerLeft=document.getElementsByClassName("scroller-left")[0],list=document.querySelectorAll(".list");let btnTriggered=!1,widthOfList=function(){let e=0;return document.querySelectorAll(".list a").forEach(t=>{let l=getOuterWidth(t);e+=l}),e},widthOfHidden=function(e){const t=document.getElementsByClassName("wrapper-nav")[0];e=e||0,oW=getOuterWidth(t)-e;let l=parseFloat((0-oW).toFixed(3)),r=oW-widthOfList()-getLeftPosi()-40,n=document.body.clientWidth-(getOuterLeft(lastNavLink)+getOuterWidth(lastNavLink))-e;return l>r?n>l?n:l:n>r?n:r},getLeftPosi=function(){let e=0-getOuterWidth(wrapper),t=getOuterLeft(list[0]);return e>t?e:t},reAdjust=function(){let e=document.body.clientWidth-(getOuterLeft(lastNavLink)+getOuterWidth(lastNavLink));getOuterWidth(wrapper){reAdjust()})}),scrollerLeft.addEventListener("click",function(){if(btnTriggered)return;btnTriggered=!0,fade(scrollerRight),unfade(scrollerLeft);let e=getOuterWidth(scrollerLeft);move(document.querySelectorAll(".list")[0]).add("left",-getLeftPosi()+e,200).end().then(()=>{reAdjust()})});let getOuterLeft=function(e){return e.getBoundingClientRect().left},getOuterWidth=function(e){return parseFloat(window.getComputedStyle(e).width)};function fade(e){e.style.display="none",e.style.transition="opacity 0.6s",e.style.opacity=0}function unfade(e){e.style.display="block",e.style.transition="opacity 0.6s",e.style.opacity=1}reAdjust(); \ No newline at end of file +function initializeScrollableTabs(e){const t=e.querySelector(".scroller-right"),l=e.querySelector(".scroller-left"),r=e.querySelector(".list"),n=r.querySelectorAll(".nav-item.nav-link")[r.querySelectorAll(".nav-item.nav-link").length-1];let i=!1,a=function(){let e=0;return r.querySelectorAll("a").forEach((t=>{let l=getOuterWidth(t);e+=l})),e},d=()=>getOuterLeft(r)-getOuterLeft(e.querySelector(".wrapper-nav")),o=()=>{let r=document.body.clientWidth-(getOuterLeft(n)+getOuterWidth(n));getOuterWidth(e.querySelector(".wrapper-nav")){if(i)return;i=!0,fade(l),unfade(t);let u=getOuterWidth(t);move(r).add("left",+function(t){t=t||0;const l=getOuterWidth(e.querySelector(".wrapper-nav"))-t,r=parseFloat((0-l).toFixed(3)),i=l-a()-d()-40,o=document.body.clientWidth-(getOuterLeft(n)+getOuterWidth(n))-t;return r>i?o>r?o:r:o>i?o:i}(u),200).end().then((()=>{o()}))})),l.addEventListener("click",(()=>{if(i)return;i=!0,fade(t),unfade(l);let e=getOuterWidth(l);move(r).add("left",-d()+e,200).end().then((()=>{o()}))})),window.addEventListener("resize",(()=>{o()}),!0),o()}let getOuterLeft=e=>e.getBoundingClientRect().left,getOuterWidth=e=>parseFloat(window.getComputedStyle(e).width);function fade(e){e.style.display="none",e.style.transition="opacity 0.6s",e.style.opacity=0}function unfade(e){e.style.display="block",e.style.transition="opacity 0.6s",e.style.opacity=1}document.querySelectorAll(".tab-wrapper").forEach((e=>{initializeScrollableTabs(e)})); \ No newline at end of file diff --git a/example/index.html b/example/index.html index 0e164e3..5b9ea39 100644 --- a/example/index.html +++ b/example/index.html @@ -1,5 +1,6 @@ + @@ -7,18 +8,23 @@ Scrollable Tabs Bootstrap 5 - - + + - + + -
+
-
+
This is the content of Tab 1...
-
+
This is the content of Tab 2...
-
+
This is the content of Tab 3...
-
+
This is the content of Tab 4...
-
+
This is the content of Tab 5...
-
+
This is the content of Tab 6...
-
+
This is the content of Tab 7...
-
+
This is the content of Tab 8...
-
+
This is the content of Tab 9...
-
+
This is the content of Tab 10...
-
+
This is the content of Tab 11...
-
+
This is the content of Tab 12...
-
+
This is the content of Tab 13...
-
+
This is the content of Tab 14...
-
+
This is the content of Tab 15...
-
+
This is the content of Tab 16...
+
+
+
+ +
+
+ This is the content of Tab 17... +
+
+ This is the content of Tab 18... +
+
+ This is the content of Tab 19... +
+
+ This is the content of Tab 20... +
+
+ This is the content of Tab 21... +
+
+ This is the content of Tab 22... +
+
+ This is the content of Tab 23... +
+
+ This is the content of Tab 24... +
+
+ This is the content of Tab 25... +
+
+
+ - - + + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 85e4803..5a0b017 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "scrolling-tabs-bootstrap-5", - "version": "1.0.2", + "version": "1.0.10", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "scrolling-tabs-bootstrap-5", - "version": "1.0.2", + "version": "1.0.10", "license": "Apache 2.0", "dependencies": { "bootstrap": "^5.1.3", diff --git a/package.json b/package.json index a68d905..0b8fa3b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "scrolling-tabs-bootstrap-5", - "version": "1.0.10", + "version": "1.1.0", "description": "A simple plugin to create scrollable tabs with Bootstrap 5.", "main": "./dist/scrollable-tabs.js", "repository": { diff --git a/src/js/scrollable-tabs.js b/src/js/scrollable-tabs.js index 4c1cff3..4299353 100644 --- a/src/js/scrollable-tabs.js +++ b/src/js/scrollable-tabs.js @@ -1,137 +1,120 @@ //let move = require('move'); - -const scrollBarWidths = 40; -const wrapper = document.getElementsByClassName("wrapper-nav")[0]; -const navLink = document.getElementsByClassName("nav-item nav-link"); -const lastNavLink = navLink[navLink.length - 1]; - -const scrollerRight = document.getElementsByClassName("scroller-right")[0]; -const scrollerLeft = document.getElementsByClassName("scroller-left")[0]; - -const list = document.querySelectorAll(".list"); - -let btnTriggered = false; - -let widthOfList = function() { - let itemsWidth = 0; - - const listLinks = document.querySelectorAll(".list a"); - - listLinks.forEach((el) => { - let itemWidth = getOuterWidth(el); - itemsWidth += itemWidth; +// Function to initialize scrollable tabs for a specific wrapper +function initializeScrollableTabs(wrapper) { + const scrollBarWidths = 40; + const scrollerRight = wrapper.querySelector(".scroller-right"); + const scrollerLeft = wrapper.querySelector(".scroller-left"); + const list = wrapper.querySelector(".list"); + const lastNavLink = list.querySelectorAll(".nav-item.nav-link")[list.querySelectorAll(".nav-item.nav-link").length - 1]; + let btnTriggered = false; + + let widthOfList = function () { + let itemsWidth = 0; + const listLinks = list.querySelectorAll("a"); + + listLinks.forEach((el) => { + let itemWidth = getOuterWidth(el); + itemsWidth += itemWidth; + }); + + return itemsWidth; + }; + + let widthOfHidden = function (w) { + w = (!w) ? 0 : w; + const oW = getOuterWidth(wrapper.querySelector(".wrapper-nav")) - w; + const ww = parseFloat((0 - oW).toFixed(3)); + const hw = (oW - widthOfList() - getLeftPosi()) - scrollBarWidths; + const rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)) - w; + + if (ww > hw) { + return (rp > ww ? rp : ww); + } else { + return (rp > hw ? rp : hw); + } + }; + + let getLeftPosi = () => { + const lp = getOuterLeft(list); + const wrapperLeft = getOuterLeft(wrapper.querySelector(".wrapper-nav")); + + return lp - wrapperLeft; + }; + + let reAdjust = () => { + let rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)); + + if (getOuterWidth(wrapper.querySelector(".wrapper-nav")) < widthOfList() && (rp < 0)) { + scrollerRight.style.display = 'flex'; + unfade(scrollerRight); + } else { + scrollerRight.style.display = 'none'; + } + + if (getLeftPosi() < 0) { + scrollerLeft.style.display = 'flex'; + unfade(scrollerLeft); + } else { + scrollerLeft.style.display = 'none'; + } + + btnTriggered = false; + }; + + scrollerRight.addEventListener("click", () => { + if (btnTriggered) return; + + btnTriggered = true; + + fade(scrollerLeft); + unfade(scrollerRight); + + let wR = getOuterWidth(scrollerRight); + + move(list).add("left", +widthOfHidden(wR), 200).end().then(() => { + reAdjust(); + }); }); - - return itemsWidth; -}; - -let widthOfHidden = function(w) { - const wrapperh = document.getElementsByClassName("wrapper-nav")[0]; - - w = (!w) ? 0 : w; - - oW = getOuterWidth(wrapperh) - w; - - let ww = parseFloat((0 - oW).toFixed(3)); - - let hw = (oW - widthOfList() - getLeftPosi()) - scrollBarWidths; - - let rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)) - w; - - if (ww > hw) { - //return ww; - return (rp > ww ? rp : ww); - } - else { - //return hw; - return (rp > hw ? rp : hw); - } -}; - -let getLeftPosi = function() { - let ww = 0 - getOuterWidth(wrapper); - let lp = getOuterLeft(list[0]); - - if (ww > lp) { - return ww; - } - else { - return lp; - } -}; - -let reAdjust = function() { - let rp = document.body.clientWidth - (getOuterLeft(lastNavLink) + getOuterWidth(lastNavLink)); - - if (getOuterWidth(wrapper) < widthOfList() && (rp < 0)) { - scrollerRight.style.cssText = 'display: flex'; - } - else { - scrollerRight.style.display = 'none'; - } - - if (getLeftPosi() < 0) { - scrollerLeft.style.cssText = 'display: flex'; - } - else { - scrollerLeft.style.display = 'none'; - } - - btnTriggered = false; -} - -window.addEventListener('resize', function(event) { - reAdjust(); -}, true); -scrollerRight.addEventListener("click", function() { - if (btnTriggered) return; + scrollerLeft.addEventListener("click", () => { + if (btnTriggered) return; - btnTriggered = true; + btnTriggered = true; - fade(scrollerLeft); - unfade(scrollerRight); + fade(scrollerRight); + unfade(scrollerLeft); - let wR = getOuterWidth(scrollerRight); + let wL = getOuterWidth(scrollerLeft); - move(document.querySelectorAll(".list")[0]).add("left", +widthOfHidden(wR), 200).end().then(x=> { - reAdjust(); + move(list).add("left", -getLeftPosi() + wL, 200).end().then(() => { + reAdjust(); + }); }); -}); -scrollerLeft.addEventListener("click", function() { - if (btnTriggered) return; - - btnTriggered = true; - - fade(scrollerRight); - unfade(scrollerLeft); - - let wL = getOuterWidth(scrollerLeft); - - move(document.querySelectorAll(".list")[0]).add("left", -getLeftPosi() + wL, 200).end().then(()=> { + window.addEventListener('resize', () => { reAdjust(); - }); -}); + }, true); -let getOuterLeft = function(elem) { - return elem.getBoundingClientRect().left; + reAdjust(); } -let getOuterWidth = function(elem) { - return parseFloat(window.getComputedStyle(elem).width); -} +let getOuterLeft = (elem) => elem.getBoundingClientRect().left; + +let getOuterWidth = (elem) => parseFloat(window.getComputedStyle(elem).width); function fade(elem) { elem.style.display = "none"; - elem.style.transition="opacity 0.6s"; - elem.style.opacity=0; + elem.style.transition = "opacity 0.6s"; + elem.style.opacity = 0; } function unfade(elem) { elem.style.display = "block"; - elem.style.transition="opacity 0.6s"; - elem.style.opacity=1; + elem.style.transition = "opacity 0.6s"; + elem.style.opacity = 1; } -reAdjust(); \ No newline at end of file +// Initialize scrollable tabs for each tab set +document.querySelectorAll('.tab-wrapper').forEach(wrapper => { + initializeScrollableTabs(wrapper); +}); \ No newline at end of file diff --git a/src/js/scrollable-tabs.min.js b/src/js/scrollable-tabs.min.js index 1d8a208..1db8a26 100644 --- a/src/js/scrollable-tabs.min.js +++ b/src/js/scrollable-tabs.min.js @@ -1 +1 @@ -const scrollBarWidths=40,wrapper=document.getElementsByClassName("wrapper-nav")[0],navLink=document.getElementsByClassName("nav-item nav-link"),lastNavLink=navLink[navLink.length-1],scrollerRight=document.getElementsByClassName("scroller-right")[0],scrollerLeft=document.getElementsByClassName("scroller-left")[0],list=document.querySelectorAll(".list");let btnTriggered=!1,widthOfList=function(){let e=0;return document.querySelectorAll(".list a").forEach(t=>{let l=getOuterWidth(t);e+=l}),e},widthOfHidden=function(e){const t=document.getElementsByClassName("wrapper-nav")[0];e=e||0,oW=getOuterWidth(t)-e;let l=parseFloat((0-oW).toFixed(3)),r=oW-widthOfList()-getLeftPosi()-40,n=document.body.clientWidth-(getOuterLeft(lastNavLink)+getOuterWidth(lastNavLink))-e;return l>r?n>l?n:l:n>r?n:r},getLeftPosi=function(){let e=0-getOuterWidth(wrapper),t=getOuterLeft(list[0]);return e>t?e:t},reAdjust=function(){let e=document.body.clientWidth-(getOuterLeft(lastNavLink)+getOuterWidth(lastNavLink));getOuterWidth(wrapper){reAdjust()})}),scrollerLeft.addEventListener("click",function(){if(btnTriggered)return;btnTriggered=!0,fade(scrollerRight),unfade(scrollerLeft);let e=getOuterWidth(scrollerLeft);move(document.querySelectorAll(".list")[0]).add("left",-getLeftPosi()+e,200).end().then(()=>{reAdjust()})});let getOuterLeft=function(e){return e.getBoundingClientRect().left},getOuterWidth=function(e){return parseFloat(window.getComputedStyle(e).width)};function fade(e){e.style.display="none",e.style.transition="opacity 0.6s",e.style.opacity=0}function unfade(e){e.style.display="block",e.style.transition="opacity 0.6s",e.style.opacity=1}reAdjust(); \ No newline at end of file +function initializeScrollableTabs(e){const t=e.querySelector(".scroller-right"),l=e.querySelector(".scroller-left"),r=e.querySelector(".list"),n=r.querySelectorAll(".nav-item.nav-link")[r.querySelectorAll(".nav-item.nav-link").length-1];let i=!1,a=function(){let e=0;return r.querySelectorAll("a").forEach((t=>{let l=getOuterWidth(t);e+=l})),e},d=()=>getOuterLeft(r)-getOuterLeft(e.querySelector(".wrapper-nav")),o=()=>{let r=document.body.clientWidth-(getOuterLeft(n)+getOuterWidth(n));getOuterWidth(e.querySelector(".wrapper-nav")){if(i)return;i=!0,fade(l),unfade(t);let u=getOuterWidth(t);move(r).add("left",+function(t){t=t||0;const l=getOuterWidth(e.querySelector(".wrapper-nav"))-t,r=parseFloat((0-l).toFixed(3)),i=l-a()-d()-40,o=document.body.clientWidth-(getOuterLeft(n)+getOuterWidth(n))-t;return r>i?o>r?o:r:o>i?o:i}(u),200).end().then((()=>{o()}))})),l.addEventListener("click",(()=>{if(i)return;i=!0,fade(t),unfade(l);let e=getOuterWidth(l);move(r).add("left",-d()+e,200).end().then((()=>{o()}))})),window.addEventListener("resize",(()=>{o()}),!0),o()}let getOuterLeft=e=>e.getBoundingClientRect().left,getOuterWidth=e=>parseFloat(window.getComputedStyle(e).width);function fade(e){e.style.display="none",e.style.transition="opacity 0.6s",e.style.opacity=0}function unfade(e){e.style.display="block",e.style.transition="opacity 0.6s",e.style.opacity=1}document.querySelectorAll(".tab-wrapper").forEach((e=>{initializeScrollableTabs(e)})); \ No newline at end of file