@materializecss/materialize 2.0.3-alpha → 2.0.3
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/README.md +1 -1
- package/dist/css/materialize.css +345 -236
- package/dist/css/materialize.min.css +2 -2
- package/dist/js/materialize.js +518 -1979
- package/dist/js/materialize.min.js +2 -2
- package/dist/js/materialize.min.js.map +1 -1
- package/dist/src/buttons.d.ts.map +1 -1
- package/dist/src/cards.d.ts.map +1 -1
- package/dist/src/collapsible.d.ts +1 -0
- package/dist/src/collapsible.d.ts.map +1 -1
- package/dist/src/dropdown.d.ts.map +1 -1
- package/dist/src/global.d.ts.map +1 -1
- package/dist/src/materialbox.d.ts +14 -10
- package/dist/src/materialbox.d.ts.map +1 -1
- package/dist/src/modal.d.ts.map +1 -1
- package/dist/src/range.d.ts.map +1 -1
- package/dist/src/scrollspy.d.ts.map +1 -1
- package/dist/src/sidenav.d.ts +25 -25
- package/dist/src/sidenav.d.ts.map +1 -1
- package/dist/src/slider.d.ts +12 -12
- package/dist/src/slider.d.ts.map +1 -1
- package/dist/src/tabs.d.ts +1 -1
- package/dist/src/tabs.d.ts.map +1 -1
- package/dist/src/toasts.d.ts +7 -2
- package/dist/src/toasts.d.ts.map +1 -1
- package/dist/src/tooltip.d.ts +8 -2
- package/dist/src/tooltip.d.ts.map +1 -1
- package/package.json +14 -13
- package/sass/components/_buttons.scss +158 -73
- package/sass/components/_chips.scss +75 -28
- package/sass/components/_collapsible.scss +14 -2
- package/sass/components/_global.scss +6 -94
- package/sass/components/_materialbox.scss +2 -2
- package/sass/components/_modal.scss +0 -1
- package/sass/components/_preloader.scss +85 -0
- package/sass/components/_tooltip.scss +18 -8
- package/sass/components/_variables.scss +5 -4
- package/sass/components/forms/_range.scss +1 -1
- package/sass/components/forms/_switches.scss +44 -14
- package/Gruntfile.js +0 -480
- package/src/autocomplete.ts +0 -553
- package/src/bounding.ts +0 -6
- package/src/buttons.ts +0 -260
- package/src/cards.ts +0 -53
- package/src/carousel.ts +0 -676
- package/src/characterCounter.ts +0 -117
- package/src/chips.ts +0 -439
- package/src/collapsible.ts +0 -249
- package/src/component.ts +0 -120
- package/src/datepicker.ts +0 -1076
- package/src/dropdown.ts +0 -644
- package/src/edges.ts +0 -6
- package/src/forms.ts +0 -132
- package/src/global.ts +0 -114
- package/src/index.ts +0 -26
- package/src/materialbox.ts +0 -404
- package/src/modal.ts +0 -341
- package/src/parallax.ts +0 -149
- package/src/pushpin.ts +0 -165
- package/src/range.ts +0 -198
- package/src/scrollspy.ts +0 -263
- package/src/select.ts +0 -484
- package/src/sidenav.ts +0 -543
- package/src/slider.ts +0 -474
- package/src/tabs.ts +0 -347
- package/src/tapTarget.ts +0 -273
- package/src/timepicker.ts +0 -832
- package/src/toasts.ts +0 -290
- package/src/tooltip.ts +0 -346
- package/src/utils.ts +0 -271
- package/src/waves.ts +0 -70
package/src/modal.ts
DELETED
|
@@ -1,341 +0,0 @@
|
|
|
1
|
-
import anim from "animejs";
|
|
2
|
-
|
|
3
|
-
import { Utils } from "./utils";
|
|
4
|
-
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
5
|
-
|
|
6
|
-
export interface ModalOptions extends BaseOptions {
|
|
7
|
-
/**
|
|
8
|
-
* Opacity of the modal overlay.
|
|
9
|
-
* @default 0.5
|
|
10
|
-
*/
|
|
11
|
-
opacity: number;
|
|
12
|
-
/**
|
|
13
|
-
* Transition in duration in milliseconds.
|
|
14
|
-
* @default 250
|
|
15
|
-
*/
|
|
16
|
-
inDuration: number;
|
|
17
|
-
/**
|
|
18
|
-
* Transition out duration in milliseconds.
|
|
19
|
-
* @default 250
|
|
20
|
-
*/
|
|
21
|
-
outDuration: number;
|
|
22
|
-
/**
|
|
23
|
-
* Prevent page from scrolling while modal is open.
|
|
24
|
-
* @default true
|
|
25
|
-
*/
|
|
26
|
-
preventScrolling: boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Callback function called before modal is opened.
|
|
29
|
-
* @default null
|
|
30
|
-
*/
|
|
31
|
-
onOpenStart: (this: Modal, el: HTMLElement) => void;
|
|
32
|
-
/**
|
|
33
|
-
* Callback function called after modal is opened.
|
|
34
|
-
* @default null
|
|
35
|
-
*/
|
|
36
|
-
onOpenEnd: (this: Modal, el: HTMLElement) => void;
|
|
37
|
-
/**
|
|
38
|
-
* Callback function called before modal is closed.
|
|
39
|
-
* @default null
|
|
40
|
-
*/
|
|
41
|
-
onCloseStart: (el: HTMLElement) => void;
|
|
42
|
-
/**
|
|
43
|
-
* Callback function called after modal is closed.
|
|
44
|
-
* @default null
|
|
45
|
-
*/
|
|
46
|
-
onCloseEnd: (el: HTMLElement) => void;
|
|
47
|
-
/**
|
|
48
|
-
* Allow modal to be dismissed by keyboard or overlay click.
|
|
49
|
-
* @default true
|
|
50
|
-
*/
|
|
51
|
-
dismissible: boolean;
|
|
52
|
-
/**
|
|
53
|
-
* Starting top offset.
|
|
54
|
-
* @default '4%'
|
|
55
|
-
*/
|
|
56
|
-
startingTop: string;
|
|
57
|
-
/**
|
|
58
|
-
* Ending top offset.
|
|
59
|
-
* @default '10%'
|
|
60
|
-
*/
|
|
61
|
-
endingTop: string;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
const _defaults = {
|
|
65
|
-
opacity: 0.5,
|
|
66
|
-
inDuration: 250,
|
|
67
|
-
outDuration: 250,
|
|
68
|
-
onOpenStart: null,
|
|
69
|
-
onOpenEnd: null,
|
|
70
|
-
onCloseStart: null,
|
|
71
|
-
onCloseEnd: null,
|
|
72
|
-
preventScrolling: true,
|
|
73
|
-
dismissible: true,
|
|
74
|
-
startingTop: '4%',
|
|
75
|
-
endingTop: '10%'
|
|
76
|
-
};
|
|
77
|
-
|
|
78
|
-
export class Modal extends Component<ModalOptions> {
|
|
79
|
-
|
|
80
|
-
static _modalsOpen: number;
|
|
81
|
-
static _count: number;
|
|
82
|
-
|
|
83
|
-
/**
|
|
84
|
-
* ID of the modal element.
|
|
85
|
-
*/
|
|
86
|
-
id: string;
|
|
87
|
-
/**
|
|
88
|
-
* If the modal is open.
|
|
89
|
-
*/
|
|
90
|
-
isOpen: boolean;
|
|
91
|
-
|
|
92
|
-
private _openingTrigger: any;
|
|
93
|
-
private _overlay: HTMLElement;
|
|
94
|
-
private _nthModalOpened: number;
|
|
95
|
-
|
|
96
|
-
constructor(el: HTMLElement, options: Partial<ModalOptions>) {
|
|
97
|
-
super(el, options, Modal);
|
|
98
|
-
(this.el as any).M_Modal = this;
|
|
99
|
-
|
|
100
|
-
this.options = {
|
|
101
|
-
...Modal.defaults,
|
|
102
|
-
...options
|
|
103
|
-
};
|
|
104
|
-
|
|
105
|
-
this.isOpen = false;
|
|
106
|
-
this.id = this.el.id;
|
|
107
|
-
this._openingTrigger = undefined;
|
|
108
|
-
this._overlay = document.createElement('div');
|
|
109
|
-
this._overlay.classList.add('modal-overlay');
|
|
110
|
-
this.el.tabIndex = 0;
|
|
111
|
-
this._nthModalOpened = 0;
|
|
112
|
-
Modal._count++;
|
|
113
|
-
this._setupEventHandlers();
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
static get defaults() {
|
|
117
|
-
return _defaults;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Initializes instance of Modal.
|
|
122
|
-
* @param el HTML element.
|
|
123
|
-
* @param options Component options.
|
|
124
|
-
*/
|
|
125
|
-
static init(el: HTMLElement, options?: Partial<ModalOptions>): Modal;
|
|
126
|
-
/**
|
|
127
|
-
* Initializes instances of Modal.
|
|
128
|
-
* @param els HTML elements.
|
|
129
|
-
* @param options Component options.
|
|
130
|
-
*/
|
|
131
|
-
static init(els: InitElements<MElement>, options?: Partial<ModalOptions>): Modal[];
|
|
132
|
-
/**
|
|
133
|
-
* Initializes instances of Modal.
|
|
134
|
-
* @param els HTML elements.
|
|
135
|
-
* @param options Component options.
|
|
136
|
-
*/
|
|
137
|
-
static init(els: HTMLElement | InitElements<MElement>, options: Partial<ModalOptions> = {}): Modal | Modal[] {
|
|
138
|
-
return super.init(els, options, Modal);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
static getInstance(el: HTMLElement): Modal {
|
|
142
|
-
return (el as any).M_Modal;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
destroy() {
|
|
146
|
-
Modal._count--;
|
|
147
|
-
this._removeEventHandlers();
|
|
148
|
-
this.el.removeAttribute('style');
|
|
149
|
-
this._overlay.remove();
|
|
150
|
-
(this.el as any).M_Modal = undefined;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
_setupEventHandlers() {
|
|
154
|
-
if (Modal._count === 1) {
|
|
155
|
-
document.body.addEventListener('click', this._handleTriggerClick);
|
|
156
|
-
}
|
|
157
|
-
this._overlay.addEventListener('click', this._handleOverlayClick);
|
|
158
|
-
this.el.addEventListener('click', this._handleModalCloseClick);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
_removeEventHandlers() {
|
|
162
|
-
if (Modal._count === 0) {
|
|
163
|
-
document.body.removeEventListener('click', this._handleTriggerClick);
|
|
164
|
-
}
|
|
165
|
-
this._overlay.removeEventListener('click', this._handleOverlayClick);
|
|
166
|
-
this.el.removeEventListener('click', this._handleModalCloseClick);
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
_handleTriggerClick = (e: MouseEvent) => {
|
|
170
|
-
const trigger = (e.target as HTMLElement).closest('.modal-trigger');
|
|
171
|
-
if (!trigger) return;
|
|
172
|
-
const modalId = Utils.getIdFromTrigger(trigger as HTMLElement);
|
|
173
|
-
const modalInstance = (document.getElementById(modalId) as any).M_Modal;
|
|
174
|
-
if (modalInstance) modalInstance.open(trigger);
|
|
175
|
-
e.preventDefault();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
_handleOverlayClick = () => {
|
|
179
|
-
if (this.options.dismissible) this.close();
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
_handleModalCloseClick = (e: MouseEvent) => {
|
|
183
|
-
const closeTrigger = (e.target as HTMLElement).closest('.modal-close');
|
|
184
|
-
if (closeTrigger) this.close();
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
_handleKeydown = (e: KeyboardEvent) => {
|
|
188
|
-
if (Utils.keys.ESC.includes(e.key) && this.options.dismissible) this.close();
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
_handleFocus = (e: FocusEvent) => {
|
|
192
|
-
// Only trap focus if this modal is the last model opened (prevents loops in nested modals).
|
|
193
|
-
if (!this.el.contains(e.target as HTMLElement) && this._nthModalOpened === Modal._modalsOpen) {
|
|
194
|
-
this.el.focus();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
_animateIn() {
|
|
199
|
-
// Set initial styles
|
|
200
|
-
this.el.style.display = 'block';
|
|
201
|
-
this.el.style.opacity = '0';
|
|
202
|
-
this._overlay.style.display = 'block';
|
|
203
|
-
this._overlay.style.opacity = '0';
|
|
204
|
-
// Animate overlay
|
|
205
|
-
anim({
|
|
206
|
-
targets: this._overlay,
|
|
207
|
-
opacity: this.options.opacity,
|
|
208
|
-
duration: this.options.inDuration,
|
|
209
|
-
easing: 'easeOutQuad'
|
|
210
|
-
});
|
|
211
|
-
// Define modal animation options
|
|
212
|
-
const enterAnimOptions = {
|
|
213
|
-
targets: this.el,
|
|
214
|
-
duration: this.options.inDuration,
|
|
215
|
-
easing: 'easeOutCubic',
|
|
216
|
-
// Handle modal onOpenEnd callback
|
|
217
|
-
complete: () => {
|
|
218
|
-
if (typeof this.options.onOpenEnd === 'function') {
|
|
219
|
-
this.options.onOpenEnd.call(this, this.el, this._openingTrigger);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
// Bottom sheet animation
|
|
224
|
-
if (this.el.classList.contains('bottom-sheet')) {
|
|
225
|
-
enterAnimOptions['bottom'] = 0;
|
|
226
|
-
enterAnimOptions['opacity'] = 1;
|
|
227
|
-
}
|
|
228
|
-
// Normal modal animation
|
|
229
|
-
else {
|
|
230
|
-
enterAnimOptions['top'] = [this.options.startingTop, this.options.endingTop];
|
|
231
|
-
enterAnimOptions['opacity'] = 1;
|
|
232
|
-
enterAnimOptions['scaleX'] = [0.8, 1];
|
|
233
|
-
enterAnimOptions['scaleY'] = [0.8, 1];
|
|
234
|
-
}
|
|
235
|
-
anim(enterAnimOptions);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
_animateOut() {
|
|
239
|
-
// Animate overlay
|
|
240
|
-
anim({
|
|
241
|
-
targets: this._overlay,
|
|
242
|
-
opacity: 0,
|
|
243
|
-
duration: this.options.outDuration,
|
|
244
|
-
easing: 'easeOutQuart'
|
|
245
|
-
});
|
|
246
|
-
// Define modal animation options
|
|
247
|
-
const exitAnimOptions = {
|
|
248
|
-
targets: this.el,
|
|
249
|
-
duration: this.options.outDuration,
|
|
250
|
-
easing: 'easeOutCubic',
|
|
251
|
-
// Handle modal ready callback
|
|
252
|
-
complete: () => {
|
|
253
|
-
this.el.style.display = 'none';
|
|
254
|
-
this._overlay.remove();
|
|
255
|
-
// Call onCloseEnd callback
|
|
256
|
-
if (typeof this.options.onCloseEnd === 'function') {
|
|
257
|
-
this.options.onCloseEnd.call(this, this.el);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
};
|
|
261
|
-
// Bottom sheet animation
|
|
262
|
-
if (this.el.classList.contains('bottom-sheet')) {
|
|
263
|
-
exitAnimOptions['bottom'] = '-100%';
|
|
264
|
-
exitAnimOptions['opacity'] = 0;
|
|
265
|
-
}
|
|
266
|
-
// Normal modal animation
|
|
267
|
-
else {
|
|
268
|
-
exitAnimOptions['top'] = [this.options.endingTop, this.options.startingTop];
|
|
269
|
-
exitAnimOptions['opacity'] = 0;
|
|
270
|
-
exitAnimOptions['scaleX'] = 0.8;
|
|
271
|
-
exitAnimOptions['scaleY'] = 0.8;
|
|
272
|
-
}
|
|
273
|
-
anim(exitAnimOptions);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Open modal.
|
|
278
|
-
*/
|
|
279
|
-
open = (trigger?: HTMLElement): Modal => {
|
|
280
|
-
if (this.isOpen) return;
|
|
281
|
-
this.isOpen = true;
|
|
282
|
-
Modal._modalsOpen++;
|
|
283
|
-
this._nthModalOpened = Modal._modalsOpen;
|
|
284
|
-
// Set Z-Index based on number of currently open modals
|
|
285
|
-
this._overlay.style.zIndex = (1000 + Modal._modalsOpen * 2).toString();
|
|
286
|
-
this.el.style.zIndex = (1000 + Modal._modalsOpen * 2 + 1).toString();
|
|
287
|
-
// Set opening trigger, undefined indicates modal was opened by javascript
|
|
288
|
-
this._openingTrigger = !!trigger ? trigger : undefined;
|
|
289
|
-
// onOpenStart callback
|
|
290
|
-
if (typeof this.options.onOpenStart === 'function') {
|
|
291
|
-
this.options.onOpenStart.call(this, this.el, this._openingTrigger);
|
|
292
|
-
}
|
|
293
|
-
if (this.options.preventScrolling) {
|
|
294
|
-
document.body.style.overflow = 'hidden';
|
|
295
|
-
}
|
|
296
|
-
this.el.classList.add('open');
|
|
297
|
-
this.el.insertAdjacentElement('afterend', this._overlay);
|
|
298
|
-
if (this.options.dismissible) {
|
|
299
|
-
document.addEventListener('keydown', this._handleKeydown);
|
|
300
|
-
document.addEventListener('focus', this._handleFocus, true);
|
|
301
|
-
}
|
|
302
|
-
anim.remove(this.el);
|
|
303
|
-
anim.remove(this._overlay);
|
|
304
|
-
this._animateIn();
|
|
305
|
-
// Focus modal
|
|
306
|
-
this.el.focus();
|
|
307
|
-
return this;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Close modal.
|
|
312
|
-
*/
|
|
313
|
-
close = () => {
|
|
314
|
-
if (!this.isOpen) return;
|
|
315
|
-
this.isOpen = false;
|
|
316
|
-
Modal._modalsOpen--;
|
|
317
|
-
this._nthModalOpened = 0;
|
|
318
|
-
// Call onCloseStart callback
|
|
319
|
-
if (typeof this.options.onCloseStart === 'function') {
|
|
320
|
-
this.options.onCloseStart.call(this, this.el);
|
|
321
|
-
}
|
|
322
|
-
this.el.classList.remove('open');
|
|
323
|
-
// Enable body scrolling only if there are no more modals open.
|
|
324
|
-
if (Modal._modalsOpen === 0) {
|
|
325
|
-
document.body.style.overflow = '';
|
|
326
|
-
}
|
|
327
|
-
if (this.options.dismissible) {
|
|
328
|
-
document.removeEventListener('keydown', this._handleKeydown);
|
|
329
|
-
document.removeEventListener('focus', this._handleFocus, true);
|
|
330
|
-
}
|
|
331
|
-
anim.remove(this.el);
|
|
332
|
-
anim.remove(this._overlay);
|
|
333
|
-
this._animateOut();
|
|
334
|
-
return this;
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
static{
|
|
338
|
-
Modal._modalsOpen = 0;
|
|
339
|
-
Modal._count = 0;
|
|
340
|
-
}
|
|
341
|
-
}
|
package/src/parallax.ts
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
import { Utils } from "./utils";
|
|
2
|
-
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
3
|
-
|
|
4
|
-
export interface ParallaxOptions extends BaseOptions {
|
|
5
|
-
/**
|
|
6
|
-
* The minimum width of the screen, in pixels, where the parallax functionality starts working.
|
|
7
|
-
* @default 0
|
|
8
|
-
*/
|
|
9
|
-
responsiveThreshold: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
let _defaults: ParallaxOptions = {
|
|
13
|
-
responsiveThreshold: 0 // breakpoint for swipeable
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export class Parallax extends Component<ParallaxOptions> {
|
|
17
|
-
private _enabled: boolean;
|
|
18
|
-
private _img: HTMLImageElement;
|
|
19
|
-
static _parallaxes: Parallax[] = [];
|
|
20
|
-
static _handleScrollThrottled: () => any;
|
|
21
|
-
static _handleWindowResizeThrottled: () => any;
|
|
22
|
-
|
|
23
|
-
constructor(el: HTMLElement, options: Partial<ParallaxOptions>) {
|
|
24
|
-
super(el, options, Parallax);
|
|
25
|
-
(this.el as any).M_Parallax = this;
|
|
26
|
-
|
|
27
|
-
this.options = {
|
|
28
|
-
...Parallax.defaults,
|
|
29
|
-
...options
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
this._enabled = window.innerWidth > this.options.responsiveThreshold;
|
|
33
|
-
this._img = this.el.querySelector('img');
|
|
34
|
-
this._updateParallax();
|
|
35
|
-
this._setupEventHandlers();
|
|
36
|
-
this._setupStyles();
|
|
37
|
-
Parallax._parallaxes.push(this);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
static get defaults(): ParallaxOptions {
|
|
41
|
-
return _defaults;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Initializes instance of Parallax.
|
|
46
|
-
* @param el HTML element.
|
|
47
|
-
* @param options Component options.
|
|
48
|
-
*/
|
|
49
|
-
static init(el: HTMLElement, options?: Partial<ParallaxOptions>): Parallax;
|
|
50
|
-
/**
|
|
51
|
-
* Initializes instances of Parallax.
|
|
52
|
-
* @param els HTML elements.
|
|
53
|
-
* @param options Component options.
|
|
54
|
-
*/
|
|
55
|
-
static init(els: InitElements<MElement>, options?: Partial<ParallaxOptions>): Parallax[];
|
|
56
|
-
/**
|
|
57
|
-
* Initializes instances of Parallax.
|
|
58
|
-
* @param els HTML elements.
|
|
59
|
-
* @param options Component options.
|
|
60
|
-
*/
|
|
61
|
-
static init(els: HTMLElement | InitElements<MElement>, options: Partial<ParallaxOptions> = {}): Parallax | Parallax[] {
|
|
62
|
-
return super.init(els, options, Parallax);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
static getInstance(el: HTMLElement): Parallax {
|
|
66
|
-
return (el as any).M_Parallax;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
destroy() {
|
|
70
|
-
Parallax._parallaxes.splice(Parallax._parallaxes.indexOf(this), 1);
|
|
71
|
-
this._img.style.transform = '';
|
|
72
|
-
this._removeEventHandlers();
|
|
73
|
-
(this.el as any).M_Parallax = undefined;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
static _handleScroll() {
|
|
77
|
-
for (let i = 0; i < Parallax._parallaxes.length; i++) {
|
|
78
|
-
let parallaxInstance = Parallax._parallaxes[i];
|
|
79
|
-
parallaxInstance._updateParallax.call(parallaxInstance);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
static _handleWindowResize() {
|
|
84
|
-
for (let i = 0; i < Parallax._parallaxes.length; i++) {
|
|
85
|
-
let parallaxInstance = Parallax._parallaxes[i];
|
|
86
|
-
parallaxInstance._enabled =
|
|
87
|
-
window.innerWidth > parallaxInstance.options.responsiveThreshold;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
_setupEventHandlers() {
|
|
92
|
-
this._img.addEventListener('load', this._handleImageLoad);
|
|
93
|
-
if (Parallax._parallaxes.length === 0) {
|
|
94
|
-
if (!Parallax._handleScrollThrottled){
|
|
95
|
-
Parallax._handleScrollThrottled = Utils.throttle(Parallax._handleScroll, 5);
|
|
96
|
-
}
|
|
97
|
-
if (!Parallax._handleWindowResizeThrottled){
|
|
98
|
-
Parallax._handleWindowResizeThrottled = Utils.throttle(Parallax._handleWindowResize, 5);
|
|
99
|
-
}
|
|
100
|
-
window.addEventListener('scroll', Parallax._handleScrollThrottled);
|
|
101
|
-
window.addEventListener('resize', Parallax._handleWindowResizeThrottled);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
_removeEventHandlers() {
|
|
106
|
-
this._img.removeEventListener('load', this._handleImageLoad);
|
|
107
|
-
if (Parallax._parallaxes.length === 0) {
|
|
108
|
-
window.removeEventListener('scroll', Parallax._handleScrollThrottled);
|
|
109
|
-
window.removeEventListener('resize', Parallax._handleWindowResizeThrottled);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
_setupStyles() {
|
|
114
|
-
this._img.style.opacity = '1';
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
_handleImageLoad = () => {
|
|
118
|
-
this._updateParallax();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
private _offset(el: Element) {
|
|
122
|
-
const box = el.getBoundingClientRect();
|
|
123
|
-
const docElem = document.documentElement;
|
|
124
|
-
return {
|
|
125
|
-
top: box.top + window.pageYOffset - docElem.clientTop,
|
|
126
|
-
left: box.left + window.pageXOffset - docElem.clientLeft
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
_updateParallax() {
|
|
131
|
-
const containerHeight = this.el.getBoundingClientRect().height > 0 ? (this.el.parentNode as any).offsetHeight : 500;
|
|
132
|
-
const imgHeight = this._img.offsetHeight;
|
|
133
|
-
const parallaxDist = imgHeight - containerHeight;
|
|
134
|
-
const bottom = this._offset(this.el).top + containerHeight;
|
|
135
|
-
const top = this._offset(this.el).top;
|
|
136
|
-
const scrollTop = Utils.getDocumentScrollTop();
|
|
137
|
-
const windowHeight = window.innerHeight;
|
|
138
|
-
const windowBottom = scrollTop + windowHeight;
|
|
139
|
-
const percentScrolled = (windowBottom - top) / (containerHeight + windowHeight);
|
|
140
|
-
const parallax = parallaxDist * percentScrolled;
|
|
141
|
-
|
|
142
|
-
if (!this._enabled) {
|
|
143
|
-
this._img.style.transform = '';
|
|
144
|
-
}
|
|
145
|
-
else if (bottom > scrollTop && top < scrollTop + windowHeight) {
|
|
146
|
-
this._img.style.transform = `translate3D(-50%, ${parallax}px, 0)`;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
}
|
package/src/pushpin.ts
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
import { Utils } from "./utils";
|
|
2
|
-
import { Component, BaseOptions, InitElements, MElement } from "./component";
|
|
3
|
-
|
|
4
|
-
export interface PushpinOptions extends BaseOptions {
|
|
5
|
-
/**
|
|
6
|
-
* The distance in pixels from the top of the page where
|
|
7
|
-
* the element becomes fixed.
|
|
8
|
-
* @default 0
|
|
9
|
-
*/
|
|
10
|
-
top: number;
|
|
11
|
-
/**
|
|
12
|
-
* The distance in pixels from the top of the page where
|
|
13
|
-
* the elements stops being fixed.
|
|
14
|
-
* @default Infinity
|
|
15
|
-
*/
|
|
16
|
-
bottom: number;
|
|
17
|
-
/**
|
|
18
|
-
* The offset from the top the element will be fixed at.
|
|
19
|
-
* @default 0
|
|
20
|
-
*/
|
|
21
|
-
offset: number;
|
|
22
|
-
/**
|
|
23
|
-
* Callback function called when pushpin position changes.
|
|
24
|
-
* You are provided with a position string.
|
|
25
|
-
* @default null
|
|
26
|
-
*/
|
|
27
|
-
onPositionChange: (position: "pinned" | "pin-top" | "pin-bottom") => void;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
let _defaults = {
|
|
31
|
-
top: 0,
|
|
32
|
-
bottom: Infinity,
|
|
33
|
-
offset: 0,
|
|
34
|
-
onPositionChange: null
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
export class Pushpin extends Component<PushpinOptions> {
|
|
38
|
-
static _pushpins: any[];
|
|
39
|
-
originalOffset: any;
|
|
40
|
-
|
|
41
|
-
constructor(el: HTMLElement, options: Partial<PushpinOptions>) {
|
|
42
|
-
super(el, options, Pushpin);
|
|
43
|
-
(this.el as any).M_Pushpin = this;
|
|
44
|
-
|
|
45
|
-
this.options = {
|
|
46
|
-
...Pushpin.defaults,
|
|
47
|
-
...options
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
this.originalOffset = (this.el as HTMLElement).offsetTop;
|
|
51
|
-
Pushpin._pushpins.push(this);
|
|
52
|
-
this._setupEventHandlers();
|
|
53
|
-
this._updatePosition();
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
static get defaults(): PushpinOptions {
|
|
57
|
-
return _defaults;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Initializes instance of Pushpin.
|
|
62
|
-
* @param el HTML element.
|
|
63
|
-
* @param options Component options.
|
|
64
|
-
*/
|
|
65
|
-
static init(el: HTMLElement, options?: Partial<PushpinOptions>): Pushpin;
|
|
66
|
-
/**
|
|
67
|
-
* Initializes instances of Pushpin.
|
|
68
|
-
* @param els HTML elements.
|
|
69
|
-
* @param options Component options.
|
|
70
|
-
*/
|
|
71
|
-
static init(els: InitElements<MElement>, options?: Partial<PushpinOptions>): Pushpin[];
|
|
72
|
-
/**
|
|
73
|
-
* Initializes instances of Pushpin.
|
|
74
|
-
* @param els HTML elements.
|
|
75
|
-
* @param options Component options.
|
|
76
|
-
*/
|
|
77
|
-
static init(els: HTMLElement | InitElements<MElement>, options: Partial<PushpinOptions> = {}): Pushpin | Pushpin[] {
|
|
78
|
-
return super.init(els, options, Pushpin);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
static getInstance(el: HTMLElement): Pushpin {
|
|
82
|
-
return (el as any).M_Pushpin;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
destroy() {
|
|
86
|
-
(this.el as HTMLElement).style.top = null;
|
|
87
|
-
this._removePinClasses();
|
|
88
|
-
// Remove pushpin Inst
|
|
89
|
-
let index = Pushpin._pushpins.indexOf(this);
|
|
90
|
-
Pushpin._pushpins.splice(index, 1);
|
|
91
|
-
if (Pushpin._pushpins.length === 0) {
|
|
92
|
-
this._removeEventHandlers();
|
|
93
|
-
}
|
|
94
|
-
(this.el as any).M_Pushpin = undefined;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
static _updateElements() {
|
|
98
|
-
for (let elIndex in Pushpin._pushpins) {
|
|
99
|
-
let pInstance = Pushpin._pushpins[elIndex];
|
|
100
|
-
pInstance._updatePosition();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
_setupEventHandlers() {
|
|
105
|
-
document.addEventListener('scroll', Pushpin._updateElements);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
_removeEventHandlers() {
|
|
109
|
-
document.removeEventListener('scroll', Pushpin._updateElements);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
_updatePosition() {
|
|
113
|
-
let scrolled = Utils.getDocumentScrollTop() + this.options.offset;
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
this.options.top <= scrolled &&
|
|
117
|
-
this.options.bottom >= scrolled &&
|
|
118
|
-
!this.el.classList.contains('pinned')
|
|
119
|
-
) {
|
|
120
|
-
this._removePinClasses();
|
|
121
|
-
(this.el as HTMLElement).style.top = `${this.options.offset}px`;
|
|
122
|
-
this.el.classList.add('pinned');
|
|
123
|
-
|
|
124
|
-
// onPositionChange callback
|
|
125
|
-
if (typeof this.options.onPositionChange === 'function') {
|
|
126
|
-
this.options.onPositionChange.call(this, 'pinned');
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Add pin-top (when scrolled position is above top)
|
|
131
|
-
if (scrolled < this.options.top && !this.el.classList.contains('pin-top')) {
|
|
132
|
-
this._removePinClasses();
|
|
133
|
-
(this.el as HTMLElement).style.top = '0';
|
|
134
|
-
this.el.classList.add('pin-top');
|
|
135
|
-
|
|
136
|
-
// onPositionChange callback
|
|
137
|
-
if (typeof this.options.onPositionChange === 'function') {
|
|
138
|
-
this.options.onPositionChange.call(this, 'pin-top');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Add pin-bottom (when scrolled position is below bottom)
|
|
143
|
-
if (scrolled > this.options.bottom && !this.el.classList.contains('pin-bottom')) {
|
|
144
|
-
this._removePinClasses();
|
|
145
|
-
this.el.classList.add('pin-bottom');
|
|
146
|
-
(this.el as HTMLElement).style.top = `${this.options.bottom - this.originalOffset}px`;
|
|
147
|
-
|
|
148
|
-
// onPositionChange callback
|
|
149
|
-
if (typeof this.options.onPositionChange === 'function') {
|
|
150
|
-
this.options.onPositionChange.call(this, 'pin-bottom');
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
_removePinClasses() {
|
|
156
|
-
// IE 11 bug (can't remove multiple classes in one line)
|
|
157
|
-
this.el.classList.remove('pin-top');
|
|
158
|
-
this.el.classList.remove('pinned');
|
|
159
|
-
this.el.classList.remove('pin-bottom');
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
static {
|
|
163
|
-
Pushpin._pushpins = [];
|
|
164
|
-
}
|
|
165
|
-
}
|