import * as i0 from '@angular/core';
import { Component, Attribute, Inject, Optional, HostBinding, ContentChildren, NgModule } from '@angular/core';
import * as i2$1 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i2 from '@wm/components/base';
import { PROP_STRING, PROP_ANY, PROP_NUMBER, PROP_BOOLEAN, register, StylableComponent, APPLY_STYLES_TYPE, styler, RedrawableDirective, provideAsWidgetRef, createArrayFrom, WmComponentsModule } from '@wm/components/base';
import * as i1 from '@wm/core';
import { setCSSFromObj, addClass, setCSS, $appDigest, isMobileApp, noop, removeAttr, removeClass, appendNode } from '@wm/core';
import { SwipeAnimation } from '@swipey';
import { find, isArray, indexOf, get, forEach, isEmpty, findIndex } from 'lodash-es';

class TabsAnimator extends SwipeAnimation {
    constructor(tabs) {
        super();
        this.tabs = tabs;
        this._$el = $(this.tabs.getNativeElement()).find('>.tab-content');
        this.init(this._$el);
    }
    calibrate() {
        const activeTabIndex = this.tabs.getActiveTabIndex();
        const panes = this._$el.find('>.tab-pane');
        let activeTabVisibleIndex = 0;
        let noOfVisiblePanes = 0;
        let visiblePanes = [];
        panes.each((i, p) => {
            if (!$(p).prop('hidden')) {
                noOfVisiblePanes++;
                if (i === activeTabIndex) {
                    activeTabVisibleIndex = noOfVisiblePanes - 1;
                }
                visiblePanes.push(p);
            }
            return true;
        });
        return {
            activeTabIndex: activeTabVisibleIndex,
            noOfTabs: noOfVisiblePanes,
            panes: visiblePanes
        };
    }
    bounds() {
        const { activeTabIndex, noOfTabs, panes } = this.calibrate(), w = $(panes[0]).width(), centerVal = -1 * activeTabIndex * w;
        this.clearContentFocus();
        return {
            strict: false,
            lower: activeTabIndex === noOfTabs - 1 ? 0 : -w,
            center: centerVal,
            upper: activeTabIndex === 0 ? centerVal : w
        };
    }
    context() {
        return {
            'w': this._$el.width()
        };
    }
    animation() {
        return {
            'transform': 'translate3d(${{ ($D + $d)/w * 100 + \'%\'}}, 0, 0)',
            '-webkit-transform': 'translate3d(${{ ($D + $d)/w * 100 + \'%\'}}, 0, 0)'
        };
    }
    /* WMS-18031 | On Tab Switch | Remove the Focus on the Existing Tab Contents */
    clearContentFocus() {
        let activeTab = this._$el.find('>.tab-pane.active');
        if (activeTab.length && activeTab.find(document.activeElement).length) {
            document.activeElement.blur();
        }
    }
    transitionTabIntoView() {
        const { activeTabIndex, noOfTabs, panes } = this.calibrate();
        const maxWidth = `${noOfTabs * 100}%`;
        setCSSFromObj(this._$el[0], { maxWidth: maxWidth, width: maxWidth });
        addClass(this.tabs.getNativeElement(), 'has-transition');
        const width = `${100 / noOfTabs}%`;
        panes.forEach(p => {
            setCSS(p, 'width', width);
        });
        setCSS(this._$el[0], 'transform', `translate3d(${-1 * activeTabIndex / noOfTabs * 100}%, 0, 0)`);
    }
    onUpper($event) {
        this.tabs.prev($event);
        $appDigest();
    }
    onLower($event) {
        this.tabs.next($event);
        $appDigest();
    }
    threshold() {
        return 5;
    }
}

const registerProps$1 = () => {
    const props = new Map([
        ['class', PROP_STRING],
        ['dataset', PROP_ANY],
        ['defaultpaneindex', { value: 0, ...PROP_NUMBER }],
        ['justified', PROP_BOOLEAN],
        ['tabsposition', { value: 'top', ...PROP_STRING }],
        ['name', PROP_STRING],
        ['nodatamessage', { value: 'No Data Found', ...PROP_STRING }],
        ['show', { value: true, ...PROP_BOOLEAN }],
        ['statehandler', { value: 'none', ...PROP_STRING }],
        ['transition', PROP_STRING],
        ['type', PROP_STRING]
    ]);
    if (isMobileApp()) {
        props.set('transition', { value: 'slide', ...PROP_STRING });
    }
    register('wm-tabs', props);
};

