kmaterialize 2.0.0 → 2.3.3-1.0.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 (156) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +55 -91
  3. package/components/appbar/_navbar.old.scss +223 -0
  4. package/components/appbar/appbar.css +235 -0
  5. package/components/appbar/appbar.mjs +54 -0
  6. package/components/appbar/appbar.test.mjs +9 -0
  7. package/components/atomic/atomic.mjs +19 -0
  8. package/components/atomic/component.mjs +67 -0
  9. package/components/badge/_badges.scss +75 -0
  10. package/components/badge/badge.mjs +11 -0
  11. package/components/breadcrumb/_breadcrumb.scss +27 -0
  12. package/components/button/_buttons.scss +352 -0
  13. package/components/button/button.mjs +11 -0
  14. package/components/button/buttons.stories.ts +150 -0
  15. package/components/button/buttons.ts +282 -0
  16. package/components/button/examples.iso.js +18 -0
  17. package/components/button/fabSpec.js +65 -0
  18. package/components/button/test-button.mjs +16 -0
  19. package/components/card/_cards.scss +229 -0
  20. package/components/card/card.mjs +10 -0
  21. package/components/card/cards.ts +185 -0
  22. package/components/card/cardsSpec.js +269 -0
  23. package/components/carousel/_carousel.scss +93 -0
  24. package/components/carousel/_slider.scss +119 -0
  25. package/components/carousel/carousel.ts +693 -0
  26. package/components/carousel/carouselSpec.js +61 -0
  27. package/components/carousel/slider.ts +431 -0
  28. package/components/carousel/sliderSpec.js +99 -0
  29. package/components/checkbox/_checkboxes.scss +281 -0
  30. package/components/checkbox/checkbox.mdx +24 -0
  31. package/components/checkbox/checkbox.stories.ts +120 -0
  32. package/components/chip/chip.mjs +37 -0
  33. package/components/chip/chip.test.mjs +10 -0
  34. package/components/chip/chips.css +126 -0
  35. package/components/chip/chips.mdx +33 -0
  36. package/components/chip/chips.ts +440 -0
  37. package/components/chip/chipsSpec.js +165 -0
  38. package/components/chip/readme.md +323 -0
  39. package/components/collapsible/_collapsible.scss +82 -0
  40. package/components/collapsible/collapsible.ts +230 -0
  41. package/components/collapsible/collapsibleSpec.js +240 -0
  42. package/components/datepicker/_datepicker.scss +268 -0
  43. package/components/datepicker/datepicker.ts +1450 -0
  44. package/components/datepicker/datepickerSpec.js +162 -0
  45. package/components/dialog/_materialbox.scss +42 -0
  46. package/components/dialog/_modal.scss +79 -0
  47. package/components/dialog/materialbox.ts +446 -0
  48. package/components/dialog/materialboxSpec.js +37 -0
  49. package/components/dialog/modal.ts +111 -0
  50. package/components/dialog/modalSpec.js +83 -0
  51. package/components/dialog/readme.md +5 -0
  52. package/components/divider/readme.md +15 -0
  53. package/components/dropdown/_dropdown.scss +83 -0
  54. package/components/dropdown/dropdown.ts +653 -0
  55. package/components/dropdown/dropdownSpec.js +108 -0
  56. package/components/list/_collection.scss +114 -0
  57. package/components/list/_list.scss +6 -0
  58. package/components/list/list.mjs +58 -0
  59. package/components/list/list.test.mjs +16 -0
  60. package/components/loading/loading.mjs +26 -0
  61. package/components/loading/loading.test.mjs +10 -0
  62. package/components/navigation-bar/_old +582 -0
  63. package/components/navigation-bar/navigation-bar.mdx +20 -0
  64. package/components/navigation-bar/navigation-bar.stories.ts +39 -0
  65. package/components/navigation-drawer/_sidenav.scss +247 -0
  66. package/components/navigation-drawer/sidenav.ts +546 -0
  67. package/components/navigation-drawer/sidenavSpec.js +124 -0
  68. package/components/pagination/_pagination.scss +47 -0
  69. package/components/progress/_preloader.scss +416 -0
  70. package/components/radio-button/_radio-buttons.scss +112 -0
  71. package/components/radio-button/radio-buttons.mdx +28 -0
  72. package/components/radio-button/radio-buttons.stories.ts +51 -0
  73. package/components/search/autocomplete.ts +620 -0
  74. package/components/search/autocompleteSpec.js +321 -0
  75. package/components/slider/_range.scss +157 -0
  76. package/components/slider/range.ts +216 -0
  77. package/components/snackbar/_toast.scss +68 -0
  78. package/components/snackbar/toastSpec.js +132 -0
  79. package/components/snackbar/toasts.ts +312 -0
  80. package/components/switch/_switches.scss +121 -0
  81. package/components/tabs/_tabs.scss +171 -0
  82. package/components/tabs/tabs.mjs +31 -0
  83. package/components/tabs/tabs.ts +358 -0
  84. package/components/tabs/tabsSpec.js +180 -0
  85. package/components/textfield/_file-input.scss +41 -0
  86. package/components/textfield/_input-fields.scss +368 -0
  87. package/components/textfield/_select.scss +104 -0
  88. package/components/textfield/formfields.css +311 -0
  89. package/components/textfield/forms.ts +182 -0
  90. package/components/textfield/formsSpec.js +142 -0
  91. package/components/textfield/select.ts +472 -0
  92. package/components/textfield/selectSpec.js +390 -0
  93. package/components/textfield/textfield.mjs +29 -0
  94. package/components/textfield/textfield.test.mjs +10 -0
  95. package/components/timepicker/_timepicker.scss +362 -0
  96. package/components/timepicker/timepicker.ts +905 -0
  97. package/components/tooltip/_tooltip.scss +40 -0
  98. package/components/tooltip/tooltip.ts +380 -0
  99. package/components/tooltip/tooltipSpec.js +145 -0
  100. package/dist/css/materialize.colors.min.css +6 -0
  101. package/dist/css/materialize.css +7578 -6326
  102. package/dist/css/materialize.min.css +6 -13
  103. package/dist/css/materialize.min.css.map +1 -0
  104. package/dist/js/materialize.cjs.js +8410 -0
  105. package/dist/js/materialize.d.ts +2625 -0
  106. package/dist/js/materialize.js +8415 -12374
  107. package/dist/js/materialize.min.js +6 -6
  108. package/dist/js/materialize.mjs +8382 -0
  109. package/package.json +82 -47
  110. package/sass/_colors.scss +417 -0
  111. package/sass/_global.scss +490 -0
  112. package/sass/_grid.scss +172 -0
  113. package/sass/_table_of_contents.scss +28 -0
  114. package/sass/_tapTarget.scss +102 -0
  115. package/sass/_typography.scss +58 -0
  116. package/sass/_variables.scss +56 -0
  117. package/sass/colors.module.css +74 -0
  118. package/sass/materialize.scss +51 -0
  119. package/sass/mixins.module.scss +168 -0
  120. package/sass/pulse.css +35 -0
  121. package/sass/theme.module.css +140 -0
  122. package/sass/tokens.module.css +272 -0
  123. package/sass/transitions.css +10 -0
  124. package/sass/typography.module.css +150 -0
  125. package/extras/noUiSlider/nouislider.css +0 -406
  126. package/extras/noUiSlider/nouislider.js +0 -2147
  127. package/extras/noUiSlider/nouislider.min.js +0 -1
  128. package/js/anime.min.js +0 -34
  129. package/js/autocomplete.js +0 -448
  130. package/js/buttons.js +0 -354
  131. package/js/cards.js +0 -40
  132. package/js/carousel.js +0 -717
  133. package/js/cash.js +0 -960
  134. package/js/characterCounter.js +0 -136
  135. package/js/chips.js +0 -481
  136. package/js/collapsible.js +0 -275
  137. package/js/component.js +0 -44
  138. package/js/datepicker.js +0 -975
  139. package/js/dropdown.js +0 -635
  140. package/js/forms.js +0 -275
  141. package/js/global.js +0 -444
  142. package/js/materialbox.js +0 -453
  143. package/js/modal.js +0 -382
  144. package/js/parallax.js +0 -138
  145. package/js/pushpin.js +0 -148
  146. package/js/range.js +0 -263
  147. package/js/scrollspy.js +0 -295
  148. package/js/select.js +0 -450
  149. package/js/sidenav.js +0 -580
  150. package/js/slider.js +0 -359
  151. package/js/tabs.js +0 -402
  152. package/js/tapTarget.js +0 -314
  153. package/js/timepicker.js +0 -647
  154. package/js/toasts.js +0 -310
  155. package/js/tooltip.js +0 -303
  156. package/js/waves.js +0 -335
