3 Polymer('paper-tabs',Polymer.mixin({
6 * If true, ink ripple effect is disabled.
15 * If true, the bottom bar to indicate the selected tab will not be shown.
24 * If true, the slide effect for the bottom bar is disabled.
33 * If true, tabs are scrollable and the tab width is based on the label width.
35 * @attribute scrollable
42 * If true, dragging on the tabs to scroll is disabled.
44 * @attribute disableDrag
51 * If true, scroll buttons (left/right arrow) will be hidden for scrollable tabs.
53 * @attribute hideScrollButton
57 hideScrollButton: false,
60 'core-resize': 'resizeHandler'
71 this._trackxHandler = this.trackx.bind(this);
72 Polymer.addEventListener(this.$.tabsContainer, 'trackx', this._trackxHandler);
73 this._tabsObserver = new MutationObserver(this.updateBar.bind(this));
76 domReady: function() {
77 this.async('resizeHandler');
78 this._tabsObserver.observe(this, {childList: true, subtree: true, characterData: true});
81 attached: function() {
82 this.resizableAttachedHandler();
85 detached: function() {
86 Polymer.removeEventListener(this.$.tabsContainer, 'trackx', this._trackxHandler);
87 this._tabsObserver.disconnect();
88 this.resizableDetachedHandler();
91 trackStart: function(e) {
92 if (!this.scrollable || this.disableDrag) {
96 if (t && t.cancelRipple) {
99 this._startx = this.$.tabsContainer.scrollLeft;
103 trackx: function(e) {
104 if (!this.scrollable || this.disableDrag) {
107 this.$.tabsContainer.scrollLeft = this._startx - e.dx;
110 resizeHandler: function() {
116 if (!this.scrollable) {
119 var tc = this.$.tabsContainer;
120 var l = tc.scrollLeft;
121 this.leftHidden = l === 0;
122 this.rightHidden = l === (tc.scrollWidth - tc.clientWidth);
125 holdLeft: function() {
126 this.holdJob = setInterval(this.scrollToLeft.bind(this), this.holdDelay);
129 holdRight: function() {
130 this.holdJob = setInterval(this.scrollToRight.bind(this), this.holdDelay);
133 releaseHold: function() {
134 clearInterval(this.holdJob);
138 scrollToLeft: function() {
139 this.$.tabsContainer.scrollLeft -= this.step;
142 scrollToRight: function() {
143 this.$.tabsContainer.scrollLeft += this.step;
147 * Invoke this to update the size and position of the bottom bar. Usually
148 * you only need to call this if the `paper-tabs` is initially hidden and
149 * later becomes visible.
153 updateBar: function() {
154 this.async('selectedItemChanged');
157 selectedItemChanged: function(old) {
158 var oldIndex = this.selectedIndex;
159 this.super(arguments);
160 var s = this.$.selectionBar.style;
162 if (!this.selectedItem) {
168 var r = this.$.tabsContent.getBoundingClientRect();
172 r = this.selectedItem.getBoundingClientRect();
175 this._sOffsetLeft = this._sl - this._l;
177 if (this.noslide || old == null) {
178 this.positionBarForSelected();
182 var oldRect = old.getBoundingClientRect();
185 this.$.selectionBar.classList.add('expand');
186 if (oldIndex < this.selectedIndex) {
187 s.width = this.calcPercent(this._sl + this._sw - oldRect.left) - m + '%';
188 this._transitionCounter = 1;
190 s.width = this.calcPercent(oldRect.left + oldRect.width - this._sl) - m + '%';
191 s.left = this.calcPercent(this._sOffsetLeft) + m + '%';
192 this._transitionCounter = 2;
194 if (this.scrollable) {
195 this.scrollToSelectedIfNeeded();
199 scrollToSelectedIfNeeded: function() {
200 var scrollLeft = this.$.tabsContainer.scrollLeft;
201 // scroll to selected if needed
202 if (this._sOffsetLeft + this._sw < scrollLeft ||
203 this._sOffsetLeft - scrollLeft > this.$.tabsContainer.offsetWidth) {
204 this.$.tabsContainer.scrollLeft = this._sOffsetLeft;
208 positionBarForSelected: function() {
209 var s = this.$.selectionBar.style;
210 s.width = this.calcPercent(this._sw) + '%';
211 s.left = this.calcPercent(this._sOffsetLeft) + '%';
214 calcPercent: function(w) {
215 return 100 * w / this._w;
218 barTransitionEnd: function(e) {
219 this._transitionCounter--;
220 var cl = this.$.selectionBar.classList;
221 if (cl.contains('expand') && !this._transitionCounter) {
224 this.positionBarForSelected();
225 } else if (cl.contains('contract')) {
226 cl.remove('contract');
230 }, Polymer.CoreResizable));