kmaterialize 2.3.3-1.0.21 → 2.3.3-1.0.23

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 (47) hide show
  1. package/components/air-datepicker/air-datepicker.js +152 -0
  2. package/components/alert/alert.js +54 -0
  3. package/components/button/buttons.js +220 -0
  4. package/components/card/cards.js +149 -0
  5. package/components/carousel/carousel.js +574 -0
  6. package/components/carousel/slider.js +340 -0
  7. package/components/chip/chips.js +341 -0
  8. package/components/collapsible/collapsible.js +156 -0
  9. package/components/color-input/color-input.js +166 -0
  10. package/components/datepicker/datepicker.js +1035 -0
  11. package/components/dialog/materialbox.js +377 -0
  12. package/components/dialog/modal.js +72 -0
  13. package/components/dropdown/dropdown.js +505 -0
  14. package/components/file-input/file-input.js +169 -0
  15. package/components/kanban/_kanban.scss +69 -0
  16. package/components/kanban/kanban.js +168 -0
  17. package/components/kanban/kanban.ts +57 -8
  18. package/components/loading/_loading.scss +68 -0
  19. package/components/loading/loading.ts +104 -0
  20. package/components/loading/loadingSpec.js +102 -0
  21. package/components/navigation-drawer/sidenav.js +454 -0
  22. package/components/number-input/number-input.js +68 -0
  23. package/components/password-input/password-input.js +49 -0
  24. package/components/popup/_popup.scss +106 -0
  25. package/components/popup/popup.ts +113 -0
  26. package/components/popup/popupSpec.js +140 -0
  27. package/components/search/autocomplete.js +470 -0
  28. package/components/slider/range.js +169 -0
  29. package/components/snackbar/toasts.js +244 -0
  30. package/components/tabs/tabs.js +289 -0
  31. package/components/textfield/forms.js +172 -0
  32. package/components/textfield/select.js +385 -0
  33. package/components/timepicker/timepicker.js +698 -0
  34. package/components/tom-select/tom-select-field.js +130 -0
  35. package/components/toolbar/toolbar.js +134 -0
  36. package/components/tooltip/tooltip.js +270 -0
  37. package/dist/css/materialize.colors.min.css +1 -1
  38. package/dist/css/materialize.css +322 -1
  39. package/dist/css/materialize.min.css +2 -2
  40. package/dist/css/materialize.min.css.map +1 -1
  41. package/dist/js/materialize.cjs.js +258 -42
  42. package/dist/js/materialize.d.ts +50 -3
  43. package/dist/js/materialize.js +258 -42
  44. package/dist/js/materialize.min.js +2 -2
  45. package/dist/js/materialize.mjs +257 -43
  46. package/package.json +6 -1
  47. package/sass/materialize.scss +2 -0
