UNPKG

k15t-aui-ng2

Version:

aui-ng2 is a set of angular 2 components, directives and services to simplify the integration with Atlassian products based on AUI/ADG. The library is still under development and is considered in an experimental state. So be aware that things will change

180 lines (154 loc) 5.76 kB
import {Component, Directive, Input, AfterViewInit, ElementRef, ViewChildren, QueryList} from '@angular/core'; import {FORM_DIRECTIVES} from '@angular/common'; import {AuiNgTabComponent} from './tab.component'; import {LogService} from '../common/services/log.service.ts'; import {AuiNgAutoFocusDirective} from '../common/directives/focus-element.directive'; /** * Directive to lookup the native element of the tab headers to determine the actual width. */ @Directive({ selector: '[auiNgTabHeaderElementRef]' }) export class AuiNgTabHeaderElementRefDirective { constructor( private selfElement: ElementRef ) {} getWidth() { return this.selfElement.nativeElement.getBoundingClientRect().width; } } /** * Container class to register individual tabs. * * Example to setup tabs in your template: * ... * <auiNgTabs maxWidth="500"> * <auiNgTab title="My tab" maxWidth="250" width="150"> * // ... here you can define your desired markup shown as part of the tab if it becomes visible(active) * <auiNgTab> * </auiNgTabs> * ... */ @Component({ selector: 'auiNgTabs', providers: [LogService], directives: [...FORM_DIRECTIVES, AuiNgAutoFocusDirective, AuiNgTabHeaderElementRefDirective], styles: [require('./tabs.component.css')], template: require('./tabs.component.html') }) export class AuiNgTabsComponent implements AfterViewInit { tabs: Array<AuiNgTabComponent> = []; tabsDropDown: Array<AuiNgTabComponent> = []; showOptions: boolean = false; selectedDropdownTab: AuiNgTabComponent = null; tabContainerVisibility: string = 'hidden'; maxWidthDropdownPx: number = 170; dropdownListOrientation: string = '0'; @Input() maxWidthPx; @ViewChildren(AuiNgTabHeaderElementRefDirective) tabTitles: QueryList<AuiNgTabHeaderElementRefDirective>; constructor( private logService: LogService, private selfElement: ElementRef ) {} /** * Registers a tab on the current tab container. * * @param tab tab to register. */ register(tab: AuiNgTabComponent) { if (this.tabs.length === 0) { tab.setActive(true); } this.tabs.push(tab); } /** * Sets a registered tab active to make it visible on the screen. A tab which is already active will be set inactive. * * @param tab Tab which should be set active * @returns {boolean} true if the state was changed other false e.g. in case of validation error. */ setActiveTab(tab: AuiNgTabComponent): boolean { if (this.tabs.length === 0 && this.tabsDropDown.length === 0) { this.logService.logInfo('There are no tabs registered yet and thus, nothing to activate.'); } else if (tab !== undefined && tab !== null) { this.hideDropdownOptions(); if (this.getActiveTab() !== undefined && this.getActiveTab() !== null) { this.getActiveTab().setActive(false); } return tab.setActive(true); } return false; } getActiveTab() { if (this.tabs.length === 0 && this.tabsDropDown.length === 0) { this.logService.logInfo('There are no tab registered yet and thus, there is no active tab.'); } else { for (let tab of this.tabs) { if (tab.isActive()) { return tab; } } for (let tab of this.tabsDropDown) { if (tab.isActive()) { return tab; } } return this.tabs[0]; } } ngAfterViewInit() { this.calculateTabWidth(); } showDropdownOptions() { this.showOptions = true; } hideDropdownOptions() { this.showOptions = false; } /** * Unregisters all tabs which is required for dynamic tabs. */ unregisterAllTabs() { this.hideTabs(); this.tabs = []; this.tabsDropDown = []; } hideTabs() { this.tabContainerVisibility = 'hidden'; } showTabs() { this.tabContainerVisibility = 'visible'; } calculateTabWidth() { setTimeout(() => { let widthTabsContainer; // get the current width of the overall tabs container if (this.maxWidthPx != null && this.maxWidthPx !== undefined) { widthTabsContainer = parseInt(this.maxWidthPx); } else { widthTabsContainer = this.selfElement.nativeElement.getBoundingClientRect().width; } // reserve already the width for the dropdown let currentTabsWidth = 0; let index = 0; // iterate over all registered tabs check verify the width of the tab if it is basically visible on the screen. // In case if not split the registered tabs and move the rest to the dropdown component. for (let tab of this.tabs) { let width = this.tabTitles.toArray()[index].getWidth(); if (width + currentTabsWidth > widthTabsContainer || (index !== this.tabs.length - 1 && width + currentTabsWidth + this.maxWidthDropdownPx > widthTabsContainer - 50)) { this.tabsDropDown = this.tabs.splice(index, this.tabs.length); this.selectedDropdownTab = this.tabsDropDown[0]; break; } else { currentTabsWidth += width; index++; } } if (this.tabs.length <= 2 ) { this.dropdownListOrientation = 'inherit'; } this.showTabs(); }, 100); } }