6 Polymer.IronResizableBehavior,
7 Polymer.IronMenubarBehavior
13 * If true, ink ripple effect is disabled.
21 * If true, the bottom bar to indicate the selected tab will not be shown.
29 * If true, the slide effect for the bottom bar is disabled.
37 * If true, tabs are scrollable and the tab width is based on the label width.
45 * If true, dragging on the tabs to scroll is disabled.
53 * If true, scroll buttons (left/right arrow) will be hidden for scrollable tabs.
61 * If true, the tabs are aligned to bottom (the selection bar appears at the top).
69 * Gets or sets the selected element. The default is to use the index of the item.
111 'iron-resize': '_onResize',
112 'iron-select': '_onIronSelect',
113 'iron-deselect': '_onIronDeselect'
116 _computeScrollButtonClass: function(hideThisButton, scrollable, hideScrollButtons) {
117 if (!scrollable || hideScrollButtons) {
121 if (hideThisButton) {
122 return 'not-visible';
128 _computeTabsContentClass: function(scrollable) {
129 return scrollable ? 'scrollable' : 'horizontal layout';
132 _computeSelectionBarClass: function(noBar, alignBottom) {
135 } else if (alignBottom) {
136 return 'align-bottom';
140 // TODO(cdata): Add `track` response back in when gesture lands.
142 _onResize: function() {
143 this.debounce('_onResize', function() {
145 this._tabChanged(this.selectedItem);
149 _onIronSelect: function(event) {
150 this._tabChanged(event.detail.item, this._previousTab);
151 this._previousTab = event.detail.item;
152 this.cancelDebouncer('tab-changed');
155 _onIronDeselect: function(event) {
156 this.debounce('tab-changed', function() {
157 this._tabChanged(null, this._previousTab);
158 // See polymer/polymer#1305
162 get _tabContainerScrollSize () {
165 this.$.tabsContainer.scrollWidth -
166 this.$.tabsContainer.offsetWidth
170 _scroll: function() {
173 if (!this.scrollable) {
177 scrollLeft = this.$.tabsContainer.scrollLeft;
179 this._leftHidden = scrollLeft === 0;
180 this._rightHidden = scrollLeft === this._tabContainerScrollSize;
183 _onLeftScrollButtonDown: function() {
184 this._holdJob = setInterval(this._scrollToLeft.bind(this), this._holdDelay);
187 _onRightScrollButtonDown: function() {
188 this._holdJob = setInterval(this._scrollToRight.bind(this), this._holdDelay);
191 _onScrollButtonUp: function() {
192 clearInterval(this._holdJob);
193 this._holdJob = null;
196 _scrollToLeft: function() {
197 this.$.tabsContainer.scrollLeft -= this._step;
200 _scrollToRight: function() {
201 this.$.tabsContainer.scrollLeft += this._step;
204 _tabChanged: function(tab, old) {
206 this._positionBar(0, 0);
210 var r = this.$.tabsContent.getBoundingClientRect();
212 var tabRect = tab.getBoundingClientRect();
213 var tabOffsetLeft = tabRect.left - r.left;
216 width: this._calcPercent(tabRect.width, w),
217 left: this._calcPercent(tabOffsetLeft, w)
220 if (this.noSlide || old == null) {
221 // position bar directly without animation
222 this._positionBar(this._pos.width, this._pos.left);
226 var oldRect = old.getBoundingClientRect();
227 var oldIndex = this.items.indexOf(old);
228 var index = this.items.indexOf(tab);
231 // bar animation: expand
232 this.$.selectionBar.classList.add('expand');
234 if (oldIndex < index) {
235 this._positionBar(this._calcPercent(tabRect.left + tabRect.width - oldRect.left, w) - m,
238 this._positionBar(this._calcPercent(oldRect.left + oldRect.width - tabRect.left, w) - m,
239 this._calcPercent(tabOffsetLeft, w) + m);
242 if (this.scrollable) {
243 this._scrollToSelectedIfNeeded(tabRect.width, tabOffsetLeft);
247 _scrollToSelectedIfNeeded: function(tabWidth, tabOffsetLeft) {
248 var l = tabOffsetLeft - this.$.tabsContainer.scrollLeft;
250 this.$.tabsContainer.scrollLeft += l;
252 l += (tabWidth - this.$.tabsContainer.offsetWidth);
254 this.$.tabsContainer.scrollLeft += l;
259 _calcPercent: function(w, w0) {
263 _positionBar: function(width, left) {
270 'translate3d(' + left + '%, 0, 0) scaleX(' + (width / 100) + ')',
271 this.$.selectionBar);
274 _onBarTransitionEnd: function(e) {
275 var cl = this.$.selectionBar.classList;
276 // bar animation: expand -> contract
277 if (cl.contains('expand')) {
280 this._positionBar(this._pos.width, this._pos.left);
281 // bar animation done
282 } else if (cl.contains('contract')) {
283 cl.remove('contract');