@materializecss/materialize 2.0.1-alpha → 2.0.2-alpha
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.
- package/Gruntfile.js +5 -2
- package/dist/css/materialize.css +90 -86
- package/dist/css/materialize.min.css +2 -2
- package/dist/js/materialize.js +2797 -2705
- package/dist/js/materialize.min.js +2 -8967
- package/dist/js/materialize.min.js.map +1 -1
- package/package.json +1 -1
- package/sass/components/_collapsible.scss +0 -41
- package/sass/components/_global.scss +3 -2
- package/sass/components/_icons-material-design.scss +2 -1
- package/sass/components/_navbar.scss +6 -3
- package/sass/components/_sidenav.scss +66 -37
- package/sass/components/_theme_variables.scss +2 -2
- package/sass/components/_typography.scss +2 -2
- package/sass/components/forms/_input-fields.scss +4 -10
- package/sass/materialize.scss +0 -4
- package/src/autocomplete.ts +188 -94
- package/src/buttons.ts +225 -260
- package/src/cards.ts +5 -6
- package/src/carousel.ts +611 -542
- package/src/characterCounter.ts +50 -21
- package/src/chips.ts +152 -63
- package/src/collapsible.ts +97 -32
- package/src/component.ts +99 -10
- package/src/datepicker.ts +905 -726
- package/src/dropdown.ts +576 -484
- package/src/edges.ts +4 -4
- package/src/forms.ts +17 -14
- package/src/global.ts +55 -324
- package/src/materialbox.ts +354 -298
- package/src/modal.ts +296 -211
- package/src/parallax.ts +129 -105
- package/src/pushpin.ts +148 -103
- package/src/range.ts +166 -150
- package/src/scrollspy.ts +214 -174
- package/src/select.ts +434 -398
- package/src/sidenav.ts +447 -381
- package/src/slider.ts +421 -362
- package/src/tabs.ts +276 -222
- package/src/tapTarget.ts +246 -213
- package/src/timepicker.ts +738 -614
- package/src/toasts.ts +254 -230
- package/src/tooltip.ts +315 -252
- package/src/utils.ts +271 -0
- package/src/waves.ts +10 -10
package/src/slider.ts
CHANGED
|
@@ -1,415 +1,474 @@
|
|
|
1
|
-
import { Component } from "./component";
|
|
2
|
-
import { M } from "./global";
|
|
3
1
|
import anim from "animejs";
|
|
4
2
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
3
|
+
import { Utils } from "./utils";
|
|
4
|
+
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
5
|
+
|
|
6
|
+
export interface SliderOptions extends BaseOptions {
|
|
7
|
+
/**
|
|
8
|
+
* Set to false to hide slide indicators.
|
|
9
|
+
* @default true
|
|
10
|
+
*/
|
|
11
|
+
indicators: boolean;
|
|
12
|
+
/**
|
|
13
|
+
* Set height of slider.
|
|
14
|
+
* @default 400
|
|
15
|
+
*/
|
|
16
|
+
height: number;
|
|
17
|
+
/**
|
|
18
|
+
* Set the duration of the transition animation in ms.
|
|
19
|
+
* @default 500
|
|
20
|
+
*/
|
|
21
|
+
duration: number;
|
|
22
|
+
/**
|
|
23
|
+
* Set the duration between transitions in ms.
|
|
24
|
+
* @default 6000
|
|
25
|
+
*/
|
|
26
|
+
interval: number;
|
|
27
|
+
/**
|
|
28
|
+
* If slider should pause when keyboard focus is received.
|
|
29
|
+
* @default true
|
|
30
|
+
*/
|
|
31
|
+
pauseOnFocus: boolean;
|
|
32
|
+
/**
|
|
33
|
+
* If slider should pause when is hovered by a pointer.
|
|
34
|
+
* @default true
|
|
35
|
+
*/
|
|
36
|
+
pauseOnHover: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Optional function used to generate ARIA label to indicators (for accessibility purposes).
|
|
39
|
+
* @param index Current index, starting from "1".
|
|
40
|
+
* @param current A which indicates whether it is the current element or not
|
|
41
|
+
* @returns a string to be used as label indicator.
|
|
42
|
+
* @default null
|
|
43
|
+
*/
|
|
44
|
+
indicatorLabelFunc: (index: number, current: boolean) => string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
let _defaults: SliderOptions = {
|
|
48
|
+
indicators: true,
|
|
49
|
+
height: 400,
|
|
50
|
+
duration: 500,
|
|
51
|
+
interval: 6000,
|
|
52
|
+
pauseOnFocus: true,
|
|
53
|
+
pauseOnHover: true,
|
|
54
|
+
indicatorLabelFunc: null // Function which will generate a label for the indicators (ARIA)
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
export class Slider extends Component<SliderOptions> {
|
|
58
|
+
/** Index of current slide. */
|
|
59
|
+
activeIndex: number;
|
|
60
|
+
interval: string | number | NodeJS.Timeout;
|
|
61
|
+
eventPause: any;
|
|
62
|
+
_slider: HTMLUListElement;
|
|
63
|
+
_slides: HTMLLIElement[];
|
|
64
|
+
_activeSlide: HTMLLIElement;
|
|
65
|
+
_indicators: HTMLLIElement[];
|
|
66
|
+
_hovered: boolean;
|
|
67
|
+
_focused: boolean;
|
|
68
|
+
_focusCurrent: boolean;
|
|
69
|
+
_sliderId: string;
|
|
70
|
+
|
|
71
|
+
constructor(el: HTMLElement, options: Partial<SliderOptions>) {
|
|
72
|
+
super(el, options, Slider);
|
|
73
|
+
(this.el as any).M_Slider = this;
|
|
74
|
+
|
|
75
|
+
this.options = {
|
|
76
|
+
...Slider.defaults,
|
|
77
|
+
...options
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
// init props
|
|
81
|
+
this.interval = null;
|
|
82
|
+
this.eventPause = false;
|
|
83
|
+
this._hovered = false;
|
|
84
|
+
this._focused = false;
|
|
85
|
+
this._focusCurrent = false;
|
|
86
|
+
|
|
87
|
+
// setup
|
|
88
|
+
this._slider = this.el.querySelector('.slides');
|
|
89
|
+
this._slides = Array.from(this._slider.querySelectorAll('li'));
|
|
90
|
+
this.activeIndex = this._slides.findIndex(li => li.classList.contains('active'));
|
|
91
|
+
|
|
92
|
+
if (this.activeIndex !== -1) {
|
|
93
|
+
this._activeSlide = this._slides[this.activeIndex];
|
|
94
|
+
}
|
|
65
95
|
|
|
66
|
-
|
|
67
|
-
// Set initial positions of captions
|
|
68
|
-
this._slides.forEach(slide => {
|
|
69
|
-
// Caption
|
|
70
|
-
//const caption = <HTMLElement|null>slide.querySelector('.caption');
|
|
71
|
-
//if (caption) this._animateCaptionIn(caption, 0);
|
|
72
|
-
// Set Images as Background Images
|
|
73
|
-
const img = slide.querySelector('img');
|
|
74
|
-
if (img) {
|
|
75
|
-
if (img.src !== placeholderBase64) {
|
|
76
|
-
img.style.backgroundImage = 'url('+ img.src +')';
|
|
77
|
-
img.src = placeholderBase64;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
// Sets slide as focusable by code
|
|
81
|
-
if (!slide.hasAttribute('tabindex'))
|
|
82
|
-
slide.setAttribute('tabindex', '-1');
|
|
83
|
-
// Removes initial visibility from "inactive" slides
|
|
84
|
-
slide.style.visibility = 'hidden';
|
|
85
|
-
});
|
|
96
|
+
this._setSliderHeight();
|
|
86
97
|
|
|
87
|
-
|
|
98
|
+
// Sets element id if it does not have one
|
|
99
|
+
if (this._slider.hasAttribute('id'))
|
|
100
|
+
this._sliderId = this._slider.getAttribute('id');
|
|
101
|
+
else {
|
|
102
|
+
this._sliderId = 'slider-' + Utils.guid();
|
|
103
|
+
this._slider.setAttribute('id', this._sliderId);
|
|
104
|
+
}
|
|
88
105
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
targets: this._slides[0],
|
|
102
|
-
opacity: 1,
|
|
103
|
-
duration: this.options.duration,
|
|
104
|
-
easing: 'easeOutQuad'
|
|
105
|
-
});
|
|
106
|
-
*/
|
|
107
|
-
// Update indicators
|
|
108
|
-
if (this.options.indicators) {
|
|
109
|
-
this._indicators[this.activeIndex].children[0].classList.add('active');
|
|
106
|
+
const placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
|
|
107
|
+
// Set initial positions of captions
|
|
108
|
+
this._slides.forEach(slide => {
|
|
109
|
+
// Caption
|
|
110
|
+
//const caption = <HTMLElement|null>slide.querySelector('.caption');
|
|
111
|
+
//if (caption) this._animateCaptionIn(caption, 0);
|
|
112
|
+
// Set Images as Background Images
|
|
113
|
+
const img = slide.querySelector('img');
|
|
114
|
+
if (img) {
|
|
115
|
+
if (img.src !== placeholderBase64) {
|
|
116
|
+
img.style.backgroundImage = 'url('+ img.src +')';
|
|
117
|
+
img.src = placeholderBase64;
|
|
110
118
|
}
|
|
111
119
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
120
|
+
// Sets slide as focusable by code
|
|
121
|
+
if (!slide.hasAttribute('tabindex'))
|
|
122
|
+
slide.setAttribute('tabindex', '-1');
|
|
123
|
+
// Removes initial visibility from "inactive" slides
|
|
124
|
+
slide.style.visibility = 'hidden';
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
this._setupIndicators();
|
|
128
|
+
|
|
129
|
+
// Show active slide
|
|
130
|
+
if (this._activeSlide) {
|
|
131
|
+
this._activeSlide.style.display = 'block';
|
|
132
|
+
this._activeSlide.style.visibility = 'visible';
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
this.activeIndex = 0;
|
|
136
|
+
this._slides[0].classList.add('active');
|
|
137
|
+
this._slides[0].style.visibility = 'visible';
|
|
138
|
+
this._activeSlide = this._slides[0];
|
|
139
|
+
this._animateSlide(this._slides[0], true);
|
|
140
|
+
/*anim({
|
|
141
|
+
targets: this._slides[0],
|
|
142
|
+
opacity: 1,
|
|
143
|
+
duration: this.options.duration,
|
|
144
|
+
easing: 'easeOutQuad'
|
|
125
145
|
});
|
|
126
146
|
*/
|
|
127
|
-
|
|
128
|
-
this.
|
|
129
|
-
|
|
130
|
-
|
|
147
|
+
// Update indicators
|
|
148
|
+
if (this.options.indicators) {
|
|
149
|
+
this._indicators[this.activeIndex].children[0].classList.add('active');
|
|
150
|
+
}
|
|
131
151
|
}
|
|
132
152
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
153
|
+
// Adjust height to current slide
|
|
154
|
+
// TODO: ??? Code does not do what it says in comment
|
|
155
|
+
/*
|
|
156
|
+
this._activeSlide.querySelectorAll('img').forEach(el => {
|
|
157
|
+
anim({
|
|
158
|
+
targets: this._activeSlide.querySelector('.caption'),
|
|
159
|
+
opacity: 1,
|
|
160
|
+
translateX: 0,
|
|
161
|
+
translateY: 0,
|
|
162
|
+
duration: this.options.duration,
|
|
163
|
+
easing: 'easeOutQuad'
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
*/
|
|
136
167
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
168
|
+
this._setupEventHandlers();
|
|
169
|
+
// auto scroll
|
|
170
|
+
this.start();
|
|
171
|
+
}
|
|
140
172
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
173
|
+
static get defaults() {
|
|
174
|
+
return _defaults;
|
|
175
|
+
}
|
|
145
176
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
177
|
+
/**
|
|
178
|
+
* Initializes instance of Slider.
|
|
179
|
+
* @param el HTML element.
|
|
180
|
+
* @param options Component options.
|
|
181
|
+
*/
|
|
182
|
+
static init(el: HTMLElement, options?: Partial<SliderOptions>): Slider;
|
|
183
|
+
/**
|
|
184
|
+
* Initializes instances of Slider.
|
|
185
|
+
* @param els HTML elements.
|
|
186
|
+
* @param options Component options.
|
|
187
|
+
*/
|
|
188
|
+
static init(els: InitElements<MElement>, options?: Partial<SliderOptions>): Slider[];
|
|
189
|
+
/**
|
|
190
|
+
* Initializes instances of Slider.
|
|
191
|
+
* @param els HTML elements.
|
|
192
|
+
* @param options Component options.
|
|
193
|
+
*/
|
|
194
|
+
static init(els: HTMLElement | InitElements<MElement>, options: Partial<SliderOptions> = {}): Slider | Slider[] {
|
|
195
|
+
return super.init(els, options, Slider);
|
|
196
|
+
}
|
|
152
197
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
this._handleAutoPauseFocusBound = this._handleAutoPauseFocus.bind(this);
|
|
157
|
-
this._handleAutoStartFocusBound = this._handleAutoStartFocus.bind(this);
|
|
158
|
-
this._handleAutoPauseHoverBound = this._handleAutoPauseHover.bind(this);
|
|
159
|
-
this._handleAutoStartHoverBound = this._handleAutoStartHover.bind(this);
|
|
160
|
-
if (this.options.pauseOnFocus) {
|
|
161
|
-
this.el.addEventListener('focusin', this._handleAutoPauseFocusBound);
|
|
162
|
-
this.el.addEventListener('focusout', this._handleAutoStartFocusBound);
|
|
163
|
-
}
|
|
164
|
-
if (this.options.pauseOnHover) {
|
|
165
|
-
this.el.addEventListener('mouseenter', this._handleAutoPauseHoverBound);
|
|
166
|
-
this.el.addEventListener('mouseleave', this._handleAutoStartHoverBound);
|
|
167
|
-
}
|
|
168
|
-
if (this.options.indicators) {
|
|
169
|
-
this._indicators.forEach((el) => {
|
|
170
|
-
el.addEventListener('click', this._handleIndicatorClickBound);
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
}
|
|
198
|
+
static getInstance(el: HTMLElement): Slider {
|
|
199
|
+
return (el as any).M_Slider;
|
|
200
|
+
}
|
|
174
201
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
this.el.removeEventListener('mouseenter', this._handleAutoPauseHoverBound);
|
|
182
|
-
this.el.removeEventListener('mouseleave', this._handleAutoStartHoverBound);
|
|
183
|
-
}
|
|
184
|
-
if (this.options.indicators) {
|
|
185
|
-
this._indicators.forEach((el) => {
|
|
186
|
-
el.removeEventListener('click', this._handleIndicatorClickBound);
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
}
|
|
202
|
+
destroy() {
|
|
203
|
+
this.pause();
|
|
204
|
+
this._removeIndicators();
|
|
205
|
+
this._removeEventHandlers();
|
|
206
|
+
(this.el as any).M_Slider = undefined;
|
|
207
|
+
}
|
|
190
208
|
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
this.
|
|
195
|
-
this.set(currIndex);
|
|
209
|
+
_setupEventHandlers() {
|
|
210
|
+
if (this.options.pauseOnFocus) {
|
|
211
|
+
this.el.addEventListener('focusin', this._handleAutoPauseFocus);
|
|
212
|
+
this.el.addEventListener('focusout', this._handleAutoStartFocus);
|
|
196
213
|
}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
this.
|
|
200
|
-
if (this.interval != null) {
|
|
201
|
-
this._pause(true);
|
|
202
|
-
}
|
|
214
|
+
if (this.options.pauseOnHover) {
|
|
215
|
+
this.el.addEventListener('mouseenter', this._handleAutoPauseHover);
|
|
216
|
+
this.el.addEventListener('mouseleave', this._handleAutoStartHover);
|
|
203
217
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
this._pause(true);
|
|
209
|
-
}
|
|
218
|
+
if (this.options.indicators) {
|
|
219
|
+
this._indicators.forEach((el) => {
|
|
220
|
+
el.addEventListener('click', this._handleIndicatorClick);
|
|
221
|
+
});
|
|
210
222
|
}
|
|
223
|
+
}
|
|
211
224
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
}
|
|
225
|
+
_removeEventHandlers() {
|
|
226
|
+
if (this.options.pauseOnFocus) {
|
|
227
|
+
this.el.removeEventListener('focusin', this._handleAutoPauseFocus);
|
|
228
|
+
this.el.removeEventListener('focusout', this._handleAutoStartFocus);
|
|
217
229
|
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
this.
|
|
221
|
-
if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
|
|
222
|
-
this.start();
|
|
223
|
-
}
|
|
230
|
+
if (this.options.pauseOnHover) {
|
|
231
|
+
this.el.removeEventListener('mouseenter', this._handleAutoPauseHover);
|
|
232
|
+
this.el.removeEventListener('mouseleave', this._handleAutoStartHover);
|
|
224
233
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (this._slides.length === newActiveIndex + 1)
|
|
230
|
-
newActiveIndex = 0; // loop to start
|
|
231
|
-
else
|
|
232
|
-
newActiveIndex += 1;
|
|
233
|
-
this.set(newActiveIndex);
|
|
234
|
+
if (this.options.indicators) {
|
|
235
|
+
this._indicators.forEach((el) => {
|
|
236
|
+
el.removeEventListener('click', this._handleIndicatorClick);
|
|
237
|
+
});
|
|
234
238
|
}
|
|
239
|
+
}
|
|
235
240
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
easing: 'easeOutQuad'
|
|
243
|
-
});
|
|
241
|
+
_handleIndicatorClick = (e: MouseEvent) => {
|
|
242
|
+
const el = (<HTMLElement>e.target).parentElement;
|
|
243
|
+
const currIndex = [...el.parentNode.children].indexOf(el);
|
|
244
|
+
this._focusCurrent = true;
|
|
245
|
+
this.set(currIndex);
|
|
246
|
+
}
|
|
244
247
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
else if (caption.classList.contains('left-align')) dx = -100;
|
|
250
|
-
anim({
|
|
251
|
-
targets: caption,
|
|
252
|
-
opacity: isDirectionIn ? [0, 1] : [1, 0],
|
|
253
|
-
translateX: isDirectionIn ? [dx, 0] : [0, dx],
|
|
254
|
-
translateY: isDirectionIn ? [dy, 0] : [0, dy],
|
|
255
|
-
duration: this.options.duration,
|
|
256
|
-
delay: this.options.duration,
|
|
257
|
-
easing: 'easeOutQuad'
|
|
258
|
-
});
|
|
248
|
+
_handleAutoPauseHover = () => {
|
|
249
|
+
this._hovered = true;
|
|
250
|
+
if (this.interval != null) {
|
|
251
|
+
this._pause(true);
|
|
259
252
|
}
|
|
253
|
+
}
|
|
260
254
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
// Add height if indicators are present
|
|
266
|
-
this.el.style.height = (this.options.height + 40)+'px'; //.css('height', this.options.height + 40 + 'px');
|
|
267
|
-
}
|
|
268
|
-
else {
|
|
269
|
-
this.el.style.height = this.options.height+'px';
|
|
270
|
-
}
|
|
271
|
-
this._slider.style.height = this.options.height+'px';
|
|
272
|
-
}
|
|
255
|
+
_handleAutoPauseFocus = () => {
|
|
256
|
+
this._focused = true;
|
|
257
|
+
if (this.interval != null) {
|
|
258
|
+
this._pause(true);
|
|
273
259
|
}
|
|
260
|
+
}
|
|
274
261
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
const arrLi = [];
|
|
281
|
-
this._slides.forEach((el, i) => {
|
|
282
|
-
const label = this.options.indicatorLabelFunc
|
|
283
|
-
? this.options.indicatorLabelFunc.call(this, i + 1, i === 0)
|
|
284
|
-
: `${i + 1}`;
|
|
285
|
-
const li = document.createElement('li');
|
|
286
|
-
li.classList.add('indicator-item');
|
|
287
|
-
li.innerHTML = `<button type="button" class="indicator-item-btn" aria-label="${label}" aria-controls="${this._sliderId}"></button>`;
|
|
288
|
-
arrLi.push(li);
|
|
289
|
-
ul.append(li);
|
|
290
|
-
});
|
|
291
|
-
|
|
292
|
-
this.el.append(ul);
|
|
293
|
-
this._indicators = arrLi;
|
|
294
|
-
}
|
|
262
|
+
_handleAutoStartHover = () => {
|
|
263
|
+
this._hovered = false;
|
|
264
|
+
if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) {
|
|
265
|
+
this.start();
|
|
295
266
|
}
|
|
267
|
+
}
|
|
296
268
|
|
|
297
|
-
|
|
298
|
-
|
|
269
|
+
_handleAutoStartFocus = () => {
|
|
270
|
+
this._focused = false;
|
|
271
|
+
if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
|
|
272
|
+
this.start();
|
|
299
273
|
}
|
|
274
|
+
}
|
|
300
275
|
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
const _caption = <HTMLElement|null>this._activeSlide.querySelector('.caption');
|
|
311
|
-
|
|
312
|
-
this._activeSlide.classList.remove('active');
|
|
313
|
-
// Enables every slide
|
|
314
|
-
this._slides.forEach(slide => slide.style.visibility = 'visible');
|
|
315
|
-
|
|
316
|
-
//--- Hide active Slide + Caption
|
|
317
|
-
// TODO: What does this do?
|
|
318
|
-
anim({
|
|
319
|
-
targets: this._activeSlide,
|
|
320
|
-
opacity: 0,
|
|
321
|
-
duration: this.options.duration,
|
|
322
|
-
easing: 'easeOutQuad',
|
|
323
|
-
complete: () => {
|
|
324
|
-
this._slides.forEach(el => {
|
|
325
|
-
if (el.classList.contains('active')) return;
|
|
326
|
-
anim({
|
|
327
|
-
targets: el,
|
|
328
|
-
opacity: 0,
|
|
329
|
-
translateX: 0,
|
|
330
|
-
translateY: 0,
|
|
331
|
-
duration: 0, // Animation with duration 0... why use anim at all then?
|
|
332
|
-
easing: 'easeOutQuad'
|
|
333
|
-
});
|
|
334
|
-
// Disables invisible slides (for assistive technologies)
|
|
335
|
-
el.style.visibility = 'hidden';
|
|
336
|
-
});
|
|
337
|
-
}
|
|
338
|
-
});
|
|
276
|
+
_handleInterval = () => {
|
|
277
|
+
const activeElem = this._slider.querySelector('.active');
|
|
278
|
+
let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem);
|
|
279
|
+
if (this._slides.length === newActiveIndex + 1)
|
|
280
|
+
newActiveIndex = 0; // loop to start
|
|
281
|
+
else
|
|
282
|
+
newActiveIndex += 1;
|
|
283
|
+
this.set(newActiveIndex);
|
|
284
|
+
}
|
|
339
285
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
286
|
+
_animateSlide(slide: HTMLElement, isDirectionIn: boolean): void {
|
|
287
|
+
let dx = 0, dy = 0;
|
|
288
|
+
anim({
|
|
289
|
+
targets: slide,
|
|
290
|
+
opacity: isDirectionIn ? [0, 1] : [1, 0],
|
|
291
|
+
duration: this.options.duration,
|
|
292
|
+
easing: 'easeOutQuad'
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
const caption = slide.querySelector('.caption');
|
|
296
|
+
if (!caption) return;
|
|
297
|
+
if (caption.classList.contains('center-align')) dy = -100;
|
|
298
|
+
else if (caption.classList.contains('right-align')) dx = 100;
|
|
299
|
+
else if (caption.classList.contains('left-align')) dx = -100;
|
|
300
|
+
anim({
|
|
301
|
+
targets: caption,
|
|
302
|
+
opacity: isDirectionIn ? [0, 1] : [1, 0],
|
|
303
|
+
translateX: isDirectionIn ? [dx, 0] : [0, dx],
|
|
304
|
+
translateY: isDirectionIn ? [dy, 0] : [0, dy],
|
|
305
|
+
duration: this.options.duration,
|
|
306
|
+
delay: this.options.duration,
|
|
307
|
+
easing: 'easeOutQuad'
|
|
308
|
+
});
|
|
309
|
+
}
|
|
343
310
|
|
|
344
|
-
|
|
311
|
+
_setSliderHeight() {
|
|
312
|
+
// If fullscreen, do nothing
|
|
313
|
+
if (!this.el.classList.contains('fullscreen')) {
|
|
345
314
|
if (this.options.indicators) {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, this.activeIndex, false);
|
|
352
|
-
nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
|
|
353
|
-
}
|
|
315
|
+
// Add height if indicators are present
|
|
316
|
+
this.el.style.height = (this.options.height + 40)+'px'; //.css('height', this.options.height + 40 + 'px');
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
this.el.style.height = this.options.height+'px';
|
|
354
320
|
}
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
321
|
+
this._slider.style.height = this.options.height+'px';
|
|
322
|
+
}
|
|
323
|
+
}
|
|
358
324
|
|
|
359
|
-
|
|
325
|
+
_setupIndicators() {
|
|
326
|
+
if (this.options.indicators) {
|
|
327
|
+
const ul = document.createElement('ul');
|
|
328
|
+
ul.classList.add('indicators');
|
|
329
|
+
|
|
330
|
+
const arrLi = [];
|
|
331
|
+
this._slides.forEach((el, i) => {
|
|
332
|
+
const label = this.options.indicatorLabelFunc
|
|
333
|
+
? this.options.indicatorLabelFunc.call(this, i + 1, i === 0)
|
|
334
|
+
: `${i + 1}`;
|
|
335
|
+
const li = document.createElement('li');
|
|
336
|
+
li.classList.add('indicator-item');
|
|
337
|
+
li.innerHTML = `<button type="button" class="indicator-item-btn" aria-label="${label}" aria-controls="${this._sliderId}"></button>`;
|
|
338
|
+
arrLi.push(li);
|
|
339
|
+
ul.append(li);
|
|
340
|
+
});
|
|
360
341
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
this._focusCurrent = false;
|
|
366
|
-
}
|
|
367
|
-
*/
|
|
342
|
+
this.el.append(ul);
|
|
343
|
+
this._indicators = arrLi;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
368
346
|
|
|
369
|
-
|
|
347
|
+
_removeIndicators() {
|
|
348
|
+
this.el.querySelector('ul.indicators').remove(); //find('ul.indicators').remove();
|
|
349
|
+
}
|
|
370
350
|
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
351
|
+
set(index: number) {
|
|
352
|
+
// Wrap around indices.
|
|
353
|
+
if (index >= this._slides.length) index = 0;
|
|
354
|
+
else if (index < 0) index = this._slides.length - 1;
|
|
355
|
+
|
|
356
|
+
// Only do if index changes
|
|
357
|
+
if (this.activeIndex === index) return;
|
|
358
|
+
|
|
359
|
+
this._activeSlide = this._slides[this.activeIndex];
|
|
360
|
+
const _caption = <HTMLElement|null>this._activeSlide.querySelector('.caption');
|
|
361
|
+
|
|
362
|
+
this._activeSlide.classList.remove('active');
|
|
363
|
+
// Enables every slide
|
|
364
|
+
this._slides.forEach(slide => slide.style.visibility = 'visible');
|
|
365
|
+
|
|
366
|
+
//--- Hide active Slide + Caption
|
|
367
|
+
// TODO: What does this do?
|
|
368
|
+
anim({
|
|
369
|
+
targets: this._activeSlide,
|
|
370
|
+
opacity: 0,
|
|
371
|
+
duration: this.options.duration,
|
|
372
|
+
easing: 'easeOutQuad',
|
|
373
|
+
complete: () => {
|
|
374
|
+
this._slides.forEach(el => {
|
|
375
|
+
if (el.classList.contains('active')) return;
|
|
376
|
+
anim({
|
|
377
|
+
targets: el,
|
|
378
|
+
opacity: 0,
|
|
379
|
+
translateX: 0,
|
|
380
|
+
translateY: 0,
|
|
381
|
+
duration: 0, // Animation with duration 0... why use anim at all then?
|
|
382
|
+
easing: 'easeOutQuad'
|
|
383
|
+
});
|
|
384
|
+
// Disables invisible slides (for assistive technologies)
|
|
385
|
+
el.style.visibility = 'hidden';
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
// Hide active Caption
|
|
391
|
+
//this._animateCaptionIn(_caption, this.options.duration);
|
|
392
|
+
_caption.style.opacity = '0';
|
|
393
|
+
|
|
394
|
+
// Update indicators
|
|
395
|
+
if (this.options.indicators) {
|
|
396
|
+
const activeIndicator = this._indicators[this.activeIndex].children[0];
|
|
397
|
+
const nextIndicator = this._indicators[index].children[0];
|
|
398
|
+
activeIndicator.classList.remove('active');
|
|
399
|
+
nextIndicator.classList.add('active');
|
|
400
|
+
if (typeof this.options.indicatorLabelFunc === "function"){
|
|
401
|
+
activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, this.activeIndex, false);
|
|
402
|
+
nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
|
|
375
403
|
}
|
|
376
404
|
}
|
|
377
405
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
this.eventPause = fromEvent;
|
|
381
|
-
this.interval = null;
|
|
382
|
-
}
|
|
406
|
+
//--- Show new Slide + Caption
|
|
407
|
+
this._animateSlide(this._slides[index], true);
|
|
383
408
|
|
|
384
|
-
|
|
385
|
-
this._pause(false);
|
|
386
|
-
}
|
|
409
|
+
this._slides[index].classList.add('active');
|
|
387
410
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
);
|
|
394
|
-
this.eventPause = false;
|
|
411
|
+
// TODO: Why focus? => causes uncontrollable page scroll
|
|
412
|
+
/*
|
|
413
|
+
if (this._focusCurrent) {
|
|
414
|
+
this._slides[index].focus();
|
|
415
|
+
this._focusCurrent = false;
|
|
395
416
|
}
|
|
417
|
+
*/
|
|
396
418
|
|
|
397
|
-
|
|
398
|
-
let newIndex = this.activeIndex + 1;
|
|
399
|
-
// Wrap around indices.
|
|
400
|
-
if (newIndex >= this._slides.length) newIndex = 0;
|
|
401
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
402
|
-
this.set(newIndex);
|
|
403
|
-
}
|
|
419
|
+
this.activeIndex = index;
|
|
404
420
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
410
|
-
this.set(newIndex);
|
|
421
|
+
// Reset interval, if allowed. This check prevents autostart
|
|
422
|
+
// when slider is paused, since it can be changed though indicators.
|
|
423
|
+
if (this.interval != null) {
|
|
424
|
+
this.start();
|
|
411
425
|
}
|
|
412
426
|
}
|
|
413
|
-
|
|
414
427
|
|
|
415
|
-
|
|
428
|
+
_pause(fromEvent: boolean) {
|
|
429
|
+
clearInterval(this.interval);
|
|
430
|
+
this.eventPause = fromEvent;
|
|
431
|
+
this.interval = null;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Pause slider autoslide.
|
|
436
|
+
*/
|
|
437
|
+
pause = () => {
|
|
438
|
+
this._pause(false);
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
/**
|
|
442
|
+
* Start slider autoslide.
|
|
443
|
+
*/
|
|
444
|
+
start = () => {
|
|
445
|
+
clearInterval(this.interval);
|
|
446
|
+
this.interval = setInterval(
|
|
447
|
+
this._handleInterval,
|
|
448
|
+
this.options.duration + this.options.interval
|
|
449
|
+
);
|
|
450
|
+
this.eventPause = false;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/**
|
|
454
|
+
* Move to next slider.
|
|
455
|
+
*/
|
|
456
|
+
next = () => {
|
|
457
|
+
let newIndex = this.activeIndex + 1;
|
|
458
|
+
// Wrap around indices.
|
|
459
|
+
if (newIndex >= this._slides.length) newIndex = 0;
|
|
460
|
+
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
461
|
+
this.set(newIndex);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Move to prev slider.
|
|
466
|
+
*/
|
|
467
|
+
prev = () => {
|
|
468
|
+
let newIndex = this.activeIndex - 1;
|
|
469
|
+
// Wrap around indices.
|
|
470
|
+
if (newIndex >= this._slides.length) newIndex = 0;
|
|
471
|
+
else if (newIndex < 0) newIndex = this._slides.length - 1;
|
|
472
|
+
this.set(newIndex);
|
|
473
|
+
}
|
|
474
|
+
}
|