const registerProps = () => {
    register('wm-tabpane', new Map([
        ['active', PROP_BOOLEAN], // internal property
        ['badgevalue', PROP_STRING],
        ['badgetype', { value: 'default', ...PROP_STRING }],
        ['class', PROP_STRING],
        ['content', PROP_STRING],
        ['disabled', PROP_BOOLEAN],
        ['dynamicPaneIndex', PROP_NUMBER], // internal property
        ['heading', PROP_STRING],
        ['isdefaulttab', PROP_STRING],
        ['isdynamic', PROP_BOOLEAN], // internal property
        ['name', PROP_STRING],
        ['paneicon', PROP_STRING],
        ['show', { value: true, ...PROP_BOOLEAN }],
        ['smoothscroll', { value: false, ...PROP_BOOLEAN }],
        ['title', { value: 'Tab Title', ...PROP_STRING }]
    ]));
};

const _c0$1 = ["wmTabPane", ""];
const _c1$1 = ["*"];
const DEFAULT_CLS$1 = 'tab-pane';
const WIDGET_CONFIG$1 = {
    widgetType: 'wm-tabpane',
    hostClass: DEFAULT_CLS$1
};
class TabPaneComponent extends StylableComponent {
    static { this.initializeProps = registerProps(); }
    constructor(inj, tabsRef, heading, title, explicitContext) {
        super(inj, WIDGET_CONFIG$1, explicitContext);
        this.tabsRef = tabsRef;
        this.heading = heading;
        this.title = title;
        this._isFirstLoad = true;
        this._isOnLoadTriggered = false;
        this.$lazyLoad = noop;
        this.isActive = false;
        this.disabled = false;
        // title property here serves the purpose of heading.
        // TODO: make it common for all the widget.
        removeAttr(this.nativeElement, 'title');
    }
    // parent tabs component will call this method for the order of callbacks to be proper
    // order of callbacks - deselect, select, change
    invokeOnSelectCallback($event) {
        this.invokeEventCallback('select', { $event });
    }
    select($event, isKeyBoardEvent) {
        // When called programatically $event won't be available
        if (this.isActive || this.disabled) {
            return;
        }
        this.isActive = true;
        this.$lazyLoad();
        this.redrawChildren();
        this.notifyParent($event, isKeyBoardEvent);
    }
    tabpaneHeaderClick($event, paneIndex) {
        this.invokeEventCallback('headerclick', { $event, paneIndex });
    }
    deselect() {
        if (this.isActive) {
            this.isActive = false;
            this.invokeEventCallback('deselect');
        }
    }
    remove() {
        if (this.isActive) {
            this === this.tabsRef.panes.last ? this.tabsRef.prev() : this.tabsRef.next();
        }
        const availablePanes = this.tabsRef.panes.toArray();
        availablePanes.splice(this.tabsRef.getPaneIndexByRef(this), 1);
        this.tabsRef.panes.reset([...availablePanes]);
        this.nativeElement.remove();
        this.tabsRef.$element.find(`.tab-header[data-paneid='${this.$element.attr('widget-id')}'] a`).remove();
    }
    redrawChildren() {
        setTimeout(() => {
            if (this.reDrawableComponents) {
                this.reDrawableComponents.forEach(c => c.redraw());
            }
            // Fix for [WMS-24564]: trigger  Onload event when it is inline content
            if (!this._isOnLoadTriggered && !this.content) {
                this.invokeEventCallback('load');
                this._isOnLoadTriggered = true;
            }
        }, 100);
    }
    notifyParent(evt, isKeyBoardEvent) {
        this.tabsRef.notifyChange(this, evt, isKeyBoardEvent);
    }
    // select next valid tab
    handleSwipeLeft() {
        this.tabsRef.next();
    }
    // select prev valid tab
    handleSwipeRight() {
        this.tabsRef.prev();
    }
    // select event is called manually
    handleEvent(node, eventName, callback, locals) {
        if (eventName !== 'select') {
            super.handleEvent(this.nativeElement, eventName, callback, locals);
        }
    }
    onPropertyChange(key, nv, ov) {
        if (key === 'content') {
            if (this.isActive) {
                setTimeout(() => this.$lazyLoad(), 100);
            }
        }
        else if (key === 'show') {
            // overridding the base component show propertyChangeHandler
            this.nativeElement.hidden = !nv;
            // setting default tab pane on pageload whenever show property is bindable
            if (this._isFirstLoad) {
                this.tabsRef.selectDefaultPaneByIndex(this.tabsRef.defaultpaneindex);
            }
            else if (!nv && this.isActive) {
                this.tabsRef.next();
            }
            else if (nv || !this.isActive) {
                this.tabsRef.tabsAnimator?.transitionTabIntoView();
            }
            this._isFirstLoad = false;
        }
        else {
            super.onPropertyChange(key, nv, ov);
        }
    }
    ngOnInit() {
        super.ngOnInit();
        this.title = this.title || this.heading;
    }
    ngAfterViewInit() {
        styler(this.nativeElement.querySelector('.tab-body'), this, APPLY_STYLES_TYPE.CONTAINER);
        super.ngAfterViewInit();
        if (this.isdynamic) {
            this.tabsRef.registerDynamicTab(this);
        }
    }
    static { this.ɵfac = function TabPaneComponent_Factory(t) { return new (t || TabPaneComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(TabsComponent), i0.ɵɵinjectAttribute('heading'), i0.ɵɵinjectAttribute('title'), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TabPaneComponent, selectors: [["div", "wmTabPane", ""]], contentQueries: function TabPaneComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
            i0.ɵɵcontentQuery(dirIndex, RedrawableDirective, 5);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.reDrawableComponents = _t);
        } }, hostVars: 4, hostBindings: function TabPaneComponent_HostBindings(rf, ctx) { if (rf & 2) {
            i0.ɵɵclassProp("active", ctx.isActive)("disabled", ctx.disabled);
        } }, features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(TabPaneComponent)
            ]), i0.ɵɵInheritDefinitionFeature], attrs: _c0$1, ngContentSelectors: _c1$1, decls: 2, vars: 1, consts: [["partial-container-target", "", 1, "tab-body", 3, "wmSmoothscroll"]], template: function TabPaneComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵprojectionDef();
            i0.ɵɵelementStart(0, "div", 0);
            i0.ɵɵprojection(1);
            i0.ɵɵelementEnd();
        } if (rf & 2) {
            i0.ɵɵproperty("wmSmoothscroll", ctx.smoothscroll);
        } }, dependencies: [i2.SmoothScrollDirective], encapsulation: 2 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TabPaneComponent, [{
        type: Component,
        args: [{ selector: 'div[wmTabPane]', providers: [
                    provideAsWidgetRef(TabPaneComponent)
                ], template: "<div class=\"tab-body\" partial-container-target [wmSmoothscroll]=\"smoothscroll\">\n    <ng-content></ng-content>\n</div>" }]
    }], () => [{ type: i0.Injector }, { type: TabsComponent }, { type: undefined, decorators: [{
                type: Attribute,
                args: ['heading']
            }] }, { type: undefined, decorators: [{
                type: Attribute,
                args: ['title']
            }] }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }], { isActive: [{
            type: HostBinding,
            args: ['class.active']
        }], disabled: [{
            type: HostBinding,
            args: ['class.disabled']
        }], reDrawableComponents: [{
            type: ContentChildren,
            args: [RedrawableDirective, { descendants: true }]
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabPaneComponent, { className: "TabPaneComponent", filePath: "tab-pane/tab-pane.component.ts", lineNumber: 31 }); })();

