@materializecss/materialize 1.2.2 → 2.0.1-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 (90) hide show
  1. package/Gruntfile.js +68 -313
  2. package/README.md +26 -14
  3. package/dist/css/materialize.css +1009 -1822
  4. package/dist/css/materialize.min.css +2 -8
  5. package/dist/js/materialize.js +8414 -12299
  6. package/dist/js/materialize.min.js +8968 -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/_theme_variables.scss +98 -0
  29. package/sass/components/_timepicker.scss +54 -46
  30. package/sass/components/_toast.scss +3 -3
  31. package/sass/components/_tooltip.scss +4 -5
  32. package/sass/components/_typography.scss +1 -1
  33. package/sass/components/_variables.scss +185 -120
  34. package/sass/components/forms/_checkboxes.scss +9 -9
  35. package/sass/components/forms/_file-input.scss +9 -7
  36. package/sass/components/forms/_input-fields.scss +173 -234
  37. package/sass/components/forms/_radio-buttons.scss +1 -1
  38. package/sass/components/forms/_range.scss +11 -11
  39. package/sass/components/forms/_select.scss +29 -19
  40. package/sass/components/forms/_switches.scss +22 -18
  41. package/sass/materialize.scss +1 -1
  42. package/src/autocomplete.ts +459 -0
  43. package/src/bounding.ts +6 -0
  44. package/{js/buttons.js → src/buttons.ts} +103 -162
  45. package/src/cards.ts +54 -0
  46. package/{js/carousel.js → src/carousel.ts} +137 -262
  47. package/src/characterCounter.ts +88 -0
  48. package/src/chips.ts +350 -0
  49. package/src/collapsible.ts +184 -0
  50. package/{js/component.js → src/component.ts} +6 -19
  51. package/{js/datepicker.js → src/datepicker.ts} +213 -299
  52. package/{js/dropdown.js → src/dropdown.ts} +140 -254
  53. package/src/edges.ts +6 -0
  54. package/src/forms.ts +120 -0
  55. package/src/global.ts +385 -0
  56. package/src/materialbox.ts +348 -0
  57. package/src/modal.ts +256 -0
  58. package/{js/parallax.js → src/parallax.ts} +47 -60
  59. package/{js/pushpin.js → src/pushpin.ts} +19 -47
  60. package/{js/range.js → src/range.ts} +58 -139
  61. package/{js/scrollspy.js → src/scrollspy.ts} +81 -153
  62. package/src/select.ts +448 -0
  63. package/{js/sidenav.js → src/sidenav.ts} +96 -202
  64. package/src/slider.ts +415 -0
  65. package/src/tabs.ts +293 -0
  66. package/src/tapTarget.ts +240 -0
  67. package/{js/timepicker.js → src/timepicker.ts} +268 -272
  68. package/{js/toasts.js → src/toasts.ts} +75 -134
  69. package/{js/tooltip.js → src/tooltip.ts} +59 -96
  70. package/src/waves.ts +70 -0
  71. package/extras/noUiSlider/nouislider.css +0 -404
  72. package/extras/noUiSlider/nouislider.js +0 -2147
  73. package/extras/noUiSlider/nouislider.min.js +0 -1
  74. package/js/anime.min.js +0 -34
  75. package/js/autocomplete.js +0 -479
  76. package/js/cards.js +0 -40
  77. package/js/cash.js +0 -960
  78. package/js/characterCounter.js +0 -136
  79. package/js/chips.js +0 -486
  80. package/js/collapsible.js +0 -275
  81. package/js/forms.js +0 -285
  82. package/js/global.js +0 -428
  83. package/js/materialbox.js +0 -453
  84. package/js/modal.js +0 -382
  85. package/js/select.js +0 -391
  86. package/js/slider.js +0 -497
  87. package/js/tabs.js +0 -402
  88. package/js/tapTarget.js +0 -315
  89. package/js/waves.js +0 -615
  90. package/sass/components/_waves.scss +0 -187
