@materializecss/materialize 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/Gruntfile.js +722 -712
  2. package/LICENSE +21 -21
  3. package/README.md +91 -91
  4. package/dist/css/materialize.css +68 -135
  5. package/dist/css/materialize.min.css +12 -12
  6. package/dist/js/materialize.js +1112 -1112
  7. package/dist/js/materialize.min.js +6 -6
  8. package/extras/noUiSlider/nouislider.css +403 -403
  9. package/extras/noUiSlider/nouislider.js +2147 -2147
  10. package/js/anime.min.js +34 -34
  11. package/js/autocomplete.js +479 -479
  12. package/js/buttons.js +354 -354
  13. package/js/cards.js +40 -40
  14. package/js/carousel.js +732 -732
  15. package/js/cash.js +960 -960
  16. package/js/characterCounter.js +136 -136
  17. package/js/chips.js +486 -486
  18. package/js/collapsible.js +275 -275
  19. package/js/component.js +44 -44
  20. package/js/datepicker.js +983 -983
  21. package/js/dropdown.js +669 -669
  22. package/js/forms.js +285 -285
  23. package/js/global.js +428 -428
  24. package/js/materialbox.js +453 -453
  25. package/js/modal.js +382 -382
  26. package/js/parallax.js +138 -138
  27. package/js/pushpin.js +148 -148
  28. package/js/range.js +263 -263
  29. package/js/scrollspy.js +295 -295
  30. package/js/select.js +391 -391
  31. package/js/sidenav.js +583 -583
  32. package/js/slider.js +359 -359
  33. package/js/tabs.js +402 -402
  34. package/js/tapTarget.js +315 -315
  35. package/js/timepicker.js +712 -712
  36. package/js/toasts.js +325 -325
  37. package/js/tooltip.js +320 -320
  38. package/js/waves.js +614 -614
  39. package/package.json +87 -84
  40. package/sass/_style.scss +929 -929
  41. package/sass/components/_badges.scss +55 -55
  42. package/sass/components/_buttons.scss +322 -322
  43. package/sass/components/_cards.scss +195 -195
  44. package/sass/components/_carousel.scss +90 -90
  45. package/sass/components/_chips.scss +96 -96
  46. package/sass/components/_collapsible.scss +91 -91
  47. package/sass/components/_collection.scss +106 -106
  48. package/sass/components/_color-classes.scss +32 -32
  49. package/sass/components/_color-variables.scss +370 -370
  50. package/sass/components/_datepicker.scss +191 -191
  51. package/sass/components/_dropdown.scss +84 -84
  52. package/sass/components/_global.scss +646 -646
  53. package/sass/components/_grid.scss +158 -158
  54. package/sass/components/_icons-material-design.scss +5 -5
  55. package/sass/components/_materialbox.scss +42 -42
  56. package/sass/components/_modal.scss +97 -97
  57. package/sass/components/_navbar.scss +208 -208
  58. package/sass/components/_normalize.scss +447 -447
  59. package/sass/components/_preloader.scss +334 -334
  60. package/sass/components/_pulse.scss +34 -34
  61. package/sass/components/_sidenav.scss +214 -214
  62. package/sass/components/_slider.scss +91 -91
  63. package/sass/components/_table_of_contents.scss +33 -33
  64. package/sass/components/_tabs.scss +99 -99
  65. package/sass/components/_tapTarget.scss +103 -103
  66. package/sass/components/_timepicker.scss +199 -199
  67. package/sass/components/_toast.scss +58 -58
  68. package/sass/components/_tooltip.scss +32 -32
  69. package/sass/components/_transitions.scss +12 -12
  70. package/sass/components/_typography.scss +62 -62
  71. package/sass/components/_variables.scss +352 -352
  72. package/sass/components/_waves.scss +187 -187
  73. package/sass/components/forms/_checkboxes.scss +200 -200
  74. package/sass/components/forms/_file-input.scss +44 -44
  75. package/sass/components/forms/_forms.scss +22 -22
  76. package/sass/components/forms/_input-fields.scss +388 -388
  77. package/sass/components/forms/_radio-buttons.scss +115 -115
  78. package/sass/components/forms/_range.scss +161 -161
  79. package/sass/components/forms/_select.scss +199 -199
  80. package/sass/components/forms/_switches.scss +91 -91
  81. package/sass/ghpages-materialize.scss +7 -7
  82. package/sass/materialize.scss +42 -42