const _c0 = ["wmTabs", ""];
const _c1 = ["*", [["div", "wmRepeatTemplate", ""]]];
const _c2 = ["*", "div[wmRepeatTemplate]"];
const _c3 = (a0, a1) => ({ "nav-stacked": a0, "nav-justified": a1 });
const _c4 = (a0, a1) => ({ "active": a0, "disabled": a1 });
const _c5 = a0 => ["app-icon", a0];
const _c6 = (a0, a1) => ({ "tab-stacked": a0, "tab-justified": a1 });
function TabsComponent_li_1_i_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "i", 8);
} if (rf & 2) {
    const pane_r3 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction1(1, _c5, pane_r3.paneicon));
} }
function TabsComponent_li_1_span_4_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelement(0, "span", 6);
} if (rf & 2) {
    const pane_r3 = i0.ɵɵnextContext().$implicit;
    i0.ɵɵclassMapInterpolate1("label label-", pane_r3.badgetype, "");
    i0.ɵɵproperty("textContent", pane_r3.badgevalue);
} }
function TabsComponent_li_1_Template(rf, ctx) { if (rf & 1) {
    const _r1 = i0.ɵɵgetCurrentView();
    i0.ɵɵelementStart(0, "li", 3)(1, "a", 4);
    i0.ɵɵlistener("click", function TabsComponent_li_1_Template_a_click_1_listener($event) { const ctx_r1 = i0.ɵɵrestoreView(_r1); const pane_r3 = ctx_r1.$implicit; const i_r4 = ctx_r1.index; pane_r3.select($event); return i0.ɵɵresetView(pane_r3.tabpaneHeaderClick($event, i_r4)); })("keydown", function TabsComponent_li_1_Template_a_keydown_1_listener($event) { i0.ɵɵrestoreView(_r1); const ctx_r4 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r4.onkeydown($event)); });
    i0.ɵɵtemplate(2, TabsComponent_li_1_i_2_Template, 1, 3, "i", 5);
    i0.ɵɵelement(3, "span", 6);
    i0.ɵɵtemplate(4, TabsComponent_li_1_span_4_Template, 1, 4, "span", 7);
    i0.ɵɵelementEnd()();
} if (rf & 2) {
    const pane_r3 = ctx.$implicit;
    i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(10, _c4, pane_r3.isActive, pane_r3.disabled))("hidden", !pane_r3.show);
    i0.ɵɵattribute("data-paneid", pane_r3.widgetId);
    i0.ɵɵadvance();
    i0.ɵɵproperty("tabindex", pane_r3.isActive ? "0" : "-1");
    i0.ɵɵattribute("aria-label", pane_r3.badgevalue ? pane_r3.title + " " + pane_r3.badgevalue : pane_r3.title)("title", pane_r3.title)("aria-selected", pane_r3.isActive);
    i0.ɵɵadvance();
    i0.ɵɵproperty("ngIf", pane_r3.paneicon);
    i0.ɵɵadvance();
    i0.ɵɵproperty("textContent", pane_r3.title);
    i0.ɵɵadvance();
    i0.ɵɵproperty("ngIf", pane_r3.badgevalue);
} }
function TabsComponent_div_2_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 9);
    i0.ɵɵprojection(1, 0, ["ngProjectAs", "div[wmTabPane]", 5, ["div", "wmTabPane", ""]]);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r4 = i0.ɵɵnextContext();
    i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(1, _c6, ctx_r4.vertical, ctx_r4.justified));
} }
function TabsComponent_div_3_div_1_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div");
    i0.ɵɵtext(1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r4 = i0.ɵɵnextContext(2);
    i0.ɵɵadvance();
    i0.ɵɵtextInterpolate(ctx_r4.nodatamessage);
} }
function TabsComponent_div_3_Template(rf, ctx) { if (rf & 1) {
    i0.ɵɵelementStart(0, "div", 9);
    i0.ɵɵtemplate(1, TabsComponent_div_3_div_1_Template, 2, 1, "div", 10);
    i0.ɵɵprojection(2, 1);
    i0.ɵɵelementEnd();
} if (rf & 2) {
    const ctx_r4 = i0.ɵɵnextContext();
    i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(2, _c6, ctx_r4.vertical, ctx_r4.justified));
    i0.ɵɵadvance();
    i0.ɵɵproperty("ngIf", ctx_r4.fieldDefs && !ctx_r4.fieldDefs.length);
} }
const DEFAULT_CLS = 'app-tabs clearfix';
const WIDGET_CONFIG = {
    widgetType: 'wm-tabs',
    hostClass: DEFAULT_CLS
};
class TabsComponent extends StylableComponent {
    static { this.initializeProps = registerProps$1(); }
    constructor(inj, dynamicComponentProvider, _transition, _tabsPosition, statePersistence, explicitContext) {
        // handle to the promise resolver
        let resolveFn = noop;
        super(inj, WIDGET_CONFIG, explicitContext, new Promise(res => resolveFn = res));
        this.transition = _transition;
        this.tabsposition = _tabsPosition;
        this.statePersistence = statePersistence;
        this.dynamicComponentProvider = dynamicComponentProvider;
        this.dynamicTabs = [];
        this.dynamicPaneIndex = 0;
        this.promiseResolverFn = resolveFn;
        styler(this.nativeElement, this, APPLY_STYLES_TYPE.CONTAINER);
    }
    animateIn(element) {
        const tabHeader = $(element);
        // when the animation is not present toggle the active class.
        tabHeader.siblings('.active').removeClass('active');
        tabHeader.addClass('active');
        const ul = this.nativeElement.querySelector('ul.nav.nav-tabs');
        // move the tabheader into the viewport
        const $prevHeaderEle = tabHeader.prev();
        if ($prevHeaderEle.length) {
            ul.scrollLeft = $prevHeaderEle[0].offsetLeft;
        }
        else {
            ul.scrollLeft = 0;
        }
    }
    /**
     * This method is used to register the dynamic panes.
     * After all panes are initialzed, update the querylist manually based on index.
     * @param paneRef - refrence of the tabpane
     */
    registerDynamicTab(paneRef) {
        this.dynamicTabs.push(paneRef);
        const isLastPane = this.dynamicTabs.length === this.dynamicPaneIndex;
        if (isLastPane) {
            for (let i = 0; i < this.dynamicTabs.length; i++) {
                const newPaneRef = find(this.dynamicTabs, pane => pane.dynamicPaneIndex === i);
                const isPaneAlreadyExist = find(this.panes.toArray(), newPaneRef);
                if (!isPaneAlreadyExist) {
                    this.panes.reset([...this.panes.toArray(), newPaneRef]);
                    if (newPaneRef.active) {
                        setTimeout(() => {
                            newPaneRef.select();
                        }, 20);
                    }
                }
            }
        }
    }
    /**
     * This method is to add the tabpane dynamically
     * @param tabpanes - list of tabpanes
     */
    addPane(tabpanes) {
        if (!isArray(tabpanes)) {
            tabpanes = [tabpanes];
        }
        const paneNamesList = [];
        forEach(tabpanes, (pane, index) => {
            const isPaneAlreadyCreated = find(this.panes.toArray(), { name: pane.name });
            const isPaneNameExist = indexOf(paneNamesList, pane.name);
            // If user tries to add tabpane with the same name which is already exists then do not create the pane
            if (isPaneAlreadyCreated || isPaneNameExist > 0) {
                console.warn(`The tab pane with name ${pane.name} already exists`);
                return;
            }
            let paramMarkup = '';
            let propsTmpl = '';
            this.dynamicPaneIndex++;
            const name = pane.name ? pane.name : `tabpane${this.panes.toArray().length + (index + 1)}`;
            paneNamesList.push(name);
            const partialParams = get(pane, 'params');
            forEach(pane, (value, key) => {
                if (key !== 'params') {
                    propsTmpl = `${propsTmpl} ${key}="${value}"`;
                }
            });
            forEach(partialParams, (value, key) => {
                paramMarkup = `${paramMarkup} <wm-param name="${key}" value="${value}"></wm-param>`;
            });
            const markup = `<wm-tabpane dynamicPaneIndex="${this.dynamicPaneIndex - 1}" isdynamic="true" name="${name}" ${propsTmpl}>
                            ${paramMarkup}
                        </wm-tabpane>`;
            if (!this._dynamicContext) {
                this._dynamicContext = Object.create(this.viewParent);
                this._dynamicContext[this.getAttr('wmTab')] = this;
            }
            this.dynamicComponentProvider.addComponent(this.getNativeElement().querySelector('.tab-content'), markup, this._dynamicContext, { inj: this.inj });
        });
        return paneNamesList;
    }
    /**
     * This method is to remove the tabpane
     * @param paneIndex - index of the pane
     */
    removePane(paneName) {
        const paneRef = this.getPaneRefByName(paneName);
        if (paneRef) {
            paneRef.remove();
        }
    }
    /**
     * TabPane children components invoke this method to communicate with the parent
     * if the evt argument is defined on-change callback will be invoked.
     */
    notifyChange(paneRef, evt, isKeyBoardEvent) {
        if (!this.isSelectableTab(paneRef)) {
            return;
        }
        let headerElement;
        // invoke deselect event callback on the preset active tab
        if (!isEmpty(this.activeTab)) {
            this.activeTab.deselect();
        }
        this.activeTab = paneRef.getWidget();
        const newPaneIndex = this.getPaneIndexByRef(paneRef);
        const mode = this.statePersistence.computeMode(this.statehandler);
        if (!this.isPageLoadCall && mode && mode.toLowerCase() !== 'none') {
            this.statePersistence.setWidgetState(this, this.activeTab.name);
        }
        else {
            this.defaultpaneindex = this.getPaneIndexByRef(paneRef);
            this.isPageLoadCall = false;
        }
        // invoke select callback on the selected tab
        paneRef.invokeOnSelectCallback(evt);
        // invoke change callback if the evt is present, select a tab programmatically will not have the event
        if (evt) {
            this.invokeEventCallback('change', {
                $event: evt,
                newPaneIndex: newPaneIndex,
                oldPaneIndex: this._oldPaneIndex || 0
            });
        }
        this._oldPaneIndex = newPaneIndex;
        if (evt) {
            headerElement = $(evt.target).closest('li.tab-header');
        }
        if (!evt || !headerElement || !headerElement.length) {
            headerElement = this.nativeElement.querySelector(`li[data-paneid=${paneRef.widgetId}]`);
            const insideTabs = !!$(headerElement).closest('.app-tabs')
                .parent().closest('.app-tabs').length;
            if (!insideTabs && isKeyBoardEvent) {
                $(headerElement).children().focus();
            }
        }
        this.animateIn(headerElement);
        // this.setTabsLeftPosition(this.getPaneIndexByRef(this.activeTab), this.panes.length);
        if (this.canSlide()) {
            if (!this.tabsAnimator) {
                this.tabsAnimator = new TabsAnimator(this);
                this.tabsAnimator.setGesturesEnabled(this.canSlide());
            }
            this.tabsAnimator.transitionTabIntoView();
        }
    }
    goToTab(tabIndex) {
        if (this.isValidPaneIndex(tabIndex - 1)) {
            const tab = this.getPaneRefByIndex(tabIndex - 1);
            tab.select();
        }
    }
    getPaneIndexByRef(paneRef) {
        return this.panes.toArray().indexOf(paneRef);
    }
    // Returns the active tab index from tabs.
    getActiveTabIndex() {
        return findIndex(this.panes.toArray(), { isActive: true });
    }
    isValidPaneIndex(index) {
        return (index >= 0 && index < this.panes.length);
    }
    getPaneRefByIndex(index) {
        return this.panes.toArray()[index];
    }
    getPaneRefByName(name) {
        return find(this.panes.toArray(), { name: name });
    }
    // returns false if the pane is hidden or disabled
    isSelectableTab(paneRef) {
        return paneRef.show && !paneRef.disabled;
    }
    canSlide() {
        return this.transition === 'slide' && !this.vertical;
    }
    getSelectableTabAfterIndex(index) {
        for (let i = index + 1; i < this.panes.length; i++) {
            const pane = this.getPaneRefByIndex(i);
            if (this.isSelectableTab(pane)) {
                return pane;
            }
        }
        if (index === this.panes.length - 1) {
            const pane = this.getPaneRefByIndex(0);
            if (this.isSelectableTab(pane)) {
                return pane;
            }
        }
    }
    getSelectableTabBeforeIndex(index) {
        for (let i = index - 1; i >= 0; i--) {
            const pane = this.getPaneRefByIndex(i);
            if (this.isSelectableTab(pane)) {
                return pane;
            }
        }
        if (index === 0) {
            const pane = this.getPaneRefByIndex(this.panes.length - 1);
            if (this.isSelectableTab(pane)) {
                return pane;
            }
        }
    }
    // select next tab relative to the current active tab
    next($event, isKeyBoardEvent) {
        const pane = this.getSelectableTabAfterIndex(this.getActiveTabIndex());
        if (pane) {
            pane.select($event, isKeyBoardEvent);
        }
    }
    // select prev tab relative to the current active tab
    prev($event, isKeyBoardEvent) {
        const pane = this.getSelectableTabBeforeIndex(this.getActiveTabIndex());
        if (pane) {
            pane.select($event, isKeyBoardEvent);
        }
    }
    /**
     * this method will be invoked during the initialization of the component and on defaultpaneindex property change,
     * if the provided defaultpaneindex is not valid, find the first pane index which can be shown and select it
     */
    selectDefaultPaneByIndex(index) {
        if (!this.isValidPaneIndex(index)) {
            return;
        }
        let paneRef = this.getPaneRefByIndex(index);
        if (!this.isSelectableTab(paneRef)) {
            paneRef = this.getSelectableTabAfterIndex(0);
        }
        if (paneRef) {
            paneRef.select();
        }
    }
    // update the postion of tab header
    setTabsPosition() {
        const ul = this.nativeElement.children[0];
        this.vertical = (this.tabsposition === 'left' || this.tabsposition === 'right');
        removeClass(this.nativeElement, 'inverted');
        if (this.tabsposition === 'bottom' || this.tabsposition === 'right') {
            appendNode(ul, this.nativeElement);
            addClass(this.nativeElement, 'inverted');
        }
    }
    onDataChange(newVal) {
        this.fieldDefs = createArrayFrom(newVal);
        setTimeout(() => this.selectDefaultPaneByIndex(this.defaultpaneindex || 0));
    }
    onPropertyChange(key, nv, ov) {
        if (key === 'defaultpaneindex') {
            this.defaultpaneindex = nv;
        }
        else if (key === 'dataset') {
            this.onDataChange(nv);
        }
        else if (key === 'statehandler') {
            this.isPageLoadCall = true;
            const widgetState = this.statePersistence.getWidgetState(this);
            if (nv !== 'none' && widgetState) {
                const paneToSelect = this.panes.filter(function (pane) {
                    return widgetState === pane.name;
                });
                if (!paneToSelect.length) {
                    console.warn('Tab pane name ' + widgetState + ' in State is incorrect. Falling back to the default pane');
                    setTimeout(() => this.selectDefaultPaneByIndex(this.defaultpaneindex || 0), 20);
                }
                else {
                    const index = this.getPaneIndexByRef(paneToSelect[0]);
                    setTimeout(() => this.selectDefaultPaneByIndex(index), 20);
                }
            }
            else {
                setTimeout(() => this.selectDefaultPaneByIndex(this.defaultpaneindex || 0), 20);
            }
        }
        else {
            super.onPropertyChange(key, nv, ov);
        }
    }
    registerTabsScroll() {
        setTimeout(() => {
            const $ul = this.$element.find('> ul');
            let $liPosition;
            const $li = $ul.children();
            $liPosition = $li.last().position();
            if ($liPosition && ($liPosition.left > $ul.width())) {
                $ul.on('mousewheel', (e) => {
                    const left = $ul[0].scrollLeft, _delta = -1 * e.originalEvent.wheelDelta;
                    e.stopPropagation();
                    e.preventDefault();
                    $ul.animate({ scrollLeft: left + _delta }, { 'duration': 10 });
                });
            }
        });
    }
    onkeydown(event) {
        switch (event.key) {
            case 'ArrowLeft':
            case 'ArrowUp':
                this.prev(null, true);
                event.preventDefault();
                break;
            case 'ArrowRight':
            case 'ArrowDown':
                this.next(null, true);
                event.preventDefault();
                break;
            default:
                break;
        }
    }
    ngAfterContentInit() {
        this.promiseResolverFn();
        super.ngAfterContentInit();
        this.setTabsPosition();
        this.panes.changes.subscribe(slides => {
            if (this.panes.length) {
                this.selectDefaultPaneByIndex(this.defaultpaneindex || 0);
            }
        });
    }
    ngAfterViewInit() {
        super.ngAfterViewInit();
        this.registerTabsScroll();
    }
    static { this.ɵfac = function TabsComponent_Factory(t) { return new (t || TabsComponent)(i0.ɵɵdirectiveInject(i0.Injector), i0.ɵɵdirectiveInject(i1.DynamicComponentRefProvider), i0.ɵɵinjectAttribute('transition'), i0.ɵɵinjectAttribute('tabsposition'), i0.ɵɵdirectiveInject(i1.StatePersistence), i0.ɵɵdirectiveInject('EXPLICIT_CONTEXT', 8)); }; }
    static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: TabsComponent, selectors: [["div", "wmTabs", ""]], contentQueries: function TabsComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) {
            i0.ɵɵcontentQuery(dirIndex, TabPaneComponent, 4);
        } if (rf & 2) {
            let _t;
            i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.panes = _t);
        } }, exportAs: ["wmTabs"], features: [i0.ɵɵProvidersFeature([
                provideAsWidgetRef(TabsComponent)
            ]), i0.ɵɵInheritDefinitionFeature], attrs: _c0, ngContentSelectors: _c2, decls: 4, vars: 7, consts: [["role", "tablist", 1, "nav", "nav-tabs", 3, "ngClass"], ["class", "tab-header", "role", "presentation", 3, "ngClass", "hidden", 4, "ngFor", "ngForOf"], ["class", "tab-content", 3, "ngClass", 4, "ngIf"], ["role", "presentation", 1, "tab-header", 3, "ngClass", "hidden"], ["href", "javascript:void(0);", "role", "tab", 1, "tab-heading", 3, "click", "keydown", "tabindex"], [3, "ngClass", 4, "ngIf"], [3, "textContent"], [3, "class", "textContent", 4, "ngIf"], [3, "ngClass"], [1, "tab-content", 3, "ngClass"], [4, "ngIf"]], template: function TabsComponent_Template(rf, ctx) { if (rf & 1) {
            i0.ɵɵprojectionDef(_c1);
            i0.ɵɵelementStart(0, "ul", 0);
            i0.ɵɵtemplate(1, TabsComponent_li_1_Template, 5, 13, "li", 1);
            i0.ɵɵelementEnd();
            i0.ɵɵtemplate(2, TabsComponent_div_2_Template, 2, 4, "div", 2)(3, TabsComponent_div_3_Template, 3, 5, "div", 2);
        } if (rf & 2) {
            i0.ɵɵproperty("ngClass", i0.ɵɵpureFunction2(4, _c3, ctx.vertical, ctx.justified));
            i0.ɵɵadvance();
            i0.ɵɵproperty("ngForOf", ctx.panes);
            i0.ɵɵadvance();
            i0.ɵɵproperty("ngIf", ctx.type !== "dynamic");
            i0.ɵɵadvance();
            i0.ɵɵproperty("ngIf", ctx.type === "dynamic");
        } }, dependencies: [i2$1.NgClass, i2$1.NgForOf, i2$1.NgIf, i2.TextContentDirective], encapsulation: 2 }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TabsComponent, [{
        type: Component,
        args: [{ selector: 'div[wmTabs]', exportAs: 'wmTabs', providers: [
                    provideAsWidgetRef(TabsComponent)
                ], template: "<ul class=\"nav nav-tabs\" [ngClass]=\"{'nav-stacked': vertical, 'nav-justified': justified}\" role=\"tablist\">\n    <li class=\"tab-header\" *ngFor=\"let pane of panes; let i=index;\" [attr.data-paneid]=\"pane.widgetId\" [ngClass]=\"{'active': pane.isActive, 'disabled': pane.disabled}\"\n        [hidden]=\"!pane.show\" role=\"presentation\">\n        <a [attr.aria-label]=\"pane.badgevalue ? pane.title + ' ' + pane.badgevalue : pane.title\"\n           [attr.title]=\"pane.title\"\n           [tabindex]=\"pane.isActive ? '0' : '-1'\"\n           class=\"tab-heading\" href=\"javascript:void(0);\"\n           [attr.aria-selected]=\"pane.isActive\" role=\"tab\" (click)=\"pane.select($event); pane.tabpaneHeaderClick($event, i);\" (keydown)=\"onkeydown($event)\">\n                <i [ngClass]=\"['app-icon', pane.paneicon]\" *ngIf=\"pane.paneicon\"></i>\n                <span [textContent]=\"pane.title\"></span>\n                <span *ngIf=\"pane.badgevalue\" class=\"label label-{{pane.badgetype}}\" [textContent]=\"pane.badgevalue\"></span>\n        </a>\n    </li>\n</ul>\n<div class=\"tab-content\" *ngIf=\"type !== 'dynamic'\" [ngClass]=\"{'tab-stacked': vertical, 'tab-justified': justified}\">\n    <ng-content ngProjectAs=\"div[wmTabPane]\"></ng-content>\n</div>\n<div class=\"tab-content\" *ngIf=\"type === 'dynamic'\" [ngClass]=\"{'tab-stacked': vertical, 'tab-justified': justified}\">\n    <div *ngIf=\"fieldDefs && !fieldDefs.length\">{{nodatamessage}}</div>\n    <ng-content select=\"div[wmRepeatTemplate]\"></ng-content>\n</div>\n" }]
    }], () => [{ type: i0.Injector }, { type: i1.DynamicComponentRefProvider }, { type: undefined, decorators: [{
                type: Attribute,
                args: ['transition']
            }] }, { type: undefined, decorators: [{
                type: Attribute,
                args: ['tabsposition']
            }] }, { type: i1.StatePersistence }, { type: undefined, decorators: [{
                type: Inject,
                args: ['EXPLICIT_CONTEXT']
            }, {
                type: Optional
            }] }], { panes: [{
            type: ContentChildren,
            args: [TabPaneComponent]
        }] }); })();
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(TabsComponent, { className: "TabsComponent", filePath: "tabs.component.ts", lineNumber: 51 }); })();

const components = [
    TabPaneComponent,
    TabsComponent
];
class TabsModule {
    static { this.ɵfac = function TabsModule_Factory(t) { return new (t || TabsModule)(); }; }
    static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: TabsModule }); }
    static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [CommonModule,
            WmComponentsModule] }); }
}
(() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TabsModule, [{
        type: NgModule,
        args: [{
                imports: [
                    CommonModule,
                    WmComponentsModule
                ],
                declarations: [...components],
                exports: [...components]
            }]
    }], null, null); })();
(function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(TabsModule, { declarations: [TabPaneComponent,
        TabsComponent], imports: [CommonModule,
        WmComponentsModule], exports: [TabPaneComponent,
        TabsComponent] }); })();

/**
 * Generated bundle index. Do not edit.
 */

export { TabPaneComponent, TabsComponent, TabsModule };
//# sourceMappingURL=index.mjs.map
