@materializecss/materialize 1.2.2 → 2.0.0-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.
Files changed (89) hide show
  1. package/Gruntfile.js +68 -313
  2. package/README.md +2 -2
  3. package/dist/css/materialize.css +1009 -1822
  4. package/dist/css/materialize.min.css +2 -8
  5. package/dist/js/materialize.js +8402 -12300
  6. package/dist/js/materialize.min.js +3 -2
  7. package/dist/js/materialize.min.js.map +1 -0
  8. package/package.json +13 -9
  9. package/sass/components/_badges.scss +12 -2
  10. package/sass/components/_buttons.scss +16 -11
  11. package/sass/components/_cards.scss +14 -9
  12. package/sass/components/_carousel.scss +5 -2
  13. package/sass/components/_chips.scss +3 -3
  14. package/sass/components/_collapsible.scss +22 -8
  15. package/sass/components/_collection.scss +14 -6
  16. package/sass/components/_datepicker.scss +30 -11
  17. package/sass/components/_dropdown.scss +6 -4
  18. package/sass/components/_global.scss +132 -111
  19. package/sass/components/_grid.scss +119 -98
  20. package/sass/components/_modal.scss +3 -3
  21. package/sass/components/_navbar.scss +31 -17
  22. package/sass/components/_normalize.scss +26 -124
  23. package/sass/components/_sidenav.scss +21 -20
  24. package/sass/components/_slider.scss +27 -7
  25. package/sass/components/_table_of_contents.scss +12 -12
  26. package/sass/components/_tabs.scss +47 -16
  27. package/sass/components/_tapTarget.scss +6 -6
  28. package/sass/components/_timepicker.scss +54 -46
  29. package/sass/components/_toast.scss +3 -3
  30. package/sass/components/_tooltip.scss +4 -5
  31. package/sass/components/_typography.scss +1 -1
  32. package/sass/components/_variables.scss +185 -120
  33. package/sass/components/forms/_checkboxes.scss +9 -9
  34. package/sass/components/forms/_file-input.scss +9 -7
  35. package/sass/components/forms/_input-fields.scss +173 -234
  36. package/sass/components/forms/_radio-buttons.scss +1 -1
  37. package/sass/components/forms/_range.scss +11 -11
  38. package/sass/components/forms/_select.scss +29 -19
  39. package/sass/components/forms/_switches.scss +22 -18
  40. package/sass/materialize.scss +1 -1
  41. package/src/autocomplete.ts +459 -0
  42. package/src/bounding.ts +6 -0
  43. package/{js/buttons.js → src/buttons.ts} +103 -162
  44. package/src/cards.ts +54 -0
  45. package/{js/carousel.js → src/carousel.ts} +137 -262
  46. package/src/characterCounter.ts +88 -0
  47. package/src/chips.ts +350 -0
  48. package/src/collapsible.ts +184 -0
  49. package/{js/component.js → src/component.ts} +6 -19
  50. package/{js/datepicker.js → src/datepicker.ts} +213 -299
  51. package/{js/dropdown.js → src/dropdown.ts} +140 -254
  52. package/src/edges.ts +6 -0
  53. package/src/forms.ts +120 -0
  54. package/src/global.ts +385 -0
  55. package/src/materialbox.ts +348 -0
  56. package/src/modal.ts +256 -0
  57. package/{js/parallax.js → src/parallax.ts} +47 -60
  58. package/{js/pushpin.js → src/pushpin.ts} +19 -47
  59. package/{js/range.js → src/range.ts} +58 -139
  60. package/{js/scrollspy.js → src/scrollspy.ts} +81 -153
  61. package/src/select.ts +448 -0
  62. package/{js/sidenav.js → src/sidenav.ts} +96 -202
  63. package/src/slider.ts +415 -0
  64. package/src/tabs.ts +290 -0
  65. package/src/tapTarget.ts +240 -0
  66. package/{js/timepicker.js → src/timepicker.ts} +268 -272
  67. package/{js/toasts.js → src/toasts.ts} +75 -134
  68. package/{js/tooltip.js → src/tooltip.ts} +59 -96
  69. package/src/waves.ts +70 -0
  70. package/extras/noUiSlider/nouislider.css +0 -404
  71. package/extras/noUiSlider/nouislider.js +0 -2147
  72. package/extras/noUiSlider/nouislider.min.js +0 -1
  73. package/js/anime.min.js +0 -34
  74. package/js/autocomplete.js +0 -479
  75. package/js/cards.js +0 -40
  76. package/js/cash.js +0 -960
  77. package/js/characterCounter.js +0 -136
  78. package/js/chips.js +0 -486
  79. package/js/collapsible.js +0 -275
  80. package/js/forms.js +0 -285
  81. package/js/global.js +0 -428
  82. package/js/materialbox.js +0 -453
  83. package/js/modal.js +0 -382
  84. package/js/select.js +0 -391
  85. package/js/slider.js +0 -497
  86. package/js/tabs.js +0 -402
  87. package/js/tapTarget.js +0 -315
  88. package/js/waves.js +0 -615
  89. package/sass/components/_waves.scss +0 -187
