@materializecss/materialize 2.0.3-alpha → 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 (71) hide show
  1. package/README.md +1 -1
  2. package/dist/css/materialize.css +345 -236
  3. package/dist/css/materialize.min.css +2 -2
  4. package/dist/js/materialize.js +518 -1979
  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 +8 -2
  27. package/dist/src/tooltip.d.ts.map +1 -1
  28. package/package.json +14 -13
  29. package/sass/components/_buttons.scss +158 -73
  30. package/sass/components/_chips.scss +75 -28
  31. package/sass/components/_collapsible.scss +14 -2
  32. package/sass/components/_global.scss +6 -94
  33. package/sass/components/_materialbox.scss +2 -2
  34. package/sass/components/_modal.scss +0 -1
  35. package/sass/components/_preloader.scss +85 -0
  36. package/sass/components/_tooltip.scss +18 -8
  37. package/sass/components/_variables.scss +5 -4
  38. package/sass/components/forms/_range.scss +1 -1
  39. package/sass/components/forms/_switches.scss +44 -14
  40. package/Gruntfile.js +0 -480
  41. package/src/autocomplete.ts +0 -553
  42. package/src/bounding.ts +0 -6
  43. package/src/buttons.ts +0 -260
  44. package/src/cards.ts +0 -53
  45. package/src/carousel.ts +0 -676
  46. package/src/characterCounter.ts +0 -117
  47. package/src/chips.ts +0 -439
  48. package/src/collapsible.ts +0 -249
  49. package/src/component.ts +0 -120
  50. package/src/datepicker.ts +0 -1076
  51. package/src/dropdown.ts +0 -644
  52. package/src/edges.ts +0 -6
  53. package/src/forms.ts +0 -132
  54. package/src/global.ts +0 -114
  55. package/src/index.ts +0 -26
  56. package/src/materialbox.ts +0 -404
  57. package/src/modal.ts +0 -341
  58. package/src/parallax.ts +0 -149
  59. package/src/pushpin.ts +0 -165
  60. package/src/range.ts +0 -198
  61. package/src/scrollspy.ts +0 -263
  62. package/src/select.ts +0 -484
  63. package/src/sidenav.ts +0 -543
  64. package/src/slider.ts +0 -474
  65. package/src/tabs.ts +0 -347
  66. package/src/tapTarget.ts +0 -273
  67. package/src/timepicker.ts +0 -832
  68. package/src/toasts.ts +0 -290
  69. package/src/tooltip.ts +0 -346
  70. package/src/utils.ts +0 -271
  71. 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
- }