Skip to content

Commit

Permalink
Allowed more than one set of tabs at the time
Browse files Browse the repository at this point in the history
  • Loading branch information
FANMixco committed Aug 25, 2024
1 parent bdc4f77 commit d5c5f34
Show file tree
Hide file tree
Showing 8 changed files with 284 additions and 259 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`

Expand Down
213 changes: 98 additions & 115 deletions dist/scrollable-tabs.js
Original file line number Diff line number Diff line change
@@ -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();
// Initialize scrollable tabs for each tab set
document.querySelectorAll('.tab-wrapper').forEach(wrapper => {
initializeScrollableTabs(wrapper);
});
2 changes: 1 addition & 1 deletion dist/scrollable-tabs.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit d5c5f34

Please sign in to comment.