kmaterialize 2.0.0 → 2.3.3-1.0.0

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 (150) 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/materialize.scss +51 -0
  118. package/sass/mixins.module.scss +168 -0
  119. package/extras/noUiSlider/nouislider.css +0 -406
  120. package/extras/noUiSlider/nouislider.js +0 -2147
  121. package/extras/noUiSlider/nouislider.min.js +0 -1
  122. package/js/anime.min.js +0 -34
  123. package/js/autocomplete.js +0 -448
  124. package/js/buttons.js +0 -354
  125. package/js/cards.js +0 -40
  126. package/js/carousel.js +0 -717
  127. package/js/cash.js +0 -960
  128. package/js/characterCounter.js +0 -136
  129. package/js/chips.js +0 -481
  130. package/js/collapsible.js +0 -275
  131. package/js/component.js +0 -44
  132. package/js/datepicker.js +0 -975
  133. package/js/dropdown.js +0 -635
  134. package/js/forms.js +0 -275
  135. package/js/global.js +0 -444
  136. package/js/materialbox.js +0 -453
  137. package/js/modal.js +0 -382
  138. package/js/parallax.js +0 -138
  139. package/js/pushpin.js +0 -148
  140. package/js/range.js +0 -263
  141. package/js/scrollspy.js +0 -295
  142. package/js/select.js +0 -450
  143. package/js/sidenav.js +0 -580
  144. package/js/slider.js +0 -359
  145. package/js/tabs.js +0 -402
  146. package/js/tapTarget.js +0 -314
  147. package/js/timepicker.js +0 -647
  148. package/js/toasts.js +0 -310
  149. package/js/tooltip.js +0 -303
  150. package/js/waves.js +0 -335