@@ -0,0 +1,172 @@
1
+ import { Utils } from '../../src/utils';
2
+ export class Forms {
3
+ /**
4
+ * Checks if the label has validation and apply
5
+ * the correct class and styles
6
+ * @param textfield
7
+ */
8
+ static validateField(textfield) {
9
+ if (!textfield) {
10
+ console.error('No text field element found');
11
+ return;
12
+ }
13
+ const hasLength = textfield.getAttribute('data-length') !== null;
14
+ const lenAttr = parseInt(textfield.getAttribute('data-length'));
15
+ const len = textfield.value.length;
16
+ if (len === 0 &&
17
+ textfield.validity.badInput === false &&
18
+ !textfield.required &&
19
+ textfield.classList.contains('validate')) {
20
+ textfield.classList.remove('invalid');
21
+ }
22
+ else if (textfield.classList.contains('validate')) {
23
+ // Check for character counter attributes
24
+ if ((textfield.validity.valid && hasLength && len <= lenAttr) ||
25
+ (textfield.validity.valid && !hasLength)) {
26
+ textfield.classList.remove('invalid');
27
+ }
28
+ else {
29
+ textfield.classList.add('invalid');
30
+ }
31
+ }
32
+ }
33
+ /**
34
+ * Resizes the given TextArea after updating the
35
+ * value content dynamically.
36
+ * @param e EventTarget
37
+ */
38
+ static textareaAutoResize(e) {
39
+ const textarea = e;
40
+ // if (!textarea) {
41
+ // console.error('No textarea element found');
42
+ // return;
43
+ // }
44
+ // Textarea Auto Resize
45
+ let hiddenDiv = document.querySelector('.hiddendiv');
46
+ if (!hiddenDiv) {
47
+ hiddenDiv = document.createElement('div');
48
+ hiddenDiv.classList.add('hiddendiv', 'common');
49
+ document.body.append(hiddenDiv);
50
+ }
51
+ const style = getComputedStyle(textarea);
52
+ // Set font properties of hiddenDiv
53
+ const fontFamily = style.fontFamily; //textarea.css('font-family');
54
+ const fontSize = style.fontSize; //textarea.css('font-size');
55
+ const lineHeight = style.lineHeight; //textarea.css('line-height');
56
+ // Firefox can't handle padding shorthand.
57
+ const paddingTop = style.paddingTop; //getComputedStyle(textarea).css('padding-top');
58
+ const paddingRight = style.paddingRight; //textarea.css('padding-right');
59
+ const paddingBottom = style.paddingBottom; //textarea.css('padding-bottom');
60
+ const paddingLeft = style.paddingLeft; //textarea.css('padding-left');
61
+ if (fontSize)
62
+ hiddenDiv.style.fontSize = fontSize; //('font-size', fontSize);
63
+ if (fontFamily)
64
+ hiddenDiv.style.fontFamily = fontFamily; //css('font-family', fontFamily);
65
+ if (lineHeight)
66
+ hiddenDiv.style.lineHeight = lineHeight; //css('line-height', lineHeight);
67
+ if (paddingTop)
68
+ hiddenDiv.style.paddingTop = paddingTop; //ss('padding-top', paddingTop);
69
+ if (paddingRight)
70
+ hiddenDiv.style.paddingRight = paddingRight; //css('padding-right', paddingRight);
71
+ if (paddingBottom)
72
+ hiddenDiv.style.paddingBottom = paddingBottom; //css('padding-bottom', paddingBottom);
73
+ if (paddingLeft)
74
+ hiddenDiv.style.paddingLeft = paddingLeft; //css('padding-left', paddingLeft);
75
+ // Set original-height, if none
76
+ if (!textarea.hasAttribute('original-height'))
77
+ textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());
78
+ if (textarea.getAttribute('wrap') === 'off') {
79
+ hiddenDiv.style.overflowWrap = 'normal'; // ('overflow-wrap', 'normal')
80
+ hiddenDiv.style.whiteSpace = 'pre'; //.css('white-space', 'pre');
81
+ }
82
+ hiddenDiv.innerText = textarea.value + '\n';
83
+ hiddenDiv.innerHTML = hiddenDiv.innerHTML.replace(/\n/g, '<br>');
84
+ // When textarea is hidden, width goes crazy.
85
+ // Approximate with half of window size
86
+ if (textarea.offsetWidth > 0 && textarea.offsetHeight > 0) {
87
+ hiddenDiv.style.width = textarea.getBoundingClientRect().width + 'px'; // ('width', textarea.width() + 'px');
88
+ }
89
+ else {
90
+ hiddenDiv.style.width = window.innerWidth / 2 + 'px'; //css('width', window.innerWidth / 2 + 'px');
91
+ }
92
+ // Resize if the new height is greater than the
93
+ // original height of the textarea
94
+ const originalHeight = parseInt(textarea.getAttribute('original-height'));
95
+ const prevLength = parseInt(textarea.getAttribute('previous-length'));
96
+ if (isNaN(originalHeight))
97
+ return;
98
+ if (originalHeight <= hiddenDiv.clientHeight) {
99
+ textarea.style.height = hiddenDiv.clientHeight + 'px'; //css('height', hiddenDiv.innerHeight() + 'px');
100
+ }
101
+ else if (textarea.value.length < prevLength) {
102
+ // In case the new height is less than original height, it
103
+ // means the textarea has less text than before
104
+ // So we set the height to the original one
105
+ textarea.style.height = originalHeight + 'px';
106
+ }
107
+ textarea.setAttribute('previous-length', (textarea.value || '').length.toString());
108
+ }
109
+ static Init() {
110
+ if (typeof document !== 'undefined')
111
+ document?.addEventListener('DOMContentLoaded', () => {
112
+ document.addEventListener('change', (e) => {
113
+ const target = e.target;
114
+ if (target instanceof HTMLInputElement) {
115
+ if (target.value.length !== 0 || target.getAttribute('placeholder') !== null) {
116
+ for (const child of target.parentNode.children) {
117
+ if (child.tagName == 'label') {
118
+ child.classList.add('active');
119
+ }
120
+ }
121
+ }
122
+ Forms.validateField(target);
123
+ }
124
+ });
125
+ document.addEventListener('keyup', (e) => {
126
+ const target = e.target;
127
+ // Radio and Checkbox focus class
128
+ if (target instanceof HTMLInputElement && ['radio', 'checkbox'].includes(target.type)) {
129
+ // TAB, check if tabbing to radio or checkbox.
130
+ if (Utils.keys.TAB.includes(e.key)) {
131
+ target.classList.add('tabbed');
132
+ target.addEventListener('blur', () => target.classList.remove('tabbed'), {
133
+ once: true
134
+ });
135
+ }
136
+ }
137
+ });
138
+ document
139
+ .querySelectorAll('.materialize-textarea')
140
+ .forEach((textArea) => {
141
+ Forms.InitTextarea(textArea);
142
+ });
143
+ // File Input Path
144
+ document
145
+ .querySelectorAll('.file-field input[type="file"]')
146
+ .forEach((fileInput) => {
147
+ Forms.InitFileInputPath(fileInput);
148
+ });
149
+ });
150
+ }
151
+ static InitTextarea(textarea) {
152
+ // Save Data in Element
153
+ textarea.setAttribute('original-height', textarea.getBoundingClientRect().height.toString());
154
+ textarea.setAttribute('previous-length', (textarea.value || '').length.toString());
155
+ Forms.textareaAutoResize(textarea);
156
+ textarea.addEventListener('keyup', (e) => Forms.textareaAutoResize(e.target));
157
+ textarea.addEventListener('keydown', (e) => Forms.textareaAutoResize(e.target));
158
+ }
159
+ static InitFileInputPath(fileInput) {
160
+ fileInput.addEventListener('change', () => {
161
+ const fileField = fileInput.closest('.file-field');
162
+ const pathInput = fileField.querySelector('input.file-path');
163
+ const files = fileInput.files;
164
+ const filenames = [];
165
+ for (let i = 0; i < files.length; i++) {
166
+ filenames.push(files[i].name);
167
+ }
168
+ pathInput.value = filenames.join(', ');
169
+ pathInput.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true }));
170
+ });
171
+ }
172
+ }
@@ -0,0 +1,385 @@
1
+ import { Utils } from '../../src/utils';
2
+ import { Dropdown } from '../dropdown/dropdown';
3
+ import { Component } from '../../src/component';
4
+ const _defaults = {
5
+ classes: '',
6
+ dropdownOptions: {}
7
+ };
8
+ export class FormSelect extends Component {
9
+ /** If this is a multiple select. */
10
+ isMultiple;
11
+ /**
12
+ * Label associated with the current select element.
13
+ * Is "null", if not detected.
14
+ */
15
+ labelEl;
16
+ /** Dropdown UL element. */
17
+ dropdownOptions;
18
+ /** Text input that shows current selected option. */
19
+ input;
20
+ /** Instance of the dropdown plugin for this select. */
21
+ dropdown;
22
+ /** The select wrapper element. */
23
+ wrapper;
24
+ selectOptions;
25
+ _values;
26
+ nativeTabIndex;
27
+ constructor(el, options) {
28
+ super(el, options, FormSelect);
29
+ if (this.el.classList.contains('browser-default'))
30
+ return;
31
+ this.el['M_FormSelect'] = this;
32
+ this.options = {
33
+ ...FormSelect.defaults,
34
+ ...options
35
+ };
36
+ this.isMultiple = this.el.multiple;
37
+ this.nativeTabIndex = this.el.tabIndex ?? -1;
38
+ this.el.tabIndex = -1;
39
+ this._values = [];
40
+ this._setupDropdown();
41
+ this._setupEventHandlers();
42
+ }
43
+ static get defaults() {
44
+ return _defaults;
45
+ }
46
+ /**
47
+ * Initializes instances of FormSelect.
48
+ * @param els HTML elements.
49
+ * @param options Component options.
50
+ */
51
+ static init(els, options = {}) {
52
+ return super.init(els, options, FormSelect);
53
+ }
54
+ static getInstance(el) {
55
+ return el['M_FormSelect'];
56
+ }
57
+ destroy() {
58
+ this._removeEventHandlers();
59
+ this._removeDropdown();
60
+ this.el['M_FormSelect'] = undefined;
61
+ }
62
+ _setupEventHandlers() {
63
+ this.dropdownOptions.querySelectorAll('li:not(.optgroup)').forEach((el) => {
64
+ el.addEventListener('click', this._handleOptionClick);
65
+ el.addEventListener('keydown', (e) => {
66
+ if (e.key === ' ' || e.key === 'Enter')
67
+ this._handleOptionClick(e);
68
+ });
69
+ });
70
+ this.el.addEventListener('change', this._handleSelectChange);
71
+ this.input.addEventListener('click', this._handleInputClick);
72
+ }
73
+ _removeEventHandlers() {
74
+ this.dropdownOptions.querySelectorAll('li:not(.optgroup)').forEach((el) => {
75
+ el.removeEventListener('click', this._handleOptionClick);
76
+ });
77
+ this.el.removeEventListener('change', this._handleSelectChange);
78
+ this.input.removeEventListener('click', this._handleInputClick);
79
+ }
80
+ _handleSelectChange = () => {
81
+ this._setValueToInput();
82
+ };
83
+ _handleOptionClick = (e) => {
84
+ e.preventDefault();
85
+ const virtualOption = e.target.closest('li');
86
+ this._selectOptionElement(virtualOption);
87
+ e.stopPropagation();
88
+ };
89
+ _arraysEqual(a, b) {
90
+ if (a === b)
91
+ return true;
92
+ if (a == null || b == null)
93
+ return false;
94
+ if (a.length !== b.length)
95
+ return false;
96
+ for (let i = 0; i < a.length; ++i)
97
+ if (a[i] !== b[i])
98
+ return false;
99
+ return true;
100
+ }
101
+ _selectOptionElement(virtualOption) {
102
+ if (!virtualOption.classList.contains('disabled') &&
103
+ !virtualOption.classList.contains('optgroup')) {
104
+ const value = this._values.find((value) => value.optionEl === virtualOption);
105
+ const previousSelectedValues = this.getSelectedValues();
106
+ if (this.isMultiple) {
107
+ // Multi-Select
108
+ this._toggleEntryFromArray(value);
109
+ }
110
+ else {
111
+ // Single-Select
112
+ this._deselectAll();
113
+ this._selectValue(value);
114
+ }
115
+ // Refresh Input-Text
116
+ this._setValueToInput();
117
+ // Trigger Change-Event only when data is different
118
+ const actualSelectedValues = this.getSelectedValues();
119
+ const selectionHasChanged = !this._arraysEqual(previousSelectedValues, actualSelectedValues);
120
+ if (selectionHasChanged)
121
+ this.el.dispatchEvent(new Event('change', { bubbles: true, cancelable: true, composed: true })); // trigger('change');
122
+ }
123
+ if (!this.isMultiple)
124
+ this.dropdown.close();
125
+ }
126
+ _handleInputClick = () => {
127
+ if (this.dropdown && this.dropdown.isOpen) {
128
+ this._setValueToInput();
129
+ this._setSelectedStates();
130
+ }
131
+ };
132
+ _setupDropdown() {
133
+ this.labelEl = document.querySelector('[for="' + this.el.id + '"]');
134
+ this.wrapper = document.createElement('div');
135
+ this.wrapper.classList.add('select-wrapper', 'input-field');
136
+ if (this.options.classes.length > 0) {
137
+ this.wrapper.classList.add(...this.options.classes.split(' '));
138
+ }
139
+ this.el.before(this.wrapper);
140
+ // Move actual select element into overflow hidden wrapper
141
+ const hiddenDiv = document.createElement('div');
142
+ hiddenDiv.classList.add('hide-select');
143
+ this.wrapper.append(hiddenDiv);
144
+ hiddenDiv.appendChild(this.el);
145
+ if (this.el.disabled)
146
+ this.wrapper.classList.add('disabled');
147
+ this.selectOptions = (Array.from(this.el.children).filter((el) => ['OPTION', 'OPTGROUP'].includes(el.tagName)));
148
+ // Create dropdown
149
+ this.dropdownOptions = document.createElement('ul');
150
+ this.dropdownOptions.id = `select-options-${Utils.guid()}`;
151
+ this.dropdownOptions.setAttribute('popover', 'auto');
152
+ this.dropdownOptions.classList.add('dropdown-content', 'select-dropdown');
153
+ this.dropdownOptions.setAttribute('role', 'listbox');
154
+ this.dropdownOptions.ariaMultiSelectable = this.isMultiple.toString();
155
+ if (this.isMultiple)
156
+ this.dropdownOptions.classList.add('multiple-select-dropdown');
157
+ // Create dropdown structure
158
+ if (this.selectOptions.length > 0) {
159
+ this.selectOptions.forEach((realOption) => {
160
+ if (realOption.tagName === 'OPTION') {
161
+ // Option
162
+ const virtualOption = this._createAndAppendOptionWithIcon(realOption, this.isMultiple ? 'multiple' : undefined);
163
+ this._addOptionToValues(realOption, virtualOption);
164
+ }
165
+ else if (realOption.tagName === 'OPTGROUP') {
166
+ // Optgroup
167
+ const groupId = 'opt-group-' + Utils.guid();
168
+ const groupParent = document.createElement('li');
169
+ groupParent.classList.add('optgroup');
170
+ groupParent.tabIndex = -1;
171
+ groupParent.setAttribute('role', 'group');
172
+ groupParent.setAttribute('aria-labelledby', groupId);
173
+ groupParent.innerHTML = `<span id="${groupId}" role="presentation">${realOption.getAttribute('label')}</span>`;
174
+ this.dropdownOptions.append(groupParent);
175
+ const groupChildren = [];
176
+ const selectOptions = (Array.from(realOption.children).filter((el) => el.tagName === 'OPTION'));
177
+ selectOptions.forEach((realOption) => {
178
+ const virtualOption = this._createAndAppendOptionWithIcon(realOption, 'optgroup-option');
179
+ const childId = 'opt-child-' + Utils.guid();
180
+ virtualOption.id = childId;
181
+ groupChildren.push(childId);
182
+ this._addOptionToValues(realOption, virtualOption);
183
+ });
184
+ groupParent.setAttribute('aria-owns', groupChildren.join(' '));
185
+ }
186
+ });
187
+ }
188
+ this.wrapper.append(this.dropdownOptions);
189
+ // Add input dropdown
190
+ this.input = document.createElement('input');
191
+ this.input.id = 'm_select-input-' + Utils.guid();
192
+ this.input.classList.add('select-dropdown', 'dropdown-trigger');
193
+ this.input.type = 'text';
194
+ this.input.readOnly = true;
195
+ this.input.setAttribute('data-target', this.dropdownOptions.id);
196
+ this.input.ariaReadOnly = 'true';
197
+ this.input.ariaRequired = this.el.hasAttribute('required').toString(); //setAttribute("aria-required", this.el.hasAttribute("required"));
198
+ if (this.el.disabled)
199
+ this.input.disabled = true; // 'true');
200
+ this.input.setAttribute('tabindex', this.nativeTabIndex.toString());
201
+ const attrs = this.el.attributes;
202
+ for (let i = 0; i < attrs.length; ++i) {
203
+ const attr = attrs[i];
204
+ if (attr.name.startsWith('aria-'))
205
+ this.input.setAttribute(attr.name, attr.value);
206
+ }
207
+ // Adds aria-attributes to input element
208
+ this.input.setAttribute('role', 'combobox');
209
+ this.input.ariaExpanded = 'false';
210
+ this.input.setAttribute('aria-owns', this.dropdownOptions.id);
211
+ this.input.setAttribute('aria-controls', this.dropdownOptions.id);
212
+ this.input.placeholder = ' ';
213
+ this.wrapper.prepend(this.input);
214
+ this._setValueToInput();
215
+ // Add caret
216
+ const dropdownIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); //document.createElement('svg')
217
+ dropdownIcon.classList.add('caret');
218
+ dropdownIcon.setAttribute('height', '24');
219
+ dropdownIcon.setAttribute('width', '24');
220
+ dropdownIcon.setAttribute('viewBox', '0 0 24 24');
221
+ dropdownIcon.ariaHidden = 'true';
222
+ dropdownIcon.innerHTML = `<path d="M7 10l5 5 5-5z"/><path d="M0 0h24v24H0z" fill="none"/>`;
223
+ this.wrapper.prepend(dropdownIcon);
224
+ // Initialize dropdown
225
+ if (!this.el.disabled) {
226
+ const dropdownOptions = { ...this.options.dropdownOptions };
227
+ dropdownOptions.coverTrigger = false;
228
+ const userOnOpenEnd = dropdownOptions.onOpenEnd;
229
+ const userOnCloseEnd = dropdownOptions.onCloseEnd;
230
+ // Add callback for centering selected option when dropdown content is scrollable
231
+ dropdownOptions.onOpenEnd = () => {
232
+ const selectedOption = this.dropdownOptions.querySelector('.selected');
233
+ if (selectedOption) {
234
+ // Focus selected option in dropdown
235
+ Utils.keyDown = true;
236
+ this.dropdown.focusedIndex = [...selectedOption.parentNode.children].indexOf(selectedOption);
237
+ this.dropdown._focusFocusedItem();
238
+ Utils.keyDown = false;
239
+ // Handle scrolling to selected option
240
+ if (this.dropdown.isScrollable) {
241
+ let scrollOffset = selectedOption.getBoundingClientRect().top -
242
+ this.dropdownOptions.getBoundingClientRect().top; // scroll to selected option
243
+ scrollOffset -= this.dropdownOptions.clientHeight / 2; // center in dropdown
244
+ this.dropdownOptions.scrollTop = scrollOffset;
245
+ }
246
+ }
247
+ this.input.ariaExpanded = 'true';
248
+ // Handle user declared onOpenEnd if needed
249
+ if (userOnOpenEnd && typeof userOnOpenEnd === 'function')
250
+ userOnOpenEnd.call(this.dropdown, this.el);
251
+ };
252
+ // Add callback for reseting "expanded" state
253
+ dropdownOptions.onCloseEnd = () => {
254
+ this.input.ariaExpanded = 'false';
255
+ // Handle user declared onOpenEnd if needed
256
+ if (userOnCloseEnd && typeof userOnCloseEnd === 'function')
257
+ userOnCloseEnd.call(this.dropdown, this.el);
258
+ };
259
+ // Prevent dropdown from closing too early
260
+ dropdownOptions.closeOnClick = false;
261
+ this.dropdown = Dropdown.init(this.input, dropdownOptions);
262
+ }
263
+ // Add initial selections
264
+ this._setSelectedStates();
265
+ // move label
266
+ if (this.labelEl)
267
+ this.input.after(this.labelEl);
268
+ }
269
+ _addOptionToValues(realOption, virtualOption) {
270
+ this._values.push({ el: realOption, optionEl: virtualOption });
271
+ }
272
+ _removeDropdown() {
273
+ this.wrapper.querySelector('.caret').remove();
274
+ this.input.remove();
275
+ this.dropdownOptions.remove();
276
+ this.wrapper.before(this.el);
277
+ this.wrapper.remove();
278
+ }
279
+ _createAndAppendOptionWithIcon(realOption, type) {
280
+ const li = document.createElement('li');
281
+ li.setAttribute('role', 'option');
282
+ if (realOption.disabled) {
283
+ li.classList.add('disabled');
284
+ li.ariaDisabled = 'true';
285
+ }
286
+ if (type === 'optgroup-option')
287
+ li.classList.add(type);
288
+ // Text / Checkbox
289
+ const span = document.createElement('span');
290
+ span.innerHTML = realOption.innerHTML;
291
+ if (this.isMultiple && !realOption.disabled) {
292
+ span.innerHTML = `<label><input type="checkbox"><span>${realOption.innerHTML}</span></label>`;
293
+ }
294
+ li.appendChild(span);
295
+ // add Icon
296
+ const iconUrl = realOption.getAttribute('data-icon');
297
+ const classes = realOption.getAttribute('class')?.split(' ');
298
+ if (iconUrl) {
299
+ const img = document.createElement('img');
300
+ if (classes)
301
+ img.classList.add(...classes);
302
+ img.src = iconUrl;
303
+ img.ariaHidden = 'true';
304
+ li.prepend(img);
305
+ }
306
+ // Check for multiple type
307
+ this.dropdownOptions.append(li);
308
+ return li;
309
+ }
310
+ _selectValue(value) {
311
+ value.el.selected = true;
312
+ value.optionEl.classList.add('selected');
313
+ value.optionEl.ariaSelected = 'true'; // setAttribute("aria-selected", true);
314
+ const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
315
+ if (checkbox)
316
+ checkbox.checked = true;
317
+ }
318
+ _deselectValue(value) {
319
+ value.el.selected = false;
320
+ value.optionEl.classList.remove('selected');
321
+ value.optionEl.ariaSelected = 'false'; //setAttribute("aria-selected", false);
322
+ const checkbox = value.optionEl.querySelector('input[type="checkbox"]');
323
+ if (checkbox)
324
+ checkbox.checked = false;
325
+ }
326
+ _deselectAll() {
327
+ this._values.forEach((value) => this._deselectValue(value));
328
+ }
329
+ _isValueSelected(value) {
330
+ const realValues = this.getSelectedValues();
331
+ return realValues.some((realValue) => realValue === value.el.value);
332
+ }
333
+ _toggleEntryFromArray(value) {
334
+ if (this._isValueSelected(value))
335
+ this._deselectValue(value);
336
+ else
337
+ this._selectValue(value);
338
+ }
339
+ _getSelectedOptions() {
340
+ // remove null, false, ... values
341
+ return Array.prototype.filter.call(this.el.selectedOptions, (realOption) => realOption);
342
+ }
343
+ _setValueToInput() {
344
+ const selectedRealOptions = this._getSelectedOptions();
345
+ const selectedOptionPairs = this._values.filter((value) => selectedRealOptions.indexOf(value.el) >= 0);
346
+ // Filter not disabled
347
+ const notDisabledOptionPairs = selectedOptionPairs.filter((op) => !op.el.disabled);
348
+ const texts = notDisabledOptionPairs.map((value) => value.optionEl.querySelector('span').innerText.trim());
349
+ // Set input-text to first Option with empty value which indicates a description like "choose your option"
350
+ if (texts.length === 0) {
351
+ const firstDisabledOption = this.el.querySelector('option:disabled');
352
+ if (firstDisabledOption && firstDisabledOption.value === '') {
353
+ this.input.value = firstDisabledOption.innerText;
354
+ return;
355
+ }
356
+ }
357
+ this.input.value = texts.join(', ');
358
+ }
359
+ _setSelectedStates() {
360
+ this._values.forEach((value) => {
361
+ const optionIsSelected = value.el.selected;
362
+ const cb = value.optionEl.querySelector('input[type="checkbox"]');
363
+ if (cb)
364
+ cb.checked = optionIsSelected;
365
+ if (optionIsSelected) {
366
+ this._activateOption(this.dropdownOptions, value.optionEl);
367
+ }
368
+ else {
369
+ value.optionEl.classList.remove('selected');
370
+ value.optionEl.ariaSelected = 'false'; // attr("aria-selected", 'false');
371
+ }
372
+ });
373
+ }
374
+ _activateOption(ul, li) {
375
+ if (!li)
376
+ return;
377
+ if (!this.isMultiple)
378
+ ul.querySelectorAll('li.selected').forEach((li) => li.classList.remove('selected'));
379
+ li.classList.add('selected');
380
+ li.ariaSelected = 'true';
381
+ }
382
+ getSelectedValues() {
383
+ return this._getSelectedOptions().map((realOption) => realOption.value);
384
+ }
385
+ }