import {NgModule,Component,ElementRef,OnDestroy,Input,Output,EventEmitter,AfterContentInit,
ContentChildren,QueryList,TemplateRef,EmbeddedViewRef,ViewContainerRef,ChangeDetectorRef,ChangeDetectionStrategy, ViewEncapsulation, ViewChild, AfterViewChecked} from '@angular/core';
import {CommonModule} from '@angular/common';
import {TooltipModule} from 'mirra-ui/tooltip';
import {RippleModule} from 'mirra-ui/ripple';
import {SharedModule,PrimeTemplate} from 'mirra-ui/api';
import {BlockableUI} from 'mirra-ui/api';
import {DomHandler} from 'mirra-ui/dom';
let idx: number = 0;
@Component({
selector: 'p-tabPanel',
template: `
`
})
export class TabPanel implements AfterContentInit,OnDestroy {
@Input() header: string;
@Input() disabled: boolean;
@Input() closable: boolean;
@Input() headerStyle: any;
@Input() headerStyleClass: string;
@Input() leftIcon: string;
@Input() rightIcon: string;
@Input() cache: boolean = true;
@Input() tooltip: any;
@Input() tooltipPosition: string = 'top';
@Input() tooltipPositionStyle: string = 'absolute';
@Input() tooltipStyleClass: string;
@ContentChildren(PrimeTemplate) templates: QueryList;
constructor(public viewContainer: ViewContainerRef, private cd: ChangeDetectorRef) {}
closed: boolean;
view: EmbeddedViewRef;
_selected: boolean;
loaded: boolean;
id: string = `p-tabpanel-${idx++}`;
contentTemplate: TemplateRef;
headerTemplate: TemplateRef;
ngAfterContentInit() {
this.templates.forEach((item) => {
switch(item.getType()) {
case 'header':
this.headerTemplate = item.template;
break;
case 'content':
this.contentTemplate = item.template;
break;
default:
this.contentTemplate = item.template;
break;
}
});
}
@Input() get selected(): boolean {
return this._selected;
}
set selected(val: boolean) {
this._selected = val;
if (!this.loaded) {
this.cd.detectChanges();
}
this.loaded = true;
}
ngOnDestroy() {
this.view = null;
}
}
@Component({
selector: 'p-tabView',
template: `
`,
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
styleUrls: ['./tabview.scss']
})
export class TabView implements AfterContentInit,AfterViewChecked,BlockableUI {
@Input() orientation: string = 'top';
@Input() style: any;
@Input() styleClass: string;
@Input() controlClose: boolean;
@ViewChild('navbar') navbar: ElementRef;
@ViewChild('inkbar') inkbar: ElementRef;
@ContentChildren(TabPanel) tabPanels: QueryList;
@Output() onChange: EventEmitter = new EventEmitter();
@Output() onClose: EventEmitter = new EventEmitter();
@Output() activeIndexChange: EventEmitter = new EventEmitter();
initialized: boolean;
tabs: TabPanel[];
_activeIndex: number;
preventActiveIndexPropagation: boolean;
tabChanged: boolean;
constructor(public el: ElementRef) {}
ngAfterContentInit() {
this.initTabs();
this.tabPanels.changes.subscribe(_ => {
this.initTabs();
});
}
ngAfterViewChecked() {
if (this.tabChanged) {
this.updateInkBar();
this.tabChanged = false;
}
}
initTabs(): void {
this.tabs = this.tabPanels.toArray();
let selectedTab: TabPanel = this.findSelectedTab();
if (!selectedTab && this.tabs.length) {
if (this.activeIndex != null && this.tabs.length > this.activeIndex)
this.tabs[this.activeIndex].selected = true;
else
this.tabs[0].selected = true;
this.tabChanged = true;
}
}
open(event: Event, tab: TabPanel) {
if (tab.disabled) {
if (event) {
event.preventDefault();
}
return;
}
if (!tab.selected) {
let selectedTab: TabPanel = this.findSelectedTab();
if (selectedTab) {
selectedTab.selected = false
}
this.tabChanged = true;
tab.selected = true;
let selectedTabIndex = this.findTabIndex(tab);
this.preventActiveIndexPropagation = true;
this.activeIndexChange.emit(selectedTabIndex);
this.onChange.emit({originalEvent: event, index: selectedTabIndex});
}
if (event) {
event.preventDefault();
}
}
close(event: Event, tab: TabPanel) {
if (this.controlClose) {
this.onClose.emit({
originalEvent: event,
index: this.findTabIndex(tab),
close: () => {
this.closeTab(tab);
}}
);
}
else {
this.closeTab(tab);
this.onClose.emit({
originalEvent: event,
index: this.findTabIndex(tab)
});
}
event.stopPropagation();
}
closeTab(tab: TabPanel) {
if (tab.disabled) {
return;
}
if (tab.selected) {
this.tabChanged = true;
tab.selected = false;
for(let i = 0; i < this.tabs.length; i++) {
let tabPanel = this.tabs[i];
if (!tabPanel.closed&&!tab.disabled) {
tabPanel.selected = true;
break;
}
}
}
tab.closed = true;
}
findSelectedTab() {
for(let i = 0; i < this.tabs.length; i++) {
if (this.tabs[i].selected) {
return this.tabs[i];
}
}
return null;
}
findTabIndex(tab: TabPanel) {
let index = -1;
for(let i = 0; i < this.tabs.length; i++) {
if (this.tabs[i] == tab) {
index = i;
break;
}
}
return index;
}
getBlockableElement(): HTMLElement {
return this.el.nativeElement.children[0];
}
@Input() get activeIndex(): number {
return this._activeIndex;
}
set activeIndex(val:number) {
this._activeIndex = val;
if (this.preventActiveIndexPropagation) {
this.preventActiveIndexPropagation = false;
return;
}
if (this.tabs && this.tabs.length && this._activeIndex != null && this.tabs.length > this._activeIndex) {
this.findSelectedTab().selected = false;
this.tabs[this._activeIndex].selected = true;
}
}
updateInkBar() {
let tabHeader = DomHandler.findSingle(this.navbar.nativeElement, 'li.p-highlight');
this.inkbar.nativeElement.style.width = DomHandler.getWidth(tabHeader) + 'px';
this.inkbar.nativeElement.style.left = DomHandler.getOffset(tabHeader).left - DomHandler.getOffset(this.navbar.nativeElement).left + 'px';
}
}
@NgModule({
imports: [CommonModule,SharedModule,TooltipModule,RippleModule],
exports: [TabView,TabPanel,SharedModule],
declarations: [TabView,TabPanel]
})
export class TabViewModule { }