@@ -0,0 +1,446 @@
1
+ import { Utils } from '../../src/utils';
2
+ import { BaseOptions, Component, InitElements, MElement } from '../../src/component';
3
+
4
+ export interface MaterialboxOptions extends BaseOptions {
5
+ /**
6
+ * Transition in duration in milliseconds.
7
+ * @default 275
8
+ */
9
+ inDuration: number;
10
+ /**
11
+ * Transition out duration in milliseconds.
12
+ * @default 200
13
+ */
14
+ outDuration: number;
15
+ /**
16
+ * Callback function called before materialbox is opened.
17
+ * @default null
18
+ */
19
+ onOpenStart: (el: Element) => void;
20
+ /**
21
+ * Callback function called after materialbox is opened.
22
+ * @default null
23
+ */
24
+ onOpenEnd: (el: Element) => void;
25
+ /**
26
+ * Callback function called before materialbox is closed.
27
+ * @default null
28
+ */
29
+ onCloseStart: (el: Element) => void;
30
+ /**
31
+ * Callback function called after materialbox is closed.
32
+ * @default null
33
+ */
34
+ onCloseEnd: (el: Element) => void;
35
+ }
36
+
37
+ const _defaults: MaterialboxOptions = {
38
+ inDuration: 275,
39
+ outDuration: 200,
40
+ onOpenStart: null,
41
+ onOpenEnd: null,
42
+ onCloseStart: null,
43
+ onCloseEnd: null
44
+ };
45
+
46
+ export class Materialbox extends Component<MaterialboxOptions> {
47
+ /** If the materialbox overlay is showing. */
48
+ overlayActive: boolean;
49
+ /** If the materialbox is no longer being animated. */
50
+ doneAnimating: boolean;
51
+ /** Caption, if specified. */
52
+ caption: string;
53
+ /** Original width of image. */
54
+ originalWidth: number;
55
+ /** Original height of image. */
56
+ originalHeight: number;
57
+ private originInlineStyles: string;
58
+ private placeholder: HTMLElement;
59
+ private _changedAncestorList: HTMLElement[];
60
+ private newHeight: number;
61
+ private newWidth: number;
62
+ private windowWidth: number;
63
+ private windowHeight: number;
64
+ private attrWidth: string;
65
+ private attrHeight: string;
66
+ private _overlay: HTMLElement;
67
+ private _photoCaption: HTMLElement;
68
+
69
+ constructor(el: HTMLElement, options: Partial<MaterialboxOptions>) {
70
+ super(el, options, Materialbox);
71
+ this.el['M_Materialbox'] = this;
72
+
73
+ this.options = {
74
+ ...Materialbox.defaults,
75
+ ...options
76
+ };
77
+
78
+ this.overlayActive = false;
79
+ this.doneAnimating = true;
80
+ this.placeholder = document.createElement('div');
81
+ this.placeholder.classList.add('material-placeholder');
82
+ this.originalWidth = 0;
83
+ this.originalHeight = 0;
84
+ this.originInlineStyles = this.el.getAttribute('style');
85
+ this.caption = this.el.getAttribute('data-caption') || '';
86
+ this.el.tabIndex = 0;
87
+ // Wrap
88
+ this.el.before(this.placeholder);
89
+ this.placeholder.append(this.el);
90
+ this._setupEventHandlers();
91
+ }
92
+
93
+ static get defaults(): MaterialboxOptions {
94
+ return _defaults;
95
+ }
96
+
97
+ /**
98
+ * Initializes instance of MaterialBox.
99
+ * @param el HTML element.
100
+ * @param options Component options.
101
+ */
102
+ static init(el: HTMLElement, options?: Partial<MaterialboxOptions>): Materialbox;
103
+ /**
104
+ * Initializes instances of MaterialBox.
105
+ * @param els HTML elements.
106
+ * @param options Component options.
107
+ */
108
+ static init(els: InitElements<MElement>, options?: Partial<MaterialboxOptions>): Materialbox[];
109
+ /**
110
+ * Initializes instances of MaterialBox.
111
+ * @param els HTML elements.
112
+ * @param options Component options.
113
+ */
114
+ static init(
115
+ els: HTMLElement | InitElements<MElement>,
116
+ options: Partial<MaterialboxOptions> = {}
117
+ ): Materialbox | Materialbox[] {
118
+ return super.init(els, options, Materialbox);
119
+ }
120
+
121
+ static getInstance(el: HTMLElement): Materialbox {
122
+ return el['M_Materialbox'];
123
+ }
124
+
125
+ destroy() {
126
+ this._removeEventHandlers();
127
+ this.el['M_Materialbox'] = undefined;
128
+ // Unwrap image
129
+ //this.placeholder.after(this.el).remove();
130
+ this.placeholder.remove();
131
+ this.el.removeAttribute('style');
132
+ }
133
+
134
+ private _setupEventHandlers() {
135
+ this.el.addEventListener('click', this._handleMaterialboxClick);
136
+ this.el.addEventListener('keypress', this._handleMaterialboxKeypress);
137
+ }
138
+
139
+ private _removeEventHandlers() {
140
+ this.el.removeEventListener('click', this._handleMaterialboxClick);
141
+ this.el.removeEventListener('keypress', this._handleMaterialboxKeypress);
142
+ }
143
+
144
+ private _handleMaterialboxClick = () => {
145
+ this._handleMaterialboxToggle();
146
+ };
147
+
148
+ private _handleMaterialboxKeypress = (e: KeyboardEvent) => {
149
+ if (Utils.keys.ENTER.includes(e.key)) {
150
+ this._handleMaterialboxToggle();
151
+ }
152
+ };
153
+
154
+ private _handleMaterialboxToggle = () => {
155
+ // If already modal, return to original
156
+ if (this.doneAnimating === false || (this.overlayActive && this.doneAnimating)) this.close();
157
+ else this.open();
158
+ };
159
+
160
+ private _handleWindowScroll = () => {
161
+ if (this.overlayActive) this.close();
162
+ };
163
+
164
+ private _handleWindowResize = () => {
165
+ if (this.overlayActive) this.close();
166
+ };
167
+
168
+ private _handleWindowEscape = (e: KeyboardEvent) => {
169
+ if (Utils.keys.ESC.includes(e.key) && this.doneAnimating && this.overlayActive) this.close();
170
+ };
171
+
172
+ private _makeAncestorsOverflowVisible() {
173
+ this._changedAncestorList = [];
174
+ let ancestor = this.placeholder.parentNode;
175
+ while (ancestor !== null && ancestor !== document) {
176
+ const curr = <HTMLElement>ancestor;
177
+ if (curr.style.overflow !== 'visible') {
178
+ curr.style.overflow = 'visible';
179
+ this._changedAncestorList.push(curr);
180
+ }
181
+ ancestor = ancestor.parentNode;
182
+ }
183
+ }
184
+
185
+ private _offset(el: HTMLElement) {
186
+ const box = el.getBoundingClientRect();
187
+ const docElem = document.documentElement;
188
+ return {
189
+ top: box.top + window.scrollY - docElem.clientTop,
190
+ left: box.left + window.scrollX - docElem.clientLeft
191
+ };
192
+ }
193
+ private _updateVars(): void {
194
+ this.windowWidth = window.innerWidth;
195
+ this.windowHeight = window.innerHeight;
196
+ this.caption = this.el.getAttribute('data-caption') || '';
197
+ }
198
+
199
+ // Image
200
+ private _animateImageIn(): void {
201
+ this.el.style.maxHeight = this.newHeight.toString() + 'px';
202
+ this.el.style.maxWidth = this.newWidth.toString() + 'px';
203
+ const duration = this.options.inDuration;
204
+ // from
205
+ this.el.style.transition = 'none';
206
+ this.el.style.height = this.originalHeight + 'px';
207
+ this.el.style.width = this.originalWidth + 'px';
208
+ setTimeout(() => {
209
+ // easeOutQuad
210
+ this.el.style.transition = `height ${duration}ms ease,
211
+ width ${duration}ms ease,
212
+ left ${duration}ms ease,
213
+ top ${duration}ms ease
214
+ `;
215
+ // to
216
+ this.el.style.height = this.newHeight + 'px';
217
+ this.el.style.width = this.newWidth + 'px';
218
+ this.el.style.left =
219
+ Utils.getDocumentScrollLeft() +
220
+ this.windowWidth / 2 -
221
+ this._offset(this.placeholder).left -
222
+ this.newWidth / 2 +
223
+ 'px';
224
+
225
+ this.el.style.top =
226
+ Utils.getDocumentScrollTop() +
227
+ this.windowHeight / 2 -
228
+ this._offset(this.placeholder).top -
229
+ this.newHeight / 2 +
230
+ 'px';
231
+ }, 1);
232
+
233
+ setTimeout(() => {
234
+ this.doneAnimating = true;
235
+ if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el);
236
+ }, duration);
237
+
238
+ /*
239
+ anim({
240
+ targets: this.el, // image
241
+ height: [this.originalHeight, this.newHeight],
242
+ width: [this.originalWidth, this.newWidth],
243
+ left:
244
+ Utils.getDocumentScrollLeft() +
245
+ this.windowWidth / 2 -
246
+ this._offset(this.placeholder).left -
247
+ this.newWidth / 2,
248
+ top:
249
+ Utils.getDocumentScrollTop() +
250
+ this.windowHeight / 2 -
251
+ this._offset(this.placeholder).top -
252
+ this.newHeight / 2,
253
+
254
+ duration: this.options.inDuration,
255
+ easing: 'easeOutQuad',
256
+ complete: () => {
257
+ this.doneAnimating = true;
258
+ if (typeof this.options.onOpenEnd === 'function') this.options.onOpenEnd.call(this, this.el);
259
+ }
260
+ });
261
+ */
262
+ }
263
+ private _animateImageOut(): void {
264
+ const duration = this.options.outDuration;
265
+ // easeOutQuad
266
+ this.el.style.transition = `height ${duration}ms ease,
267
+ width ${duration}ms ease,
268
+ left ${duration}ms ease,
269
+ top ${duration}ms ease
270
+ `;
271
+ // to
272
+ this.el.style.height = this.originalWidth + 'px';
273
+ this.el.style.width = this.originalWidth + 'px';
274
+ this.el.style.left = '0';
275
+ this.el.style.top = '0';
276
+ setTimeout(() => {
277
+ this.placeholder.style.height = '';
278
+ this.placeholder.style.width = '';
279
+ this.placeholder.style.position = '';
280
+ this.placeholder.style.top = '';
281
+ this.placeholder.style.left = '';
282
+ // Revert to width or height attribute
283
+ if (this.attrWidth) this.el.setAttribute('width', this.attrWidth.toString());
284
+ if (this.attrHeight) this.el.setAttribute('height', this.attrHeight.toString());
285
+ this.el.removeAttribute('style');
286
+ if (this.originInlineStyles) this.el.setAttribute('style', this.originInlineStyles);
287
+ // Remove class
288
+ this.el.classList.remove('active');
289
+ this.doneAnimating = true;
290
+ // Remove overflow overrides on ancestors
291
+ this._changedAncestorList.forEach((anchestor) => (anchestor.style.overflow = ''));
292
+ // onCloseEnd callback
293
+ if (typeof this.options.onCloseEnd === 'function')
294
+ this.options.onCloseEnd.call(this, this.el);
295
+ }, duration);
296
+ }
297
+
298
+ // Caption
299
+ private _addCaption(): void {
300
+ this._photoCaption = document.createElement('div');
301
+ this._photoCaption.classList.add('materialbox-caption');
302
+ this._photoCaption.innerText = this.caption;
303
+ document.body.append(this._photoCaption);
304
+ this._photoCaption.style.display = 'inline';
305
+ // Animate
306
+ this._photoCaption.style.transition = 'none';
307
+ this._photoCaption.style.opacity = '0';
308
+ const duration = this.options.inDuration;
309
+ setTimeout(() => {
310
+ this._photoCaption.style.transition = `opacity ${duration}ms ease`;
311
+ this._photoCaption.style.opacity = '1';
312
+ }, 1);
313
+ }
314
+ private _removeCaption(): void {
315
+ const duration = this.options.outDuration;
316
+ this._photoCaption.style.transition = `opacity ${duration}ms ease`;
317
+ this._photoCaption.style.opacity = '0';
318
+ setTimeout(() => {
319
+ this._photoCaption.remove();
320
+ }, duration);
321
+ }
322
+
323
+ // Overlay
324
+ private _addOverlay(): void {
325
+ this._overlay = document.createElement('div');
326
+ this._overlay.id = 'materialbox-overlay';
327
+ this._overlay.addEventListener(
328
+ 'click',
329
+ () => {
330
+ if (this.doneAnimating) this.close();
331
+ },
332
+ { once: true }
333
+ );
334
+
335
+ // Put before in origin image to preserve z-index layering.
336
+ this.el.before(this._overlay);
337
+
338
+ // Set dimensions if needed
339
+ const overlayOffset = this._overlay.getBoundingClientRect();
340
+ this._overlay.style.width = this.windowWidth + 'px';
341
+ this._overlay.style.height = this.windowHeight + 'px';
342
+ this._overlay.style.left = -1 * overlayOffset.left + 'px';
343
+ this._overlay.style.top = -1 * overlayOffset.top + 'px';
344
+
345
+ // Animate
346
+ this._overlay.style.transition = 'none';
347
+ this._overlay.style.opacity = '0';
348
+ const duration = this.options.inDuration;
349
+ setTimeout(() => {
350
+ this._overlay.style.transition = `opacity ${duration}ms ease`;
351
+ this._overlay.style.opacity = '1';
352
+ }, 1);
353
+ }
354
+ private _removeOverlay(): void {
355
+ const duration = this.options.outDuration;
356
+ this._overlay.style.transition = `opacity ${duration}ms ease`;
357
+ this._overlay.style.opacity = '0';
358
+ setTimeout(() => {
359
+ this.overlayActive = false;
360
+ this._overlay.remove();
361
+ }, duration);
362
+ }
363
+
364
+ /**
365
+ * Open materialbox.
366
+ */
367
+ open = () => {
368
+ this._updateVars();
369
+ this.originalWidth = this.el.getBoundingClientRect().width;
370
+ this.originalHeight = this.el.getBoundingClientRect().height;
371
+ // Set states
372
+ this.doneAnimating = false;
373
+ this.el.classList.add('active');
374
+ this.overlayActive = true;
375
+ // onOpenStart callback
376
+ if (typeof this.options.onOpenStart === 'function')
377
+ this.options.onOpenStart.call(this, this.el);
378
+ // Set positioning for placeholder
379
+ this.placeholder.style.width = this.placeholder.getBoundingClientRect().width + 'px';
380
+ this.placeholder.style.height = this.placeholder.getBoundingClientRect().height + 'px';
381
+ this.placeholder.style.position = 'relative';
382
+ this.placeholder.style.top = '0';
383
+ this.placeholder.style.left = '0';
384
+ this._makeAncestorsOverflowVisible();
385
+ // Set css on origin
386
+ this.el.style.position = 'absolute';
387
+ this.el.style.zIndex = '1000';
388
+ this.el.style.willChange = 'left, top, width, height';
389
+ // Change from width or height attribute to css
390
+ this.attrWidth = this.el.getAttribute('width');
391
+ this.attrHeight = this.el.getAttribute('height');
392
+ if (this.attrWidth) {
393
+ this.el.style.width = this.attrWidth + 'px';
394
+ this.el.removeAttribute('width');
395
+ }
396
+ if (this.attrHeight) {
397
+ this.el.style.width = this.attrHeight + 'px';
398
+ this.el.removeAttribute('height');
399
+ }
400
+ this._addOverlay();
401
+ // Add and animate caption if it exists
402
+ if (this.caption !== '') this._addCaption();
403
+ // Resize Image
404
+ const widthPercent = this.originalWidth / this.windowWidth;
405
+ const heightPercent = this.originalHeight / this.windowHeight;
406
+ this.newWidth = 0;
407
+ this.newHeight = 0;
408
+ if (widthPercent > heightPercent) {
409
+ // Width first
410
+ const ratio = this.originalHeight / this.originalWidth;
411
+ this.newWidth = this.windowWidth * 0.9;
412
+ this.newHeight = this.windowWidth * 0.9 * ratio;
413
+ } else {
414
+ // Height first
415
+ const ratio = this.originalWidth / this.originalHeight;
416
+ this.newWidth = this.windowHeight * 0.9 * ratio;
417
+ this.newHeight = this.windowHeight * 0.9;
418
+ }
419
+ this._animateImageIn();
420
+ // Handle Exit triggers
421
+ window.addEventListener('scroll', this._handleWindowScroll);
422
+ window.addEventListener('resize', this._handleWindowResize);
423
+ window.addEventListener('keyup', this._handleWindowEscape);
424
+ };
425
+
426
+ /**
427
+ * Close materialbox.
428
+ */
429
+ close = () => {
430
+ this._updateVars();
431
+ this.doneAnimating = false;
432
+ // onCloseStart callback
433
+ if (typeof this.options.onCloseStart === 'function')
434
+ this.options.onCloseStart.call(this, this.el);
435
+ //anim.remove(this.el);
436
+ //anim.remove(this._overlay);
437
+ //if (this.caption !== '') anim.remove(this._photoCaption);
438
+ // disable exit handlers
439
+ window.removeEventListener('scroll', this._handleWindowScroll);
440
+ window.removeEventListener('resize', this._handleWindowResize);
441
+ window.removeEventListener('keyup', this._handleWindowEscape);
442
+ this._removeOverlay();
443
+ this._animateImageOut();
444
+ if (this.caption !== '') this._removeCaption();
445
+ };
446
+ }
@@ -0,0 +1,37 @@
1
+ describe('Materialbox:', () => {
2
+ const fixture = `<div id="transformTest" style="transform: translate3d(1px,1px,1px)">
3
+ <img
4
+ class="materialboxed"
5
+ width="650"
6
+ src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">
7
+ </div>`;
8
+
9
+ beforeEach(() => XloadHtml(fixture));
10
+ afterEach(() => XunloadFixtures());
11
+
12
+ describe('Materialbox opens correctly with transformed ancestor', () => {
13
+ it('Opens a correctly placed overlay when clicked', (done) => {
14
+ const transformMaterialbox = document.querySelector('#transformTest');
15
+ M.Materialbox.init(document.querySelector('.materialboxed'), {
16
+ inDuration: 0,
17
+ outDuration: 0
18
+ });
19
+ // Mouse click
20
+ click(transformMaterialbox.querySelector('.materialboxed'));
21
+ setTimeout(() => {
22
+ // Check overlay is attached
23
+ const overlay = transformMaterialbox.querySelector('#materialbox-overlay');
24
+ const overlayRect = overlay.getBoundingClientRect();
25
+ const windowWidth = window.innerWidth;
26
+ const windowHeight = window.innerHeight;
27
+ expect(overlay).toExist('because it is generated on init');
28
+ expect(overlay).toBeVisible('because materialbox was clicked');
29
+ expect(overlayRect.top).toEqual(0);
30
+ expect(overlayRect.left).toEqual(0);
31
+ expect(overlayRect.width).toEqual(windowWidth);
32
+ expect(overlayRect.height).toEqual(windowHeight);
33
+ done();
34
+ }, 10);
35
+ });
36
+ });
37
+ });
@@ -0,0 +1,111 @@
1
+ import { Component, BaseOptions, InitElements, MElement } from '../../src/component';
2
+
3
+ // Obsolete for versions > 2.1.1
4
+
5
+ interface ModalOptions extends BaseOptions {
6
+ opacity: number;
7
+ inDuration: number;
8
+ outDuration: number;
9
+ preventScrolling: boolean;
10
+ onOpenStart: (this: Modal, el: HTMLElement) => void;
11
+ onOpenEnd: (this: Modal, el: HTMLElement) => void;
12
+ onCloseStart: (el: HTMLElement) => void;
13
+ onCloseEnd: (el: HTMLElement) => void;
14
+ dismissible: boolean;
15
+ startingTop: string;
16
+ endingTop: string;
17
+ }
18
+
19
+ const _defaults = {
20
+ opacity: 0.5,
21
+ inDuration: 250,
22
+ outDuration: 250,
23
+ onOpenStart: null,
24
+ onOpenEnd: null,
25
+ onCloseStart: null,
26
+ onCloseEnd: null,
27
+ preventScrolling: true,
28
+ dismissible: true,
29
+ startingTop: '4%',
30
+ endingTop: '10%'
31
+ };
32
+
33
+ class Modal extends Component<ModalOptions> {
34
+ constructor(el: HTMLElement, options: Partial<ModalOptions>) {
35
+ super(el, options, Modal);
36
+ this.el['M_Modal'] = this;
37
+ this.options = {
38
+ ...Modal.defaults,
39
+ ...options
40
+ };
41
+ this.el.tabIndex = 0;
42
+ this._setupEventHandlers();
43
+ }
44
+
45
+ static get defaults() {
46
+ return _defaults;
47
+ }
48
+
49
+ static init(el: HTMLElement, options?: Partial<ModalOptions>): Modal;
50
+ static init(els: InitElements<MElement>, options?: Partial<ModalOptions>): Modal[];
51
+ static init(
52
+ els: HTMLElement | InitElements<MElement>,
53
+ options: Partial<ModalOptions> = {}
54
+ ): Modal | Modal[] {
55
+ return super.init(els, options, Modal);
56
+ }
57
+
58
+ static getInstance(el: HTMLElement): Modal {
59
+ return el['M_Modal'];
60
+ }
61
+
62
+ destroy() {}
63
+ _setupEventHandlers() {}
64
+ _removeEventHandlers() {}
65
+ _handleTriggerClick() {}
66
+ _handleOverlayClick() {}
67
+ _handleModalCloseClick() {}
68
+ _handleKeydown() {}
69
+ _handleFocus() {}
70
+ open() {
71
+ return this;
72
+ }
73
+ close() {
74
+ return this;
75
+ }
76
+
77
+ // Experimental!
78
+
79
+ static #createHtml(config: ModalCreateConfig) {
80
+ return `<dialog id="modal1" class="modal">
81
+ ${config.header ? '<div class="modal-header">' + config.header + '</div>' : ''}
82
+ <div class="modal-content">
83
+ ${config.content}
84
+ </div>
85
+ ${config.header ? '<div class="modal-footer">' + config.footer + '</div>' : ''}
86
+ </dialog>`;
87
+ }
88
+
89
+ static #createHtmlElement(config: ModalCreateConfig) {
90
+ const dialog = document.createElement('dialog');
91
+ dialog.id = config.id;
92
+ return dialog;
93
+ }
94
+
95
+ static create(config) {
96
+ const isServer = false;
97
+ if (isServer) return this.#createHtml(config);
98
+ return this.#createHtmlElement(config);
99
+ }
100
+
101
+ static {}
102
+ }
103
+
104
+ interface ModalCreateConfig {
105
+ id: string;
106
+ header: string | HTMLElement;
107
+ content: string | HTMLElement;
108
+ footer: string | HTMLElement;
109
+ }
110
+
111
+ export { Modal, ModalOptions };
@@ -0,0 +1,83 @@
1
+ describe('Modal:', () => {
2
+ const fixture = `<a class="btn tonal trigger waves-effect waves-light" href="#" onclick="modal1.showModal(); return false;">Modal</a>
3
+ <button class="btn btn-floating fixed-action-btn" onclick="modal1.showModal()"><i class="material-icons">menu</i></button>
4
+
5
+ <dialog id="modal1" class="modal">
6
+ <div class="modal-header">
7
+ <h4>Modal Header</h4>
8
+ </div>
9
+ <div class="modal-content">
10
+ <p>A bunch of text</p>
11
+ </div>
12
+ <div class="modal-footer">
13
+ <a href="#" onclick="modal1.close(); return false;" class="waves-effect waves-green btn-flat">Agree</a>
14
+ </div>
15
+ </dialog>
16
+ `;
17
+
18
+ beforeEach(() => XloadHtml(fixture));
19
+ afterEach(() => XunloadFixtures());
20
+
21
+ describe('Modals', () => {
22
+ it('Should open and close correctly', (done) => {
23
+ const modal1 = document.querySelector('.modal');
24
+ const trigger = document.querySelector('.trigger');
25
+ expect(modal1).toBeHidden('Modal should be hidden');
26
+ click(trigger);
27
+ setTimeout(() => {
28
+ expect(modal1).toBeVisible('Modal should be shown');
29
+ done();
30
+ }, 10);
31
+ });
32
+
33
+ it('Should open and close correctly with children elements in trigger', (done) => {
34
+ const modal1 = document.querySelector('.modal');
35
+ const triggerIcon1 = document.querySelector('button i');
36
+ expect(modal1).toBeHidden('Modal should be hidden');
37
+ click(triggerIcon1);
38
+ setTimeout(() => {
39
+ expect(modal1).toBeVisible('Modal should be shown');
40
+ done();
41
+ }, 10);
42
+ });
43
+
44
+ // it('Should have a dismissible option', (done) => {
45
+ // // M.Modal.init(modal1, {
46
+ // // dismissible: false,
47
+ // // inDuration: 0,
48
+ // // outDuration: 0
49
+ // // });
50
+ // click(trigger1);
51
+ // setTimeout(() => {
52
+ // expect(modal1).toBeVisible('Modal should be shown');
53
+ // let overlay = M.Modal.getInstance(modal1)._overlay;
54
+ // let overlayInDOM = document.contains(overlay);
55
+ // expect(overlayInDOM).toEqual(true, 'Overlay should be attached on open');
56
+ // click(overlay);
57
+ // setTimeout(() => {
58
+ // expect(modal1).toBeVisible('Modal should be shown');
59
+ // let overlayInDOM = document.contains(overlay);
60
+ // expect(overlayInDOM).toEqual(true, 'modal should not be dismissable');
61
+ // done();
62
+ // }, 10);
63
+ // }, 10);
64
+ // });
65
+
66
+ it('Should have callbacks', (done) => {
67
+ let hasBeenClosed = false;
68
+ const modal = document.querySelector('.modal');
69
+ const trigger1 = document.querySelector('.trigger');
70
+
71
+ modal.addEventListener('close', () => {
72
+ hasBeenClosed = true;
73
+ });
74
+ click(trigger1);
75
+ expect(hasBeenClosed).toEqual(false, 'callback not yet fired');
76
+ click(document.querySelector('.modal-footer a'));
77
+ setTimeout(() => {
78
+ expect(hasBeenClosed).toEqual(true, 'callback fired');
79
+ done();
80
+ }, 200);
81
+ });
82
+ });
83
+ });
@@ -0,0 +1,5 @@
1
+ # Dialog
2
+
3
+ *THIS SECTION IS FOR DEMONSTRATION ONLY*
4
+
5
+ Also called Modal.
@@ -0,0 +1,15 @@
1
+ # Divider
2
+
3
+ *THIS SECTION IS FOR DEMONSTRATION ONLY*
4
+
5
+ Usage:
6
+
7
+ ```html
8
+ <div class="divider"></div>
9
+ ```
10
+
11
+ ## Vertical Divider
12
+
13
+ ```html
14
+ <div class="divider-vertical"></div>
15
+ ```