@materializecss/materialize 2.0.3-beta → 2.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +1 -1
  2. package/dist/css/materialize.css +37 -15
  3. package/dist/css/materialize.min.css +2 -2
  4. package/dist/js/materialize.js +503 -1974
  5. package/dist/js/materialize.min.js +2 -2
  6. package/dist/js/materialize.min.js.map +1 -1
  7. package/dist/src/buttons.d.ts.map +1 -1
  8. package/dist/src/cards.d.ts.map +1 -1
  9. package/dist/src/collapsible.d.ts +1 -0
  10. package/dist/src/collapsible.d.ts.map +1 -1
  11. package/dist/src/dropdown.d.ts.map +1 -1
  12. package/dist/src/global.d.ts.map +1 -1
  13. package/dist/src/materialbox.d.ts +14 -10
  14. package/dist/src/materialbox.d.ts.map +1 -1
  15. package/dist/src/modal.d.ts.map +1 -1
  16. package/dist/src/range.d.ts.map +1 -1
  17. package/dist/src/scrollspy.d.ts.map +1 -1
  18. package/dist/src/sidenav.d.ts +25 -25
  19. package/dist/src/sidenav.d.ts.map +1 -1
  20. package/dist/src/slider.d.ts +12 -12
  21. package/dist/src/slider.d.ts.map +1 -1
  22. package/dist/src/tabs.d.ts +1 -1
  23. package/dist/src/tabs.d.ts.map +1 -1
  24. package/dist/src/toasts.d.ts +7 -2
  25. package/dist/src/toasts.d.ts.map +1 -1
  26. package/dist/src/tooltip.d.ts.map +1 -1
  27. package/package.json +14 -10
  28. package/sass/components/_collapsible.scss +14 -2
  29. package/sass/components/_materialbox.scss +2 -2
  30. package/sass/components/_modal.scss +0 -1
  31. package/sass/components/_tooltip.scss +18 -8
  32. package/sass/components/_variables.scss +2 -2
  33. package/Gruntfile.js +0 -385
  34. package/src/autocomplete.ts +0 -553
  35. package/src/bounding.ts +0 -6
  36. package/src/buttons.ts +0 -260
  37. package/src/cards.ts +0 -53
  38. package/src/carousel.ts +0 -676
  39. package/src/characterCounter.ts +0 -117
  40. package/src/chips.ts +0 -439
  41. package/src/collapsible.ts +0 -249
  42. package/src/component.ts +0 -120
  43. package/src/datepicker.ts +0 -1076
  44. package/src/dropdown.ts +0 -644
  45. package/src/edges.ts +0 -6
  46. package/src/forms.ts +0 -132
  47. package/src/global.ts +0 -114
  48. package/src/index.ts +0 -26
  49. package/src/materialbox.ts +0 -404
  50. package/src/modal.ts +0 -341
  51. package/src/parallax.ts +0 -149
  52. package/src/pushpin.ts +0 -165
  53. package/src/range.ts +0 -198
  54. package/src/scrollspy.ts +0 -263
  55. package/src/select.ts +0 -484
  56. package/src/sidenav.ts +0 -543
  57. package/src/slider.ts +0 -474
  58. package/src/tabs.ts +0 -347
  59. package/src/tapTarget.ts +0 -273
  60. package/src/timepicker.ts +0 -832
  61. package/src/toasts.ts +0 -290
  62. package/src/tooltip.ts +0 -366
  63. package/src/utils.ts +0 -271
  64. package/src/waves.ts +0 -70