package/js/tabs.js CHANGED
@@ -1,402 +1,402 @@
1
- (function($, anim) {
2
- 'use strict';
3
-
4
- let _defaults = {
5
- duration: 300,
6
- onShow: null,
7
- swipeable: false,
8
- responsiveThreshold: Infinity // breakpoint for swipeable
9
- };
10
-
11
- /**
12
- * @class
13
- *
14
- */
15
- class Tabs extends Component {
16
- /**
17
- * Construct Tabs instance
18
- * @constructor
19
- * @param {Element} el
20
- * @param {Object} options
21
- */
22
- constructor(el, options) {
23
- super(Tabs, el, options);
24
-
25
- this.el.M_Tabs = this;
26
-
27
- /**
28
- * Options for the Tabs
29
- * @member Tabs#options
30
- * @prop {Number} duration
31
- * @prop {Function} onShow
32
- * @prop {Boolean} swipeable
33
- * @prop {Number} responsiveThreshold
34
- */
35
- this.options = $.extend({}, Tabs.defaults, options);
36
-
37
- // Setup
38
- this.$tabLinks = this.$el.children('li.tab').children('a');
39
- this.index = 0;
40
- this._setupActiveTabLink();
41
-
42
- // Setup tabs content
43
- if (this.options.swipeable) {
44
- this._setupSwipeableTabs();
45
- } else {
46
- this._setupNormalTabs();
47
- }
48
-
49
- // Setup tabs indicator after content to ensure accurate widths
50
- this._setTabsAndTabWidth();
51
- this._createIndicator();
52
-
53
- this._setupEventHandlers();
54
- }
55
-
56
- static get defaults() {
57
- return _defaults;
58
- }
59
-
60
- static init(els, options) {
61
- return super.init(this, els, options);
62
- }
63
-
64
- /**
65
- * Get Instance
66
- */
67
- static getInstance(el) {
68
- let domElem = !!el.jquery ? el[0] : el;
69
- return domElem.M_Tabs;
70
- }
71
-
72
- /**
73
- * Teardown component
74
- */
75
- destroy() {
76
- this._removeEventHandlers();
77
- this._indicator.parentNode.removeChild(this._indicator);
78
-
79
- if (this.options.swipeable) {
80
- this._teardownSwipeableTabs();
81
- } else {
82
- this._teardownNormalTabs();
83
- }
84
-
85
- this.$el[0].M_Tabs = undefined;
86
- }
87
-
88
- /**
89
- * Setup Event Handlers
90
- */
91
- _setupEventHandlers() {
92
- this._handleWindowResizeBound = this._handleWindowResize.bind(this);
93
- window.addEventListener('resize', this._handleWindowResizeBound);
94
-
95
- this._handleTabClickBound = this._handleTabClick.bind(this);
96
- this.el.addEventListener('click', this._handleTabClickBound);
97
- }
98
-
99
- /**
100
- * Remove Event Handlers
101
- */
102
- _removeEventHandlers() {
103
- window.removeEventListener('resize', this._handleWindowResizeBound);
104
- this.el.removeEventListener('click', this._handleTabClickBound);
105
- }
106
-
107
- /**
108
- * Handle window Resize
109
- */
110
- _handleWindowResize() {
111
- this._setTabsAndTabWidth();
112
-
113
- if (this.tabWidth !== 0 && this.tabsWidth !== 0) {
114
- this._indicator.style.left = this._calcLeftPos(this.$activeTabLink) + 'px';
115
- this._indicator.style.right = this._calcRightPos(this.$activeTabLink) + 'px';
116
- }
117
- }
118
-
119
- /**
120
- * Handle tab click
121
- * @param {Event} e
122
- */
123
- _handleTabClick(e) {
124
- let tab = $(e.target).closest('li.tab');
125
- let tabLink = $(e.target).closest('a');
126
-
127
- // Handle click on tab link only
128
- if (!tabLink.length || !tabLink.parent().hasClass('tab')) {
129
- return;
130
- }
131
-
132
- if (tab.hasClass('disabled')) {
133
- e.preventDefault();
134
- return;
135
- }
136
-
137
- // Act as regular link if target attribute is specified.
138
- if (!!tabLink.attr('target')) {
139
- return;
140
- }
141
-
142
- // Make the old tab inactive.
143
- this.$activeTabLink.removeClass('active');
144
- let $oldContent = this.$content;
145
-
146
- // Update the variables with the new link and content
147
- this.$activeTabLink = tabLink;
148
- this.$content = $(M.escapeHash(tabLink[0].hash));
149
- this.$tabLinks = this.$el.children('li.tab').children('a');
150
-
151
- // Make the tab active.
152
- this.$activeTabLink.addClass('active');
153
- let prevIndex = this.index;
154
- this.index = Math.max(this.$tabLinks.index(tabLink), 0);
155
-
156
- // Swap content
157
- if (this.options.swipeable) {
158
- if (this._tabsCarousel) {
159
- this._tabsCarousel.set(this.index, () => {
160
- if (typeof this.options.onShow === 'function') {
161
- this.options.onShow.call(this, this.$content[0]);
162
- }
163
- });
164
- }
165
- } else {
166
- if (this.$content.length) {
167
- this.$content[0].style.display = 'block';
168
- this.$content.addClass('active');
169
- if (typeof this.options.onShow === 'function') {
170
- this.options.onShow.call(this, this.$content[0]);
171
- }
172
-
173
- if ($oldContent.length && !$oldContent.is(this.$content)) {
174
- $oldContent[0].style.display = 'none';
175
- $oldContent.removeClass('active');
176
- }
177
- }
178
- }
179
-
180
- // Update widths after content is swapped (scrollbar bugfix)
181
- this._setTabsAndTabWidth();
182
-
183
- // Update indicator
184
- this._animateIndicator(prevIndex);
185
-
186
- // Prevent the anchor's default click action
187
- e.preventDefault();
188
- }
189
-
190
- /**
191
- * Generate elements for tab indicator.
192
- */
193
- _createIndicator() {
194
- let indicator = document.createElement('li');
195
- indicator.classList.add('indicator');
196
-
197
- this.el.appendChild(indicator);
198
- this._indicator = indicator;
199
-
200
- setTimeout(() => {
201
- this._indicator.style.left = this._calcLeftPos(this.$activeTabLink) + 'px';
202
- this._indicator.style.right = this._calcRightPos(this.$activeTabLink) + 'px';
203
- }, 0);
204
- }
205
-
206
- /**
207
- * Setup first active tab link.
208
- */
209
- _setupActiveTabLink() {
210
- // If the location.hash matches one of the links, use that as the active tab.
211
- this.$activeTabLink = $(this.$tabLinks.filter('[href="' + location.hash + '"]'));
212
-
213
- // If no match is found, use the first link or any with class 'active' as the initial active tab.
214
- if (this.$activeTabLink.length === 0) {
215
- this.$activeTabLink = this.$el
216
- .children('li.tab')
217
- .children('a.active')
218
- .first();
219
- }
220
- if (this.$activeTabLink.length === 0) {
221
- this.$activeTabLink = this.$el
222
- .children('li.tab')
223
- .children('a')
224
- .first();
225
- }
226
-
227
- this.$tabLinks.removeClass('active');
228
- this.$activeTabLink[0].classList.add('active');
229
-
230
- this.index = Math.max(this.$tabLinks.index(this.$activeTabLink), 0);
231
-
232
- if (this.$activeTabLink.length) {
233
- this.$content = $(M.escapeHash(this.$activeTabLink[0].hash));
234
- this.$content.addClass('active');
235
- }
236
- }
237
-
238
- /**
239
- * Setup swipeable tabs
240
- */
241
- _setupSwipeableTabs() {
242
- // Change swipeable according to responsive threshold
243
- if (window.innerWidth > this.options.responsiveThreshold) {
244
- this.options.swipeable = false;
245
- }
246
-
247
- let $tabsContent = $();
248
- this.$tabLinks.each((link) => {
249
- let $currContent = $(M.escapeHash(link.hash));
250
- $currContent.addClass('carousel-item');
251
- $tabsContent = $tabsContent.add($currContent);
252
- });
253
-
254
- let $tabsWrapper = $('<div class="tabs-content carousel carousel-slider"></div>');
255
- $tabsContent.first().before($tabsWrapper);
256
- $tabsWrapper.append($tabsContent);
257
- $tabsContent[0].style.display = '';
258
-
259
- // Keep active tab index to set initial carousel slide
260
- let activeTabIndex = this.$activeTabLink.closest('.tab').index();
261
-
262
- this._tabsCarousel = M.Carousel.init($tabsWrapper[0], {
263
- fullWidth: true,
264
- noWrap: true,
265
- onCycleTo: (item) => {
266
- let prevIndex = this.index;
267
- this.index = $(item).index();
268
- this.$activeTabLink.removeClass('active');
269
- this.$activeTabLink = this.$tabLinks.eq(this.index);
270
- this.$activeTabLink.addClass('active');
271
- this._animateIndicator(prevIndex);
272
- if (typeof this.options.onShow === 'function') {
273
- this.options.onShow.call(this, this.$content[0]);
274
- }
275
- }
276
- });
277
-
278
- // Set initial carousel slide to active tab
279
- this._tabsCarousel.set(activeTabIndex);
280
- }
281
-
282
- /**
283
- * Teardown normal tabs.
284
- */
285
- _teardownSwipeableTabs() {
286
- let $tabsWrapper = this._tabsCarousel.$el;
287
- this._tabsCarousel.destroy();
288
-
289
- // Unwrap
290
- $tabsWrapper.after($tabsWrapper.children());
291
- $tabsWrapper.remove();
292
- }
293
-
294
- /**
295
- * Setup normal tabs.
296
- */
297
- _setupNormalTabs() {
298
- // Hide Tabs Content
299
- this.$tabLinks.not(this.$activeTabLink).each((link) => {
300
- if (!!link.hash) {
301
- let $currContent = $(M.escapeHash(link.hash));
302
- if ($currContent.length) {
303
- $currContent[0].style.display = 'none';
304
- }
305
- }
306
- });
307
- }
308
-
309
- /**
310
- * Teardown normal tabs.
311
- */
312
- _teardownNormalTabs() {
313
- // show Tabs Content
314
- this.$tabLinks.each((link) => {
315
- if (!!link.hash) {
316
- let $currContent = $(M.escapeHash(link.hash));
317
- if ($currContent.length) {
318
- $currContent[0].style.display = '';
319
- }
320
- }
321
- });
322
- }
323
-
324
- /**
325
- * set tabs and tab width
326
- */
327
- _setTabsAndTabWidth() {
328
- this.tabsWidth = this.$el.width();
329
- this.tabWidth = Math.max(this.tabsWidth, this.el.scrollWidth) / this.$tabLinks.length;
330
- }
331
-
332
- /**
333
- * Finds right attribute for indicator based on active tab.
334
- * @param {cash} el
335
- */
336
- _calcRightPos(el) {
337
- return Math.ceil(this.tabsWidth - el.position().left - el[0].getBoundingClientRect().width);
338
- }
339
-
340
- /**
341
- * Finds left attribute for indicator based on active tab.
342
- * @param {cash} el
343
- */
344
- _calcLeftPos(el) {
345
- return Math.floor(el.position().left);
346
- }
347
-
348
- updateTabIndicator() {
349
- this._setTabsAndTabWidth();
350
- this._animateIndicator(this.index);
351
- }
352
-
353
- /**
354
- * Animates Indicator to active tab.
355
- * @param {Number} prevIndex
356
- */
357
- _animateIndicator(prevIndex) {
358
- let leftDelay = 0,
359
- rightDelay = 0;
360
-
361
- if (this.index - prevIndex >= 0) {
362
- leftDelay = 90;
363
- } else {
364
- rightDelay = 90;
365
- }
366
-
367
- // Animate
368
- let animOptions = {
369
- targets: this._indicator,
370
- left: {
371
- value: this._calcLeftPos(this.$activeTabLink),
372
- delay: leftDelay
373
- },
374
- right: {
375
- value: this._calcRightPos(this.$activeTabLink),
376
- delay: rightDelay
377
- },
378
- duration: this.options.duration,
379
- easing: 'easeOutQuad'
380
- };
381
- anim.remove(this._indicator);
382
- anim(animOptions);
383
- }
384
-
385
- /**
386
- * Select tab.
387
- * @param {String} tabId
388
- */
389
- select(tabId) {
390
- let tab = this.$tabLinks.filter('[href="#' + tabId + '"]');
391
- if (tab.length) {
392
- tab.trigger('click');
393
- }
394
- }
395
- }
396
-
397
- M.Tabs = Tabs;
398
-
399
- if (M.jQueryLoaded) {
400
- M.initializeJqueryWrapper(Tabs, 'tabs', 'M_Tabs');
401
- }
402
- })(cash, M.anime);
1
+ (function($, anim) {
2
+ 'use strict';
3
+
4
+ let _defaults = {
5
+ duration: 300,
6
+ onShow: null,
7
+ swipeable: false,
8
+ responsiveThreshold: Infinity // breakpoint for swipeable
9
+ };
10
+
11
+ /**
12
+ * @class
13
+ *
14
+ */
15
+ class Tabs extends Component {
16
+ /**
17
+ * Construct Tabs instance
18
+ * @constructor
19
+ * @param {Element} el
20
+ * @param {Object} options
21
+ */
22
+ constructor(el, options) {
23
+ super(Tabs, el, options);
24
+
25
+ this.el.M_Tabs = this;
26
+
27
+ /**
28
+ * Options for the Tabs
29
+ * @member Tabs#options
30
+ * @prop {Number} duration
31
+ * @prop {Function} onShow
32
+ * @prop {Boolean} swipeable
33
+ * @prop {Number} responsiveThreshold
34
+ */
35
+ this.options = $.extend({}, Tabs.defaults, options);
36
+
37
+ // Setup
38
+ this.$tabLinks = this.$el.children('li.tab').children('a');
39
+ this.index = 0;
40
+ this._setupActiveTabLink();
41
+
42
+ // Setup tabs content
43
+ if (this.options.swipeable) {
44
+ this._setupSwipeableTabs();
45
+ } else {
46
+ this._setupNormalTabs();
47
+ }
48
+
49
+ // Setup tabs indicator after content to ensure accurate widths
50
+ this._setTabsAndTabWidth();
51
+ this._createIndicator();
52
+
53
+ this._setupEventHandlers();
54
+ }
55
+
56
+ static get defaults() {
57
+ return _defaults;
58
+ }
59
+
60
+ static init(els, options) {
61
+ return super.init(this, els, options);
62
+ }
63
+
64
+ /**
65
+ * Get Instance
66
+ */
67
+ static getInstance(el) {
68
+ let domElem = !!el.jquery ? el[0] : el;
69
+ return domElem.M_Tabs;
70
+ }
71
+
72
+ /**
73
+ * Teardown component
74
+ */
75
+ destroy() {
76
+ this._removeEventHandlers();
77
+ this._indicator.parentNode.removeChild(this._indicator);
78
+
79
+ if (this.options.swipeable) {
80
+ this._teardownSwipeableTabs();
81
+ } else {
82
+ this._teardownNormalTabs();
83
+ }
84
+
85
+ this.$el[0].M_Tabs = undefined;
86
+ }
87
+
88
+ /**
89
+ * Setup Event Handlers
90
+ */
91
+ _setupEventHandlers() {
92
+ this._handleWindowResizeBound = this._handleWindowResize.bind(this);
93
+ window.addEventListener('resize', this._handleWindowResizeBound);
94
+
95
+ this._handleTabClickBound = this._handleTabClick.bind(this);
96
+ this.el.addEventListener('click', this._handleTabClickBound);
97
+ }
98
+
99
+ /**
100
+ * Remove Event Handlers
101
+ */
102
+ _removeEventHandlers() {
103
+ window.removeEventListener('resize', this._handleWindowResizeBound);
104
+ this.el.removeEventListener('click', this._handleTabClickBound);
105
+ }
106
+
107
+ /**
108
+ * Handle window Resize
109
+ */
110
+ _handleWindowResize() {
111
+ this._setTabsAndTabWidth();
112
+
113
+ if (this.tabWidth !== 0 && this.tabsWidth !== 0) {
114
+ this._indicator.style.left = this._calcLeftPos(this.$activeTabLink) + 'px';
115
+ this._indicator.style.right = this._calcRightPos(this.$activeTabLink) + 'px';
116
+ }
117
+ }
118
+
119
+ /**
120
+ * Handle tab click
121
+ * @param {Event} e
122
+ */
123
+ _handleTabClick(e) {
124
+ let tab = $(e.target).closest('li.tab');
125
+ let tabLink = $(e.target).closest('a');
126
+
127
+ // Handle click on tab link only
128
+ if (!tabLink.length || !tabLink.parent().hasClass('tab')) {
129
+ return;
130
+ }
131
+
132
+ if (tab.hasClass('disabled')) {
133
+ e.preventDefault();
134
+ return;
135
+ }
136
+
137
+ // Act as regular link if target attribute is specified.
138
+ if (!!tabLink.attr('target')) {
139
+ return;
140
+ }
141
+
142
+ // Make the old tab inactive.
143
+ this.$activeTabLink.removeClass('active');
144
+ let $oldContent = this.$content;
145
+
146
+ // Update the variables with the new link and content
147
+ this.$activeTabLink = tabLink;
148
+ this.$content = $(M.escapeHash(tabLink[0].hash));
149
+ this.$tabLinks = this.$el.children('li.tab').children('a');
150
+
151
+ // Make the tab active.
152
+ this.$activeTabLink.addClass('active');
153
+ let prevIndex = this.index;
154
+ this.index = Math.max(this.$tabLinks.index(tabLink), 0);
155
+
156
+ // Swap content
157
+ if (this.options.swipeable) {
158
+ if (this._tabsCarousel) {
159
+ this._tabsCarousel.set(this.index, () => {
160
+ if (typeof this.options.onShow === 'function') {
161
+ this.options.onShow.call(this, this.$content[0]);
162
+ }
163
+ });
164
+ }
165
+ } else {
166
+ if (this.$content.length) {
167
+ this.$content[0].style.display = 'block';
168
+ this.$content.addClass('active');
169
+ if (typeof this.options.onShow === 'function') {
170
+ this.options.onShow.call(this, this.$content[0]);
171
+ }
172
+
173
+ if ($oldContent.length && !$oldContent.is(this.$content)) {
174
+ $oldContent[0].style.display = 'none';
175
+ $oldContent.removeClass('active');
176
+ }
177
+ }
178
+ }
179
+
180
+ // Update widths after content is swapped (scrollbar bugfix)
181
+ this._setTabsAndTabWidth();
182
+
183
+ // Update indicator
184
+ this._animateIndicator(prevIndex);
185
+
186
+ // Prevent the anchor's default click action
187
+ e.preventDefault();
188
+ }
189
+
190
+ /**
191
+ * Generate elements for tab indicator.
192
+ */
193
+ _createIndicator() {
194
+ let indicator = document.createElement('li');
195
+ indicator.classList.add('indicator');
196
+
197
+ this.el.appendChild(indicator);
198
+ this._indicator = indicator;
199
+
200
+ setTimeout(() => {
201
+ this._indicator.style.left = this._calcLeftPos(this.$activeTabLink) + 'px';
202
+ this._indicator.style.right = this._calcRightPos(this.$activeTabLink) + 'px';
203
+ }, 0);
204
+ }
205
+
206
+ /**
207
+ * Setup first active tab link.
208
+ */
209
+ _setupActiveTabLink() {
210
+ // If the location.hash matches one of the links, use that as the active tab.
211
+ this.$activeTabLink = $(this.$tabLinks.filter('[href="' + location.hash + '"]'));
212
+
213
+ // If no match is found, use the first link or any with class 'active' as the initial active tab.
214
+ if (this.$activeTabLink.length === 0) {
215
+ this.$activeTabLink = this.$el
216
+ .children('li.tab')
217
+ .children('a.active')
218
+ .first();
219
+ }
220
+ if (this.$activeTabLink.length === 0) {
221
+ this.$activeTabLink = this.$el
222
+ .children('li.tab')
223
+ .children('a')
224
+ .first();
225
+ }
226
+
227
+ this.$tabLinks.removeClass('active');
228
+ this.$activeTabLink[0].classList.add('active');
229
+
230
+ this.index = Math.max(this.$tabLinks.index(this.$activeTabLink), 0);
231
+
232
+ if (this.$activeTabLink.length) {
233
+ this.$content = $(M.escapeHash(this.$activeTabLink[0].hash));
234
+ this.$content.addClass('active');
235
+ }
236
+ }
237
+
238
+ /**
239
+ * Setup swipeable tabs
240
+ */
241
+ _setupSwipeableTabs() {
242
+ // Change swipeable according to responsive threshold
243
+ if (window.innerWidth > this.options.responsiveThreshold) {
244
+ this.options.swipeable = false;
245
+ }
246
+
247
+ let $tabsContent = $();
248
+ this.$tabLinks.each((link) => {
249
+ let $currContent = $(M.escapeHash(link.hash));
250
+ $currContent.addClass('carousel-item');
251
+ $tabsContent = $tabsContent.add($currContent);
252
+ });
253
+
254
+ let $tabsWrapper = $('<div class="tabs-content carousel carousel-slider"></div>');
255
+ $tabsContent.first().before($tabsWrapper);
256
+ $tabsWrapper.append($tabsContent);
257
+ $tabsContent[0].style.display = '';
258
+
259
+ // Keep active tab index to set initial carousel slide
260
+ let activeTabIndex = this.$activeTabLink.closest('.tab').index();
261
+
262
+ this._tabsCarousel = M.Carousel.init($tabsWrapper[0], {
263
+ fullWidth: true,
264
+ noWrap: true,
265
+ onCycleTo: (item) => {
266
+ let prevIndex = this.index;
267
+ this.index = $(item).index();
268
+ this.$activeTabLink.removeClass('active');
269
+ this.$activeTabLink = this.$tabLinks.eq(this.index);
270
+ this.$activeTabLink.addClass('active');
271
+ this._animateIndicator(prevIndex);
272
+ if (typeof this.options.onShow === 'function') {
273
+ this.options.onShow.call(this, this.$content[0]);
274
+ }
275
+ }
276
+ });
277
+
278
+ // Set initial carousel slide to active tab
279
+ this._tabsCarousel.set(activeTabIndex);
280
+ }
281
+
282
+ /**
283
+ * Teardown normal tabs.
284
+ */
285
+ _teardownSwipeableTabs() {
286
+ let $tabsWrapper = this._tabsCarousel.$el;
287
+ this._tabsCarousel.destroy();
288
+
289
+ // Unwrap
290
+ $tabsWrapper.after($tabsWrapper.children());
291
+ $tabsWrapper.remove();
292
+ }
293
+
294
+ /**
295
+ * Setup normal tabs.
296
+ */
297
+ _setupNormalTabs() {
298
+ // Hide Tabs Content
299
+ this.$tabLinks.not(this.$activeTabLink).each((link) => {
300
+ if (!!link.hash) {
301
+ let $currContent = $(M.escapeHash(link.hash));
302
+ if ($currContent.length) {
303
+ $currContent[0].style.display = 'none';
304
+ }
305
+ }
306
+ });
307
+ }
308
+
309
+ /**
310
+ * Teardown normal tabs.
311
+ */
312
+ _teardownNormalTabs() {
313
+ // show Tabs Content
314
+ this.$tabLinks.each((link) => {
315
+ if (!!link.hash) {
316
+ let $currContent = $(M.escapeHash(link.hash));
317
+ if ($currContent.length) {
318
+ $currContent[0].style.display = '';
319
+ }
320
+ }
321
+ });
322
+ }
323
+
324
+ /**
325
+ * set tabs and tab width
326
+ */
327
+ _setTabsAndTabWidth() {
328
+ this.tabsWidth = this.$el.width();
329
+ this.tabWidth = Math.max(this.tabsWidth, this.el.scrollWidth) / this.$tabLinks.length;
330
+ }
331
+
332
+ /**
333
+ * Finds right attribute for indicator based on active tab.
334
+ * @param {cash} el
335
+ */
336
+ _calcRightPos(el) {
337
+ return Math.ceil(this.tabsWidth - el.position().left - el[0].getBoundingClientRect().width);
338
+ }
339
+
340
+ /**
341
+ * Finds left attribute for indicator based on active tab.
342
+ * @param {cash} el
343
+ */
344
+ _calcLeftPos(el) {
345
+ return Math.floor(el.position().left);
346
+ }
347
+
348
+ updateTabIndicator() {
349
+ this._setTabsAndTabWidth();
350
+ this._animateIndicator(this.index);
351
+ }
352
+
353
+ /**
354
+ * Animates Indicator to active tab.
355
+ * @param {Number} prevIndex
356
+ */
357
+ _animateIndicator(prevIndex) {
358
+ let leftDelay = 0,
359
+ rightDelay = 0;
360
+
361
+ if (this.index - prevIndex >= 0) {
362
+ leftDelay = 90;
363
+ } else {
364
+ rightDelay = 90;
365
+ }
366
+
367
+ // Animate
368
+ let animOptions = {
369
+ targets: this._indicator,
370
+ left: {
371
+ value: this._calcLeftPos(this.$activeTabLink),
372
+ delay: leftDelay
373
+ },
374
+ right: {
375
+ value: this._calcRightPos(this.$activeTabLink),
376
+ delay: rightDelay
377
+ },
378
+ duration: this.options.duration,
379
+ easing: 'easeOutQuad'
380
+ };
381
+ anim.remove(this._indicator);
382
+ anim(animOptions);
383
+ }
384
+
385
+ /**
386
+ * Select tab.
387
+ * @param {String} tabId
388
+ */
389
+ select(tabId) {
390
+ let tab = this.$tabLinks.filter('[href="#' + tabId + '"]');
391
+ if (tab.length) {
392
+ tab.trigger('click');
393
+ }
394
+ }
395
+ }
396
+
397
+ M.Tabs = Tabs;
398
+
399
+ if (M.jQueryLoaded) {
400
+ M.initializeJqueryWrapper(Tabs, 'tabs', 'M_Tabs');
401
+ }
402
+ })(cash, M.anime);