UNPKG

@scania/tegel

Version:
208 lines (204 loc) 10.7 kB
import { r as registerInstance, c as createEvent, h, H as Host, a as getElement } from './index-9xxNGlso.js'; const navigationTabsCss = () => `:host{box-sizing:border-box;display:flex;background-color:var(--tds-navigation-tabs-background);position:relative}:host *{box-sizing:border-box}:host::after{content:" ";display:block;border-bottom:1px solid var(--tds-navigation-tabs-horizontal-divider-background);left:0;right:0;bottom:0;position:absolute}:host .wrapper{display:flex;flex-wrap:nowrap;white-space:nowrap;width:100%;overflow-x:scroll;scrollbar-width:none;gap:16px}:host .wrapper::-webkit-scrollbar{display:none}:host .scroll-right-button{right:0;z-index:1}:host .scroll-left-button{left:0;z-index:1}:host .scroll-right-button,:host .scroll-left-button{color:var(--tds-folder-tabs-scroll-btn-color);cursor:pointer;border:0;width:0;background-color:var(--tds-inline-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::before,:host .scroll-left-button:focus::before{content:"";position:absolute;left:3px;right:3px;top:3px;bottom:3px;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:focus,:host .scroll-left-button:focus{outline:0}:host .scroll-right-button svg,:host .scroll-left-button svg{fill:var(--tds-folder-tabs-scroll-btn-color)}`; const TdsNavigationTabs = class { constructor(hostRef) { registerInstance(this, hostRef); this.tdsChange = createEvent(this, "tdsChange", 7); /** Variant of the Tabs, primary= on white, secondary= on grey50 */ this.modeVariant = 'primary'; /** Sets the default selected Tab. */ this.defaultSelectedIndex = 0; /** Custom left padding value for the wrapper element. */ this.leftPadding = 32; /** Defines aria-label on left scroll button */ this.tdsScrollLeftAriaLabel = 'Scroll left'; /** Defines aria-label on right scroll button */ this.tdsScrollRightAriaLabel = 'Scroll right'; this.showLeftScroll = false; this.showRightScroll = false; 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.scrollableWidth = 0; // total amount that is possible to scroll in the nav wrapper this.tabElements = []; 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.scrollableWidth = buttonsWidth - componentWidth; this.updateScrollButtons(); }); }); if (this.navWrapperElement) resizeObserver.observe(this.navWrapperElement); }; this.addEventListenerToTabs = () => { this.tabElements = Array.from(this.host.children); this.tabElements.map((item, index) => { const clickHandler = () => { if (!item.disabled) { const tdsChangeEvent = this.tdsChange.emit({ selectedTabIndex: this.tabElements.indexOf(item), }); if (!tdsChangeEvent.defaultPrevented) { this.tabElements.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.tabElements.forEach((item) => { const clickHandler = this.clickHandlers.get(item); if (clickHandler) { item.removeEventListener('click', clickHandler); this.clickHandlers.delete(item); } }); }; } /** Sets the passed tabindex as the selected Tab. */ async selectTab(tabIndex) { if (!this.tabElements[tabIndex].disabled) { this.tabElements.forEach((element) => element.setSelected(false)); this.tabElements = this.tabElements.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.tabElements = Array.from(this.host.children).map((tabElement) => { tabElement.setSelected(false); return tabElement; }); if (this.selectedIndex) { this.tabElements[this.selectedIndex].setSelected(true); } } scrollRight() { if (!this.navWrapperElement) return; const scroll = this.navWrapperElement.scrollLeft; this.navWrapperElement.scrollLeft = scroll + this.buttonsWidth; this.evaluateScrollButtons(); } scrollLeft() { if (!this.navWrapperElement) return; const scroll = this.navWrapperElement.scrollLeft; this.navWrapperElement.scrollLeft = scroll - this.buttonsWidth; this.evaluateScrollButtons(); } evaluateScrollButtons() { if (!this.navWrapperElement) return; const scroll = this.navWrapperElement.scrollLeft; this.showRightScroll = scroll <= this.scrollableWidth; this.showLeftScroll = scroll > 0; } initializeTabs() { this.tabElements = Array.from(this.host.children); // remove first and last class from other tabs in case of initialization this.tabElements.forEach((child) => { child.classList.remove('last'); child.classList.remove('first'); }); if (this.tabElements.length > 0) { this.tabElements[0].classList.add('first'); this.tabElements[this.tabElements.length - 1].classList.add('last'); } } initializeSelectedTab() { if (this.selectedIndex === undefined) { this.addEventListenerToTabs(); this.tabElements[this.defaultSelectedIndex].setSelected(true); this.selectedIndex = this.defaultSelectedIndex; } else { this.tabElements[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; } } applyCustomLeftPadding() { if (this.navWrapperElement) { this.navWrapperElement.style.paddingLeft = `${this.leftPadding}px`; } } handleSlotChange() { this.initializeTabs(); this.addEventListenerToTabs(); this.initializeSelectedTab(); this.updateScrollButtons(); this.addResizeObserver(); this.applyCustomLeftPadding(); // Apply custom left padding to the wrapper } connectedCallback() { this.initializeTabs(); } componentDidLoad() { this.initializeSelectedTab(); } componentDidRender() { this.updateScrollButtons(); this.addResizeObserver(); } disconnectedCallback() { this.removeEventListenerFromTabs(); } render() { return (h(Host, { key: '30d0734a2ac6fe0a585ca7e15fe08f9feceb2303', role: "tablist", class: { [`tds-mode-variant-${this.modeVariant}`]: this.modeVariant !== null } }, h("div", { key: 'b27101ea4c520eb434ba26c425e6179c1b0bdd8b', class: "wrapper", ref: (el) => { this.navWrapperElement = el; }, style: { paddingLeft: `${this.leftPadding}px` } }, h("button", { key: 'a2214da9d20638ee1896cb04c759f598caee3425', "aria-label": this.tdsScrollLeftAriaLabel, class: { 'scroll-left-button': true, 'show': this.showLeftScroll, }, onClick: () => this.scrollLeft(), disabled: !this.showLeftScroll }, h("tds-icon", { key: '54fc194d33c682ecf03c51af39ce5290de199c29', name: "chevron_left", size: "20px" })), h("slot", { key: '8c673f8d743352b4f5228c434ea6ba73b35d5916', onSlotchange: () => this.handleSlotChange() }), h("button", { key: 'f89e20284ad64bb864e84c28015f162fdf744b62', "aria-label": this.tdsScrollRightAriaLabel, class: { 'scroll-right-button': true, 'show': this.showRightScroll, }, onClick: () => this.scrollRight(), disabled: !this.showRightScroll }, h("tds-icon", { key: '6099eec68724b31d6ec71e5f6491313cae51db1f', name: "chevron_right", size: "20px" }))))); } get host() { return getElement(this); } static get watchers() { return { "selectedIndex": [{ "handleSelectedIndexUpdate": 0 }] }; } }; TdsNavigationTabs.style = navigationTabsCss(); export { TdsNavigationTabs as tds_navigation_tabs };