@scania/tegel
Version:
Tegel Design System
218 lines (213 loc) • 10.7 kB
JavaScript
import { p as proxyCustomElement, H, d as createEvent, h, c as Host } from './p-28ef5186.js';
import { d as defineCustomElement$2 } from './p-b390ece5.js';
const folderTabsCss = ":host{box-sizing:border-box;overflow:hidden;outline:0}:host *{box-sizing:border-box}:host .wrapper{display:flex;overflow-x:scroll;scrollbar-width:none;position:relative}:host .wrapper::-webkit-scrollbar{display:none}:host .scroll-right-button{z-index:1;right:0}:host .scroll-left-button{z-index:1;left:0}:host .scroll-right-button,:host .scroll-left-button{height:50px;color:var(--tds-folder-tabs-scroll-btn-color);cursor:pointer;border:0;width:0;background-color:var(--tds-folder-tabs-scroll-btn-background);display:none;justify-content:center;align-items:center;opacity:0;pointer-events:none;position:sticky}:host .scroll-right-button.show,:host .scroll-left-button.show{min-width:48px;display:block;opacity:1;pointer-events:all}:host .scroll-right-button:hover,:host .scroll-left-button:hover{background-color:var(--tds-folder-tabs-scroll-btn-background-hover)}:host .scroll-right-button:active,:host .scroll-left-button:active{background-color:var(--tds-folder-tabs-scroll-btn-background-active)}:host .scroll-right-button:focus,:host .scroll-left-button:focus{outline:2px solid var(--tds-focus-outline-color);box-shadow:0 0 0 1px var(--tds-white);outline-offset:1px;z-index:1}:host .scroll-right-button svg,:host .scroll-left-button svg{fill:var(--tds-folder-tabs-scroll-btn-color)}";
const TdsFolderTabsStyle0 = folderTabsCss;
const TdsFolderTabs$1 = /*@__PURE__*/ proxyCustomElement(class TdsFolderTabs extends H {
constructor() {
super();
this.__registerHost();
this.__attachShadow();
this.tdsChange = createEvent(this, "tdsChange", 7);
this.navWrapperElement = null; // reference to container with nav buttons
this.componentWidth = 0; // visible width of this component
this.buttonsWidth = 0; // total width of all nav items combined
this.scrollWidth = 0; // total amount that is possible to scroll in the nav wrapper
this.clickHandlers = new WeakMap();
this.addResizeObserver = () => {
const resizeObserver = new ResizeObserver((entries) => {
entries.forEach((entry) => {
const componentWidth = entry.contentRect.width;
let buttonsWidth = 0;
const navButtons = Array.from(this.host.children);
navButtons.forEach((navButton) => {
const style = window.getComputedStyle(navButton);
buttonsWidth +=
navButton.clientWidth + parseFloat(style.marginLeft) + parseFloat(style.marginRight);
});
this.componentWidth = componentWidth;
this.buttonsWidth = buttonsWidth;
this.scrollWidth = buttonsWidth - componentWidth;
this.updateScrollButtons();
});
});
resizeObserver.observe(this.navWrapperElement);
};
this.addEventListenerToTabs = () => {
this.children = Array.from(this.host.children);
this.children.map((item, index) => {
const clickHandler = () => {
if (!item.disabled) {
const tdsChangeEvent = this.tdsChange.emit({
selectedTabIndex: this.children.indexOf(item),
});
if (!tdsChangeEvent.defaultPrevented) {
this.children.forEach((element) => element.setSelected(false));
item.setSelected(true);
this.selectedIndex = index;
}
}
};
item.addEventListener('click', clickHandler);
this.clickHandlers.set(item, clickHandler); // Store the handler in WeakMap
return item;
});
};
this.removeEventListenerFromTabs = () => {
this.children.forEach((item) => {
const clickHandler = this.clickHandlers.get(item);
if (clickHandler) {
item.removeEventListener('click', clickHandler);
this.clickHandlers.delete(item);
}
});
};
this.modeVariant = null;
this.defaultSelectedIndex = 0;
this.selectedIndex = undefined;
this.tdsScrollLeftAriaLabel = 'Scroll left';
this.tdsScrollRightAriaLabel = 'Scroll right';
this.buttonWidth = 0;
this.showLeftScroll = false;
this.showRightScroll = false;
}
/** Sets the passed tabindex as the selected Tab. */
async selectTab(tabIndex) {
if (tabIndex < 0 || tabIndex >= this.children.length) {
throw new Error('Tab index out of bounds');
}
if (!this.children[tabIndex].disabled) {
this.children.forEach((element) => element.setSelected(false));
this.children = this.children.map((element, index) => {
if (index === tabIndex) {
element.setSelected(true);
this.selectedIndex = tabIndex;
}
return element;
});
}
return { selectedTabIndex: this.selectedIndex };
}
/** Reinitializes the component. */
async reinitialize() {
this.handleSlotChange();
}
handleSelectedIndexUpdate() {
this.children = Array.from(this.host.children).map((tabElement) => {
tabElement.setSelected(false);
return tabElement;
});
this.children[this.selectedIndex].setSelected(true);
}
scrollRight() {
const scroll = this.navWrapperElement.scrollLeft;
this.navWrapperElement.scrollLeft = scroll + this.buttonsWidth;
this.evaluateScrollButtons();
}
scrollLeft() {
const scroll = this.navWrapperElement.scrollLeft;
this.navWrapperElement.scrollLeft = scroll - this.buttonsWidth;
this.evaluateScrollButtons();
}
evaluateScrollButtons() {
const scroll = this.navWrapperElement.scrollLeft;
this.showRightScroll = scroll <= this.scrollWidth;
this.showLeftScroll = scroll > 0;
}
initializeTabs() {
this.children = Array.from(this.host.children);
// remove first and last class from other tabs in case of initialization
this.children.forEach((child) => {
child.classList.remove('last');
child.classList.remove('first');
});
this.children[0].classList.add('first');
this.children[this.children.length - 1].classList.add('last');
}
initializeSelectedTab() {
if (this.selectedIndex === undefined) {
this.addEventListenerToTabs();
this.children[this.defaultSelectedIndex].setSelected(true);
this.selectedIndex = this.defaultSelectedIndex;
}
else {
this.children[this.selectedIndex].setSelected(true);
}
this.tdsChange.emit({
selectedTabIndex: this.selectedIndex,
});
}
updateScrollButtons() {
if (this.buttonsWidth > this.componentWidth) {
this.evaluateScrollButtons();
}
else {
this.showLeftScroll = false;
this.showRightScroll = false;
}
}
handleSlotChange() {
this.initializeTabs();
this.addEventListenerToTabs();
this.initializeSelectedTab();
this.updateScrollButtons();
this.addResizeObserver();
}
connectedCallback() {
this.initializeTabs();
}
componentDidLoad() {
this.initializeSelectedTab();
}
componentDidRender() {
this.updateScrollButtons();
this.addResizeObserver();
}
disconnectedCallback() {
this.removeEventListenerFromTabs();
}
render() {
return (h(Host, { key: 'c56bf987e23ade8b30cd2470ab1ed0f4273bd191', role: "tablist", class: `${this.modeVariant ? `tds-mode-variant-${this.modeVariant}` : ''}` }, h("div", { key: 'afab8a86427918d5ac4bbc17dd2a436a986df577', class: "wrapper", ref: (el) => {
this.navWrapperElement = el;
} }, h("button", { key: '0b82a953932e888d05478d82944c90768f97bb36', "aria-label": this.tdsScrollLeftAriaLabel, class: `scroll-left-button ${this.showLeftScroll ? 'show' : ''}`, disabled: !this.showLeftScroll, onClick: () => this.scrollLeft() }, h("tds-icon", { key: '50cd22c5be43ae452e0896b449570774c3ab0151', name: "chevron_left", size: "20px" })), h("slot", { key: '3cb17dddc8592241c467167b3a0028355f2b7d5e', onSlotchange: () => this.handleSlotChange() }), h("button", { key: '23c289b70d723b2d0705692835a510b8a650fcfa', "aria-label": this.tdsScrollRightAriaLabel, class: `scroll-right-button ${this.showRightScroll ? 'show' : ''}`, disabled: !this.showRightScroll, onClick: () => this.scrollRight() }, h("tds-icon", { key: 'fff2bfcbcf916d1b391aa25ee5f6fda3c8e63d23', name: "chevron_right", size: "20px" })))));
}
get host() { return this; }
static get watchers() { return {
"selectedIndex": ["handleSelectedIndexUpdate"]
}; }
static get style() { return TdsFolderTabsStyle0; }
}, [1, "tds-folder-tabs", {
"modeVariant": [1, "mode-variant"],
"defaultSelectedIndex": [2, "default-selected-index"],
"selectedIndex": [514, "selected-index"],
"tdsScrollLeftAriaLabel": [1, "tds-scroll-left-aria-label"],
"tdsScrollRightAriaLabel": [1, "tds-scroll-right-aria-label"],
"buttonWidth": [32],
"showLeftScroll": [32],
"showRightScroll": [32],
"selectTab": [64],
"reinitialize": [64]
}, undefined, {
"selectedIndex": ["handleSelectedIndexUpdate"]
}]);
function defineCustomElement$1() {
if (typeof customElements === "undefined") {
return;
}
const components = ["tds-folder-tabs", "tds-icon"];
components.forEach(tagName => { switch (tagName) {
case "tds-folder-tabs":
if (!customElements.get(tagName)) {
customElements.define(tagName, TdsFolderTabs$1);
}
break;
case "tds-icon":
if (!customElements.get(tagName)) {
defineCustomElement$2();
}
break;
} });
}
defineCustomElement$1();
const TdsFolderTabs = TdsFolderTabs$1;
const defineCustomElement = defineCustomElement$1;
export { TdsFolderTabs, defineCustomElement };