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,693 @@
1
+ import { Utils } from '../../src/utils';
2
+ import { Component, BaseOptions, InitElements, MElement } from '../../src/component';
3
+
4
+ export interface CarouselOptions extends BaseOptions {
5
+ /**
6
+ * Transition duration in milliseconds.
7
+ * @default 200
8
+ */
9
+ duration: number;
10
+ /**
11
+ * Perspective zoom. If 0, all items are the same size.
12
+ * @default -100
13
+ */
14
+ dist: number;
15
+ /**
16
+ * Set the spacing of the center item.
17
+ * @default 0
18
+ */
19
+ shift: number;
20
+ /**
21
+ * Set the padding between non center items.
22
+ * @default 0
23
+ */
24
+ padding: number;
25
+ /**
26
+ * Set the number of visible items.
27
+ * @default 5
28
+ */
29
+ numVisible: number;
30
+ /**
31
+ * Make the carousel a full width slider like the second example.
32
+ * @default false
33
+ */
34
+ fullWidth: boolean;
35
+ /**
36
+ * Set to true to show indicators.
37
+ * @default false
38
+ */
39
+ indicators: boolean;
40
+ /**
41
+ * Don't wrap around and cycle through items.
42
+ * @default false
43
+ */
44
+ noWrap: boolean;
45
+ /**
46
+ * Callback for when a new slide is cycled to.
47
+ * @default null
48
+ */
49
+ onCycleTo: (current: Element, dragged: boolean) => void;
50
+ }
51
+
52
+ const _defaults: CarouselOptions = {
53
+ duration: 200, // ms
54
+ dist: -100, // zoom scale TODO: make this more intuitive as an option
55
+ shift: 0, // spacing for center image
56
+ padding: 0, // Padding between non center items
57
+ numVisible: 5, // Number of visible items in carousel
58
+ fullWidth: false, // Change to full width styles
59
+ indicators: false, // Toggle indicators
60
+ noWrap: false, // Don't wrap around and cycle through items.
61
+ onCycleTo: null // Callback for when a new slide is cycled to.
62
+ };
63
+
64
+ export class Carousel extends Component<CarouselOptions> {
65
+ hasMultipleSlides: boolean;
66
+ showIndicators: boolean;
67
+ noWrap: boolean;
68
+ /** If the carousel is being clicked or tapped. */
69
+ pressed: boolean;
70
+ /** If the carousel is currently being dragged. */
71
+ dragged: boolean;
72
+ offset: number;
73
+ target: number;
74
+ images: HTMLElement[];
75
+ itemWidth: number;
76
+ itemHeight: number;
77
+ dim: number;
78
+ _indicators: HTMLUListElement;
79
+ count: number;
80
+ xform: string;
81
+ verticalDragged: boolean;
82
+ reference: number;
83
+ referenceY: number;
84
+ velocity: number;
85
+ frame: number;
86
+ timestamp: number;
87
+ ticker: string | number | NodeJS.Timeout;
88
+ amplitude: number;
89
+ /** The index of the center carousel item. */
90
+ center: number = 0;
91
+ imageHeight: number;
92
+ scrollingTimeout: number | NodeJS.Timeout;
93
+ oneTimeCallback: (current: Element, dragged: boolean) => void | null;
94
+
95
+ constructor(el: HTMLElement, options: Partial<CarouselOptions>) {
96
+ super(el, options, Carousel);
97
+ this.el['M_Carousel'] = this;
98
+
99
+ this.options = {
100
+ ...Carousel.defaults,
101
+ ...options
102
+ };
103
+
104
+ // Setup
105
+ this.hasMultipleSlides = this.el.querySelectorAll('.carousel-item').length > 1;
106
+ this.showIndicators = this.options.indicators && this.hasMultipleSlides;
107
+ this.noWrap = this.options.noWrap || !this.hasMultipleSlides;
108
+ this.pressed = false;
109
+ this.dragged = false;
110
+ this.offset = this.target = 0;
111
+ this.images = [];
112
+ this.itemWidth = this.el.querySelector('.carousel-item').clientWidth;
113
+ this.itemHeight = this.el.querySelector('.carousel-item').clientHeight;
114
+ this.dim = this.itemWidth * 2 + this.options.padding || 1; // Make sure dim is non zero for divisions.
115
+
116
+ // Full Width carousel setup
117
+ if (this.options.fullWidth) {
118
+ this.options.dist = 0;
119
+ this._setCarouselHeight();
120
+
121
+ // Offset fixed items when indicators.
122
+ if (this.showIndicators) {
123
+ this.el.querySelector('.carousel-fixed-item')?.classList.add('with-indicators');
124
+ }
125
+ }
126
+
127
+ // Iterate through slides
128
+ this._indicators = document.createElement('ul');
129
+ this._indicators.classList.add('indicators');
130
+
131
+ this.el.querySelectorAll('.carousel-item').forEach((item: HTMLElement, i) => {
132
+ this.images.push(item);
133
+ if (this.showIndicators) {
134
+ const indicator = document.createElement('li');
135
+ indicator.classList.add('indicator-item');
136
+ indicator.tabIndex = 0;
137
+ if (i === 0) {
138
+ indicator.classList.add('active');
139
+ }
140
+ this._indicators.appendChild(indicator);
141
+ }
142
+ });
143
+
144
+ if (this.showIndicators) this.el.appendChild(this._indicators);
145
+
146
+ this.count = this.images.length;
147
+
148
+ // Cap numVisible at count
149
+ this.options.numVisible = Math.min(this.count, this.options.numVisible);
150
+
151
+ // Setup cross browser string
152
+ this.xform = 'transform';
153
+ ['webkit', 'Moz', 'O', 'ms'].every((prefix) => {
154
+ const e = prefix + 'Transform';
155
+ if (typeof document.body.style[e] !== 'undefined') {
156
+ this.xform = e;
157
+ return false;
158
+ }
159
+ return true;
160
+ });
161
+
162
+ this._setupEventHandlers();
163
+ this._scroll(this.offset);
164
+ }
165
+
166
+ static get defaults(): CarouselOptions {
167
+ return _defaults;
168
+ }
169
+
170
+ /**
171
+ * Initializes instance of Carousel.
172
+ * @param el HTML element.
173
+ * @param options Component options.
174
+ */
175
+ static init(el: HTMLElement, options?: Partial<CarouselOptions>): Carousel;
176
+ /**
177
+ * Initializes instances of Carousel.
178
+ * @param els HTML elements.
179
+ * @param options Component options.
180
+ */
181
+ static init(els: InitElements<MElement>, options?: Partial<CarouselOptions>): Carousel[];
182
+ /**
183
+ * Initializes instances of Carousel.
184
+ * @param els HTML elements.
185
+ * @param options Component options.
186
+ */
187
+ static init(
188
+ els: HTMLElement | InitElements<MElement>,
189
+ options: Partial<CarouselOptions> = {}
190
+ ): Carousel | Carousel[] {
191
+ return super.init(els, options, Carousel);
192
+ }
193
+
194
+ static getInstance(el: HTMLElement): Carousel {
195
+ return el['M_Carousel'];
196
+ }
197
+
198
+ destroy() {
199
+ this._removeEventHandlers();
200
+ this.el['M_Carousel'] = undefined;
201
+ }
202
+
203
+ _setupEventHandlers() {
204
+ if (typeof window.ontouchstart !== 'undefined') {
205
+ this.el.addEventListener('touchstart', this._handleCarouselTap);
206
+ this.el.addEventListener('touchmove', this._handleCarouselDrag);
207
+ this.el.addEventListener('touchend', this._handleCarouselRelease);
208
+ }
209
+ this.el.addEventListener('mousedown', this._handleCarouselTap);
210
+ this.el.addEventListener('mousemove', this._handleCarouselDrag);
211
+ this.el.addEventListener('mouseup', this._handleCarouselRelease);
212
+ this.el.addEventListener('mouseleave', this._handleCarouselRelease);
213
+ this.el.addEventListener('click', this._handleCarouselClick);
214
+ if (this.showIndicators && this._indicators) {
215
+ this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
216
+ el.addEventListener('click', this._handleIndicatorClick);
217
+ el.addEventListener('keypress', this._handleIndicatorKeyPress);
218
+ });
219
+ }
220
+ // Resize
221
+ window.addEventListener('resize', this._handleThrottledResize);
222
+ }
223
+
224
+ _removeEventHandlers() {
225
+ if (typeof window.ontouchstart !== 'undefined') {
226
+ this.el.removeEventListener('touchstart', this._handleCarouselTap);
227
+ this.el.removeEventListener('touchmove', this._handleCarouselDrag);
228
+ this.el.removeEventListener('touchend', this._handleCarouselRelease);
229
+ }
230
+ this.el.removeEventListener('mousedown', this._handleCarouselTap);
231
+ this.el.removeEventListener('mousemove', this._handleCarouselDrag);
232
+ this.el.removeEventListener('mouseup', this._handleCarouselRelease);
233
+ this.el.removeEventListener('mouseleave', this._handleCarouselRelease);
234
+ this.el.removeEventListener('click', this._handleCarouselClick);
235
+ if (this.showIndicators && this._indicators) {
236
+ this._indicators.querySelectorAll('.indicator-item').forEach((el) => {
237
+ el.removeEventListener('click', this._handleIndicatorClick);
238
+ });
239
+ }
240
+ window.removeEventListener('resize', this._handleThrottledResize);
241
+ }
242
+
243
+ _handleThrottledResize = (): void => Utils.throttle(this._handleResize, 200, null).bind(this);
244
+
245
+ _handleCarouselTap = (e: MouseEvent | TouchEvent) => {
246
+ // Fixes firefox draggable image bug
247
+ if (e.type === 'mousedown' && (<HTMLElement>e.target).tagName === 'IMG') {
248
+ e.preventDefault();
249
+ }
250
+ this.pressed = true;
251
+ this.dragged = false;
252
+ this.verticalDragged = false;
253
+ this.reference = this._xpos(e);
254
+ this.referenceY = this._ypos(e);
255
+
256
+ this.velocity = this.amplitude = 0;
257
+ this.frame = this.offset;
258
+ this.timestamp = Date.now();
259
+ clearInterval(this.ticker);
260
+ this.ticker = setInterval(this._track, 100);
261
+ };
262
+
263
+ _handleCarouselDrag = (e: MouseEvent | TouchEvent) => {
264
+ let x: number, y: number, delta: number, deltaY: number;
265
+ if (this.pressed) {
266
+ x = this._xpos(e);
267
+ y = this._ypos(e);
268
+ delta = this.reference - x;
269
+ deltaY = Math.abs(this.referenceY - y);
270
+ if (deltaY < 30 && !this.verticalDragged) {
271
+ // If vertical scrolling don't allow dragging.
272
+ if (delta > 2 || delta < -2) {
273
+ this.dragged = true;
274
+ this.reference = x;
275
+ this._scroll(this.offset + delta);
276
+ }
277
+ } else if (this.dragged) {
278
+ // If dragging don't allow vertical scroll.
279
+ e.preventDefault();
280
+ e.stopPropagation();
281
+ return false;
282
+ } else {
283
+ // Vertical scrolling.
284
+ this.verticalDragged = true;
285
+ }
286
+ }
287
+ if (this.dragged) {
288
+ // If dragging don't allow vertical scroll.
289
+ e.preventDefault();
290
+ e.stopPropagation();
291
+ return false;
292
+ }
293
+ };
294
+
295
+ _handleCarouselRelease = (e: MouseEvent | TouchEvent) => {
296
+ if (this.pressed) {
297
+ this.pressed = false;
298
+ } else {
299
+ return;
300
+ }
301
+ clearInterval(this.ticker);
302
+ this.target = this.offset;
303
+ if (this.velocity > 10 || this.velocity < -10) {
304
+ this.amplitude = 0.9 * this.velocity;
305
+ this.target = this.offset + this.amplitude;
306
+ }
307
+ this.target = Math.round(this.target / this.dim) * this.dim;
308
+ // No wrap of items.
309
+ if (this.noWrap) {
310
+ if (this.target >= this.dim * (this.count - 1)) {
311
+ this.target = this.dim * (this.count - 1);
312
+ } else if (this.target < 0) {
313
+ this.target = 0;
314
+ }
315
+ }
316
+ this.amplitude = this.target - this.offset;
317
+ this.timestamp = Date.now();
318
+ requestAnimationFrame(this._autoScroll);
319
+ if (this.dragged) {
320
+ e.preventDefault();
321
+ e.stopPropagation();
322
+ }
323
+ return false;
324
+ };
325
+
326
+ _handleCarouselClick = (e: MouseEvent | TouchEvent) => {
327
+ // Disable clicks if carousel was dragged.
328
+ if (this.dragged) {
329
+ e.preventDefault();
330
+ e.stopPropagation();
331
+ return false;
332
+ } else if (!this.options.fullWidth) {
333
+ const clickedElem = (<HTMLElement>e.target).closest('.carousel-item');
334
+ if (!clickedElem) return;
335
+ const clickedIndex = [...clickedElem.parentNode.children].indexOf(clickedElem);
336
+ const diff = this._wrap(this.center) - clickedIndex;
337
+ // Disable clicks if carousel was shifted by click
338
+ if (diff !== 0) {
339
+ e.preventDefault();
340
+ e.stopPropagation();
341
+ }
342
+ // fixes https://github.com/materializecss/materialize/issues/180
343
+ if (clickedIndex < 0) {
344
+ // relative X position > center of carousel = clicked at the right part of the carousel
345
+ if (
346
+ (e as MouseEvent).clientX - (e.target as HTMLElement).getBoundingClientRect().left >
347
+ this.el.clientWidth / 2
348
+ ) {
349
+ this.next();
350
+ } else {
351
+ this.prev();
352
+ }
353
+ } else {
354
+ this._cycleTo(clickedIndex);
355
+ }
356
+ }
357
+ };
358
+
359
+ _handleIndicatorClick = (e: Event) => {
360
+ e.stopPropagation();
361
+ this._handleIndicatorInteraction(e);
362
+ };
363
+
364
+ _handleIndicatorKeyPress = (e: KeyboardEvent) => {
365
+ e.stopPropagation();
366
+ if (Utils.keys.ENTER.includes(e.key)) {
367
+ this._handleIndicatorInteraction(e);
368
+ }
369
+ };
370
+
371
+ _handleIndicatorInteraction = (e: Event) => {
372
+ const indicator = (<HTMLElement>e.target).closest('.indicator-item');
373
+ if (indicator) {
374
+ const index = [...indicator.parentNode.children].indexOf(indicator);
375
+ this._cycleTo(index);
376
+ }
377
+ };
378
+
379
+ _handleResize = () => {
380
+ if (this.options.fullWidth) {
381
+ this.itemWidth = this.el.querySelector('.carousel-item').clientWidth;
382
+ this.imageHeight = this.el.querySelector('.carousel-item.active').clientHeight;
383
+ this.dim = this.itemWidth * 2 + this.options.padding;
384
+ this.offset = this.center * 2 * this.itemWidth;
385
+ this.target = this.offset;
386
+ this._setCarouselHeight(true);
387
+ } else {
388
+ this._scroll();
389
+ }
390
+ };
391
+
392
+ _setCarouselHeight(imageOnly: boolean = false) {
393
+ const firstSlide = this.el.querySelector('.carousel-item.active')
394
+ ? this.el.querySelector('.carousel-item.active')
395
+ : this.el.querySelector('.carousel-item');
396
+
397
+ const firstImage = firstSlide.querySelector('img');
398
+ if (firstImage) {
399
+ if (firstImage.complete) {
400
+ // If image won't trigger the load event
401
+ const imageHeight = firstImage.clientHeight;
402
+ if (imageHeight > 0) {
403
+ this.el.style.height = imageHeight + 'px';
404
+ } else {
405
+ // If image still has no height, use the natural dimensions to calculate
406
+ const naturalWidth = firstImage.naturalWidth;
407
+ const naturalHeight = firstImage.naturalHeight;
408
+ const adjustedHeight = (this.el.clientWidth / naturalWidth) * naturalHeight;
409
+ this.el.style.height = adjustedHeight + 'px';
410
+ }
411
+ } else {
412
+ // Get height when image is loaded normally
413
+ firstImage.addEventListener('load', () => {
414
+ this.el.style.height = firstImage.offsetHeight + 'px';
415
+ });
416
+ }
417
+ } else if (!imageOnly) {
418
+ const slideHeight = firstSlide.clientHeight;
419
+ this.el.style.height = slideHeight + 'px';
420
+ }
421
+ }
422
+
423
+ _xpos(e: MouseEvent | TouchEvent) {
424
+ // touch event
425
+ if (e.type.startsWith('touch') && (e as TouchEvent).targetTouches.length >= 1) {
426
+ return (e as TouchEvent).targetTouches[0].clientX;
427
+ }
428
+ // mouse event
429
+ return (e as MouseEvent).clientX;
430
+ }
431
+
432
+ _ypos(e: MouseEvent | TouchEvent) {
433
+ // touch event
434
+ if (e.type.startsWith('touch') && (e as TouchEvent).targetTouches.length >= 1) {
435
+ return (e as TouchEvent).targetTouches[0].clientY;
436
+ }
437
+ // mouse event
438
+ return (e as MouseEvent).clientY;
439
+ }
440
+
441
+ _wrap(x: number) {
442
+ return x >= this.count ? x % this.count : x < 0 ? this._wrap(this.count + (x % this.count)) : x;
443
+ }
444
+
445
+ _track = () => {
446
+ const now: number = Date.now(),
447
+ elapsed: number = now - this.timestamp,
448
+ delta: number = this.offset - this.frame,
449
+ v: number = (1000 * delta) / (1 + elapsed);
450
+ // now = Date.now();
451
+ // elapsed = now - this.timestamp;
452
+ this.timestamp = now;
453
+ // delta = this.offset - this.frame;
454
+ this.frame = this.offset;
455
+ // v = (1000 * delta) / (1 + elapsed);
456
+ this.velocity = 0.8 * v + 0.2 * this.velocity;
457
+ };
458
+
459
+ _autoScroll = () => {
460
+ let elapsed: number, delta: number;
461
+ if (this.amplitude) {
462
+ elapsed = Date.now() - this.timestamp;
463
+ delta = this.amplitude * Math.exp(-elapsed / this.options.duration);
464
+ if (delta > 2 || delta < -2) {
465
+ this._scroll(this.target - delta);
466
+ requestAnimationFrame(this._autoScroll);
467
+ } else {
468
+ this._scroll(this.target);
469
+ }
470
+ }
471
+ };
472
+
473
+ _scroll(x: number = 0) {
474
+ // Track scrolling state
475
+ if (!this.el.classList.contains('scrolling')) {
476
+ this.el.classList.add('scrolling');
477
+ }
478
+ if (this.scrollingTimeout != null) {
479
+ clearTimeout(this.scrollingTimeout);
480
+ }
481
+ this.scrollingTimeout = setTimeout(() => {
482
+ this.el.classList.remove('scrolling');
483
+ }, this.options.duration);
484
+
485
+ // Save last center before updating the center for onCycleTo callback
486
+ const lastCenter = this.center;
487
+
488
+ // Start actual scroll
489
+ this.offset = typeof x === 'number' ? x : this.offset;
490
+ this.center = Math.floor((this.offset + this.dim / 2) / this.dim);
491
+
492
+ const half: number = this.count >> 1,
493
+ delta: number = this.offset - this.center * this.dim,
494
+ dir: number = delta < 0 ? 1 : -1,
495
+ tween: number = (-dir * delta * 2) / this.dim;
496
+ let i: number,
497
+ el: HTMLElement,
498
+ alignment: string,
499
+ zTranslation: number,
500
+ tweenedOpacity: number,
501
+ centerTweenedOpacity: number;
502
+ const numVisibleOffset = 1 / this.options.numVisible;
503
+
504
+ // delta = this.offset - this.center * this.dim;
505
+ // dir = delta < 0 ? 1 : -1;
506
+ // tween = (-dir * delta * 2) / this.dim;
507
+ // half = this.count >> 1;
508
+
509
+ if (this.options.fullWidth) {
510
+ alignment = 'translateX(0)';
511
+ centerTweenedOpacity = 1;
512
+ } else {
513
+ alignment = 'translateX(' + (this.el.clientWidth - this.itemWidth) / 2 + 'px) ';
514
+ alignment += 'translateY(' + (this.el.clientHeight - this.itemHeight) / 2 + 'px)';
515
+ centerTweenedOpacity = 1 - numVisibleOffset * tween;
516
+ }
517
+
518
+ // Set indicator active
519
+ if (this.showIndicators) {
520
+ const diff = this.center % this.count;
521
+ const activeIndicator = this._indicators.querySelector('.indicator-item.active');
522
+ const activeIndicatorIndex = [...activeIndicator.parentNode.children].indexOf(
523
+ activeIndicator
524
+ );
525
+ if (activeIndicatorIndex !== diff) {
526
+ activeIndicator.classList.remove('active');
527
+ const pos = diff < 0 ? this.count + diff : diff;
528
+ this._indicators.querySelectorAll('.indicator-item')[pos].classList.add('active');
529
+ }
530
+ }
531
+
532
+ // center
533
+ // Don't show wrapped items.
534
+ if (!this.noWrap || (this.center >= 0 && this.center < this.count)) {
535
+ el = this.images[this._wrap(this.center)];
536
+
537
+ // Add active class to center item.
538
+ if (!el.classList.contains('active')) {
539
+ this.el.querySelector('.carousel-item').classList.remove('active');
540
+ el.classList.add('active');
541
+ }
542
+
543
+ const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${
544
+ dir * this.options.shift * tween * i
545
+ }px) translateZ(${this.options.dist * tween}px)`;
546
+ this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
547
+ }
548
+
549
+ for (i = 1; i <= half; ++i) {
550
+ // right side
551
+ if (this.options.fullWidth) {
552
+ zTranslation = this.options.dist;
553
+ tweenedOpacity = i === half && delta < 0 ? 1 - tween : 1;
554
+ } else {
555
+ zTranslation = this.options.dist * (i * 2 + tween * dir);
556
+ tweenedOpacity = 1 - numVisibleOffset * (i * 2 + tween * dir);
557
+ }
558
+ // Don't show wrapped items.
559
+ if (!this.noWrap || this.center + i < this.count) {
560
+ el = this.images[this._wrap(this.center + i)];
561
+ const transformString = `${alignment} translateX(${
562
+ this.options.shift + (this.dim * i - delta) / 2
563
+ }px) translateZ(${zTranslation}px)`;
564
+ this._updateItemStyle(el, tweenedOpacity, -i, transformString);
565
+ }
566
+ // left side
567
+ if (this.options.fullWidth) {
568
+ zTranslation = this.options.dist;
569
+ tweenedOpacity = i === half && delta > 0 ? 1 - tween : 1;
570
+ } else {
571
+ zTranslation = this.options.dist * (i * 2 - tween * dir);
572
+ tweenedOpacity = 1 - numVisibleOffset * (i * 2 - tween * dir);
573
+ }
574
+ // Don't show wrapped items.
575
+ if (!this.noWrap || this.center - i >= 0) {
576
+ el = this.images[this._wrap(this.center - i)];
577
+ const transformString = `${alignment} translateX(${
578
+ -this.options.shift + (-this.dim * i - delta) / 2
579
+ }px) translateZ(${zTranslation}px)`;
580
+ this._updateItemStyle(el, tweenedOpacity, -i, transformString);
581
+ }
582
+ }
583
+ // center
584
+ // Don't show wrapped items.
585
+ if (!this.noWrap || (this.center >= 0 && this.center < this.count)) {
586
+ el = this.images[this._wrap(this.center)];
587
+ const transformString = `${alignment} translateX(${-delta / 2}px) translateX(${
588
+ dir * this.options.shift * tween
589
+ }px) translateZ(${this.options.dist * tween}px)`;
590
+ this._updateItemStyle(el, centerTweenedOpacity, 0, transformString);
591
+ }
592
+ // onCycleTo callback
593
+ const _currItem = this.el.querySelectorAll('.carousel-item')[this._wrap(this.center)];
594
+
595
+ if (lastCenter !== this.center && typeof this.options.onCycleTo === 'function') {
596
+ this.options.onCycleTo.call(this, _currItem, this.dragged);
597
+ }
598
+ // One time callback
599
+ if (typeof this.oneTimeCallback === 'function') {
600
+ this.oneTimeCallback.call(this, _currItem, this.dragged);
601
+ this.oneTimeCallback = null;
602
+ }
603
+ }
604
+
605
+ _updateItemStyle(el: HTMLElement, opacity: number, zIndex: number, transform: string) {
606
+ el.style[this.xform] = transform;
607
+ el.style.zIndex = zIndex.toString();
608
+ el.style.opacity = opacity.toString();
609
+ el.style.visibility = 'visible';
610
+ }
611
+
612
+ _cycleTo(n: number, callback: CarouselOptions['onCycleTo'] = null) {
613
+ let diff = (this.center % this.count) - n;
614
+ // Account for wraparound.
615
+ if (!this.noWrap) {
616
+ if (diff < 0) {
617
+ if (Math.abs(diff + this.count) < Math.abs(diff)) {
618
+ diff += this.count;
619
+ }
620
+ } else if (diff > 0) {
621
+ if (Math.abs(diff - this.count) < diff) {
622
+ diff -= this.count;
623
+ }
624
+ }
625
+ }
626
+ this.target = this.dim * Math.round(this.offset / this.dim);
627
+ // Next
628
+ if (diff < 0) {
629
+ this.target += this.dim * Math.abs(diff);
630
+ } // Prev
631
+ else if (diff > 0) {
632
+ this.target -= this.dim * diff;
633
+ }
634
+ // Set one time callback
635
+ if (typeof callback === 'function') {
636
+ this.oneTimeCallback = callback;
637
+ }
638
+ // Scroll
639
+ if (this.offset !== this.target) {
640
+ this.amplitude = this.target - this.offset;
641
+ this.timestamp = Date.now();
642
+ requestAnimationFrame(this._autoScroll);
643
+ }
644
+ }
645
+
646
+ /**
647
+ * Move carousel to next slide or go forward a given amount of slides.
648
+ * @param n How many times the carousel slides.
649
+ */
650
+ next(n: number = 1) {
651
+ if (n === undefined || isNaN(n)) {
652
+ n = 1;
653
+ }
654
+ let index = this.center + n;
655
+ if (index >= this.count || index < 0) {
656
+ if (this.noWrap) return;
657
+ index = this._wrap(index);
658
+ }
659
+ this._cycleTo(index);
660
+ }
661
+
662
+ /**
663
+ * Move carousel to previous slide or go back a given amount of slides.
664
+ * @param n How many times the carousel slides.
665
+ */
666
+ prev(n: number = 1) {
667
+ if (n === undefined || isNaN(n)) {
668
+ n = 1;
669
+ }
670
+ let index = this.center - n;
671
+ if (index >= this.count || index < 0) {
672
+ if (this.noWrap) return;
673
+ index = this._wrap(index);
674
+ }
675
+ this._cycleTo(index);
676
+ }
677
+
678
+ /**
679
+ * Move carousel to nth slide.
680
+ * @param n Index of slide.
681
+ * @param callback "onCycleTo" optional callback.
682
+ */
683
+ set(n: number, callback?: CarouselOptions['onCycleTo']) {
684
+ if (n === undefined || isNaN(n)) {
685
+ n = 0;
686
+ }
687
+ if (n > this.count || n < 0) {
688
+ if (this.noWrap) return;
689
+ n = this._wrap(n);
690
+ }
691
+ this._cycleTo(n, callback);
692
+ }
693
+ }