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,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
+ ```