UNPKG

ag-grid

Version:

Advanced Data Grid / Data Table supporting Javascript / React / AngularJS / Web Components

154 lines (119 loc) 4.62 kB
import {Promise, Utils as _} from '../utils'; export class TabbedLayout { private eGui: HTMLElement; private eHeader: HTMLElement; private eBody: HTMLElement; private params: TabbedLayoutParams; private afterAttachedParams: any; private static TEMPLATE = '<div>'+ '<div ref="tabHeader" class="ag-tab-header"></div>'+ '<div ref="tabBody" class="ag-tab-body"></div>'+ '</div>'; private items: TabbedItemWrapper[] = []; private activeItem: TabbedItemWrapper; constructor(params: TabbedLayoutParams) { this.params = params; this.eGui = document.createElement('div'); this.eGui.innerHTML = TabbedLayout.TEMPLATE; this.eHeader = <HTMLElement> this.eGui.querySelector('[ref="tabHeader"]'); this.eBody = <HTMLElement> this.eGui.querySelector('[ref="tabBody"]'); _.addCssClass(this.eGui, params.cssClass); if (params.items) { params.items.forEach( item => this.addItem(item) ); } } public setAfterAttachedParams(params: any): void { this.afterAttachedParams = params; } public getMinWidth(): number { let eDummyContainer = document.createElement('span'); // position fixed, so it isn't restricted to the boundaries of the parent eDummyContainer.style.position = 'fixed'; // we put the dummy into the body container, so it will inherit all the // css styles that the real cells are inheriting this.eGui.appendChild(eDummyContainer); let minWidth = 0; this.items.forEach( (itemWrapper: TabbedItemWrapper) => { _.removeAllChildren(eDummyContainer); let eClone: HTMLElement = <HTMLElement> itemWrapper.tabbedItem.bodyPromise.resolveNow(null, body=>body.cloneNode(true)); if (eClone == null) { return; } eDummyContainer.appendChild(eClone); if (minWidth<eDummyContainer.offsetWidth) { minWidth = eDummyContainer.offsetWidth; } }); // finally check the parent tabs are no wider, as if they // are, then these are the min width and not the child tabs if (minWidth<this.eGui.offsetWidth) { minWidth = this.eGui.offsetWidth; } this.eGui.removeChild(eDummyContainer); return minWidth; } public showFirstItem(): void { if (this.items.length>0) { this.showItemWrapper(this.items[0]); } } private addItem(item: TabbedItem): void { let eHeaderButton = document.createElement('span'); eHeaderButton.appendChild(item.title); _.addCssClass(eHeaderButton, 'ag-tab'); this.eHeader.appendChild(eHeaderButton); let wrapper: TabbedItemWrapper = { tabbedItem: item, eHeaderButton: eHeaderButton }; this.items.push(wrapper); eHeaderButton.addEventListener('click', this.showItemWrapper.bind(this, wrapper)); } public showItem(tabbedItem: TabbedItem): void { let itemWrapper = _.find(this.items, (itemWrapper)=> { return itemWrapper.tabbedItem === tabbedItem; }); if (itemWrapper) { this.showItemWrapper(itemWrapper); } } private showItemWrapper(wrapper: TabbedItemWrapper): void { if (this.params.onItemClicked) { this.params.onItemClicked({item: wrapper.tabbedItem}); } if (this.activeItem === wrapper) { _.callIfPresent(this.params.onActiveItemClicked); return; } _.removeAllChildren(this.eBody); wrapper.tabbedItem.bodyPromise.then(body=> { this.eBody.appendChild(body); }); if (this.activeItem) { _.removeCssClass(this.activeItem.eHeaderButton, 'ag-tab-selected'); } _.addCssClass(wrapper.eHeaderButton, 'ag-tab-selected'); this.activeItem = wrapper; if (wrapper.tabbedItem.afterAttachedCallback) { wrapper.tabbedItem.afterAttachedCallback(this.afterAttachedParams); } } public getGui(): HTMLElement { return this.eGui; } } export interface TabbedLayoutParams { items: TabbedItem[]; cssClass?: string; onItemClicked?: Function; onActiveItemClicked?: Function; } export interface TabbedItem { title: Element; bodyPromise: Promise<HTMLElement>; name: string; afterAttachedCallback?: Function; } interface TabbedItemWrapper { tabbedItem: TabbedItem; eHeaderButton: HTMLElement; }