@materializecss/materialize 1.1.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 (83) hide show
  1. package/Gruntfile.js +38 -24
  2. package/LICENSE +21 -21
  3. package/README.md +91 -97
  4. package/dist/css/materialize.css +8608 -8631
  5. package/dist/css/materialize.min.css +12 -12
  6. package/dist/js/materialize.js +12816 -12669
  7. package/dist/js/materialize.min.js +6 -6
  8. package/extras/noUiSlider/nouislider.css +404 -406
  9. package/extras/noUiSlider/nouislider.js +2147 -2147
  10. package/extras/noUiSlider/nouislider.min.js +0 -0
  11. package/js/anime.min.js +34 -34
  12. package/js/autocomplete.js +479 -479
  13. package/js/buttons.js +354 -354
  14. package/js/cards.js +40 -40
  15. package/js/carousel.js +732 -732
  16. package/js/cash.js +960 -960
  17. package/js/characterCounter.js +136 -136
  18. package/js/chips.js +486 -486
  19. package/js/collapsible.js +275 -275
  20. package/js/component.js +44 -44
  21. package/js/datepicker.js +983 -983
  22. package/js/dropdown.js +669 -669
  23. package/js/forms.js +285 -275
  24. package/js/global.js +428 -424
  25. package/js/materialbox.js +453 -453
  26. package/js/modal.js +382 -382
  27. package/js/parallax.js +138 -138
  28. package/js/pushpin.js +148 -148
  29. package/js/range.js +263 -263
  30. package/js/scrollspy.js +295 -295
  31. package/js/select.js +391 -310
  32. package/js/sidenav.js +583 -583
  33. package/js/slider.js +359 -359
  34. package/js/tabs.js +402 -402
  35. package/js/tapTarget.js +315 -315
  36. package/js/timepicker.js +712 -648
  37. package/js/toasts.js +325 -322
  38. package/js/tooltip.js +320 -320
  39. package/js/waves.js +614 -614
  40. package/package.json +87 -82
  41. package/sass/_style.scss +929 -929
  42. package/sass/components/_badges.scss +55 -55
  43. package/sass/components/_buttons.scss +322 -322
  44. package/sass/components/_cards.scss +195 -195
  45. package/sass/components/_carousel.scss +90 -90
  46. package/sass/components/_chips.scss +96 -96
  47. package/sass/components/_collapsible.scss +91 -91
  48. package/sass/components/_collection.scss +106 -106
  49. package/sass/components/_color-classes.scss +32 -32
  50. package/sass/components/_color-variables.scss +370 -370
  51. package/sass/components/_datepicker.scss +191 -191
  52. package/sass/components/_dropdown.scss +84 -84
  53. package/sass/components/_global.scss +646 -642
  54. package/sass/components/_grid.scss +158 -158
  55. package/sass/components/_icons-material-design.scss +5 -5
  56. package/sass/components/_materialbox.scss +42 -42
  57. package/sass/components/_modal.scss +97 -97
  58. package/sass/components/_navbar.scss +208 -208
  59. package/sass/components/_normalize.scss +447 -447
  60. package/sass/components/_preloader.scss +334 -334
  61. package/sass/components/_pulse.scss +34 -34
  62. package/sass/components/_sidenav.scss +214 -214
  63. package/sass/components/_slider.scss +91 -91
  64. package/sass/components/_table_of_contents.scss +33 -33
  65. package/sass/components/_tabs.scss +99 -99
  66. package/sass/components/_tapTarget.scss +103 -103
  67. package/sass/components/_timepicker.scss +199 -183
  68. package/sass/components/_toast.scss +58 -58
  69. package/sass/components/_tooltip.scss +32 -32
  70. package/sass/components/_transitions.scss +12 -12
  71. package/sass/components/_typography.scss +62 -62
  72. package/sass/components/_variables.scss +352 -352
  73. package/sass/components/_waves.scss +187 -187
  74. package/sass/components/forms/_checkboxes.scss +200 -200
  75. package/sass/components/forms/_file-input.scss +44 -44
  76. package/sass/components/forms/_forms.scss +22 -22
  77. package/sass/components/forms/_input-fields.scss +388 -379
  78. package/sass/components/forms/_radio-buttons.scss +115 -115
  79. package/sass/components/forms/_range.scss +161 -161
  80. package/sass/components/forms/_select.scss +199 -199
  81. package/sass/components/forms/_switches.scss +91 -91
  82. package/sass/ghpages-materialize.scss +7 -7
  83. 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);