package/src/select.ts DELETED
@@ -1,484 +0,0 @@
1
- import { Utils } from "./utils";
2
- import { Dropdown, DropdownOptions } from "./dropdown";
3
- import { Component, BaseOptions, InitElements, MElement } from "./component";
4
-
5
- export interface FormSelectOptions extends BaseOptions {
6
- /**
7
- * Classes to be added to the select wrapper element.
8
- * @default ""
9
- */
10
- classes: string;
11
- /**
12
- * Pass options object to select dropdown initialization.
13
- * @default {}
14
- */
15
- dropdownOptions: Partial<DropdownOptions>;
16
- }
17
-
18
- let _defaults: FormSelectOptions = {
19
- classes: '',
20
- dropdownOptions: {}
21
- };
22
-
23
- type ValueStruct = {
24
- el: HTMLOptionElement,
25
- optionEl: HTMLElement,
26
- }
27
-
28
- export class FormSelect extends Component<FormSelectOptions> {
29
- declare el: HTMLSelectElement;
30
- /** If this is a multiple select. */
31
- isMultiple: boolean;
32
- /**
33
- * Label associated with the current select element.
34
- * Is "null", if not detected.
35
- */
36
- labelEl: HTMLLabelElement;
37
- /** Dropdown UL element. */
38
- dropdownOptions: HTMLUListElement;
39
- /** Text input that shows current selected option. */
40
- input: HTMLInputElement;
41
- /** Instance of the dropdown plugin for this select. */
42
- dropdown: Dropdown;
43
- /** The select wrapper element. */
44
- wrapper: HTMLDivElement;
45
- selectOptions: (HTMLOptionElement|HTMLOptGroupElement)[];
46
- private _values: ValueStruct[];
47
-
48
- constructor(el: HTMLSelectElement, options: FormSelectOptions) {
49
- super(el, options, FormSelect);
50
- if (this.el.classList.contains('browser-default')) return;
51
- (this.el as any).M_FormSelect = this;
52
-
53
- this.options = {
54
- ...FormSelect.defaults,
55
- ...options
56
- };
57
-
58
- this.isMultiple = this.el.multiple;
59
- this.el.tabIndex = -1;
60
- this._values = [];
61
- //this.labelEl = null;
62
- //this._labelFor = false;
63
- this._setupDropdown();
64
- this._setupEventHandlers();
65
- }
66
-
67
- static get defaults(): FormSelectOptions {
68
- return _defaults;
69
- }
70
-
71
- /**
72
- * Initializes instance of FormSelect.
73
- * @param el HTML element.
74
- * @param options Component options.
75
- */
76
- static init(el: HTMLSelectElement, options?: Partial<FormSelectOptions>): FormSelect;
77
- /**
78
- * Initializes instances of FormSelect.
79
- * @param els HTML elements.
80
- * @param options Component options.
81
- */
82
- static init(els: InitElements<HTMLSelectElement | MElement>, options?: Partial<FormSelectOptions>): FormSelect[];
83
- /**
84
- * Initializes instances of FormSelect.
85
- * @param els HTML elements.
86
- * @param options Component options.
87
- */
88
- static init(els: HTMLSelectElement | InitElements<HTMLSelectElement | MElement>, options: Partial<FormSelectOptions> = {}): FormSelect | FormSelect[] {
89
- return super.init(els, options, FormSelect);
90
- }
91
-
92
- static getInstance(el: HTMLElement): FormSelect {
93
- return (el as any).M_FormSelect;
94
- }
95
-
96
- destroy() {
97
- // Returns label to its original owner
98
- //if (this._labelFor) this.labelEl.setAttribute("for", this.el.id);
99
- this._removeEventHandlers();
100
- this._removeDropdown();
101
- (this.el as any).M_FormSelect = undefined;
102
- }
103
-
104
- _setupEventHandlers() {
105
- this.dropdownOptions.querySelectorAll('li:not(.optgroup)').forEach((el) => {
106
- el.addEventListener('click', this._handleOptionClick);
107
- el.addEventListener('keydown', (e: KeyboardEvent) => {
108
- if (e.key === " " || e.key === "Enter") this._handleOptionClick(e);
109
- });
110
- });
111
- this.el.addEventListener('change', this._handleSelectChange);
112
- this.input.addEventListener('click', this._handleInputClick);
113
- }
114
-
115
- _removeEventHandlers() {
116
- this.dropdownOptions.querySelectorAll('li:not(.optgroup)').forEach((el) => {
117
- el.removeEventListener('click', this._handleOptionClick);
118
- });
119
- this.el.removeEventListener('change', this._handleSelectChange);
120
- this.input.removeEventListener('click', this._handleInputClick);
121
- }
122
-
123
- _handleSelectChange = () => {
124
- this._setValueToInput();
125
- }
126
-
127
- _handleOptionClick = (e: MouseEvent | KeyboardEvent) => {
128
- e.preventDefault();
129
- const virtualOption = (e.target as HTMLLIElement).closest('li');
130
- this._selectOptionElement(virtualOption);
131
- e.stopPropagation();
132
- }
133
-
134
- _arraysEqual<T, E>(a: T[], b: (E|T)[]) {
135
- if (a === b) return true;
136
- if (a == null || b == null) return false;
137
- if (a.length !== b.length) return false;
138
- for (let i = 0; i < a.length; ++i) if (a[i] !== b[i]) return false;
139
- return true;
140
- }
141
-
142
- _selectOptionElement(virtualOption: HTMLElement) {
143
- if (!virtualOption.classList.contains('disabled') && !virtualOption.classList.contains('optgroup')) {
144
- const value = this._values.find((value) => value.optionEl === virtualOption);
145
- const previousSelectedValues = this.getSelectedValues();
146
- if (this.isMultiple) {
147
- // Multi-Select
148
- this._toggleEntryFromArray(value);
149
- }
150
- else {
151
- // Single-Select
152
- this._deselectAll();
153
- this._selectValue(value);
154
- }
155
- // Refresh Input-Text
156
- this._setValueToInput();
157
- // Trigger Change-Event only when data is different
158
- const actualSelectedValues = this.getSelectedValues();
159
- const selectionHasChanged = !this._arraysEqual(
160
- previousSelectedValues,
161
- actualSelectedValues
162
- );
163
- if (selectionHasChanged) this.el.dispatchEvent(new Event('change',{bubbles:true, cancelable:true, composed:true})); // trigger('change');
164
- }
165
- if (!this.isMultiple) this.dropdown.close();
166
- }
167
-
168
- _handleInputClick = () => {
169
- if (this.dropdown && this.dropdown.isOpen) {
170
- this._setValueToInput();
171
- this._setSelectedStates();
172
- }
173
- }
174
-
175
- _setupDropdown() {
176
- // Get Label
177
- this.labelEl = this.el.parentElement.querySelector('label');
178
-
179
- // Create Wrapper
180
- this.wrapper = document.createElement('div');
181
- this.wrapper.classList.add('select-wrapper', 'input-field');
182
- if (this.options.classes.length > 0) {
183
- this.wrapper.classList.add(...this.options.classes.split(' '));
184
- }
185
- this.el.before(this.wrapper);
186
-
187
- // Move actual select element into overflow hidden wrapper
188
- const hideSelect = document.createElement('div');
189
- hideSelect.classList.add('hide-select');
190
- this.wrapper.append(hideSelect);
191
- hideSelect.appendChild(this.el);
192
-
193
- if (this.el.disabled) this.wrapper.classList.add('disabled');
194
-
195
- this.selectOptions = <(HTMLOptGroupElement|HTMLOptionElement)[]>Array.from(this.el.children).filter(el => ['OPTION','OPTGROUP'].includes(el.tagName));
196
-
197
- // Create dropdown
198
- this.dropdownOptions = document.createElement('ul');
199
- this.dropdownOptions.id = `select-options-${Utils.guid()}`;
200
- this.dropdownOptions.classList.add('dropdown-content', 'select-dropdown');
201
- this.dropdownOptions.setAttribute('role', 'listbox');
202
- this.dropdownOptions.ariaMultiSelectable = this.isMultiple.toString();
203
- if (this.isMultiple) this.dropdownOptions.classList.add('multiple-select-dropdown');
204
-
205
- // Create dropdown structure
206
- if (this.selectOptions.length > 0) {
207
- this.selectOptions.forEach((realOption) => {
208
- if (realOption.tagName === 'OPTION') {
209
- // Option
210
- const virtualOption = this._createAndAppendOptionWithIcon(realOption, this.isMultiple ? 'multiple' : undefined);
211
- this._addOptionToValues(realOption as HTMLOptionElement, virtualOption);
212
- }
213
- else if (realOption.tagName === 'OPTGROUP') {
214
- // Optgroup
215
- const groupId = "opt-group-"+Utils.guid();
216
- const groupParent = document.createElement('li');
217
- groupParent.classList.add('optgroup');
218
- groupParent.tabIndex = -1;
219
- groupParent.setAttribute('role', 'group');
220
- groupParent.setAttribute('aria-labelledby', groupId);
221
- groupParent.innerHTML = `<span id="${groupId}" role="presentation">${realOption.getAttribute('label')}</span>`;
222
- this.dropdownOptions.append(groupParent);
223
-
224
- const groupChildren = [];
225
- const selectOptions = <HTMLOptionElement[]>Array.from(realOption.children).filter(el => el.tagName === 'OPTION');
226
- selectOptions.forEach(realOption => {
227
- const virtualOption = this._createAndAppendOptionWithIcon(realOption, 'optgroup-option');
228
- const childId = "opt-child-"+Utils.guid();
229
- virtualOption.id = childId;
230
- groupChildren.push(childId);
231
- this._addOptionToValues(realOption, virtualOption);
232
- });
233
- groupParent.setAttribute("aria-owns", groupChildren.join(" "));
234
- }
235
- });
236
- }
237
- this.wrapper.append(this.dropdownOptions);
238
-
239
- // Add input dropdown
240
- this.input = document.createElement('input');
241
- this.input.id = "m_select-input-" + Utils.guid();
242
- this.input.classList.add('select-dropdown', 'dropdown-trigger');
243
- this.input.type = 'text';
244
- this.input.readOnly = true;
245
- this.input.setAttribute('data-target', this.dropdownOptions.id);
246
- this.input.ariaReadOnly = 'true';
247
- this.input.ariaRequired = this.el.hasAttribute("required").toString(); //setAttribute("aria-required", this.el.hasAttribute("required"));
248
- if (this.el.disabled) this.input.disabled = true; // 'true');
249
-
250
- // Place Label after input
251
- if (this.labelEl) {
252
- this.input.after(this.labelEl);
253
- this.labelEl.setAttribute('for', this.input.id);
254
- this.labelEl.id = "m_select-label-" + Utils.guid();
255
- this.dropdownOptions.setAttribute("aria-labelledby", this.labelEl.id);
256
- }
257
-
258
- // Makes new element to assume HTML's select label and aria-attributes, if exists
259
- /*
260
- if (this.el.hasAttribute("aria-labelledby")){
261
- console.log(1);
262
- this.labelEl = <HTMLLabelElement>document.getElementById(this.el.getAttribute("aria-labelledby"));
263
- }
264
- else if (this.el.id != ""){
265
- console.log(2);
266
- const label = document.createElement('label');
267
- label.setAttribute('for', this.el.id);
268
- if (label){
269
- this.labelEl = label;
270
- this.labelEl.removeAttribute("for");
271
- this._labelFor = true;
272
- }
273
- }
274
- */
275
- // Tries to find a valid label in parent element
276
- // if (!this.labelEl) {
277
- // this.labelEl = this.el.parentElement.querySelector('label');
278
- // }
279
- // if (this.labelEl && this.labelEl.id == "") {
280
- // this.labelEl.id = "m_select-label-" + Utils.guid();
281
- // }
282
- // if (this.labelEl) {
283
- // this.labelEl.setAttribute("for", this.input.id);
284
- // this.dropdownOptions.setAttribute("aria-labelledby", this.labelEl.id);
285
- // }
286
- // else
287
- // this.dropdownOptions.ariaLabel = '';
288
-
289
- const attrs = this.el.attributes;
290
- for (let i = 0; i < attrs.length; ++i){
291
- const attr = attrs[i];
292
- if (attr.name.startsWith("aria-"))
293
- this.input.setAttribute(attr.name, attr.value);
294
- }
295
-
296
- // Adds aria-attributes to input element
297
- this.input.setAttribute('role', 'combobox');
298
- this.input.ariaExpanded = 'false';
299
- this.input.setAttribute("aria-owns", this.dropdownOptions.id);
300
- this.input.setAttribute("aria-controls", this.dropdownOptions.id);
301
- this.input.placeholder = " ";
302
-
303
- this.wrapper.prepend(this.input);
304
- this._setValueToInput();
305
-
306
- // Add caret
307
- const dropdownIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); //document.createElement('svg')
308
- dropdownIcon.classList.add('caret');
309
- dropdownIcon.setAttribute('height', '24');
310
- dropdownIcon.setAttribute('width', '24');
311
- dropdownIcon.setAttribute('viewBox', '0 0 24 24');
312
- dropdownIcon.ariaHidden = 'true';
313
- dropdownIcon.innerHTML = `<path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/>`;
314
- this.wrapper.prepend(dropdownIcon);
315
-
316
- // Initialize dropdown
317
- if (!this.el.disabled) {
318
- const dropdownOptions = {...this.options.dropdownOptions}; // TODO:
319
- dropdownOptions.coverTrigger = false;
320
- const userOnOpenEnd = dropdownOptions.onOpenEnd;
321
- const userOnCloseEnd = dropdownOptions.onCloseEnd;
322
- // Add callback for centering selected option when dropdown content is scrollable
323
- dropdownOptions.onOpenEnd = (el) => {
324
- const selectedOption = this.dropdownOptions.querySelector('.selected');
325
- if (selectedOption) {
326
- // Focus selected option in dropdown
327
- Utils.keyDown = true;
328
- this.dropdown.focusedIndex = [...selectedOption.parentNode.children].indexOf(selectedOption);
329
- this.dropdown._focusFocusedItem();
330
- Utils.keyDown = false;
331
- // Handle scrolling to selected option
332
- if (this.dropdown.isScrollable) {
333
- let scrollOffset =
334
- selectedOption.getBoundingClientRect().top -
335
- (this.dropdownOptions as HTMLElement).getBoundingClientRect().top; // scroll to selected option
336
- scrollOffset -= this.dropdownOptions.clientHeight / 2; // center in dropdown
337
- this.dropdownOptions.scrollTop = scrollOffset;
338
- }
339
- }
340
- this.input.ariaExpanded = 'true';
341
- // Handle user declared onOpenEnd if needed
342
- if (userOnOpenEnd && typeof userOnOpenEnd === 'function')
343
- userOnOpenEnd.call(this.dropdown, this.el);
344
- };
345
- // Add callback for reseting "expanded" state
346
- dropdownOptions.onCloseEnd = (el) => {
347
- this.input.ariaExpanded = 'false';
348
- // Handle user declared onOpenEnd if needed
349
- if (userOnCloseEnd && typeof userOnCloseEnd === 'function')
350
- userOnCloseEnd.call(this.dropdown, this.el);
351
- };
352
- // Prevent dropdown from closing too early
353
- dropdownOptions.closeOnClick = false;
354
- this.dropdown = Dropdown.init(this.input, dropdownOptions);
355
- }
356
- // Add initial selections
357
- this._setSelectedStates();
358
-
359
- // ! Workaround for Label: move label up again
360
- if (this.labelEl) this.input.after(this.labelEl);
361
- }
362
-
363
- _addOptionToValues(realOption: HTMLOptionElement, virtualOption: HTMLElement) {
364
- this._values.push({ el: realOption, optionEl: virtualOption });
365
- }
366
-
367
- _removeDropdown() {
368
- this.wrapper.querySelector('.caret').remove();
369
- this.input.remove();
370
- this.dropdownOptions.remove();
371
- this.wrapper.before(this.el);
372
- this.wrapper.remove();
373
- }
374
-
375
- _createAndAppendOptionWithIcon(realOption, type: string) {
376
- const li = document.createElement('li');
377
- li.setAttribute('role', 'option');
378
- if (realOption.disabled){
379
- li.classList.add('disabled');
380
- li.ariaDisabled = 'true';
381
- }
382
- if (type === 'optgroup-option') li.classList.add(type);
383
- // Text / Checkbox
384
- const span = document.createElement('span');
385
- if (this.isMultiple)
386
- span.innerHTML = `<label><input type="checkbox"${
387
- realOption.disabled ? ' disabled="disabled"' : ''
388
- }><span>${realOption.innerHTML}</span></label>`;
389
- else
390
- span.innerHTML = realOption.innerHTML;
391
- li.appendChild(span);
392
- // add Icon
393
- const iconUrl = realOption.getAttribute('data-icon');
394
- const classes = realOption.getAttribute('class')?.split();
395
- if (iconUrl) {
396
- const img = document.createElement('img');
397
- if (classes) img.classList.add(classes);
398
- img.src = iconUrl;
399
- img.ariaHidden = 'true';
400
- li.prepend(img);
401
- }
402
- // Check for multiple type
403
- this.dropdownOptions.append(li);
404
- return li;
405
- }
406
-
407
- _selectValue(value: ValueStruct) {
408
- value.el.selected = true;
409
- value.optionEl.classList.add('selected');
410
- value.optionEl.ariaSelected = 'true'; // setAttribute("aria-selected", true);
411
- const checkbox = <HTMLInputElement>value.optionEl.querySelector('input[type="checkbox"]');
412
- if (checkbox) checkbox.checked = true;
413
- }
414
-
415
- _deselectValue(value: ValueStruct) {
416
- value.el.selected = false;
417
- value.optionEl.classList.remove('selected');
418
- value.optionEl.ariaSelected = 'false'; //setAttribute("aria-selected", false);
419
- const checkbox = <HTMLInputElement>value.optionEl.querySelector('input[type="checkbox"]');
420
- if (checkbox) checkbox.checked = false;
421
- }
422
-
423
- _deselectAll() {
424
- this._values.forEach(value => this._deselectValue(value));
425
- }
426
-
427
- _isValueSelected(value: ValueStruct) {
428
- const realValues = this.getSelectedValues();
429
- return realValues.some((realValue) => realValue === value.el.value);
430
- }
431
-
432
- _toggleEntryFromArray(value: ValueStruct) {
433
- if (this._isValueSelected(value))
434
- this._deselectValue(value);
435
- else
436
- this._selectValue(value);
437
- }
438
-
439
- _getSelectedOptions(): HTMLOptionElement[] {
440
- // remove null, false, ... values
441
- return Array.prototype.filter.call(this.el.selectedOptions, (realOption: HTMLOptionElement) => realOption);
442
- }
443
-
444
- _setValueToInput() {
445
- const realOptions = this._getSelectedOptions();
446
- const values = this._values.filter((value) => realOptions.indexOf(value.el) >= 0);
447
- const texts = values.map((value) => value.optionEl.querySelector('span').innerText.trim());
448
- // Set input-text to first Option with empty value which indicates a description like "choose your option"
449
- if (texts.length === 0) {
450
- const firstDisabledOption = <HTMLOptionElement>this.el.querySelector('option:disabled');
451
- if (firstDisabledOption && firstDisabledOption.value === '') {
452
- this.input.value = firstDisabledOption.innerText;
453
- return;
454
- }
455
- }
456
- this.input.value = texts.join(', ');
457
- }
458
-
459
- _setSelectedStates() {
460
- this._values.forEach((value) => {
461
- const optionIsSelected = value.el.selected;
462
- const cb = <HTMLInputElement>value.optionEl.querySelector('input[type="checkbox"]');
463
- if (cb) cb.checked = optionIsSelected;
464
- if (optionIsSelected) {
465
- this._activateOption(this.dropdownOptions, value.optionEl);
466
- }
467
- else {
468
- value.optionEl.classList.remove('selected');
469
- value.optionEl.ariaSelected = 'false'; // attr("aria-selected", 'false');
470
- }
471
- });
472
- }
473
-
474
- _activateOption(ul: HTMLElement, li: HTMLElement) {
475
- if (!li) return;
476
- if (!this.isMultiple) ul.querySelectorAll('li.selected').forEach(li => li.classList.remove('selected'));
477
- li.classList.add('selected');
478
- li.ariaSelected = 'true';
479
- }
480
-
481
- getSelectedValues() {
482
- return this._getSelectedOptions().map((realOption) => realOption.value);
483
- }
484
- }