@@ -1,7 +1,8 @@
1
- (function($, anim) {
2
- 'use strict';
1
+ import { Component } from "./component";
2
+ import { M } from "./global";
3
+ import anim from "animejs";
3
4
 
4
- let _defaults = {
5
+ const _defaults = {
5
6
  alignment: 'left',
6
7
  autoFocus: true,
7
8
  constrainWidth: true,
@@ -18,63 +19,44 @@
18
19
  onItemClick: null
19
20
  };
20
21
 
21
- /**
22
- * @class
23
- */
24
- class Dropdown extends Component {
22
+ export class Dropdown extends Component {
23
+ el: HTMLElement;
24
+ static _dropdowns: Dropdown[] = [];
25
+ id: string;
26
+ dropdownEl: HTMLElement;
27
+ isOpen: boolean;
28
+ isScrollable: boolean;
29
+ isTouchMoving: boolean;
30
+ focusedIndex: number;
31
+ filterQuery: any[];
32
+ private _resetFilterQueryBound: any;
33
+ private _handleDocumentClickBound: any;
34
+ private _handleDocumentTouchmoveBound: any;
35
+ private _handleDropdownClickBound: any;
36
+ private _handleDropdownKeydownBound: any;
37
+ private _handleTriggerKeydownBound: any;
38
+ private _handleMouseEnterBound: any;
39
+ private _handleMouseLeaveBound: any;
40
+ _handleClickBound: any;
41
+ filterTimeout: NodeJS.Timeout;
42
+
25
43
  constructor(el, options) {
26
44
  super(Dropdown, el, options);
27
-
28
- this.el.M_Dropdown = this;
45
+ (this.el as any).M_Dropdown = this;
29
46
  Dropdown._dropdowns.push(this);
30
-
31
47
  this.id = M.getIdFromTrigger(el);
32
48
  this.dropdownEl = document.getElementById(this.id);
33
- this.$dropdownEl = $(this.dropdownEl);
34
-
35
- /**
36
- * Options for the dropdown
37
- * @member Dropdown#options
38
- * @prop {String} [alignment='left'] - Edge which the dropdown is aligned to
39
- * @prop {Boolean} [autoFocus=true] - Automatically focus dropdown el for keyboard
40
- * @prop {Boolean} [constrainWidth=true] - Constrain width to width of the button
41
- * @prop {Element} container - Container element to attach dropdown to (optional)
42
- * @prop {Boolean} [coverTrigger=true] - Place dropdown over trigger
43
- * @prop {Boolean} [closeOnClick=true] - Close on click of dropdown item
44
- * @prop {Boolean} [hover=false] - Open dropdown on hover
45
- * @prop {Number} [inDuration=150] - Duration of open animation in ms
46
- * @prop {Number} [outDuration=250] - Duration of close animation in ms
47
- * @prop {Function} onOpenStart - Function called when dropdown starts opening
48
- * @prop {Function} onOpenEnd - Function called when dropdown finishes opening
49
- * @prop {Function} onCloseStart - Function called when dropdown starts closing
50
- * @prop {Function} onCloseEnd - Function called when dropdown finishes closing
51
- */
52
- this.options = $.extend({}, Dropdown.defaults, options);
53
-
54
- /**
55
- * Describes open/close state of dropdown
56
- * @type {Boolean}
57
- */
58
- this.isOpen = false;
49
+ //this.$dropdownEl = $(this.dropdownEl);
50
+ this.options = {...Dropdown.defaults, ...options};
59
51
 
60
- /**
61
- * Describes if dropdown content is scrollable
62
- * @type {Boolean}
63
- */
52
+ this.isOpen = false;
64
53
  this.isScrollable = false;
65
-
66
- /**
67
- * Describes if touch moving on dropdown content
68
- * @type {Boolean}
69
- */
70
54
  this.isTouchMoving = false;
71
-
72
55
  this.focusedIndex = -1;
73
56
  this.filterQuery = [];
74
57
 
75
58
  // Move dropdown-content after dropdown-trigger
76
59
  this._moveDropdown();
77
-
78
60
  this._makeDropdownFocusable();
79
61
  this._resetFilterQueryBound = this._resetFilterQuery.bind(this);
80
62
  this._handleDocumentClickBound = this._handleDocumentClick.bind(this);
@@ -93,34 +75,23 @@
93
75
  return super.init(this, els, options);
94
76
  }
95
77
 
96
- /**
97
- * Get Instance
98
- */
99
78
  static getInstance(el) {
100
- let domElem = !!el.jquery ? el[0] : el;
79
+ const domElem = !!el.jquery ? el[0] : el;
101
80
  return domElem.M_Dropdown;
102
81
  }
103
82
 
104
- /**
105
- * Teardown component
106
- */
107
83
  destroy() {
108
84
  this._resetDropdownStyles();
109
85
  this._removeEventHandlers();
110
86
  Dropdown._dropdowns.splice(Dropdown._dropdowns.indexOf(this), 1);
111
- this.el.M_Dropdown = undefined;
87
+ (this.el as any).M_Dropdown = undefined;
112
88
  }
113
89
 
114
- /**
115
- * Setup Event Handlers
116
- */
117
90
  _setupEventHandlers() {
118
91
  // Trigger keydown handler
119
92
  this.el.addEventListener('keydown', this._handleTriggerKeydownBound);
120
-
121
93
  // Item click handler
122
- this.dropdownEl.addEventListener('click', this._handleDropdownClickBound);
123
-
94
+ this.dropdownEl?.addEventListener('click', this._handleDropdownClickBound);
124
95
  // Hover event handlers
125
96
  if (this.options.hover) {
126
97
  this._handleMouseEnterBound = this._handleMouseEnter.bind(this);
@@ -128,7 +99,6 @@
128
99
  this._handleMouseLeaveBound = this._handleMouseLeave.bind(this);
129
100
  this.el.addEventListener('mouseleave', this._handleMouseLeaveBound);
130
101
  this.dropdownEl.addEventListener('mouseleave', this._handleMouseLeaveBound);
131
-
132
102
  // Click event handlers
133
103
  } else {
134
104
  this._handleClickBound = this._handleClick.bind(this);
@@ -136,13 +106,9 @@
136
106
  }
137
107
  }
138
108
 
139
- /**
140
- * Remove Event Handlers
141
- */
142
109
  _removeEventHandlers() {
143
110
  this.el.removeEventListener('keydown', this._handleTriggerKeydownBound);
144
111
  this.dropdownEl.removeEventListener('click', this._handleDropdownClickBound);
145
-
146
112
  if (this.options.hover) {
147
113
  this.el.removeEventListener('mouseenter', this._handleMouseEnterBound);
148
114
  this.el.removeEventListener('mouseleave', this._handleMouseLeaveBound);
@@ -176,19 +142,17 @@
176
142
  }
177
143
 
178
144
  _handleMouseLeave(e) {
179
- let toEl = e.toElement || e.relatedTarget;
180
- let leaveToDropdownContent = !!$(toEl).closest('.dropdown-content').length;
145
+ const toEl = e.toElement || e.relatedTarget;
146
+ const leaveToDropdownContent = !!toEl.closest('.dropdown-content');
181
147
  let leaveToActiveDropdownTrigger = false;
182
-
183
- let $closestTrigger = $(toEl).closest('.dropdown-trigger');
148
+ const closestTrigger = toEl.closest('.dropdown-trigger');
184
149
  if (
185
- $closestTrigger.length &&
186
- !!$closestTrigger[0].M_Dropdown &&
187
- $closestTrigger[0].M_Dropdown.isOpen
150
+ closestTrigger &&
151
+ !!(<any>closestTrigger).M_Dropdown &&
152
+ (<any>closestTrigger).M_Dropdown.isOpen
188
153
  ) {
189
154
  leaveToActiveDropdownTrigger = true;
190
155
  }
191
-
192
156
  // Close hover dropdown if mouse did not leave to either active dropdown-trigger or dropdown-content
193
157
  if (!leaveToActiveDropdownTrigger && !leaveToDropdownContent) {
194
158
  this.close();
@@ -196,23 +160,24 @@
196
160
  }
197
161
 
198
162
  _handleDocumentClick(e) {
199
- let $target = $(e.target);
163
+ const target = <HTMLElement>e.target;
200
164
  if (
201
165
  this.options.closeOnClick &&
202
- $target.closest('.dropdown-content').length &&
166
+ target.closest('.dropdown-content') &&
203
167
  !this.isTouchMoving
204
168
  ) {
205
169
  // isTouchMoving to check if scrolling on mobile.
206
- setTimeout(() => {
207
- this.close();
208
- }, 0);
209
- } else if (
210
- $target.closest('.dropdown-trigger').length ||
211
- !$target.closest('.dropdown-content').length
170
+ //setTimeout(() => {
171
+ this.close();
172
+ //}, 0);
173
+ }
174
+ else if (
175
+ target.closest('.dropdown-trigger') ||
176
+ !target.closest('.dropdown-content')
212
177
  ) {
213
- setTimeout(() => {
214
- this.close();
215
- }, 0);
178
+ //setTimeout(() => {
179
+ this.close();
180
+ //}, 0);
216
181
  }
217
182
  this.isTouchMoving = false;
218
183
  }
@@ -225,157 +190,127 @@
225
190
  }
226
191
  }
227
192
 
228
- /**
229
- * Handle Document Touchmove
230
- * @param {Event} e
231
- */
232
193
  _handleDocumentTouchmove(e) {
233
- let $target = $(e.target);
234
- if ($target.closest('.dropdown-content').length) {
194
+ const target = <HTMLElement>e.target;
195
+ if (target.closest('.dropdown-content')) {
235
196
  this.isTouchMoving = true;
236
197
  }
237
198
  }
238
199
 
239
- /**
240
- * Handle Dropdown Click
241
- * @param {Event} e
242
- */
243
200
  _handleDropdownClick(e) {
244
201
  // onItemClick callback
245
202
  if (typeof this.options.onItemClick === 'function') {
246
- let itemEl = $(e.target).closest('li')[0];
203
+ const itemEl = <HTMLElement>e.target.closest('li');
247
204
  this.options.onItemClick.call(this, itemEl);
248
205
  }
249
206
  }
250
207
 
251
- /**
252
- * Handle Dropdown Keydown
253
- * @param {Event} e
254
- */
255
208
  _handleDropdownKeydown(e) {
256
209
  if (e.which === M.keys.TAB) {
257
210
  e.preventDefault();
258
211
  this.close();
259
-
260
- // Navigate down dropdown list
261
- } else if ((e.which === M.keys.ARROW_DOWN || e.which === M.keys.ARROW_UP) && this.isOpen) {
212
+ }
213
+ // Navigate down dropdown list
214
+ else if ((e.which === M.keys.ARROW_DOWN || e.which === M.keys.ARROW_UP) && this.isOpen) {
262
215
  e.preventDefault();
263
- let direction = e.which === M.keys.ARROW_DOWN ? 1 : -1;
216
+ const direction = e.which === M.keys.ARROW_DOWN ? 1 : -1;
264
217
  let newFocusedIndex = this.focusedIndex;
265
- let foundNewIndex = false;
218
+ let hasFoundNewIndex = false;
266
219
  do {
267
220
  newFocusedIndex = newFocusedIndex + direction;
268
-
269
221
  if (
270
222
  !!this.dropdownEl.children[newFocusedIndex] &&
271
- this.dropdownEl.children[newFocusedIndex].tabIndex !== -1
223
+ (<any>this.dropdownEl.children[newFocusedIndex]).tabIndex !== -1
272
224
  ) {
273
- foundNewIndex = true;
225
+ hasFoundNewIndex = true;
274
226
  break;
275
227
  }
276
228
  } while (newFocusedIndex < this.dropdownEl.children.length && newFocusedIndex >= 0);
277
229
 
278
- if (foundNewIndex) {
230
+ if (hasFoundNewIndex) {
279
231
  // Remove active class from old element
280
232
  if (this.focusedIndex >= 0)
281
233
  this.dropdownEl.children[this.focusedIndex].classList.remove('active');
282
234
  this.focusedIndex = newFocusedIndex;
283
235
  this._focusFocusedItem();
284
236
  }
285
-
286
- // ENTER selects choice on focused item
287
- } else if (e.which === M.keys.ENTER && this.isOpen) {
237
+ }
238
+ // ENTER selects choice on focused item
239
+ else if (e.which === M.keys.ENTER && this.isOpen) {
288
240
  // Search for <a> and <button>
289
- let focusedElement = this.dropdownEl.children[this.focusedIndex];
290
- let $activatableElement = $(focusedElement)
291
- .find('a, button')
292
- .first();
293
-
241
+ const focusedElement = this.dropdownEl.children[this.focusedIndex];
242
+ const activatableElement = <HTMLElement>focusedElement.querySelector('a, button');
294
243
  // Click a or button tag if exists, otherwise click li tag
295
- if (!!$activatableElement.length) {
296
- $activatableElement[0].click();
297
- } else if (!!focusedElement) {
298
- focusedElement.click();
244
+ if (!!activatableElement) {
245
+ activatableElement.click();
299
246
  }
300
-
301
- // Close dropdown on ESC
302
- } else if (e.which === M.keys.ESC && this.isOpen) {
247
+ else if (!!focusedElement) {
248
+ if (focusedElement instanceof HTMLElement) {
249
+ focusedElement.click();
250
+ }
251
+ }
252
+ }
253
+ // Close dropdown on ESC
254
+ else if (e.which === M.keys.ESC && this.isOpen) {
303
255
  e.preventDefault();
304
256
  this.close();
305
257
  }
306
258
 
307
259
  // CASE WHEN USER TYPE LETTERS
308
- let letter = String.fromCharCode(e.which).toLowerCase(),
309
- nonLetters = [9, 13, 27, 38, 40];
260
+ const letter = String.fromCharCode(e.which).toLowerCase();
261
+ const nonLetters = [9, 13, 27, 38, 40];
310
262
  if (letter && nonLetters.indexOf(e.which) === -1) {
311
263
  this.filterQuery.push(letter);
312
-
313
- let string = this.filterQuery.join(''),
314
- newOptionEl = $(this.dropdownEl)
315
- .find('li')
316
- .filter((el) => {
317
- return (
318
- $(el)
319
- .text()
320
- .toLowerCase()
321
- .indexOf(string) === 0
322
- );
323
- })[0];
324
-
264
+ const string = this.filterQuery.join('');
265
+ const newOptionEl = Array.from(this.dropdownEl.querySelectorAll('li'))
266
+ .find((el) => el.innerText.toLowerCase().indexOf(string) === 0);
325
267
  if (newOptionEl) {
326
- this.focusedIndex = $(newOptionEl).index();
268
+ this.focusedIndex = [...newOptionEl.parentNode.children].indexOf(newOptionEl);
327
269
  this._focusFocusedItem();
328
270
  }
329
271
  }
330
-
331
272
  this.filterTimeout = setTimeout(this._resetFilterQueryBound, 1000);
332
273
  }
333
274
 
334
- /**
335
- * Setup dropdown
336
- */
337
275
  _resetFilterQuery() {
338
276
  this.filterQuery = [];
339
277
  }
340
278
 
341
279
  _resetDropdownStyles() {
342
- this.$dropdownEl.css({
343
- display: '',
344
- width: '',
345
- height: '',
346
- left: '',
347
- top: '',
348
- 'transform-origin': '',
349
- transform: '',
350
- opacity: ''
351
- });
280
+ this.dropdownEl.style.display = '';
281
+ this.dropdownEl.style.width = '';
282
+ this.dropdownEl.style.height = '';
283
+ this.dropdownEl.style.left = '';
284
+ this.dropdownEl.style.top = '';
285
+ this.dropdownEl.style.transformOrigin = '';
286
+ this.dropdownEl.style.transform = '';
287
+ this.dropdownEl.style.opacity = '';
352
288
  }
353
289
 
354
290
  // Move dropdown after container or trigger
355
- _moveDropdown(containerEl) {
291
+ _moveDropdown(containerEl = null) {
356
292
  if (!!this.options.container) {
357
- $(this.options.container).append(this.dropdownEl);
358
- } else if (containerEl) {
293
+ this.options.container.append(this.dropdownEl);
294
+ }
295
+ else if (containerEl) {
359
296
  if (!containerEl.contains(this.dropdownEl)) {
360
- $(containerEl).append(this.dropdownEl);
297
+ containerEl.append(this.dropdownEl);
361
298
  }
362
- } else {
363
- this.$el.after(this.dropdownEl);
299
+ }
300
+ else {
301
+ this.el.after(this.dropdownEl);
364
302
  }
365
303
  }
366
304
 
367
305
  _makeDropdownFocusable() {
306
+ if (!this.dropdownEl) return;
368
307
  // Needed for arrow key navigation
369
308
  this.dropdownEl.tabIndex = 0;
370
-
371
309
  // Only set tabindex if it hasn't been set by user
372
- $(this.dropdownEl)
373
- .children()
374
- .each(function(el) {
375
- if (!el.getAttribute('tabindex')) {
376
- el.setAttribute('tabindex', 0);
377
- }
378
- });
310
+ Array.from(this.dropdownEl.children).forEach((el)=> {
311
+ if (!el.getAttribute('tabindex'))
312
+ el.setAttribute('tabindex', '0');
313
+ });
379
314
  }
380
315
 
381
316
  _focusFocusedItem() {
@@ -384,7 +319,7 @@
384
319
  this.focusedIndex < this.dropdownEl.children.length &&
385
320
  this.options.autoFocus
386
321
  ) {
387
- this.dropdownEl.children[this.focusedIndex].focus({
322
+ (this.dropdownEl.children[this.focusedIndex] as HTMLElement).focus({
388
323
  preventScroll: true
389
324
  });
390
325
  this.dropdownEl.children[this.focusedIndex].scrollIntoView({
@@ -396,23 +331,23 @@
396
331
  }
397
332
 
398
333
  _getDropdownPosition(closestOverflowParent) {
399
- let offsetParentBRect = this.el.offsetParent.getBoundingClientRect();
400
- let triggerBRect = this.el.getBoundingClientRect();
401
- let dropdownBRect = this.dropdownEl.getBoundingClientRect();
334
+ const offsetParentBRect = this.el.offsetParent.getBoundingClientRect();
335
+ const triggerBRect = this.el.getBoundingClientRect();
336
+ const dropdownBRect = this.dropdownEl.getBoundingClientRect();
402
337
 
403
338
  let idealHeight = dropdownBRect.height;
404
339
  let idealWidth = dropdownBRect.width;
405
340
  let idealXPos = triggerBRect.left - dropdownBRect.left;
406
341
  let idealYPos = triggerBRect.top - dropdownBRect.top;
407
342
 
408
- let dropdownBounds = {
343
+ const dropdownBounds = {
409
344
  left: idealXPos,
410
345
  top: idealYPos,
411
346
  height: idealHeight,
412
347
  width: idealWidth
413
348
  };
414
349
 
415
- let alignments = M.checkPossibleAlignments(
350
+ const alignments = M.checkPossibleAlignments(
416
351
  this.el,
417
352
  closestOverflowParent,
418
353
  dropdownBounds,
@@ -452,7 +387,7 @@
452
387
 
453
388
  // If preferred horizontal alignment is possible
454
389
  if (!alignments[horizontalAlignment]) {
455
- let oppositeAlignment = horizontalAlignment === 'left' ? 'right' : 'left';
390
+ const oppositeAlignment = horizontalAlignment === 'left' ? 'right' : 'left';
456
391
  if (alignments[oppositeAlignment]) {
457
392
  horizontalAlignment = oppositeAlignment;
458
393
  } else {
@@ -485,9 +420,6 @@
485
420
  };
486
421
  }
487
422
 
488
- /**
489
- * Animate in dropdown
490
- */
491
423
  _animateIn() {
492
424
  anim.remove(this.dropdownEl);
493
425
  anim({
@@ -501,10 +433,7 @@
501
433
  duration: this.options.inDuration,
502
434
  easing: 'easeOutQuint',
503
435
  complete: (anim) => {
504
- if (this.options.autoFocus) {
505
- this.dropdownEl.focus();
506
- }
507
-
436
+ if (this.options.autoFocus) this.dropdownEl.focus();
508
437
  // onOpenEnd callback
509
438
  if (typeof this.options.onOpenEnd === 'function') {
510
439
  this.options.onOpenEnd.call(this, this.el);
@@ -513,9 +442,6 @@
513
442
  });
514
443
  }
515
444
 
516
- /**
517
- * Animate out dropdown
518
- */
519
445
  _animateOut() {
520
446
  anim.remove(this.dropdownEl);
521
447
  anim({
@@ -530,7 +456,6 @@
530
456
  easing: 'easeOutQuint',
531
457
  complete: (anim) => {
532
458
  this._resetDropdownStyles();
533
-
534
459
  // onCloseEnd callback
535
460
  if (typeof this.options.onCloseEnd === 'function') {
536
461
  this.options.onCloseEnd.call(this, this.el);
@@ -539,49 +464,41 @@
539
464
  });
540
465
  }
541
466
 
542
- /**
543
- * Place dropdown
544
- */
545
- _placeDropdown() {
546
- /**
547
- * Get closest ancestor that satisfies the condition
548
- * @param {Element} el Element to find ancestors on
549
- * @param {Function} condition Function that given an ancestor element returns true or false
550
- * @returns {Element} Return closest ancestor or null if none satisfies the condition
551
- */
552
- const getClosestAncestor = function(el, condition) {
553
- let ancestor = el.parentNode;
554
- while (ancestor !== null && !$(ancestor).is(document)) {
555
- if (condition(ancestor)) {
556
- return ancestor;
557
- }
558
- ancestor = ancestor.parentNode;
467
+ private _getClosestAncestor(el: Element, condition: Function): Element {
468
+ let ancestor = el.parentNode;
469
+ while (ancestor !== null && ancestor !== document) {
470
+ if (condition(ancestor)) {
471
+ return <Element>ancestor;
559
472
  }
560
- return null;
561
- };
473
+ ancestor = ancestor.parentNode;
474
+ }
475
+ return null;
476
+ };
562
477
 
478
+ _placeDropdown() {
563
479
  // Container here will be closest ancestor with overflow: hidden
564
- let closestOverflowParent = getClosestAncestor(this.dropdownEl, (ancestor) => {
565
- return !$(ancestor).is('html,body') && $(ancestor).css('overflow') !== 'visible';
480
+ let closestOverflowParent: HTMLElement = <HTMLElement>this._getClosestAncestor(this.dropdownEl, (ancestor: HTMLElement) => {
481
+ return !['HTML','BODY'].includes(ancestor.tagName) && getComputedStyle(ancestor).overflow !== 'visible';
566
482
  });
567
483
  // Fallback
568
484
  if (!closestOverflowParent) {
569
- closestOverflowParent = !!this.dropdownEl.offsetParent
485
+ closestOverflowParent = <HTMLElement>(!!this.dropdownEl.offsetParent
570
486
  ? this.dropdownEl.offsetParent
571
- : this.dropdownEl.parentNode;
487
+ : this.dropdownEl.parentNode);
572
488
  }
573
- if ($(closestOverflowParent).css('position') === 'static')
574
- $(closestOverflowParent).css('position', 'relative');
489
+
490
+ if (getComputedStyle(closestOverflowParent).position === 'static')
491
+ closestOverflowParent.style.position = 'relative';
575
492
 
576
493
  this._moveDropdown(closestOverflowParent);
577
494
 
578
495
  // Set width before calculating positionInfo
579
- let idealWidth = this.options.constrainWidth
496
+ const idealWidth = this.options.constrainWidth
580
497
  ? this.el.getBoundingClientRect().width
581
498
  : this.dropdownEl.getBoundingClientRect().width;
582
499
  this.dropdownEl.style.width = idealWidth + 'px';
583
500
 
584
- let positionInfo = this._getDropdownPosition(closestOverflowParent);
501
+ const positionInfo = this._getDropdownPosition(closestOverflowParent);
585
502
  this.dropdownEl.style.left = positionInfo.x + 'px';
586
503
  this.dropdownEl.style.top = positionInfo.y + 'px';
587
504
  this.dropdownEl.style.height = positionInfo.height + 'px';
@@ -591,79 +508,48 @@
591
508
  } ${positionInfo.verticalAlignment === 'top' ? '0' : '100%'}`;
592
509
  }
593
510
 
594
- /**
595
- * Open Dropdown
596
- */
597
511
  open() {
598
- if (this.isOpen) {
599
- return;
600
- }
512
+ if (this.isOpen) return;
601
513
  this.isOpen = true;
602
-
603
514
  // onOpenStart callback
604
515
  if (typeof this.options.onOpenStart === 'function') {
605
516
  this.options.onOpenStart.call(this, this.el);
606
517
  }
607
-
608
518
  // Reset styles
609
519
  this._resetDropdownStyles();
610
520
  this.dropdownEl.style.display = 'block';
611
-
612
521
  this._placeDropdown();
613
522
  this._animateIn();
614
523
  this._setupTemporaryEventHandlers();
615
524
  }
616
525
 
617
- /**
618
- * Close Dropdown
619
- */
620
526
  close() {
621
- if (!this.isOpen) {
622
- return;
623
- }
624
-
527
+ if (!this.isOpen) return;
625
528
  this.isOpen = false;
626
529
  this.focusedIndex = -1;
627
-
628
530
  // onCloseStart callback
629
531
  if (typeof this.options.onCloseStart === 'function') {
630
532
  this.options.onCloseStart.call(this, this.el);
631
533
  }
632
-
633
534
  this._animateOut();
634
535
  this._removeTemporaryEventHandlers();
635
-
636
536
  if (this.options.autoFocus) {
637
537
  this.el.focus();
638
538
  }
639
539
  }
640
540
 
641
- /**
642
- * Recalculate dimensions
643
- */
644
541
  recalculateDimensions() {
645
542
  if (this.isOpen) {
646
- this.$dropdownEl.css({
647
- width: '',
648
- height: '',
649
- left: '',
650
- top: '',
651
- 'transform-origin': ''
652
- });
543
+ this.dropdownEl.style.width = '';
544
+ this.dropdownEl.style.height = '';
545
+ this.dropdownEl.style.left = '';
546
+ this.dropdownEl.style.top = '';
547
+ this.dropdownEl.style.transformOrigin = '';
653
548
  this._placeDropdown();
654
549
  }
655
550
  }
656
- }
657
551
 
658
- /**
659
- * @static
660
- * @memberof Dropdown
661
- */
662
- Dropdown._dropdowns = [];
663
-
664
- M.Dropdown = Dropdown;
665
-
666
- if (M.jQueryLoaded) {
667
- M.initializeJqueryWrapper(Dropdown, 'dropdown', 'M_Dropdown');
552
+ static {
553
+ Dropdown._dropdowns = [];
554
+ }
668
555
  }
669
- })(cash, M.anime);
package/src/edges.ts ADDED
@@ -0,0 +1,6 @@
1
+ export class Edges {
2
+ public top: Boolean; // If the top edge was exceeded
3
+ public right: Boolean; // If the right edge was exceeded
4
+ public bottom: Boolean; // If the bottom edge was exceeded
5
+ public left: Boolean; // If the left edge was exceeded
6
+ }