UNPKG

@alyle/ui

Version:

Minimal Design, a set of components for Angular

750 lines (744 loc) 39.8 kB
import { __decorate } from 'tslib'; import * as i0 from '@angular/core'; import { Directive, EventEmitter, ElementRef, ViewChildren, forwardRef, ContentChildren, Output, Input, ViewChild, ViewEncapsulation, ChangeDetectionStrategy, Component, TemplateRef, ContentChild, HostListener, Optional, NgModule } from '@angular/core'; import * as i1 from '@alyle/ui'; import { st2c, LY_COMMON_STYLES, StyleCollection, mixinStyleUpdater, mixinBg, mixinElevation, mixinShadowColor, mixinColor, mixinRaised, mixinDisabled, mixinOutlined, mixinDisableRipple, XPosition, YPosition, AlignAlias, StyleRenderer, Style, Dir, scrollWithAnimation, LyCommonModule, LyThemeModule, NgTranscludeModule } from '@alyle/ui'; import { LyButton } from '@alyle/ui/button'; import { Subscription, Subject } from 'rxjs'; import * as i5 from '@angular/cdk/portal'; import { TemplatePortal, PortalModule } from '@angular/cdk/portal'; import { switchMapTo, take, takeUntil } from 'rxjs/operators'; import { coerceBooleanProperty } from '@angular/cdk/coercion'; import * as i2 from '@angular/cdk/scrolling'; import * as i3 from '@angular/cdk/platform'; import * as i4 from '@angular/common'; import { CommonModule } from '@angular/common'; import * as i6 from '@angular/cdk/a11y'; class LyTabContent { constructor(template) { this.template = template; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabContent, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive }); } static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.10", type: LyTabContent, isStandalone: false, selector: "[ly-tab-content]", ngImport: i0 }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabContent, decorators: [{ type: Directive, args: [{ selector: '[ly-tab-content]', standalone: false }] }], ctorParameters: () => [{ type: i0.TemplateRef }] }); const DEFAULT_DISABLE_RIPPLE = false; const STYLE_PRIORITY = -2; const DEFAULT_BG = 'primary'; const DEFAULT_INDICATOR_COLOR = 'accent'; const DEFAULT_ELEVATION = 4; const DEFAULT_HEADER_PLACEMENT = 'above'; const STYLES = (theme, ref) => { const __ = ref.selectorsOf(STYLES); return { $name: LyTabs.и, $priority: STYLE_PRIORITY, root: () => (_className) => `${_className}{display:flex;}${st2c(((theme.tab && theme.tab.root && (theme.tab.root instanceof StyleCollection ? theme.tab.root.setTransformer(fn => fn(__)).css : theme.tab.root(__)))), `${_className}`)}`, tab: (_className) => `${_className}{position:relative;display:inline-flex;}`, /** Tab container */ contentContainer: (_className) => `${_className}{display:flex;overflow:hidden;flex-grow:1;width:100%;position:relative;}`, /** Tab header */ labels: (_className) => `${_className}{display:flex;position:relative;height:100%;}`, labelsContainer: () => (_className) => `${_className}{overflow:hidden;flex-shrink:0;}@media (hover: none){${__.scrollable} ${_className}{overflow:auto;}}`, label: (_className) => `${_className}{-webkit-tap-highlight-color:transparent;-webkit-appearance:none;background-color:transparent;user-select:none;border:0;min-width:72px;padding:0 24px;cursor:pointer;height:48px;display:inline-flex;justify-content:center;align-items:center;position:relative;overflow:hidden;font-family:${theme.typography.fontFamily};font-size:${theme.pxToRem(theme.typography.fontSize)};letter-spacing:0.02857em;color:currentColor;outline:none;width:100%;font-weight:500;opacity:.7;}@media ${theme.breakpoints['XSmall']}{${_className}{padding:0 12px;}}`, labelActive: (_className) => `${_className}{opacity:1;}`, contents: (_className) => `${_className}{display:flex;width:100%;}`, content: (_className) => `${st2c((LY_COMMON_STYLES.fill), `${_className}`)}${_className}{width:100%;height:100%;position:absolute;overflow:auto;}`, contentActive: (_className) => `${_className}{position:relative;z-index:1;}`, contentInner: null, indicator: (_className) => `${_className}{position:absolute;height:2px;transition:450ms cubic-bezier(.1,1,0.5,1);background:currentColor;}`, indicatorForServer: (_className) => `${_className}{position:absolute;background:currentColor;}`, rippleContainer: (_className) => `${st2c((LY_COMMON_STYLES.fill), `${_className}`)}${_className}{overflow:hidden;}`, scrollable: null, hiddenContent: () => (_className) => `${_className}{visibility:hidden;}`, column: null, row: null }; }; /** @docs-private */ class LyTabsBase { constructor(_theme) { this._theme = _theme; } } /** @docs-private */ const LyTabsMixinBase = mixinStyleUpdater(mixinBg(mixinElevation(mixinShadowColor(LyTabsBase)))); /** @docs-private */ class LyTabLabelBase { constructor(_theme, _ngZone, _platform) { this._theme = _theme; this._ngZone = _ngZone; this._platform = _platform; } } /** @docs-private */ const LyTabLabelMixinBase = mixinStyleUpdater(mixinBg(mixinColor(mixinRaised(mixinDisabled(mixinOutlined(mixinElevation(mixinShadowColor(mixinDisableRipple(LyTabLabelBase))))))))); /** * @dynamic */ class LyTabs extends LyTabsMixinBase { /** @docs-private */ static { this.и = 'LyTabs'; } /** * Keep the content. * By default, when changing a tab, the previous one is created and deleted. * With this, the content will only be hidden instead of deleting it. */ set keepContent(val) { const newVal = coerceBooleanProperty(val); this._keepContent = newVal; } get keepContent() { return this._keepContent; } /** Animation duration in milliseconds */ set animationDuration(val) { this._animationDuration = val; Promise.resolve().then(() => { this.tabContents.nativeElement.style.transitionDuration = `${val}ms`; }); } get animationDuration() { return this._animationDuration; } /** * Whether the tab group should grow to the size of the active tab. */ set dynamicHeight(val) { const newVal = coerceBooleanProperty(val); this._dynamicHeight = newVal; } get dynamicHeight() { return this._dynamicHeight; } set scrollable(val) { const newVal = coerceBooleanProperty(val); if (newVal) { this.renderer.addClass(this.el.nativeElement, this.classes.scrollable); } else if (this._scrollable != null) { this.renderer.removeClass(this.el.nativeElement, this.classes.scrollable); } this._scrollable = newVal; } get scrollable() { return this._scrollable; } set headerPlacement(val) { if (val !== this.headerPlacement) { this._headerPlacement = val; this.sRenderer.toggleClass(this.classes.column, val === 'above' || val === 'below'); this.sRenderer.toggleClass(this.classes.row, val === 'before' || val === 'after'); this._headerPlacementClass = this.theme.addStyle(`lyTabs.headerPlacement:${val}`, () => { let flexDirectionContainer; let flexDirection = this._getFlexDirection(val); let position; let height = null; let width = null; let heightServer = null; let widthServer = null; switch (val) { case YPosition.above: flexDirectionContainer = 'column'; position = YPosition.below; height = '2px'; widthServer = '100%'; break; case YPosition.below: flexDirectionContainer = 'column-reverse'; position = YPosition.above; height = '2px'; widthServer = '100%'; break; case XPosition.before: flexDirectionContainer = 'row'; position = XPosition.after; width = '2px'; heightServer = '100%'; break; case XPosition.after: flexDirectionContainer = 'row-reverse'; position = XPosition.before; width = '2px'; heightServer = '100%'; break; default: throw new Error(`LyTabs: value:${val} do not is valid for \`headerPlacement\``); } if (val === YPosition.above || val === YPosition.below) { flexDirection = 'row'; } else { flexDirection = 'column'; } return { [`&`]: { flexDirection: flexDirectionContainer }, [`& .${this.classes.indicator},& .${this.classes.indicatorForServer}`]: { [position]: 0, height, width }, [`.${this.classes.indicatorForServer}`]: { width: widthServer, height: heightServer }, [`& .${this.classes.labels},& .${this.classes.contents}`]: { flexDirection }, [`.${this.classes.contents}`]: { flexDirection } }; }, this.el.nativeElement, this._headerPlacementClass, STYLE_PRIORITY); } } get headerPlacement() { return this._headerPlacement; } set alignTabs(val) { this._alignTabs = val; this._alignTabsClass = this.theme.addStyle(`lyAlignTabs: ${val}`, (val === 'stretch' ? { [`& .${this.classes.labels} .${this.classes.tab}`]: { flexBasis: 0, flexGrow: 1 } } : { [`& .${this.classes.labels}`]: { justifyContent: val in AlignAlias ? AlignAlias[val] : val } }), this.el.nativeElement, this._alignTabsClass, STYLE_PRIORITY); } get alignTabs() { return this._alignTabs; } set textColor(val) { this._textColor = val; this._textColorClass = this.theme.addStyle(`lyTabs.textColor:${val}`, (theme) => ({ [`& .${this.classes.labelActive}`]: { color: theme.colorOf(val) } }), this.el.nativeElement, this._textColorClass, STYLE_PRIORITY); } get textColor() { return this._textColor; } set selectedIndex(val) { if (val !== this.selectedIndex) { this._selectedBeforeIndex = this._selectedIndex; this._selectedIndex = this._findIndex(val, 'auto'); this._selectedBeforeTab = this._selectedTab; if (this._isViewInitLoaded) { this._updateTabs(); } else { Promise.resolve(null).then(() => this._updateTabs()); } this.selectedIndexChange.emit(this._selectedIndex); this._markForCheck(); } } get selectedIndex() { return this._selectedIndex; } constructor(theme, renderer, el, cd, _viewportRuler, sRenderer, _platform, _ngZone) { super(theme); this.theme = theme; this.renderer = renderer; this.el = el; this.cd = cd; this._viewportRuler = _viewportRuler; this.sRenderer = sRenderer; this._platform = _platform; this._ngZone = _ngZone; /** @docs-private */ this.$priority = STYLE_PRIORITY; /** @docs-private */ this.classes = this.sRenderer.renderSheet(STYLES, true); this._tabsSubscription = Subscription.EMPTY; this._timeoutIds = {}; /** Emits whenever the component is destroyed. */ this._destroy = new Subject(); this.selectedIndexOnChange = 'auto'; this.selectedIndexChange = new EventEmitter(); this.setAutoContrast(); this.animationDuration = 500; } ngOnChanges() { if (this._isViewInitLoaded) { this.updateStyle(this.tabsRef.nativeElement); } } ngOnInit() { if (this.selectedIndex == null) { this.selectedIndex = 0; } this.renderer.addClass(this.el.nativeElement, this.classes.root); const tabsIndicatorEl = this.tabsIndicator.nativeElement; this.renderer.addClass(tabsIndicatorEl, this.classes.indicator); /** Set default Color */ if (!this.indicatorColor && !this.bg && !this.textColor && !this.elevation) { this.indicatorColor = DEFAULT_INDICATOR_COLOR; this.bg = DEFAULT_BG; this.elevation = DEFAULT_ELEVATION; } if (!this.headerPlacement) { this.headerPlacement = DEFAULT_HEADER_PLACEMENT; } } ngAfterContentInit() { this._tabsSubscription = this.tabsList.changes.subscribe(() => { if (this._selectedIndex !== this.selectedIndexOnChange) { this.selectedIndex = this._findIndex(this.selectedIndex, this.selectedIndexOnChange); } this.cd.markForCheck(); }); } ngAfterViewInit() { this._isViewInitLoaded = true; this.tabsList.changes .pipe(switchMapTo(this._ngZone.onStable.asObservable().pipe(take(1))), takeUntil(this._destroy)) .subscribe(() => { this._updateTabs(); }); this._updateTabs(); this.updateStyle(this.tabsRef.nativeElement); if (this._platform.isBrowser) { this._tabResizeSub = this._viewportRuler.change().subscribe(() => { if (this._selectedTab) { this._updateIndicator(this._selectedTab); this._selectedTab._tabLabel._updateTabScroll(); } }); } } ngOnDestroy() { this._destroy.next(); this._destroy.complete(); this._tabsSubscription.unsubscribe(); if (this._tabResizeSub) { this._tabResizeSub.unsubscribe(); } this._clearTimeouts(); } _findIndex(selectedIndex, index) { if (!this.tabsList) { return selectedIndex; } const indexOfLastTab = this.tabsList.length - 1; const currentIndex = typeof index === 'number' ? index : selectedIndex; return currentIndex < 0 ? 0 : currentIndex > indexOfLastTab ? indexOfLastTab : currentIndex; } _updateIndicator(currentTab, beforeTab) { if (currentTab) { if (beforeTab) { beforeTab._renderer.removeAttribute(beforeTab._tabIndicator.nativeElement, 'class'); } const el = currentTab._el.nativeElement; const rects = el.getBoundingClientRect(); if (this.headerPlacement === XPosition.after || this.headerPlacement === XPosition.before) { this.renderer.setStyle(this.tabsIndicator.nativeElement, 'height', `${rects.height}px`); this.renderer.setStyle(this.tabsIndicator.nativeElement, 'top', `${el.offsetTop}px`); this.renderer.removeStyle(this.tabsIndicator.nativeElement, 'width'); this.renderer.removeStyle(this.tabsIndicator.nativeElement, 'left'); } else { this.renderer.setStyle(this.tabsIndicator.nativeElement, 'width', `${rects.width}px`); this.renderer.setStyle(this.tabsIndicator.nativeElement, 'left', `${el.offsetLeft}px`); this.renderer.removeStyle(this.tabsIndicator.nativeElement, 'height'); this.renderer.removeStyle(this.tabsIndicator.nativeElement, 'top'); } } } _markForCheck() { this.cd.markForCheck(); } _updateTabs() { if (!this._isViewInitLoaded) { return; } const tabsContents = this.tabContentList.toArray(); const tabsForUpdate = []; this.tabsList.forEach((tab, index) => { const tabContent = tabsContents[index].nativeElement; if (this.selectedIndex === index || this._selectedBeforeIndex === index) { tab._activeContent = true; tabsForUpdate.push([tab, tabContent, index]); } else { if (this.keepContent) { this.renderer.addClass(tabContent, this.classes.hiddenContent); } } }); this._ngZone.run(() => { this._markForCheck(); }); this._ngZone.onStable.asObservable() .pipe(take(1), takeUntil(this._destroy)) .subscribe(() => tabsForUpdate.forEach(parms => this._updateContentStyle(...parms))); } loadTemplate(tab, index) { tab.index = index; if (this.selectedIndex === tab.index) { // set 0 if is null this._selectedTab = tab; Promise.resolve(null).then(() => { // this._updateDynamicHeight(tabContent, index); if (this._platform.isBrowser) { this._updateIndicator(tab); } else { // for server const selectedBeforeTab = this._selectedBeforeTab; if (selectedBeforeTab) { this.renderer.removeClass(selectedBeforeTab._tabIndicator.nativeElement, this.classes.indicatorForServer); } this.renderer.addClass(this._selectedTab._tabIndicator.nativeElement, this.classes.indicatorForServer); } }); } else if (this._selectedBeforeIndex === index) { // Promise.resolve(null).then(() => this._updateDynamicHeight(tabContent, index)); } tab._tabLabel._updateTabState(); if (this.keepContent) { return tab.content; } if (tab._activeContent) { return tab.content; } return null; } _getFlexDirection(val) { let flexDirection; if (val === YPosition.above || val === YPosition.below) { flexDirection = 'row'; } else { flexDirection = 'column'; } return flexDirection; } _updateContentStyle(tab, tabContent, index) { if (this.selectedIndex === index || this._selectedBeforeIndex === index) { const prevIndex = this._selectedBeforeIndex; const currentIndex = this.selectedIndex; const dynamicHeight = this.dynamicHeight && this._platform.isBrowser && prevIndex != null; const contentInner = tabContent.firstElementChild; const contentHeight = dynamicHeight ? contentInner.getBoundingClientRect().height : null; const contentHeightPrev = dynamicHeight ? this.tabContentList.toArray()[prevIndex].nativeElement.firstElementChild.getBoundingClientRect().height : null; if (currentIndex === index) { this.renderer.addClass(tabContent, this.classes.contentActive); if (this.keepContent) { this.renderer.removeClass(tabContent, this.classes.hiddenContent); } } else { this.renderer.removeClass(tabContent, this.classes.contentActive); } if (prevIndex == null || !this._platform.isBrowser || prevIndex === currentIndex) { return; } this._clearTimeouts(index); const { before } = this._theme.variables; const isDirRow = this.headerPlacement === XPosition.after || this.headerPlacement === XPosition.before; const x = before === 'left' ? 100 : isDirRow ? 100 : -100; if (currentIndex === index) { const sign = prevIndex < index ? 1 : -1; const pos = isDirRow ? `0,${x * sign}%` : `${x * sign}%, 0`; tabContent.style.overflow = 'hidden'; if (dynamicHeight) { tabContent.style.height = `${contentHeightPrev}px`; } tabContent.style.transform = `translate3d(${pos}, 0)`; enforceStyleRecalculation(tabContent); tabContent.style.transition = `${this.animationDuration}ms cubic-bezier(0.35, 0, 0.25, 1)`; tabContent.style.transform = `translate3d(0%, 0, 0)`; if (dynamicHeight) { tabContent.style.height = `${contentHeight}px`; } } else { const sign = currentIndex < index ? 1 : -1; const pos = isDirRow ? `0,${x * sign}%` : `${x * sign}%, 0`; tabContent.style.overflow = 'hidden'; tabContent.style.transform = `translate3d(0%, 0, 0)`; enforceStyleRecalculation(tabContent); tabContent.style.transition = `${this.animationDuration}ms cubic-bezier(0.35, 0, 0.25, 1)`; tabContent.style.transform = `translate3d(${pos}, 0)`; } this._runTimeoutOutsideZone(index, () => { tabContent.style.transform = ``; tabContent.style.transition = ``; tabContent.style.overflow = ``; if (dynamicHeight) { tabContent.style.height = ``; } if (currentIndex !== index) { if (this.keepContent) { this.renderer.addClass(tabContent, this.classes.hiddenContent); } tab._activeContent = false; this._ngZone.run(() => this._markForCheck()); } }, this.animationDuration); } } /** Runs a timeout outside of the Angular zone to avoid triggering the change detection. */ _runTimeoutOutsideZone(index, fn, delay = 0) { this._ngZone.runOutsideAngular(() => this._timeoutIds[`_${index}`] = window.setTimeout(fn, delay)); } _clearTimeouts(tabIndex) { if (tabIndex != null) { const key = `_${tabIndex}`; if (this._timeoutIds[key] != null) { window.clearTimeout(this._timeoutIds[key]); delete this._timeoutIds[key]; } } else { Object.keys(this._timeoutIds) .forEach(key => window.clearTimeout(this._timeoutIds[`_${key}`])); } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabs, deps: [{ token: i1.LyTheme2 }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i2.ViewportRuler }, { token: i1.StyleRenderer }, { token: i3.Platform }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: LyTabs, isStandalone: false, selector: "ly-tabs", inputs: { bg: "bg", elevation: "elevation", shadowColor: "shadowColor", selectedIndexOnChange: "selectedIndexOnChange", keepContent: "keepContent", animationDuration: "animationDuration", dynamicHeight: "dynamicHeight", scrollable: "scrollable", indicatorColor: "indicatorColor", headerPlacement: "headerPlacement", alignTabs: "alignTabs", textColor: "textColor", selectedIndex: "selectedIndex" }, outputs: { selectedIndexChange: "selectedIndexChange" }, providers: [ StyleRenderer ], queries: [{ propertyName: "tabsList", predicate: i0.forwardRef(() => LyTab) }], viewQueries: [{ propertyName: "tabsRef", first: true, predicate: ["tabs"], descendants: true, static: true }, { propertyName: "tabContents", first: true, predicate: ["tabContents"], descendants: true, static: true }, { propertyName: "tabsIndicator", first: true, predicate: ["tabsIndicator"], descendants: true, read: ElementRef, static: true }, { propertyName: "tabContentList", predicate: ["tabContent"], descendants: true }], exportAs: ["lyTabs"], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div #tabs [className]=\"classes.labelsContainer\">\n <div [className]=\"classes.labels\">\n <ng-content></ng-content>\n <span #tabsIndicator></span>\n </div>\n</div>\n<div [className]=\"classes.contentContainer\">\n <div [className]=\"classes.contents\" #tabContents>\n <div #tabContent *ngFor=\"let item of tabsList; index as x\" [className]=\"classes.content\">\n <div [className]=\"classes.contentInner\">\n <ng-template\n [cdkPortalOutlet]=\"loadTemplate(item, x)\"\n ></ng-template>\n </div>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } __decorate([ Style(val => (theme, ref) => { const __ = ref.selectorsOf(STYLES); return (_className) => `${_className} ${__.indicator}{color:${theme.colorOf(val)};}`; }) ], LyTabs.prototype, "indicatorColor", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabs, decorators: [{ type: Component, args: [{ selector: 'ly-tabs', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, exportAs: 'lyTabs', inputs: [ 'bg', 'elevation', 'shadowColor' ], providers: [ StyleRenderer ], standalone: false, template: "<div #tabs [className]=\"classes.labelsContainer\">\n <div [className]=\"classes.labels\">\n <ng-content></ng-content>\n <span #tabsIndicator></span>\n </div>\n</div>\n<div [className]=\"classes.contentContainer\">\n <div [className]=\"classes.contents\" #tabContents>\n <div #tabContent *ngFor=\"let item of tabsList; index as x\" [className]=\"classes.content\">\n <div [className]=\"classes.contentInner\">\n <ng-template\n [cdkPortalOutlet]=\"loadTemplate(item, x)\"\n ></ng-template>\n </div>\n </div>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.LyTheme2 }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i2.ViewportRuler }, { type: i1.StyleRenderer }, { type: i3.Platform }, { type: i0.NgZone }], propDecorators: { tabsRef: [{ type: ViewChild, args: ['tabs', { static: true }] }], tabContents: [{ type: ViewChild, args: ['tabContents', { static: true }] }], tabsIndicator: [{ type: ViewChild, args: ['tabsIndicator', { static: true, read: ElementRef }] }], selectedIndexOnChange: [{ type: Input }], keepContent: [{ type: Input }], animationDuration: [{ type: Input }], dynamicHeight: [{ type: Input }], scrollable: [{ type: Input }], indicatorColor: [{ type: Input }], headerPlacement: [{ type: Input }], alignTabs: [{ type: Input }], textColor: [{ type: Input }], selectedIndex: [{ type: Input }], selectedIndexChange: [{ type: Output }], tabsList: [{ type: ContentChildren, args: [forwardRef(() => LyTab)] }], tabContentList: [{ type: ViewChildren, args: ['tabContent'] }] } }); class LyTab { /** @docs-private */ get content() { return this._contentPortal; } constructor(_tabs, _renderer, _el, sRenderer, _platform, _viewContainerRef) { this._tabs = _tabs; this._renderer = _renderer; this._el = _el; this.sRenderer = sRenderer; this._platform = _platform; this._viewContainerRef = _viewContainerRef; this._isBrowser = this._platform.isBrowser; /** Portal that will be the hosted content of the tab */ this._contentPortal = null; } ngOnInit() { this._renderer.addClass(this._el.nativeElement, this._tabs.classes.tab); this._contentPortal = new TemplatePortal(this._templateRefLazy || this._templateRef, this._viewContainerRef); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTab, deps: [{ token: LyTabs }, { token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.StyleRenderer }, { token: i3.Platform }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: LyTab, isStandalone: false, selector: "ly-tab", providers: [ StyleRenderer ], queries: [{ propertyName: "_templateRefLazy", first: true, predicate: LyTabContent, descendants: true, read: TemplateRef, static: true }, { propertyName: "_tabLabel", first: true, predicate: i0.forwardRef(() => LyTabLabel), descendants: true, static: true }], viewQueries: [{ propertyName: "_templateRef", first: true, predicate: ["_templateNgContent"], descendants: true, static: true }, { propertyName: "_tabIndicator", first: true, predicate: ["tabIndicator"], descendants: true }], ngImport: i0, template: "<ng-content select=\"ly-tab-label\"></ng-content>\n<ng-content select=\"[ly-tab-label]\"></ng-content>\n<ng-content select=\"[ly-tab-label-native]\"></ng-content>\n<div></div>\n<span *ngIf=\"!_isBrowser\" #tabIndicator></span>\n<ng-template #_templateNgContent>\n <ng-content></ng-content>\n</ng-template>", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTab, decorators: [{ type: Component, args: [{ selector: 'ly-tab', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [ StyleRenderer ], standalone: false, template: "<ng-content select=\"ly-tab-label\"></ng-content>\n<ng-content select=\"[ly-tab-label]\"></ng-content>\n<ng-content select=\"[ly-tab-label-native]\"></ng-content>\n<div></div>\n<span *ngIf=\"!_isBrowser\" #tabIndicator></span>\n<ng-template #_templateNgContent>\n <ng-content></ng-content>\n</ng-template>" }] }], ctorParameters: () => [{ type: LyTabs }, { type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.StyleRenderer }, { type: i3.Platform }, { type: i0.ViewContainerRef }], propDecorators: { _templateRefLazy: [{ type: ContentChild, args: [LyTabContent, { read: TemplateRef, static: true }] }], _templateRef: [{ type: ViewChild, args: ['_templateNgContent', { static: true }] }], _tabIndicator: [{ type: ViewChild, args: ['tabIndicator'] }], _tabLabel: [{ type: ContentChild, args: [forwardRef(() => LyTabLabel), { static: true }] }] } }); class LyTabLabel extends LyButton { get active() { return this._active; } set active(val) { const newVal = coerceBooleanProperty(val); if (newVal && val !== this.active) { Promise.resolve(null).then(() => this._tabs.selectedIndex = this._tab.index); } } _onClickTab() { if (!this.disabled) { this._tabs.selectedIndex = this._tab.index; } } constructor(_el, _renderer, _theme, _ngZone, _rippleService, _focusMonitor, sRenderer, _tab, _tabs, platform) { super(_el, _renderer, _theme, _ngZone, _rippleService, _focusMonitor, sRenderer, platform, null); this.sRenderer = sRenderer; this._tab = _tab; this._tabs = _tabs; this._isBrowser = platform.isBrowser; } ngOnInit() { this._renderer.addClass(this._el.nativeElement, this._tabs.classes.label); // set default disable ripple if (this.disableRipple == null) { this.disableRipple = DEFAULT_DISABLE_RIPPLE; } } _updateTabState() { // update styles for active tab if (this._tabs._selectedIndex === this._tab.index) { if (!this._activeTabStyle) { this._activeTabStyle = true; this._renderer.addClass(this._el.nativeElement, this._tabs.classes.labelActive); this._updateTabScroll(); } } else if (this._activeTabStyle) { this._activeTabStyle = false; this._renderer.removeClass(this._el.nativeElement, this._tabs.classes.labelActive); } } _updateTabScroll() { if (this._isBrowser && this._tabs.scrollable) { const tab = this._tab._el.nativeElement; const tabContainer = this._tabs.tabsRef.nativeElement; if (tabContainer.scrollWidth !== tabContainer.offsetWidth) { const dir = this._theme.variables.direction; const max = tabContainer.scrollWidth - tabContainer.offsetWidth; const offsetBefore = dir === Dir.rtl ? max + tab.offsetLeft : tab.offsetLeft; const l = offsetBefore + tab.offsetWidth / 2 - tabContainer.offsetWidth / 2; const newVal = l >= max ? max : l <= 0 ? 0 : l; scrollWithAnimation(this._tabs.tabsRef.nativeElement, newVal, 350, 'x'); } } } ngAfterViewInit() { } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabLabel, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1.LyTheme2 }, { token: i0.NgZone }, { token: i1.LyRippleService }, { token: i6.FocusMonitor }, { token: i1.StyleRenderer }, { token: LyTab, optional: true }, { token: LyTabs, optional: true }, { token: i3.Platform }], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.10", type: LyTabLabel, isStandalone: false, selector: "button[ly-tab-label], a[ly-tab-label]", inputs: { bg: "bg", color: "color", raised: "raised", disabled: "disabled", outlined: "outlined", elevation: "elevation", shadowColor: "shadowColor", disableRipple: "disableRipple", active: "active" }, host: { listeners: { "click": "_onClickTab()" } }, providers: [ StyleRenderer ], viewQueries: [{ propertyName: "_rippleContainer", first: true, predicate: ["rippleContainer"], descendants: true }], usesInheritance: true, ngImport: i0, template: "<span [className]=\"classes.content\">\n <ng-content></ng-content>\n</span>\n<div *ngIf=\"_isBrowser\" #rippleContainer [className]=\"_rippleService.classes.container\"></div>\n", dependencies: [{ kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabLabel, decorators: [{ type: Component, args: [{ selector: 'button[ly-tab-label], a[ly-tab-label]', inputs: [ 'bg', 'color', 'raised', 'disabled', 'outlined', 'elevation', 'shadowColor', 'disableRipple' ], providers: [ StyleRenderer ], standalone: false, template: "<span [className]=\"classes.content\">\n <ng-content></ng-content>\n</span>\n<div *ngIf=\"_isBrowser\" #rippleContainer [className]=\"_rippleService.classes.container\"></div>\n" }] }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1.LyTheme2 }, { type: i0.NgZone }, { type: i1.LyRippleService }, { type: i6.FocusMonitor }, { type: i1.StyleRenderer }, { type: LyTab, decorators: [{ type: Optional }] }, { type: LyTabs, decorators: [{ type: Optional }] }, { type: i3.Platform }], propDecorators: { active: [{ type: Input }], _rippleContainer: [{ type: ViewChild, args: ['rippleContainer'] }], _onClickTab: [{ type: HostListener, args: ['click'] }] } }); /** Enforces a style recalculation of a DOM element by computing its styles. */ function enforceStyleRecalculation(element) { window.getComputedStyle(element).getPropertyValue('opacity'); } class LyTabsModule { static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.2.10", ngImport: i0, type: LyTabsModule, declarations: [LyTabs, LyTab, LyTabLabel, LyTabContent], imports: [LyThemeModule, CommonModule, LyCommonModule, NgTranscludeModule, PortalModule], exports: [LyCommonModule, LyTabs, LyTab, LyTabLabel, LyTabContent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabsModule, imports: [LyThemeModule, CommonModule, LyCommonModule, NgTranscludeModule, PortalModule, LyCommonModule] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.10", ngImport: i0, type: LyTabsModule, decorators: [{ type: NgModule, args: [{ imports: [ LyThemeModule, CommonModule, LyCommonModule, NgTranscludeModule, PortalModule ], exports: [LyCommonModule, LyTabs, LyTab, LyTabLabel, LyTabContent], declarations: [LyTabs, LyTab, LyTabLabel, LyTabContent] }] }] }); /** * Generated bundle index. Do not edit. */ export { LyTab, LyTabContent, LyTabLabel, LyTabLabelBase, LyTabLabelMixinBase, LyTabs, LyTabsBase, LyTabsMixinBase, LyTabsModule, STYLES }; //# sourceMappingURL=alyle-ui-tabs.mjs.map