@@ -0,0 +1,88 @@
1
+ import { Component } from "./component";
2
+
3
+ let _defaults = {};
4
+
5
+ export class CharacterCounter extends Component {
6
+ isInvalid: boolean;
7
+ isValidLength: boolean;
8
+ private _handleUpdateCounterBound: any;
9
+ counterEl: HTMLSpanElement;
10
+
11
+ constructor(el: Element, options: Object) {
12
+ super(CharacterCounter, el, options);
13
+ (this.el as any).M_CharacterCounter = this;
14
+ this.options = {...CharacterCounter.defaults, ...options};
15
+ this.isInvalid = false;
16
+ this.isValidLength = false;
17
+ this._setupCounter();
18
+ this._setupEventHandlers();
19
+ }
20
+
21
+ static get defaults() {
22
+ return _defaults;
23
+ }
24
+
25
+ static init(els, options) {
26
+ return super.init(this, els, options);
27
+ }
28
+
29
+ static getInstance(el) {
30
+ let domElem = !!el.jquery ? el[0] : el;
31
+ return domElem.M_CharacterCounter;
32
+ }
33
+
34
+ destroy() {
35
+ this._removeEventHandlers();
36
+ (this.el as any).CharacterCounter = undefined;
37
+ this._removeCounter();
38
+ }
39
+
40
+ _setupEventHandlers() {
41
+ this._handleUpdateCounterBound = this.updateCounter.bind(this);
42
+ this.el.addEventListener('focus', this._handleUpdateCounterBound, true);
43
+ this.el.addEventListener('input', this._handleUpdateCounterBound, true);
44
+ }
45
+
46
+ _removeEventHandlers() {
47
+ this.el.removeEventListener('focus', this._handleUpdateCounterBound, true);
48
+ this.el.removeEventListener('input', this._handleUpdateCounterBound, true);
49
+ }
50
+
51
+ _setupCounter() {
52
+ this.counterEl = document.createElement('span');
53
+ this.counterEl.classList.add('character-counter');
54
+ this.counterEl.style.float = 'right';
55
+ this.counterEl.style.fontSize = '12px';
56
+ this.counterEl.style.height = '1';
57
+ this.el.parentElement.appendChild(this.counterEl);
58
+ }
59
+
60
+ _removeCounter() {
61
+ this.counterEl.remove();
62
+ }
63
+
64
+ updateCounter() {
65
+ let maxLength = parseInt(this.el.getAttribute('data-length')),
66
+ actualLength = (this.el as HTMLInputElement).value.length;
67
+
68
+ this.isValidLength = actualLength <= maxLength;
69
+ let counterString = actualLength.toString();
70
+ if (maxLength) {
71
+ counterString += '/' + maxLength;
72
+ this._validateInput();
73
+ }
74
+ this.counterEl.innerHTML = counterString;
75
+ }
76
+
77
+ _validateInput() {
78
+ if (this.isValidLength && this.isInvalid) {
79
+ this.isInvalid = false;
80
+ this.el.classList.remove('invalid');
81
+ }
82
+ else if (!this.isValidLength && !this.isInvalid) {
83
+ this.isInvalid = true;
84
+ this.el.classList.remove('valid');
85
+ this.el.classList.add('invalid');
86
+ }
87
+ }
88
+ }
package/src/chips.ts ADDED
@@ -0,0 +1,350 @@
1
+ import { Component } from "./component";
2
+ import { M } from "./global";
3
+ import { Autocomplete } from "./autocomplete";
4
+
5
+ let _defaults = {
6
+ data: [],
7
+ placeholder: '',
8
+ secondaryPlaceholder: '',
9
+ autocompleteOptions: {},
10
+ autocompleteOnly: false,
11
+ limit: Infinity,
12
+ onChipAdd: null,
13
+ onChipSelect: null,
14
+ onChipDelete: null
15
+ };
16
+
17
+ interface DataBit {
18
+ id: string, // required
19
+ text?: string,
20
+ image?: string,
21
+ description?: string,
22
+ }
23
+
24
+ function gGetIndex(el: HTMLElement): number {
25
+ return [...el.parentNode.children].indexOf(el);
26
+ }
27
+
28
+ export class Chips extends Component {
29
+ chipsData: DataBit[];
30
+ hasAutocomplete: boolean;
31
+ autocomplete: Autocomplete;
32
+ _input: HTMLInputElement;
33
+ _label: any;
34
+ _chips: HTMLElement[];
35
+ private _handleChipClickBound: any;
36
+ private _handleInputKeydownBound: any;
37
+ private _handleInputFocusBound: any;
38
+ private _handleInputBlurBound: any;
39
+ static _keydown: boolean;
40
+ private _selectedChip: any;
41
+
42
+ constructor(el, options) {
43
+ super(Chips, el, options);
44
+ (this.el as any).M_Chips = this;
45
+ this.options = {...Chips.defaults, ...options};
46
+
47
+ this.el.classList.add('chips', 'input-field');
48
+ this.chipsData = [];
49
+ this._chips = [];
50
+ this._setupInput();
51
+ this.hasAutocomplete = Object.keys(this.options.autocompleteOptions).length > 0;
52
+
53
+ // Set input id
54
+ if (!this._input.getAttribute('id'))
55
+ this._input.setAttribute('id', M.guid());
56
+
57
+ // Render initial chips
58
+ if (this.options.data.length) {
59
+ this.chipsData = this.options.data;
60
+ this._renderChips();
61
+ }
62
+ // Setup autocomplete if needed
63
+ if (this.hasAutocomplete) this._setupAutocomplete();
64
+ this._setPlaceholder();
65
+ this._setupLabel();
66
+ this._setupEventHandlers();
67
+ }
68
+
69
+ static get defaults() {
70
+ return _defaults;
71
+ }
72
+
73
+ static init(els, options) {
74
+ return super.init(this, els, options);
75
+ }
76
+
77
+ static getInstance(el) {
78
+ const domElem = !!el.jquery ? el[0] : el;
79
+ return domElem.M_Chips;
80
+ }
81
+
82
+ getData() {
83
+ return this.chipsData;
84
+ }
85
+
86
+ destroy() {
87
+ this._removeEventHandlers();
88
+ this._chips.forEach(c => c.remove());
89
+ this._chips = [];
90
+ (this.el as any).M_Chips = undefined;
91
+ }
92
+
93
+ _setupEventHandlers() {
94
+ this._handleChipClickBound = this._handleChipClick.bind(this);
95
+ this._handleInputKeydownBound = this._handleInputKeydown.bind(this);
96
+ this._handleInputFocusBound = this._handleInputFocus.bind(this);
97
+ this._handleInputBlurBound = this._handleInputBlur.bind(this);
98
+ this.el.addEventListener('click', this._handleChipClickBound);
99
+ document.addEventListener('keydown', Chips._handleChipsKeydown);
100
+ document.addEventListener('keyup', Chips._handleChipsKeyup);
101
+ this.el.addEventListener('blur', Chips._handleChipsBlur, true);
102
+ this._input.addEventListener('focus', this._handleInputFocusBound);
103
+ this._input.addEventListener('blur', this._handleInputBlurBound);
104
+ this._input.addEventListener('keydown', this._handleInputKeydownBound);
105
+ }
106
+
107
+ _removeEventHandlers() {
108
+ this.el.removeEventListener('click', this._handleChipClickBound);
109
+ document.removeEventListener('keydown', Chips._handleChipsKeydown);
110
+ document.removeEventListener('keyup', Chips._handleChipsKeyup);
111
+ this.el.removeEventListener('blur', Chips._handleChipsBlur, true);
112
+ this._input.removeEventListener('focus', this._handleInputFocusBound);
113
+ this._input.removeEventListener('blur', this._handleInputBlurBound);
114
+ this._input.removeEventListener('keydown', this._handleInputKeydownBound);
115
+ }
116
+
117
+ _handleChipClick(e) {
118
+ const _chip = (<HTMLElement>e.target).closest('.chip');
119
+ const clickedClose = (<HTMLElement>e.target).classList.contains('close');
120
+ if (_chip) {
121
+ const index = [..._chip.parentNode.children].indexOf(_chip);
122
+ if (clickedClose) {
123
+ this.deleteChip(index);
124
+ this._input.focus();
125
+ }
126
+ else {
127
+ this.selectChip(index);
128
+ }
129
+ // Default handle click to focus on input
130
+ }
131
+ else {
132
+ this._input.focus();
133
+ }
134
+ }
135
+
136
+ static _handleChipsKeydown(e) {
137
+ Chips._keydown = true;
138
+ const chips = (<HTMLElement>e.target).closest('.chips');
139
+ const chipsKeydown = e.target && chips;
140
+
141
+ // Don't handle keydown inputs on input and textarea
142
+ const tag = (<HTMLElement>e.target).tagName;
143
+ if (tag === 'INPUT' || tag === 'TEXTAREA' || !chipsKeydown) return;
144
+
145
+ const currChips: Chips = (chips as any).M_Chips;
146
+ // backspace and delete
147
+ if (e.keyCode === 8 || e.keyCode === 46) {
148
+ e.preventDefault();
149
+ let selectIndex = currChips.chipsData.length;
150
+ if (currChips._selectedChip) {
151
+ const index = gGetIndex(currChips._selectedChip);
152
+ currChips.deleteChip(index);
153
+ currChips._selectedChip = null;
154
+ // Make sure selectIndex doesn't go negative
155
+ selectIndex = Math.max(index - 1, 0);
156
+ }
157
+ if (currChips.chipsData.length)
158
+ currChips.selectChip(selectIndex);
159
+ else
160
+ currChips._input.focus();
161
+ }
162
+ // left arrow key
163
+ else if (e.keyCode === 37) {
164
+ if (currChips._selectedChip) {
165
+ const selectIndex = gGetIndex(currChips._selectedChip) - 1;
166
+ if (selectIndex < 0) return;
167
+ currChips.selectChip(selectIndex);
168
+ }
169
+ }
170
+ // right arrow key
171
+ else if (e.keyCode === 39) {
172
+ if (currChips._selectedChip) {
173
+ const selectIndex = gGetIndex(currChips._selectedChip) + 1;
174
+ if (selectIndex >= currChips.chipsData.length)
175
+ currChips._input.focus();
176
+ else
177
+ currChips.selectChip(selectIndex);
178
+ }
179
+ }
180
+ }
181
+
182
+ static _handleChipsKeyup(e) {
183
+ Chips._keydown = false;
184
+ }
185
+
186
+ static _handleChipsBlur(e) {
187
+ if (!Chips._keydown && document.hidden) {
188
+ const chips = (<HTMLElement>e.target).closest('.chips');
189
+ const currChips: Chips = (chips as any).M_Chips;
190
+ currChips._selectedChip = null;
191
+ }
192
+ }
193
+
194
+ _handleInputFocus() {
195
+ this.el.classList.add('focus');
196
+ }
197
+
198
+ _handleInputBlur() {
199
+ this.el.classList.remove('focus');
200
+ }
201
+
202
+ _handleInputKeydown(e) {
203
+ Chips._keydown = true;
204
+ // enter
205
+ if (e.keyCode === 13) {
206
+ // Override enter if autocompleting.
207
+ if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
208
+ return;
209
+ }
210
+ e.preventDefault();
211
+ if (!this.hasAutocomplete || (this.hasAutocomplete && !this.options.autocompleteOnly)) {
212
+ this.addChip({id: this._input.value});
213
+ }
214
+ this._input.value = '';
215
+ // delete or left
216
+ }
217
+ else if (
218
+ (e.keyCode === 8 || e.keyCode === 37) &&
219
+ this._input.value === '' &&
220
+ this.chipsData.length
221
+ ) {
222
+ e.preventDefault();
223
+ this.selectChip(this.chipsData.length - 1);
224
+ }
225
+ }
226
+
227
+ _renderChip(chip: DataBit): HTMLDivElement {
228
+ if (!chip.id) return;
229
+ const renderedChip = document.createElement('div');
230
+ renderedChip.classList.add('chip');
231
+ renderedChip.innerText = chip.text || chip.id;
232
+ renderedChip.setAttribute('tabindex', "0");
233
+ const closeIcon = document.createElement('i');
234
+ closeIcon.classList.add('material-icons', 'close');
235
+ closeIcon.innerText = 'close';
236
+ // attach image if needed
237
+ if (chip.image) {
238
+ const img = document.createElement('img');
239
+ img.setAttribute('src', chip.image);
240
+ renderedChip.insertBefore(img, renderedChip.firstChild);
241
+ }
242
+ renderedChip.appendChild(closeIcon);
243
+ return renderedChip;
244
+ }
245
+
246
+ _renderChips() {
247
+ this._chips = []; //.remove();
248
+ for (let i = 0; i < this.chipsData.length; i++) {
249
+ const chipElem = this._renderChip(this.chipsData[i]);
250
+ this.el.appendChild(chipElem);
251
+ this._chips.push(chipElem);
252
+ }
253
+ // move input to end
254
+ this.el.append(this._input);
255
+ }
256
+
257
+ _setupAutocomplete() {
258
+ this.options.autocompleteOptions.onAutocomplete = (items) => {
259
+ if (items.length > 0) this.addChip(items[0]);
260
+ this._input.value = '';
261
+ this._input.focus();
262
+ };
263
+ this.autocomplete = Autocomplete.init(this._input, this.options.autocompleteOptions);
264
+ }
265
+
266
+ _setupInput() {
267
+ this._input = this.el.querySelector('input');
268
+ if (!this._input) {
269
+ this._input = document.createElement('input');
270
+ this.el.append(this._input);
271
+ }
272
+ this._input.classList.add('input');
273
+ }
274
+
275
+ _setupLabel() {
276
+ this._label = this.el.querySelector('label');
277
+ if (this._label) this._label.setAttribute('for', this._input.getAttribute('id'));
278
+ }
279
+
280
+ _setPlaceholder() {
281
+ if (this.chipsData !== undefined && !this.chipsData.length && this.options.placeholder) {
282
+ this._input.placeholder = this.options.placeholder;
283
+ }
284
+ else if (
285
+ (this.chipsData === undefined || !!this.chipsData.length) &&
286
+ this.options.secondaryPlaceholder
287
+ ) {
288
+ this._input.placeholder = this.options.secondaryPlaceholder;
289
+ }
290
+ }
291
+
292
+ _isValidAndNotExist(chip: DataBit) {
293
+ const isValid = !!chip.id;
294
+ const doesNotExist = !this.chipsData.some(item => item.id == chip.id);
295
+ return isValid && doesNotExist;
296
+ }
297
+
298
+ addChip(chip: DataBit) {
299
+ if (!this._isValidAndNotExist(chip) || this.chipsData.length >= this.options.limit) return;
300
+ const renderedChip = this._renderChip(chip);
301
+ this._chips.push(renderedChip);
302
+ this.chipsData.push(chip);
303
+ //$(this._input).before(renderedChip);
304
+ this._input.before(renderedChip);
305
+ this._setPlaceholder();
306
+ // fire chipAdd callback
307
+ if (typeof this.options.onChipAdd === 'function') {
308
+ this.options.onChipAdd(this.el, renderedChip);
309
+ }
310
+ }
311
+
312
+ deleteChip(chipIndex: number) {
313
+ const chip = this._chips[chipIndex];
314
+ this._chips[chipIndex].remove();
315
+ this._chips.splice(chipIndex, 1);
316
+ this.chipsData.splice(chipIndex, 1);
317
+ this._setPlaceholder();
318
+ // fire chipDelete callback
319
+ if (typeof this.options.onChipDelete === 'function') {
320
+ this.options.onChipDelete(this.el, chip);
321
+ }
322
+ }
323
+
324
+ selectChip(chipIndex: number) {
325
+ const chip = this._chips[chipIndex];
326
+ this._selectedChip = chip;
327
+ chip.focus();
328
+ // fire chipSelect callback
329
+ if (typeof this.options.onChipSelect === 'function') {
330
+ this.options.onChipSelect(this.el, chip);
331
+ }
332
+ }
333
+
334
+ static Init(){
335
+ document.addEventListener("DOMContentLoaded", () => {
336
+ // Handle removal of static chips.
337
+ document.body.addEventListener('click', e => {
338
+ if ((<HTMLElement>e.target).closest('.chip .close')) {
339
+ const chips = (<HTMLElement>e.target).closest('.chips');
340
+ if (chips && (chips as any).M_Chips == undefined) return;
341
+ (<HTMLElement>e.target).closest('.chip').remove();
342
+ }
343
+ });
344
+ });
345
+ }
346
+
347
+ static {
348
+ Chips._keydown = false;
349
+ }
350
+ }
@@ -0,0 +1,184 @@
1
+ import { Component } from "./component";
2
+ import anim from "animejs";
3
+
4
+ const _defaults = {
5
+ accordion: true,
6
+ onOpenStart: undefined,
7
+ onOpenEnd: undefined,
8
+ onCloseStart: undefined,
9
+ onCloseEnd: undefined,
10
+ inDuration: 300,
11
+ outDuration: 300
12
+ };
13
+
14
+ export class Collapsible extends Component {
15
+ private _headers: HTMLElement[];
16
+ private _handleCollapsibleClickBound: any;
17
+ private _handleCollapsibleKeydownBound: any;
18
+
19
+ constructor(el, options) {
20
+ super(Collapsible, el, options);
21
+ (this.el as any).M_Collapsible = this;
22
+ this.options = {...Collapsible.defaults, ...options};
23
+ // Setup tab indices
24
+ this._headers = Array.from(this.el.querySelectorAll('li > .collapsible-header'));
25
+ this._headers.forEach(el => el.tabIndex = 0);
26
+ this._setupEventHandlers();
27
+ // Open first active
28
+ const activeBodies: HTMLElement[] = Array.from(this.el.querySelectorAll('li.active > .collapsible-body'));
29
+ if (this.options.accordion)
30
+ if (activeBodies.length > 0)
31
+ activeBodies[0].style.display = 'block'; // Accordion
32
+ else
33
+ activeBodies.forEach(el => el.style.display = 'block'); // Expandables
34
+ }
35
+
36
+ static get defaults() {
37
+ return _defaults;
38
+ }
39
+
40
+ static init(els, options) {
41
+ return super.init(this, els, options);
42
+ }
43
+
44
+ static getInstance(el) {
45
+ const domElem = !!el.jquery ? el[0] : el;
46
+ return domElem.M_Collapsible;
47
+ }
48
+
49
+ destroy() {
50
+ this._removeEventHandlers();
51
+ (this.el as any).M_Collapsible = undefined;
52
+ }
53
+
54
+ _setupEventHandlers() {
55
+ this._handleCollapsibleClickBound = this._handleCollapsibleClick.bind(this);
56
+ this._handleCollapsibleKeydownBound = this._handleCollapsibleKeydown.bind(this);
57
+ this.el.addEventListener('click', this._handleCollapsibleClickBound);
58
+ this._headers.forEach(header => header.addEventListener('keydown', this._handleCollapsibleKeydownBound));
59
+ }
60
+
61
+ _removeEventHandlers() {
62
+ this.el.removeEventListener('click', this._handleCollapsibleClickBound);
63
+ this._headers.forEach(header => header.removeEventListener('keydown', this._handleCollapsibleKeydownBound));
64
+ }
65
+
66
+ _handleCollapsibleClick(e) {
67
+ const header = e.target.closest('.collapsible-header');
68
+ if (e.target && header) {
69
+ const collapsible = header.closest('.collapsible');
70
+ if (collapsible !== this.el) return;
71
+
72
+ const li = header.closest('li');
73
+ const isActive = li.classList.contains('active');
74
+ const index = [...li.parentNode.children].indexOf(li);
75
+
76
+ if (isActive)
77
+ this.close(index);
78
+ else
79
+ this.open(index);
80
+ }
81
+ }
82
+
83
+ _handleCollapsibleKeydown(e) {
84
+ if (e.keyCode === 13) {
85
+ this._handleCollapsibleClickBound(e);
86
+ }
87
+ }
88
+
89
+ _animateIn(index: number) {
90
+ const li = this.el.children[index];
91
+ if (!li) return;
92
+ const body: HTMLElement = li.querySelector('.collapsible-body');
93
+ anim.remove(body);
94
+ body.style.display = 'block';
95
+ body.style.overflow = 'hidden';
96
+ body.style.height = '0';
97
+ body.style.paddingTop = '';
98
+ body.style.paddingBottom = '';
99
+ const pTop = getComputedStyle(body).paddingTop; // . css('padding-top');
100
+ const pBottom = getComputedStyle(body).paddingBottom; //body.css('padding-bottom');
101
+ const finalHeight = body.scrollHeight;
102
+ body.style.paddingTop = '0';
103
+ body.style.paddingBottom = '0';
104
+ anim({
105
+ targets: body,
106
+ height: finalHeight,
107
+ paddingTop: pTop,
108
+ paddingBottom: pBottom,
109
+ duration: this.options.inDuration,
110
+ easing: 'easeInOutCubic',
111
+ complete: (anim) => {
112
+ body.style.overflow = '';
113
+ body.style.height = '';
114
+ body.style.paddingTop = '';
115
+ body.style.paddingBottom = '';
116
+ // onOpenEnd callback
117
+ if (typeof this.options.onOpenEnd === 'function') {
118
+ this.options.onOpenEnd.call(this, li);
119
+ }
120
+ }
121
+ });
122
+ }
123
+
124
+ _animateOut(index: number) {
125
+ const li = this.el.children[index];
126
+ if (!li) return;
127
+ const body: HTMLElement = li.querySelector('.collapsible-body');
128
+ anim.remove(body);
129
+ body.style.overflow = 'hidden';
130
+ anim({
131
+ targets: body,
132
+ height: 0,
133
+ paddingTop: 0,
134
+ paddingBottom: 0,
135
+ duration: this.options.outDuration,
136
+ easing: 'easeInOutCubic',
137
+ complete: () => {
138
+ body.style.overflow = '';
139
+ body.style.height = '';
140
+ body.style.padding = '';
141
+ body.style.display = '';
142
+ // onCloseEnd callback
143
+ if (typeof this.options.onCloseEnd === 'function') {
144
+ this.options.onCloseEnd.call(this, li);
145
+ }
146
+ }
147
+ });
148
+ }
149
+
150
+ open(index: number) {
151
+ const listItems = Array.from(this.el.children).filter(c => c.tagName === 'LI');
152
+ const li = listItems[index];
153
+ if (li && !li.classList.contains('active')) {
154
+ // onOpenStart callback
155
+ if (typeof this.options.onOpenStart === 'function') {
156
+ this.options.onOpenStart.call(this, li);
157
+ }
158
+ // Handle accordion behavior
159
+ if (this.options.accordion) {
160
+ const activeLis = listItems.filter(li => li.classList.contains('active'));
161
+ activeLis.forEach(activeLi => {
162
+ const index = listItems.indexOf(activeLi);
163
+ this.close(index);
164
+ });
165
+ }
166
+ // Animate in
167
+ li.classList.add('active');
168
+ this._animateIn(index);
169
+ }
170
+ }
171
+
172
+ close(index: number) {
173
+ const li = Array.from(this.el.children).filter(c => c.tagName === 'LI')[index];
174
+ if (li && li.classList.contains('active')) {
175
+ // onCloseStart callback
176
+ if (typeof this.options.onCloseStart === 'function') {
177
+ this.options.onCloseStart.call(this, li);
178
+ }
179
+ // Animate out
180
+ li.classList.remove('active');
181
+ this._animateOut(index);
182
+ }
183
+ }
184
+ }
@@ -1,44 +1,31 @@
1
- class Component {
2
- /**
3
- * Generic constructor for all components
4
- * @constructor
5
- * @param {Element} el
6
- * @param {Object} options
7
- */
8
- constructor(classDef, el, options) {
1
+
2
+ export class Component {
3
+
4
+ constructor(classDef, protected el: Element, protected options) {
9
5
  // Display error if el is valid HTML Element
10
6
  if (!(el instanceof Element)) {
11
7
  console.error(Error(el + ' is not an HTML Element'));
12
8
  }
13
-
14
9
  // If exists, destroy and reinitialize in child
15
10
  let ins = classDef.getInstance(el);
16
11
  if (!!ins) {
17
12
  ins.destroy();
18
13
  }
19
-
20
14
  this.el = el;
21
- this.$el = cash(el);
22
15
  }
23
16
 
24
- /**
25
- * Initializes components
26
- * @param {class} classDef
27
- * @param {Element | NodeList | jQuery} els
28
- * @param {Object} options
29
- */
30
17
  static init(classDef, els, options) {
31
18
  let instances = null;
32
19
  if (els instanceof Element) {
33
20
  instances = new classDef(els, options);
34
- } else if (!!els && (els.jquery || els.cash || els instanceof NodeList)) {
21
+ }
22
+ else if (!!els && (els.jquery || els.cash || els instanceof NodeList || els instanceof HTMLCollection)) {
35
23
  let instancesArr = [];
36
24
  for (let i = 0; i < els.length; i++) {
37
25
  instancesArr.push(new classDef(els[i], options));
38
26
  }
39
27
  instances = instancesArr;
40
28
  }
41
-
42
29
  return instances;
43
30
  }
44
31
  }