@angular-mdc/web
Version:
533 lines (529 loc) • 15.5 kB
JavaScript
/**
* @license
* Copyright (c) Dominic Carretto
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/trimox/angular-mdc-web/blob/master/LICENSE
*/
import { EventEmitter, Component, ChangeDetectionStrategy, ViewEncapsulation, ChangeDetectorRef, ElementRef, Input, Output, ContentChild, ContentChildren, NgModule } from '@angular/core';
import { MdcTabIndicatorModule } from '@angular-mdc/web/tab-indicator';
import { MDC_TAB_BAR_PARENT_COMPONENT, MdcTab, MdcTabModule } from '@angular-mdc/web/tab';
import { MdcTabScroller, MdcTabScrollerModule } from '@angular-mdc/web/tab-scroller';
import { coerceBooleanProperty } from '@angular/cdk/coercion';
import { Platform } from '@angular/cdk/platform';
import { Subject, merge } from 'rxjs';
import { startWith } from 'rxjs/operators';
import { MDCComponent } from '@angular-mdc/web/base';
import { MDCTabBarFoundation } from '@material/tab-bar';
/**
* @fileoverview added by tsickle
* Generated from: tab-bar/tab-bar.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class MdcTabActivatedEvent {
/**
* @param {?} source
* @param {?} index
* @param {?} tab
*/
constructor(source, index, tab) {
this.source = source;
this.index = index;
this.tab = tab;
}
}
class MdcTabBar extends MDCComponent {
/**
* @param {?} _platform
* @param {?} _changeDetectorRef
* @param {?} elementRef
*/
constructor(_platform, _changeDetectorRef, elementRef) {
super(elementRef);
this._platform = _platform;
this._changeDetectorRef = _changeDetectorRef;
this.elementRef = elementRef;
/**
* Emits whenever the component is destroyed.
*/
this._destroy = new Subject();
this._fade = false;
this._stacked = false;
this._fixed = false;
this._align = null;
this._iconIndicator = null;
this._useAutomaticActivation = true;
this._activeTabIndex = 0;
this._focusOnActivate = true;
this.activated = new EventEmitter();
/**
* Subscription to changes in tabs.
*/
this._changeSubscription = null;
/**
* Subscription to interaction events in tabs.
*/
this._tabInteractionSubscription = null;
}
/**
* @return {?}
*/
get fade() { return this._fade; }
/**
* @param {?} value
* @return {?}
*/
set fade(value) {
this._fade = coerceBooleanProperty(value);
this._syncTabs();
}
/**
* @return {?}
*/
get stacked() { return this._stacked; }
/**
* @param {?} value
* @return {?}
*/
set stacked(value) {
this._stacked = coerceBooleanProperty(value);
this._syncTabs();
}
/**
* @return {?}
*/
get fixed() { return this._fixed; }
/**
* @param {?} value
* @return {?}
*/
set fixed(value) {
this._fixed = coerceBooleanProperty(value);
this._syncTabs();
}
/**
* @return {?}
*/
get align() { return this._align; }
/**
* @param {?} value
* @return {?}
*/
set align(value) {
this._align = value || 'start';
this.tabScroller.align = this.align;
}
/**
* @return {?}
*/
get iconIndicator() { return this._iconIndicator; }
/**
* @param {?} value
* @return {?}
*/
set iconIndicator(value) {
this._iconIndicator = value;
this._syncTabs();
}
/**
* @return {?}
*/
get useAutomaticActivation() { return this._useAutomaticActivation; }
/**
* @param {?} value
* @return {?}
*/
set useAutomaticActivation(value) {
this._useAutomaticActivation = coerceBooleanProperty(value);
this._foundation.setUseAutomaticActivation(this._useAutomaticActivation);
}
/**
* @return {?}
*/
get activeTabIndex() { return this._activeTabIndex; }
/**
* @param {?} value
* @return {?}
*/
set activeTabIndex(value) {
if (this.activeTabIndex !== value) {
this._activeTabIndex = value;
this.activateTab(this.activeTabIndex);
}
}
/**
* @return {?}
*/
get focusOnActivate() { return this._focusOnActivate; }
/**
* @param {?} value
* @return {?}
*/
set focusOnActivate(value) {
this._focusOnActivate = coerceBooleanProperty(value);
this._syncTabs();
}
/**
* Combined stream of all of the tab interaction events.
* @return {?}
*/
get tabInteractions() {
return merge(...this.tabs.map((/**
* @param {?} tab
* @return {?}
*/
tab => tab.interacted)));
}
/**
* @return {?}
*/
getDefaultFoundation() {
/** @type {?} */
const adapter = {
scrollTo: (/**
* @param {?} scrollX
* @return {?}
*/
(scrollX) => this.tabScroller.scrollTo(scrollX)),
incrementScroll: (/**
* @param {?} scrollXIncrement
* @return {?}
*/
(scrollXIncrement) => this.tabScroller.incrementScroll(scrollXIncrement)),
getScrollPosition: (/**
* @return {?}
*/
() => this.tabScroller.getScrollPosition()),
getScrollContentWidth: (/**
* @return {?}
*/
() => this.tabScroller.getScrollContentWidth()),
getOffsetWidth: (/**
* @return {?}
*/
() => this._getHostElement().offsetWidth),
isRTL: (/**
* @return {?}
*/
() => this._platform.isBrowser ?
window.getComputedStyle(this._getHostElement()).getPropertyValue('direction') === 'rtl' : false),
setActiveTab: (/**
* @param {?} index
* @return {?}
*/
(index) => this.activateTab(index)),
activateTabAtIndex: (/**
* @param {?} index
* @param {?=} clientRect
* @return {?}
*/
(index, clientRect) => {
if (this._indexIsInRange(index)) {
this.tabs.toArray()[index].activate(clientRect);
}
}),
deactivateTabAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => {
if (this._indexIsInRange(index)) {
this.tabs.toArray()[index].deactivate();
}
}),
focusTabAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => this.tabs.toArray()[index].focus()),
getTabIndicatorClientRectAtIndex: (/**
* @param {?} previousActiveIndex
* @return {?}
*/
(previousActiveIndex) => {
if (!this._platform.isBrowser) {
return { height: 0, width: 0, bottom: 0, top: 0, left: 0, right: 0 };
}
if (!this._indexIsInRange(previousActiveIndex)) {
previousActiveIndex = this.activeTabIndex;
}
return this.tabs.toArray()[previousActiveIndex].computeIndicatorClientRect();
}),
getTabDimensionsAtIndex: (/**
* @param {?} index
* @return {?}
*/
(index) => this.tabs.toArray()[index].computeDimensions()),
getPreviousActiveTabIndex: (/**
* @return {?}
*/
() => this.tabs.toArray().findIndex((/**
* @param {?} _
* @return {?}
*/
(_) => _.active))),
getFocusedTabIndex: (/**
* @return {?}
*/
() => this._platform.isBrowser ? this.tabs.toArray().findIndex((/**
* @param {?} tab
* @return {?}
*/
tab => tab.elementRef.nativeElement === (/** @type {?} */ (document.activeElement)))) : -1),
getIndexOfTabById: (/**
* @param {?} id
* @return {?}
*/
(id) => this.tabs.toArray().findIndex((/**
* @param {?} tab
* @return {?}
*/
tab => id === tab.id))),
getTabListLength: (/**
* @return {?}
*/
() => this.tabs.length),
notifyTabActivated: (/**
* @param {?} index
* @return {?}
*/
(index) => this.activated.emit({ source: this, index: index, tab: this.tabs.toArray()[index] }))
};
return new MDCTabBarFoundation(adapter);
}
/**
* @return {?}
*/
ngAfterContentInit() {
this._foundation.init();
// When the list changes, re-subscribe
this._changeSubscription = this.tabs.changes.pipe(startWith(null)).subscribe((/**
* @return {?}
*/
() => {
Promise.resolve().then((/**
* @return {?}
*/
() => {
if (this.tabs.length) {
this._syncTabs();
this.activateTab(this.activeTabIndex);
this._resetTabSubscriptions();
}
}));
}));
}
/**
* @return {?}
*/
ngOnDestroy() {
this._destroy.next();
this._destroy.complete();
if (this._changeSubscription) {
this._changeSubscription.unsubscribe();
}
this._dropSubscriptions();
}
/**
* @private
* @return {?}
*/
_syncTabs() {
if (!this.tabs) {
return;
}
this.tabs.forEach((/**
* @param {?} tab
* @return {?}
*/
tab => {
tab.stacked = this._stacked;
tab.fixed = this._fixed;
tab.tabIndicator.fade = this._fade;
tab.tabIndicator.icon = this._iconIndicator;
tab.focusOnActivate = this._focusOnActivate;
}));
}
/**
* @private
* @return {?}
*/
_resetTabSubscriptions() {
this._dropSubscriptions();
this._listenToTabInteraction();
}
/**
* @private
* @return {?}
*/
_dropSubscriptions() {
if (this._tabInteractionSubscription) {
this._tabInteractionSubscription.unsubscribe();
this._tabInteractionSubscription = null;
}
}
/**
* Listens to interaction events on each tab.
* @private
* @return {?}
*/
_listenToTabInteraction() {
this._tabInteractionSubscription = this.tabInteractions.subscribe((/**
* @param {?} event
* @return {?}
*/
event => {
/** @type {?} */
const previousTab = this.getActiveTab();
if (previousTab) {
previousTab.tabIndicator.active = false;
}
event.detail.tab.tabIndicator.active = true;
this._foundation.handleTabInteraction((/** @type {?} */ (event)));
}));
}
/**
* Activates the tab at the given index
* @param {?} index
* @return {?}
*/
activateTab(index) {
if (!this.tabs) {
return;
}
this.activeTabIndex = index;
if (this._platform.isBrowser) {
this._foundation.activateTab(index);
}
this._changeDetectorRef.markForCheck();
}
/**
* Scrolls the tab at the given index into view
* @param {?} index
* @return {?}
*/
scrollIntoView(index) {
this._foundation.scrollIntoView(index);
}
/**
* @return {?}
*/
getActiveTabIndex() {
return this.tabs.toArray().findIndex((/**
* @param {?} _
* @return {?}
*/
(_) => _.active));
}
/**
* @return {?}
*/
getActiveTab() {
return this.tabs.toArray().find((/**
* @param {?} _
* @return {?}
*/
(_) => _.active));
}
/**
* Returns an index for given tab
* @param {?} tab
* @return {?}
*/
getTabIndex(tab) {
return this.tabs.toArray().indexOf(tab);
}
/**
* Disable or enable the tab at the given index
* @param {?} index
* @param {?} disabled
* @return {?}
*/
disableTab(index, disabled) {
if (!this.tabs) {
return;
}
this.tabs.toArray()[index].disabled = coerceBooleanProperty(disabled);
}
/**
* @param {?} evt
* @return {?}
*/
_onKeydown(evt) {
this._foundation.handleKeyDown(evt);
}
/**
* @private
* @param {?} index
* @return {?}
*/
_indexIsInRange(index) {
return index >= 0 && index < this.tabs.length;
}
/**
* Retrieves the DOM element of the component host.
* @private
* @return {?}
*/
_getHostElement() {
return this.elementRef.nativeElement;
}
}
MdcTabBar.decorators = [
{ type: Component, args: [{selector: '[mdcTabBar], mdc-tab-bar',
exportAs: 'mdcTabBar',
host: {
'role': 'tablist',
'class': 'mdc-tab-bar',
'(keydown)': '_onKeydown($event)'
},
template: '<ng-content></ng-content>',
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
providers: [{ provide: MDC_TAB_BAR_PARENT_COMPONENT, useExisting: MdcTabBar }]
},] },
];
/** @nocollapse */
MdcTabBar.ctorParameters = () => [
{ type: Platform },
{ type: ChangeDetectorRef },
{ type: ElementRef }
];
MdcTabBar.propDecorators = {
fade: [{ type: Input }],
stacked: [{ type: Input }],
fixed: [{ type: Input }],
align: [{ type: Input }],
iconIndicator: [{ type: Input }],
useAutomaticActivation: [{ type: Input }],
activeTabIndex: [{ type: Input }],
focusOnActivate: [{ type: Input }],
activated: [{ type: Output }],
tabScroller: [{ type: ContentChild, args: [MdcTabScroller, { static: true },] }],
tabs: [{ type: ContentChildren, args: [MdcTab, { descendants: true },] }]
};
/**
* @fileoverview added by tsickle
* Generated from: tab-bar/module.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
class MdcTabBarModule {
}
MdcTabBarModule.decorators = [
{ type: NgModule, args: [{
imports: [
MdcTabIndicatorModule,
MdcTabModule,
MdcTabScrollerModule
],
exports: [
MdcTabBar,
MdcTabIndicatorModule,
MdcTabModule,
MdcTabScrollerModule
],
declarations: [MdcTabBar]
},] },
];
export { MdcTabActivatedEvent, MdcTabBar, MdcTabBarModule };
//# sourceMappingURL=tab-bar.js.map