md-tabs
Version:
Angular 2 Material tabs
357 lines (355 loc) • 16.9 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var core_1 = require('@angular/core');
var common_1 = require('@angular/common');
var transclude_1 = require('./transclude');
var MdTabChangeEvent = (function () {
function MdTabChangeEvent() {
}
return MdTabChangeEvent;
}());
exports.MdTabChangeEvent = MdTabChangeEvent;
var MdTabLabel = (function () {
function MdTabLabel(templateRef) {
this.templateRef = templateRef;
}
MdTabLabel = __decorate([
core_1.Directive({ selector: '[md-tab-label]' }),
__metadata('design:paramtypes', [core_1.TemplateRef])
], MdTabLabel);
return MdTabLabel;
}());
exports.MdTabLabel = MdTabLabel;
var MdTab = (function () {
function MdTab() {
}
Object.defineProperty(MdTab.prototype, "labelTemplate", {
get: function () {
return this.tabLabel ? this.tabLabel.templateRef : null;
},
enumerable: true,
configurable: true
});
__decorate([
core_1.ContentChild(MdTabLabel),
__metadata('design:type', MdTabLabel)
], MdTab.prototype, "tabLabel", void 0);
__decorate([
core_1.Input(),
__metadata('design:type', String)
], MdTab.prototype, "label", void 0);
__decorate([
core_1.Input(),
__metadata('design:type', Boolean)
], MdTab.prototype, "active", void 0);
__decorate([
core_1.Input(),
__metadata('design:type', Boolean)
], MdTab.prototype, "disabled", void 0);
__decorate([
core_1.Input('class'),
__metadata('design:type', String)
], MdTab.prototype, "mdClass", void 0);
MdTab = __decorate([
core_1.Component({
moduleId: module.id,
selector: 'md-tab',
template: "<ng-content></ng-content>",
host: {
'[class]': 'mdClass',
'[class.md-tab]': 'true',
'[class.active]': 'active'
}
}),
__metadata('design:paramtypes', [])
], MdTab);
return MdTab;
}());
exports.MdTab = MdTab;
var MdTabs = (function () {
function MdTabs(elementRef) {
this.elementRef = elementRef;
this._isInitialized = false;
this._focusIndex = 0;
this._selectedIndex = 0;
this.shouldPaginate = false;
this.offsetLeft = 0;
this.inkBarLeft = '0';
this.inkBarWidth = '0';
this.change = new core_1.EventEmitter();
}
Object.defineProperty(MdTabs.prototype, "selectedIndex", {
get: function () { return this._selectedIndex; },
set: function (value) {
if (typeof value === 'string') {
value = parseInt(value);
}
if (value != this._selectedIndex) {
this._selectedIndex = value;
this.adjustOffset(value);
this._updateInkBar();
if (this.tabs) {
var tabs = this.tabs.toArray();
if (!tabs[value].disabled) {
tabs.forEach(function (tab) { return tab.active = false; });
tabs[value].active = true;
}
}
if (this._isInitialized) {
this.change.emit(this._createChangeEvent(value));
}
}
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdTabs.prototype, "focusIndex", {
get: function () { return this._focusIndex; },
set: function (value) {
this._focusIndex = value;
this.adjustOffset(value);
},
enumerable: true,
configurable: true
});
Object.defineProperty(MdTabs.prototype, "element", {
get: function () {
var elements = { root: this.elementRef.nativeElement, wrapper: null, canvas: null, paging: null, tabs: null };
elements.wrapper = elements.root.querySelector('.md-tabs-header-wrapper');
elements.canvas = elements.wrapper.querySelector('.md-tabs-canvas');
elements.paging = elements.canvas.querySelector('.md-tabs-header');
elements.tabs = elements.paging.querySelectorAll('.md-tab-label');
return elements;
},
enumerable: true,
configurable: true
});
/**
* After Content Init
*/
MdTabs.prototype.ngAfterContentInit = function () {
var _this = this;
setTimeout(function () {
_this.updatePagination();
}, 0);
setTimeout(function () {
var tabs = _this.tabs.toArray();
if (_this.selectedIndex) {
tabs.forEach(function (tab) { return tab.active = false; });
tabs[_this.selectedIndex].active = true;
_this.adjustOffset(_this.selectedIndex);
}
else {
var index = tabs.findIndex(function (t) { return t.active; });
if (index < 0) {
tabs[0].active = true;
}
else {
_this.selectedIndex = index;
}
}
_this._updateInkBar();
}, 0);
this._isInitialized = true;
};
/**
* Calculates the styles from the selected tab for the ink-bar.
*/
MdTabs.prototype._updateInkBar = function () {
var elements = this.element;
if (!elements.tabs[this.selectedIndex]) {
return;
}
var tab = elements.tabs[this.selectedIndex];
this.inkBarLeft = tab.offsetLeft + 'px';
this.inkBarWidth = tab.offsetWidth + 'px';
};
/**
* Create Change Event
* @param index
* @return event of MdTabChangeEvent
*/
MdTabs.prototype._createChangeEvent = function (index) {
var event = new MdTabChangeEvent;
event.index = index;
if (this.tabs && this.tabs.length) {
event.tab = this.tabs.toArray()[index];
}
return event;
};
/**
* Focus next Tab
*/
MdTabs.prototype.focusNextTab = function () { this.incrementIndex(1); };
/**
* Focus previous Tab
*/
MdTabs.prototype.focusPreviousTab = function () { this.incrementIndex(-1); };
/**
* Mouse Wheel scroll
* @param event
*/
MdTabs.prototype.scroll = function (event) {
if (!this.shouldPaginate) {
return;
}
event.preventDefault();
this.offsetLeft = this.fixOffset(this.offsetLeft - event.wheelDelta);
};
/**
* Next Page
*/
MdTabs.prototype.nextPage = function () {
var elements = this.element;
var viewportWidth = elements.canvas.clientWidth, totalWidth = viewportWidth + this.offsetLeft, i, tab;
for (i = 0; i < elements.tabs.length; i++) {
tab = elements.tabs[i];
if (tab.offsetLeft + tab.offsetWidth > totalWidth) {
break;
}
}
this.offsetLeft = this.fixOffset(tab.offsetLeft);
};
/**
* Previous Page
*/
MdTabs.prototype.previousPage = function () {
var i, tab, elements = this.element;
for (i = 0; i < elements.tabs.length; i++) {
tab = elements.tabs[i];
if (tab.offsetLeft + tab.offsetWidth >= this.offsetLeft) {
break;
}
}
this.offsetLeft = this.fixOffset(tab.offsetLeft + tab.offsetWidth - elements.canvas.clientWidth);
};
/**
* On Window Resize
* @param event
*/
MdTabs.prototype.onWindowResize = function (event) {
this.offsetLeft = this.fixOffset(this.offsetLeft);
this.updatePagination();
};
/**
* Can page Back
*/
MdTabs.prototype.canPageBack = function () { return this.offsetLeft > 0; };
/**
* Can page Previous
*/
MdTabs.prototype.canPageForward = function () {
var elements = this.element;
var lastTab = elements.tabs[elements.tabs.length - 1];
return lastTab && lastTab.offsetLeft + lastTab.offsetWidth > elements.canvas.clientWidth +
this.offsetLeft;
};
/**
* Update Pagination
*/
MdTabs.prototype.updatePagination = function () {
var canvasWidth = this.element.root.clientWidth;
this.element.tabs.forEach(function (tab) {
canvasWidth -= tab.offsetWidth;
});
this.shouldPaginate = canvasWidth < 0;
};
/**
* Increment Focus Tab
* @param inc
*/
MdTabs.prototype.incrementIndex = function (inc) {
var newIndex, index = this.focusIndex;
for (newIndex = index + inc; this.tabs.toArray()[newIndex] && this.tabs.toArray()[newIndex].disabled; newIndex += inc) { }
if (this.tabs.toArray()[newIndex]) {
this.focusIndex = newIndex;
}
};
/**
* Adjust Offset of Tab
* @param index
*/
MdTabs.prototype.adjustOffset = function (index) {
var elements = this.element;
if (!elements.tabs[index]) {
return;
}
var tab = elements.tabs[index], left = tab.offsetLeft, right = tab.offsetWidth + left;
this.offsetLeft = Math.max(this.offsetLeft, this.fixOffset(right - elements.canvas.clientWidth + 32 * 2));
this.offsetLeft = Math.min(this.offsetLeft, this.fixOffset(left));
};
/**
* Fix Offset of Tab
* @param value
* @return value
*/
MdTabs.prototype.fixOffset = function (value) {
var elements = this.element;
if (!elements.tabs.length || !this.shouldPaginate) {
return 0;
}
var lastTab = elements.tabs[elements.tabs.length - 1], totalWidth = lastTab.offsetLeft + lastTab.offsetWidth;
value = Math.max(0, value);
value = Math.min(totalWidth - elements.canvas.clientWidth, value);
return value;
};
__decorate([
core_1.ContentChildren(MdTab),
__metadata('design:type', core_1.QueryList)
], MdTabs.prototype, "tabs", void 0);
__decorate([
core_1.Input('class'),
__metadata('design:type', String)
], MdTabs.prototype, "mdClass", void 0);
__decorate([
core_1.Input(),
__metadata('design:type', Object),
__metadata('design:paramtypes', [Object])
], MdTabs.prototype, "selectedIndex", null);
__decorate([
core_1.Output(),
__metadata('design:type', core_1.EventEmitter)
], MdTabs.prototype, "change", void 0);
MdTabs = __decorate([
core_1.Component({
moduleId: module.id,
selector: 'md-tabs',
template: "\n <div class=\"md-tabs-header-wrapper\">\n <div role=\"button\" class=\"md-prev-button\" [class.disabled]=\"!canPageBack()\" *ngIf=\"shouldPaginate\" (click)=\"previousPage()\">\n <em class=\"prev-icon\">Prev</em>\n </div>\n <div role=\"button\" class=\"md-next-button\" [class.disabled]=\"!canPageForward()\" *ngIf=\"shouldPaginate\" (click)=\"nextPage()\">\n <em class=\"next-icon\">Next</em>\n </div>\n <div class=\"md-tabs-canvas\" [class.md-paginated]=\"shouldPaginate\" role=\"tablist\" tabindex=\"0\" (keydown.arrowRight)=\"focusNextTab()\" (keydown.arrowLeft)=\"focusPreviousTab()\" (keydown.enter)=\"selectedIndex = focusIndex\" (mousewheel)=\"scroll($event)\">\n <div class=\"md-tabs-header\" [style.marginLeft]=\"-offsetLeft + 'px'\">\n <div class=\"md-tab-label\" role=\"tab\" *ngFor=\"let tab of tabs; let i = index\" [class.focus]=\"focusIndex === i\" [class.active]=\"selectedIndex === i\" [class.disabled]=\"tab.disabled\" (click)=\"focusIndex = selectedIndex = i\">\n <span [mdTransclude]=\"tab.labelTemplate\">{{tab.label}}</span>\n </div>\n <div class=\"md-tab-ink-bar\" [style.left]=\"inkBarLeft\" [style.width]=\"inkBarWidth\"></div>\n </div>\n </div>\n </div>\n <div class=\"md-tabs-body-wrapper\">\n <ng-content></ng-content>\n </div>\n ",
styles: ["\n .md-tabs { position: relative; overflow: hidden; display: block; margin: 0; border: 1px solid #e1e1e1; border-radius: 2px; }\n .md-tabs-header-wrapper { position: relative; display: block; height: 48px; background: white; border-width: 0 0 1px; border-style: solid; border-color: rgba(0,0,0,0.12); display: block; margin: 0; padding: 0; list-style: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; }\n .md-tabs-header-wrapper:after { content: ''; display: table; clear: both; }\n .md-prev-button,\n .md-next-button { position: absolute; top: 0; height: 100%; width: 32px; padding: 8px 0; z-index: 2; cursor: pointer; }\n .md-prev-button { left: 0; }\n .md-next-button { right: 0; }\n .md-prev-button.disabled,\n .md-next-button.disabled { opacity: .25; cursor: default; }\n .md-prev-button .prev-icon,\n .md-next-button .next-icon { display: block; width: 12px; height: 12px; font-size: 0; border-width: 0 0 2px 2px; border-style: solid; border-color: #757575; border-radius: 1px; transform: rotate(45deg); margin: 10px; }\n .md-next-button .next-icon { border-width: 2px 2px 0 0; }\n .md-tabs-canvas { position: relative; height: 100%; overflow: hidden; display: block; outline: none; }\n .md-tabs-canvas.md-paginated { margin: 0 32px; }\n .md-tabs-header { position: relative; display: inline-block; height: 100%; white-space: nowrap; -moz-transition: 0.5s cubic-bezier(0.35,0,0.25,1); -o-transition: 0.5s cubic-bezier(0.35,0,0.25,1); -webkit-transition: 0.5s cubic-bezier(0.35,0,0.25,1); transition: 0.5s cubic-bezier(0.35,0,0.25,1); }\n .md-tab-label { position: relative; height: 100%; color: rgba(0,0,0,0.54); font-size: 14px; text-align: center; line-height: 24px; padding: 12px 24px; -moz-transition: background-color .35s cubic-bezier(.35,0,.25,1); -o-transition: background-color .35s cubic-bezier(.35,0,.25,1); -webkit-transition: background-color .35s cubic-bezier(.35,0,.25,1); transition: background-color .35s cubic-bezier(.35,0,.25,1); cursor: pointer; white-space: nowrap; text-transform: uppercase; display: inline-block; font-weight: 500; -moz-box-sizing: border-box; -webkit-box-sizing: border-box; box-sizing: border-box; overflow: hidden; -ms-text-overflow: ellipsis; -o-text-overflow: ellipsis; text-overflow: ellipsis; }\n .md-tab-label.active { color: rgb(16,108,200); }\n .md-tabs-canvas:focus .md-tab-label.focus { background: rgba(0,0,0,0.05); }\n .md-tab-label.disabled { color: rgba(0,0,0,0.26); pointer-events: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; -webkit-user-drag: none; opacity: 0.5; cursor: default; }\n .md-tab-ink-bar { position: absolute; bottom: 0; height: 2px; background: rgb(255,82,82); transition: .25s cubic-bezier(.35,0,.25,1); }\n .md-tabs-body-wrapper { position: relative; min-height: 0; display: block; clear: both; }\n .md-tab { padding: 16px; display: none; position: relative; }\n .md-tab.active { display: block; position: relative; }\n "],
host: {
'[class]': 'mdClass',
'[class.md-tabs]': 'true',
'(window:resize)': 'onWindowResize($event)'
},
encapsulation: core_1.ViewEncapsulation.None
}),
__metadata('design:paramtypes', [core_1.ElementRef])
], MdTabs);
return MdTabs;
}());
exports.MdTabs = MdTabs;
exports.TABS_DIRECTIVES = [MdTabs, MdTab, MdTabLabel];
exports.MD_TABS_DIRECTIVES = [MdTabs, MdTab, MdTabLabel, transclude_1.MdTransclude];
var MdTabsModule = (function () {
function MdTabsModule() {
}
MdTabsModule = __decorate([
core_1.NgModule({
imports: [common_1.CommonModule],
exports: exports.MD_TABS_DIRECTIVES,
declarations: exports.MD_TABS_DIRECTIVES,
}),
__metadata('design:paramtypes', [])
], MdTabsModule);
return MdTabsModule;
}());
exports.MdTabsModule = MdTabsModule;
//# sourceMappingURL=tabs.js.map