@@ -0,0 +1,61 @@
1
+ describe('Carousel', () => {
2
+ const fixture = `<div class="carousel carousel-slider" id="slider-no-wrap">
3
+ <div class="carousel-item">
4
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
5
+ </div>
6
+ <div class="carousel-item">
7
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
8
+ </div>
9
+ <div class="carousel-item">
10
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
11
+ </div>
12
+ <div class="carousel-item">
13
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
14
+ </div>
15
+ </div>`;
16
+
17
+ beforeEach(() => XloadHtml(fixture));
18
+ afterEach(() => XunloadFixtures());
19
+
20
+ describe('carousel plugin', () => {
21
+ afterEach(() => {
22
+ M.Carousel.getInstance(document.querySelector('.carousel')).destroy();
23
+ });
24
+
25
+ it('No wrap next and prev should not overflow', (done) => {
26
+ const noWrap = M.Carousel.init(document.querySelector('#slider-no-wrap'), {
27
+ duration: 10,
28
+ noWrap: true
29
+ });
30
+ noWrap.prev();
31
+ expect(noWrap.center).toEqual(0, 'Prev should do nothing');
32
+
33
+ noWrap.set(3);
34
+ setTimeout(() => {
35
+ expect(noWrap.center).toEqual(3);
36
+
37
+ noWrap.next();
38
+ setTimeout(() => {
39
+ expect(noWrap.center).toEqual(3, 'Next should do nothing');
40
+ done();
41
+ }, 30);
42
+ }, 50);
43
+ });
44
+
45
+ it('should change index and focus its respective item on indicator click', (done) => {
46
+ const carousel = M.Carousel.init(document.querySelector('.carousel'), {
47
+ duration: 10,
48
+ indicators: true
49
+ });
50
+
51
+ document.querySelectorAll('.indicator-item')[1].click();
52
+ setTimeout(() => {
53
+ expect(carousel.center).toEqual(
54
+ 1,
55
+ 'carousel item was not visible after indicator interaction'
56
+ );
57
+ done();
58
+ }, 30);
59
+ });
60
+ });
61
+ });
@@ -0,0 +1,431 @@
1
+ import { Utils } from '../../src/utils';
2
+ import { Component, BaseOptions, InitElements, MElement } from '../../src/component';
3
+
4
+ export interface SliderOptions extends BaseOptions {
5
+ /**
6
+ * Set to false to hide slide indicators.
7
+ * @default true
8
+ */
9
+ indicators: boolean;
10
+ /**
11
+ * Set height of slider.
12
+ * @default 400
13
+ */
14
+ height: number;
15
+ /**
16
+ * Set the duration of the transition animation in ms.
17
+ * @default 500
18
+ */
19
+ duration: number;
20
+ /**
21
+ * Set the duration between transitions in ms.
22
+ * @default 6000
23
+ */
24
+ interval: number;
25
+ /**
26
+ * If slider should pause when keyboard focus is received.
27
+ * @default true
28
+ */
29
+ pauseOnFocus: boolean;
30
+ /**
31
+ * If slider should pause when is hovered by a pointer.
32
+ * @default true
33
+ */
34
+ pauseOnHover: boolean;
35
+ /**
36
+ * Optional function used to generate ARIA label to indicators (for accessibility purposes).
37
+ * @param index Current index, starting from "1".
38
+ * @param current A which indicates whether it is the current element or not
39
+ * @returns a string to be used as label indicator.
40
+ * @default null
41
+ */
42
+ indicatorLabelFunc: (index: number, current: boolean) => string;
43
+ }
44
+
45
+ const _defaults: SliderOptions = {
46
+ indicators: true,
47
+ height: 400,
48
+ duration: 500,
49
+ interval: 6000,
50
+ pauseOnFocus: true,
51
+ pauseOnHover: true,
52
+ indicatorLabelFunc: null // Function which will generate a label for the indicators (ARIA)
53
+ };
54
+
55
+ export class Slider extends Component<SliderOptions> {
56
+ /** Index of current slide. */
57
+ activeIndex: number;
58
+ interval: string | number | NodeJS.Timeout;
59
+ eventPause: boolean;
60
+ _slider: HTMLUListElement;
61
+ _slides: HTMLLIElement[];
62
+ _activeSlide: HTMLLIElement;
63
+ _indicators: HTMLLIElement[];
64
+ _hovered: boolean;
65
+ _focused: boolean;
66
+ _focusCurrent: boolean;
67
+ _sliderId: string;
68
+
69
+ constructor(el: HTMLElement, options: Partial<SliderOptions>) {
70
+ super(el, options, Slider);
71
+ this.el['M_Slider'] = this;
72
+
73
+ this.options = {
74
+ ...Slider.defaults,
75
+ ...options
76
+ };
77
+
78
+ // init props
79
+ this.interval = null;
80
+ this.eventPause = false;
81
+ this._hovered = false;
82
+ this._focused = false;
83
+ this._focusCurrent = false;
84
+
85
+ // setup
86
+ this._slider = this.el.querySelector('.slides');
87
+ this._slides = Array.from(this._slider.querySelectorAll('li'));
88
+ this.activeIndex = this._slides.findIndex((li) => li.classList.contains('active'));
89
+
90
+ if (this.activeIndex !== -1) {
91
+ this._activeSlide = this._slides[this.activeIndex];
92
+ }
93
+
94
+ this._setSliderHeight();
95
+
96
+ // Sets element id if it does not have one
97
+ if (this._slider.hasAttribute('id')) this._sliderId = this._slider.getAttribute('id');
98
+ else {
99
+ this._sliderId = 'slider-' + Utils.guid();
100
+ this._slider.setAttribute('id', this._sliderId);
101
+ }
102
+
103
+ const placeholderBase64 =
104
+ 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
105
+ // Set initial positions of captions
106
+ this._slides.forEach((slide) => {
107
+ // Caption
108
+ //const caption = <HTMLElement|null>slide.querySelector('.caption');
109
+ //if (caption) this._animateCaptionIn(caption, 0);
110
+ // Set Images as Background Images
111
+ const img = slide.querySelector('img');
112
+ if (img) {
113
+ if (img.src !== placeholderBase64) {
114
+ img.style.backgroundImage = 'url(' + img.src + ')';
115
+ img.src = placeholderBase64;
116
+ }
117
+ }
118
+ // Sets slide as focusable by code
119
+ if (!slide.hasAttribute('tabindex')) slide.setAttribute('tabindex', '-1');
120
+ // Removes initial visibility from "inactive" slides
121
+ slide.style.visibility = 'hidden';
122
+ });
123
+
124
+ this._setupIndicators();
125
+
126
+ // Show active slide
127
+ if (this._activeSlide) {
128
+ this._activeSlide.style.display = 'block';
129
+ this._activeSlide.style.visibility = 'visible';
130
+ } else {
131
+ this.activeIndex = 0;
132
+ this._slides[0].classList.add('active');
133
+ this._slides[0].style.visibility = 'visible';
134
+ this._activeSlide = this._slides[0];
135
+ this._animateSlide(this._slides[0], true);
136
+ // Update indicators
137
+ if (this.options.indicators) {
138
+ this._indicators[this.activeIndex].children[0].classList.add('active');
139
+ }
140
+ }
141
+ this._setupEventHandlers();
142
+ // auto scroll
143
+ this.start();
144
+ }
145
+
146
+ static get defaults() {
147
+ return _defaults;
148
+ }
149
+
150
+ /**
151
+ * Initializes instance of Slider.
152
+ * @param el HTML element.
153
+ * @param options Component options.
154
+ */
155
+ static init(el: HTMLElement, options?: Partial<SliderOptions>): Slider;
156
+ /**
157
+ * Initializes instances of Slider.
158
+ * @param els HTML elements.
159
+ * @param options Component options.
160
+ */
161
+ static init(els: InitElements<MElement>, options?: Partial<SliderOptions>): Slider[];
162
+ /**
163
+ * Initializes instances of Slider.
164
+ * @param els HTML elements.
165
+ * @param options Component options.
166
+ */
167
+ static init(
168
+ els: HTMLElement | InitElements<MElement>,
169
+ options: Partial<SliderOptions> = {}
170
+ ): Slider | Slider[] {
171
+ return super.init(els, options, Slider);
172
+ }
173
+
174
+ static getInstance(el: HTMLElement): Slider {
175
+ return el['M_Slider'];
176
+ }
177
+
178
+ destroy() {
179
+ this.pause();
180
+ this._removeIndicators();
181
+ this._removeEventHandlers();
182
+ this.el['M_Slider'] = undefined;
183
+ }
184
+
185
+ private _setupEventHandlers() {
186
+ if (this.options.pauseOnFocus) {
187
+ this.el.addEventListener('focusin', this._handleAutoPauseFocus);
188
+ this.el.addEventListener('focusout', this._handleAutoStartFocus);
189
+ }
190
+ if (this.options.pauseOnHover) {
191
+ this.el.addEventListener('mouseenter', this._handleAutoPauseHover);
192
+ this.el.addEventListener('mouseleave', this._handleAutoStartHover);
193
+ }
194
+ if (this.options.indicators) {
195
+ this._indicators.forEach((el) => {
196
+ el.addEventListener('click', this._handleIndicatorClick);
197
+ });
198
+ }
199
+ }
200
+
201
+ private _removeEventHandlers() {
202
+ if (this.options.pauseOnFocus) {
203
+ this.el.removeEventListener('focusin', this._handleAutoPauseFocus);
204
+ this.el.removeEventListener('focusout', this._handleAutoStartFocus);
205
+ }
206
+ if (this.options.pauseOnHover) {
207
+ this.el.removeEventListener('mouseenter', this._handleAutoPauseHover);
208
+ this.el.removeEventListener('mouseleave', this._handleAutoStartHover);
209
+ }
210
+ if (this.options.indicators) {
211
+ this._indicators.forEach((el) => {
212
+ el.removeEventListener('click', this._handleIndicatorClick);
213
+ });
214
+ }
215
+ }
216
+
217
+ private _handleIndicatorClick = (e: MouseEvent) => {
218
+ const el = (<HTMLElement>e.target).parentElement;
219
+ const currIndex = [...el.parentNode.children].indexOf(el);
220
+ this._focusCurrent = true;
221
+ this.set(currIndex);
222
+ };
223
+
224
+ private _handleAutoPauseHover = () => {
225
+ this._hovered = true;
226
+ if (this.interval != null) {
227
+ this._pause(true);
228
+ }
229
+ };
230
+
231
+ private _handleAutoPauseFocus = () => {
232
+ this._focused = true;
233
+ if (this.interval != null) {
234
+ this._pause(true);
235
+ }
236
+ };
237
+
238
+ private _handleAutoStartHover = () => {
239
+ this._hovered = false;
240
+ if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) {
241
+ this.start();
242
+ }
243
+ };
244
+
245
+ private _handleAutoStartFocus = () => {
246
+ this._focused = false;
247
+ if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
248
+ this.start();
249
+ }
250
+ };
251
+
252
+ private _handleInterval = () => {
253
+ const activeElem = this._slider.querySelector('.active');
254
+ let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem);
255
+ if (this._slides.length === newActiveIndex + 1) newActiveIndex = 0; // loop to start
256
+ else newActiveIndex += 1;
257
+ this.set(newActiveIndex);
258
+ };
259
+
260
+ private _animateSlide(slide: HTMLElement, isDirectionIn: boolean): void {
261
+ let dx = 0,
262
+ dy = 0;
263
+ // from
264
+ slide.style.opacity = isDirectionIn ? '0' : '1';
265
+ setTimeout(() => {
266
+ slide.style.transition = `opacity ${this.options.duration}ms ease`;
267
+ // to
268
+ slide.style.opacity = isDirectionIn ? '1' : '0';
269
+ }, 1);
270
+ // Caption
271
+ const caption: HTMLElement = slide.querySelector('.caption');
272
+ if (!caption) return;
273
+ if (caption.classList.contains('center-align')) dy = -100;
274
+ else if (caption.classList.contains('right-align')) dx = 100;
275
+ else if (caption.classList.contains('left-align')) dx = -100;
276
+ // from
277
+ caption.style.opacity = isDirectionIn ? '0' : '1';
278
+ caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`;
279
+ setTimeout(() => {
280
+ caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`;
281
+ // to
282
+ caption.style.opacity = isDirectionIn ? '1' : '0';
283
+ caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`;
284
+ }, this.options.duration); // delay
285
+ }
286
+
287
+ private _setSliderHeight() {
288
+ // If fullscreen, do nothing
289
+ if (!this.el.classList.contains('fullscreen')) {
290
+ if (this.options.indicators) {
291
+ // Add height if indicators are present
292
+ this.el.style.height = this.options.height + 40 + 'px'; //.css('height', this.options.height + 40 + 'px');
293
+ } else {
294
+ this.el.style.height = this.options.height + 'px';
295
+ }
296
+ this._slider.style.height = this.options.height + 'px';
297
+ }
298
+ }
299
+
300
+ private _setupIndicators() {
301
+ if (this.options.indicators) {
302
+ const ul = document.createElement('ul');
303
+ ul.classList.add('indicators');
304
+
305
+ const arrLi = [];
306
+ this._slides.forEach((el, i) => {
307
+ const label = this.options.indicatorLabelFunc
308
+ ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0)
309
+ : `${i + 1}`;
310
+ const li = document.createElement('li');
311
+ li.classList.add('indicator-item');
312
+ li.innerHTML = `<button type="button" class="indicator-item-btn" aria-label="${label}" aria-controls="${this._sliderId}"></button>`;
313
+ arrLi.push(li);
314
+ ul.append(li);
315
+ });
316
+
317
+ this.el.append(ul);
318
+ this._indicators = arrLi;
319
+ }
320
+ }
321
+
322
+ private _removeIndicators() {
323
+ this.el.querySelector('ul.indicators').remove(); //find('ul.indicators').remove();
324
+ }
325
+
326
+ set(index: number) {
327
+ // Wrap around indices.
328
+ if (index >= this._slides.length) index = 0;
329
+ else if (index < 0) index = this._slides.length - 1;
330
+
331
+ // Only do if index changes
332
+ if (this.activeIndex === index) return;
333
+
334
+ this._activeSlide = this._slides[this.activeIndex];
335
+ const _caption = <HTMLElement | null>this._activeSlide.querySelector('.caption');
336
+
337
+ this._activeSlide.classList.remove('active');
338
+ // Enables every slide
339
+ this._slides.forEach((slide) => (slide.style.visibility = 'visible'));
340
+
341
+ //--- Hide active Slide + Caption
342
+ this._activeSlide.style.opacity = '0';
343
+ setTimeout(() => {
344
+ this._slides.forEach((slide) => {
345
+ if (slide.classList.contains('active')) return;
346
+ slide.style.opacity = '0';
347
+ slide.style.transform = 'translate(0, 0)';
348
+ // Disables invisible slides (for assistive technologies)
349
+ slide.style.visibility = 'hidden';
350
+ });
351
+ }, this.options.duration);
352
+
353
+ // Hide active Caption
354
+ //this._animateCaptionIn(_caption, this.options.duration);
355
+ _caption.style.opacity = '0';
356
+
357
+ // Update indicators
358
+ if (this.options.indicators) {
359
+ const activeIndicator = this._indicators[this.activeIndex].children[0];
360
+ const nextIndicator = this._indicators[index].children[0];
361
+ activeIndicator.classList.remove('active');
362
+ nextIndicator.classList.add('active');
363
+ if (typeof this.options.indicatorLabelFunc === 'function') {
364
+ activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(
365
+ this,
366
+ this.activeIndex,
367
+ false
368
+ );
369
+ nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
370
+ }
371
+ }
372
+
373
+ //--- Show new Slide + Caption
374
+ this._animateSlide(this._slides[index], true);
375
+ this._slides[index].classList.add('active');
376
+ this.activeIndex = index;
377
+
378
+ // Reset interval, if allowed. This check prevents autostart
379
+ // when slider is paused, since it can be changed though indicators.
380
+ if (this.interval != null) {
381
+ this.start();
382
+ }
383
+ }
384
+
385
+ _pause(fromEvent: boolean) {
386
+ clearInterval(this.interval);
387
+ this.eventPause = fromEvent;
388
+ this.interval = null;
389
+ }
390
+
391
+ /**
392
+ * Pause slider autoslide.
393
+ */
394
+ pause = () => {
395
+ this._pause(false);
396
+ };
397
+
398
+ /**
399
+ * Start slider autoslide.
400
+ */
401
+ start = () => {
402
+ clearInterval(this.interval);
403
+ this.interval = setInterval(
404
+ this._handleInterval,
405
+ this.options.duration + this.options.interval
406
+ );
407
+ this.eventPause = false;
408
+ };
409
+
410
+ /**
411
+ * Move to next slider.
412
+ */
413
+ next = () => {
414
+ let newIndex = this.activeIndex + 1;
415
+ // Wrap around indices.
416
+ if (newIndex >= this._slides.length) newIndex = 0;
417
+ else if (newIndex < 0) newIndex = this._slides.length - 1;
418
+ this.set(newIndex);
419
+ };
420
+
421
+ /**
422
+ * Move to prev slider.
423
+ */
424
+ prev = () => {
425
+ let newIndex = this.activeIndex - 1;
426
+ // Wrap around indices.
427
+ if (newIndex >= this._slides.length) newIndex = 0;
428
+ else if (newIndex < 0) newIndex = this._slides.length - 1;
429
+ this.set(newIndex);
430
+ };
431
+ }
@@ -0,0 +1,99 @@
1
+ describe('Slider Plugin:', () => {
2
+ const fixture = `<div class="slider simple-slider">
3
+ <ul class="slides">
4
+ <li>
5
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="First slide">
6
+ <div class="caption center-align">
7
+ <h3>This is our big Tagline!</h3>
8
+ <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
9
+ </div>
10
+ </li>
11
+ <li>
12
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Second slide">
13
+ <div class="caption left-align">
14
+ <h3>Left Aligned Caption</h3>
15
+ <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
16
+ </div>
17
+ </li>
18
+ <li>
19
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Third slide">
20
+ <div class="caption right-align">
21
+ <h3>Right Aligned Caption</h3>
22
+ <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
23
+ </div>
24
+ </li>
25
+ <li>
26
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==" alt="Fourth slide">
27
+ <div class="caption center-align">
28
+ <h3>This is our big Tagline!</h3>
29
+ <h5 class="light grey-text text-lighten-3">Here's our small slogan.</h5>
30
+ </div>
31
+ </li>
32
+ </ul>
33
+ </div>`;
34
+
35
+ beforeEach(() => XloadHtml(fixture));
36
+ afterEach(() => XunloadFixtures());
37
+
38
+ describe('Slider:', () => {
39
+ let slider;
40
+
41
+ beforeEach(() => {
42
+ slider = M.Slider.init(document.querySelector('.slider'), {
43
+ interval: 100,
44
+ duration: 0, // transition
45
+ pauseOnFocus: true,
46
+ indicatorLabelFunc: (idx) => 'Slide ' + idx
47
+ });
48
+ });
49
+
50
+ afterEach(() => {
51
+ if (slider) slider.destroy();
52
+ slider = null;
53
+ });
54
+
55
+ it('should change after first interval', (done) => {
56
+ const O_INDEX = slider.activeIndex;
57
+ setTimeout(() => {
58
+ expect(slider.activeIndex).not.toBe(O_INDEX);
59
+ done();
60
+ }, 150);
61
+ });
62
+
63
+ it('should not change if paused', (done) => {
64
+ const O_INDEX = slider.activeIndex;
65
+ slider.pause();
66
+ setTimeout(() => {
67
+ expect(slider.activeIndex).toBe(O_INDEX);
68
+ done();
69
+ }, 200);
70
+ });
71
+
72
+ it('should not change if focused', (done) => {
73
+ const O_INDEX = slider.activeIndex;
74
+ slider.start();
75
+ slider.el.dispatchEvent(new Event('focusin'));
76
+ //focus(slider.el);
77
+ setTimeout(() => {
78
+ expect(slider.eventPause).toBe(true);
79
+ expect(slider.activeIndex).toBe(O_INDEX);
80
+ done();
81
+ }, 150);
82
+ });
83
+
84
+ it("start with 'Slide ' in indicators labels ", () => {
85
+ expect(
86
+ Array.from(document.querySelectorAll('button')).map((btn) =>
87
+ btn.getAttribute('aria-label').startsWith('Slide ')
88
+ )
89
+ ).toEqual([true, true, true, true]);
90
+ });
91
+
92
+ it('should change index and focus its respective item on indicator click', () => {
93
+ const IDX = 2;
94
+ document.querySelectorAll('button')[IDX].click();
95
+ expect(slider.activeIndex).toBe(IDX);
96
+ //expect(document.activeElement).toBe(document.querySelectorAll(".slides > li")[IDX]);
97
+ });
98
+ });
99
+ });