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,340 @@
1
+ import { Utils } from '../../src/utils';
2
+ import { Component } from '../../src/component';
3
+ const _defaults = {
4
+ indicators: true,
5
+ height: 400,
6
+ duration: 500,
7
+ interval: 6000,
8
+ pauseOnFocus: true,
9
+ pauseOnHover: true,
10
+ indicatorLabelFunc: null // Function which will generate a label for the indicators (ARIA)
11
+ };
12
+ export class Slider extends Component {
13
+ /** Index of current slide. */
14
+ activeIndex;
15
+ interval;
16
+ eventPause;
17
+ _slider;
18
+ _slides;
19
+ _activeSlide;
20
+ _indicators;
21
+ _hovered;
22
+ _focused;
23
+ _focusCurrent;
24
+ _sliderId;
25
+ constructor(el, options) {
26
+ super(el, options, Slider);
27
+ this.el['M_Slider'] = this;
28
+ this.options = {
29
+ ...Slider.defaults,
30
+ ...options
31
+ };
32
+ // init props
33
+ this.interval = null;
34
+ this.eventPause = false;
35
+ this._hovered = false;
36
+ this._focused = false;
37
+ this._focusCurrent = false;
38
+ // setup
39
+ this._slider = this.el.querySelector('.slides');
40
+ this._slides = Array.from(this._slider.querySelectorAll('li'));
41
+ this.activeIndex = this._slides.findIndex((li) => li.classList.contains('active'));
42
+ if (this.activeIndex !== -1) {
43
+ this._activeSlide = this._slides[this.activeIndex];
44
+ }
45
+ this._setSliderHeight();
46
+ // Sets element id if it does not have one
47
+ if (this._slider.hasAttribute('id'))
48
+ this._sliderId = this._slider.getAttribute('id');
49
+ else {
50
+ this._sliderId = 'slider-' + Utils.guid();
51
+ this._slider.setAttribute('id', this._sliderId);
52
+ }
53
+ const placeholderBase64 = 'data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==';
54
+ // Set initial positions of captions
55
+ this._slides.forEach((slide) => {
56
+ // Caption
57
+ //const caption = <HTMLElement|null>slide.querySelector('.caption');
58
+ //if (caption) this._animateCaptionIn(caption, 0);
59
+ // Set Images as Background Images
60
+ const img = slide.querySelector('img');
61
+ if (img) {
62
+ if (img.src !== placeholderBase64) {
63
+ img.style.backgroundImage = 'url(' + img.src + ')';
64
+ img.src = placeholderBase64;
65
+ }
66
+ }
67
+ // Sets slide as focusable by code
68
+ if (!slide.hasAttribute('tabindex'))
69
+ slide.setAttribute('tabindex', '-1');
70
+ // Removes initial visibility from "inactive" slides
71
+ slide.style.visibility = 'hidden';
72
+ });
73
+ this._setupIndicators();
74
+ // Show active slide
75
+ if (this._activeSlide) {
76
+ this._activeSlide.style.display = 'block';
77
+ this._activeSlide.style.visibility = 'visible';
78
+ }
79
+ else {
80
+ this.activeIndex = 0;
81
+ this._slides[0].classList.add('active');
82
+ this._slides[0].style.visibility = 'visible';
83
+ this._activeSlide = this._slides[0];
84
+ this._animateSlide(this._slides[0], true);
85
+ // Update indicators
86
+ if (this.options.indicators) {
87
+ this._indicators[this.activeIndex].children[0].classList.add('active');
88
+ }
89
+ }
90
+ this._setupEventHandlers();
91
+ // auto scroll
92
+ this.start();
93
+ }
94
+ static get defaults() {
95
+ return _defaults;
96
+ }
97
+ /**
98
+ * Initializes instances of Slider.
99
+ * @param els HTML elements.
100
+ * @param options Component options.
101
+ */
102
+ static init(els, options = {}) {
103
+ return super.init(els, options, Slider);
104
+ }
105
+ static getInstance(el) {
106
+ return el['M_Slider'];
107
+ }
108
+ destroy() {
109
+ this.pause();
110
+ this._removeIndicators();
111
+ this._removeEventHandlers();
112
+ this.el['M_Slider'] = undefined;
113
+ }
114
+ _setupEventHandlers() {
115
+ if (this.options.pauseOnFocus) {
116
+ this.el.addEventListener('focusin', this._handleAutoPauseFocus);
117
+ this.el.addEventListener('focusout', this._handleAutoStartFocus);
118
+ }
119
+ if (this.options.pauseOnHover) {
120
+ this.el.addEventListener('mouseenter', this._handleAutoPauseHover);
121
+ this.el.addEventListener('mouseleave', this._handleAutoStartHover);
122
+ }
123
+ if (this.options.indicators) {
124
+ this._indicators.forEach((el) => {
125
+ el.addEventListener('click', this._handleIndicatorClick);
126
+ });
127
+ }
128
+ }
129
+ _removeEventHandlers() {
130
+ if (this.options.pauseOnFocus) {
131
+ this.el.removeEventListener('focusin', this._handleAutoPauseFocus);
132
+ this.el.removeEventListener('focusout', this._handleAutoStartFocus);
133
+ }
134
+ if (this.options.pauseOnHover) {
135
+ this.el.removeEventListener('mouseenter', this._handleAutoPauseHover);
136
+ this.el.removeEventListener('mouseleave', this._handleAutoStartHover);
137
+ }
138
+ if (this.options.indicators) {
139
+ this._indicators.forEach((el) => {
140
+ el.removeEventListener('click', this._handleIndicatorClick);
141
+ });
142
+ }
143
+ }
144
+ _handleIndicatorClick = (e) => {
145
+ const el = e.target.parentElement;
146
+ const currIndex = [...el.parentNode.children].indexOf(el);
147
+ this._focusCurrent = true;
148
+ this.set(currIndex);
149
+ };
150
+ _handleAutoPauseHover = () => {
151
+ this._hovered = true;
152
+ if (this.interval != null) {
153
+ this._pause(true);
154
+ }
155
+ };
156
+ _handleAutoPauseFocus = () => {
157
+ this._focused = true;
158
+ if (this.interval != null) {
159
+ this._pause(true);
160
+ }
161
+ };
162
+ _handleAutoStartHover = () => {
163
+ this._hovered = false;
164
+ if (!(this.options.pauseOnFocus && this._focused) && this.eventPause) {
165
+ this.start();
166
+ }
167
+ };
168
+ _handleAutoStartFocus = () => {
169
+ this._focused = false;
170
+ if (!(this.options.pauseOnHover && this._hovered) && this.eventPause) {
171
+ this.start();
172
+ }
173
+ };
174
+ _handleInterval = () => {
175
+ const activeElem = this._slider.querySelector('.active');
176
+ let newActiveIndex = [...activeElem.parentNode.children].indexOf(activeElem);
177
+ if (this._slides.length === newActiveIndex + 1)
178
+ newActiveIndex = 0; // loop to start
179
+ else
180
+ newActiveIndex += 1;
181
+ this.set(newActiveIndex);
182
+ };
183
+ _animateSlide(slide, isDirectionIn) {
184
+ let dx = 0, dy = 0;
185
+ // from
186
+ slide.style.opacity = isDirectionIn ? '0' : '1';
187
+ setTimeout(() => {
188
+ slide.style.transition = `opacity ${this.options.duration}ms ease`;
189
+ // to
190
+ slide.style.opacity = isDirectionIn ? '1' : '0';
191
+ }, 1);
192
+ // Caption
193
+ const caption = slide.querySelector('.caption');
194
+ if (!caption)
195
+ return;
196
+ if (caption.classList.contains('center-align'))
197
+ dy = -100;
198
+ else if (caption.classList.contains('right-align'))
199
+ dx = 100;
200
+ else if (caption.classList.contains('left-align'))
201
+ dx = -100;
202
+ // from
203
+ caption.style.opacity = isDirectionIn ? '0' : '1';
204
+ caption.style.transform = isDirectionIn ? `translate(${dx}px, ${dy}px)` : `translate(0, 0)`;
205
+ setTimeout(() => {
206
+ caption.style.transition = `opacity ${this.options.duration}ms ease, transform ${this.options.duration}ms ease`;
207
+ // to
208
+ caption.style.opacity = isDirectionIn ? '1' : '0';
209
+ caption.style.transform = isDirectionIn ? `translate(0, 0)` : `translate(${dx}px, ${dy}px)`;
210
+ }, this.options.duration); // delay
211
+ }
212
+ _setSliderHeight() {
213
+ // If fullscreen, do nothing
214
+ if (!this.el.classList.contains('fullscreen')) {
215
+ if (this.options.indicators) {
216
+ // Add height if indicators are present
217
+ this.el.style.height = this.options.height + 40 + 'px'; //.css('height', this.options.height + 40 + 'px');
218
+ }
219
+ else {
220
+ this.el.style.height = this.options.height + 'px';
221
+ }
222
+ this._slider.style.height = this.options.height + 'px';
223
+ }
224
+ }
225
+ _setupIndicators() {
226
+ if (this.options.indicators) {
227
+ const ul = document.createElement('ul');
228
+ ul.classList.add('indicators');
229
+ const arrLi = [];
230
+ this._slides.forEach((el, i) => {
231
+ const label = this.options.indicatorLabelFunc
232
+ ? this.options.indicatorLabelFunc.call(this, i + 1, i === 0)
233
+ : `${i + 1}`;
234
+ const li = document.createElement('li');
235
+ li.classList.add('indicator-item');
236
+ li.innerHTML = `<button type="button" class="indicator-item-btn" aria-label="${label}" aria-controls="${this._sliderId}"></button>`;
237
+ arrLi.push(li);
238
+ ul.append(li);
239
+ });
240
+ this.el.append(ul);
241
+ this._indicators = arrLi;
242
+ }
243
+ }
244
+ _removeIndicators() {
245
+ this.el.querySelector('ul.indicators').remove(); //find('ul.indicators').remove();
246
+ }
247
+ set(index) {
248
+ // Wrap around indices.
249
+ if (index >= this._slides.length)
250
+ index = 0;
251
+ else if (index < 0)
252
+ index = this._slides.length - 1;
253
+ // Only do if index changes
254
+ if (this.activeIndex === index)
255
+ return;
256
+ this._activeSlide = this._slides[this.activeIndex];
257
+ const _caption = this._activeSlide.querySelector('.caption');
258
+ this._activeSlide.classList.remove('active');
259
+ // Enables every slide
260
+ this._slides.forEach((slide) => (slide.style.visibility = 'visible'));
261
+ //--- Hide active Slide + Caption
262
+ this._activeSlide.style.opacity = '0';
263
+ setTimeout(() => {
264
+ this._slides.forEach((slide) => {
265
+ if (slide.classList.contains('active'))
266
+ return;
267
+ slide.style.opacity = '0';
268
+ slide.style.transform = 'translate(0, 0)';
269
+ // Disables invisible slides (for assistive technologies)
270
+ slide.style.visibility = 'hidden';
271
+ });
272
+ }, this.options.duration);
273
+ // Hide active Caption
274
+ //this._animateCaptionIn(_caption, this.options.duration);
275
+ _caption.style.opacity = '0';
276
+ // Update indicators
277
+ if (this.options.indicators) {
278
+ const activeIndicator = this._indicators[this.activeIndex].children[0];
279
+ const nextIndicator = this._indicators[index].children[0];
280
+ activeIndicator.classList.remove('active');
281
+ nextIndicator.classList.add('active');
282
+ if (typeof this.options.indicatorLabelFunc === 'function') {
283
+ activeIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, this.activeIndex, false);
284
+ nextIndicator.ariaLabel = this.options.indicatorLabelFunc.call(this, index, true);
285
+ }
286
+ }
287
+ //--- Show new Slide + Caption
288
+ this._animateSlide(this._slides[index], true);
289
+ this._slides[index].classList.add('active');
290
+ this.activeIndex = index;
291
+ // Reset interval, if allowed. This check prevents autostart
292
+ // when slider is paused, since it can be changed though indicators.
293
+ if (this.interval != null) {
294
+ this.start();
295
+ }
296
+ }
297
+ _pause(fromEvent) {
298
+ clearInterval(this.interval);
299
+ this.eventPause = fromEvent;
300
+ this.interval = null;
301
+ }
302
+ /**
303
+ * Pause slider autoslide.
304
+ */
305
+ pause = () => {
306
+ this._pause(false);
307
+ };
308
+ /**
309
+ * Start slider autoslide.
310
+ */
311
+ start = () => {
312
+ clearInterval(this.interval);
313
+ this.interval = setInterval(this._handleInterval, this.options.duration + this.options.interval);
314
+ this.eventPause = false;
315
+ };
316
+ /**
317
+ * Move to next slider.
318
+ */
319
+ next = () => {
320
+ let newIndex = this.activeIndex + 1;
321
+ // Wrap around indices.
322
+ if (newIndex >= this._slides.length)
323
+ newIndex = 0;
324
+ else if (newIndex < 0)
325
+ newIndex = this._slides.length - 1;
326
+ this.set(newIndex);
327
+ };
328
+ /**
329
+ * Move to prev slider.
330
+ */
331
+ prev = () => {
332
+ let newIndex = this.activeIndex - 1;
333
+ // Wrap around indices.
334
+ if (newIndex >= this._slides.length)
335
+ newIndex = 0;
336
+ else if (newIndex < 0)
337
+ newIndex = this._slides.length - 1;
338
+ this.set(newIndex);
339
+ };
340
+ }
@@ -0,0 +1,341 @@
1
+ var _a;
2
+ import { Utils } from '../../src/utils';
3
+ import { Autocomplete } from '../search/autocomplete';
4
+ import { Component } from '../../src/component';
5
+ const _defaults = {
6
+ data: [],
7
+ placeholder: '',
8
+ secondaryPlaceholder: '',
9
+ closeIconClass: 'material-icons',
10
+ autocompleteOptions: {},
11
+ autocompleteOnly: false,
12
+ limit: Infinity,
13
+ allowUserInput: false,
14
+ onChipAdd: null,
15
+ onChipSelect: null,
16
+ onChipDelete: null
17
+ };
18
+ function gGetIndex(el) {
19
+ return [...el.parentNode.children].indexOf(el);
20
+ }
21
+ class Chips extends Component {
22
+ /** Array of the current chips data. */
23
+ chipsData;
24
+ /** If the chips has autocomplete enabled. */
25
+ hasAutocomplete;
26
+ /** Autocomplete instance, if any. */
27
+ autocomplete;
28
+ #input;
29
+ #label;
30
+ #chips;
31
+ static #keydown;
32
+ #selectedChip;
33
+ constructor(el, options) {
34
+ super(el, options, _a);
35
+ this.el['M_Chips'] = this;
36
+ this.options = {
37
+ ..._a.defaults,
38
+ ...options
39
+ };
40
+ this.el.classList.add('chips');
41
+ this.chipsData = [];
42
+ this.#chips = [];
43
+ // Render initial chips
44
+ if (this.options.data.length) {
45
+ this.chipsData = this.options.data;
46
+ this.#renderChips();
47
+ }
48
+ // Render input element, setup event handlers
49
+ if (this.options.allowUserInput) {
50
+ this.#setupLabel();
51
+ this.el.classList.add('input-field');
52
+ this.#setupInput();
53
+ this.#setupEventHandlers();
54
+ // move input to end
55
+ this.el.append(this.#input);
56
+ }
57
+ }
58
+ static get defaults() {
59
+ return _defaults;
60
+ }
61
+ /**
62
+ * Initializes instances of Chips.
63
+ * @param els HTML elements.
64
+ * @param options Component options.
65
+ */
66
+ static init(els, options = {}) {
67
+ return super.init(els, options, _a);
68
+ }
69
+ static getInstance(el) {
70
+ return el['M_Chips'];
71
+ }
72
+ getData() {
73
+ return this.chipsData;
74
+ }
75
+ destroy() {
76
+ if (this.options.allowUserInput)
77
+ this.#removeEventHandlers();
78
+ this.#chips.forEach((c) => c.remove());
79
+ this.#chips = [];
80
+ this.el['M_Chips'] = undefined;
81
+ }
82
+ #setupEventHandlers() {
83
+ this.el.addEventListener('click', this.#handleChipClick);
84
+ // @todo why do we need this as document event listener, shouldn't we apply it to the element wrapper itself?
85
+ document.addEventListener('keydown', _a.#handleChipsKeydown);
86
+ document.addEventListener('keyup', _a.#handleChipsKeyup);
87
+ this.el.addEventListener('blur', _a.#handleChipsBlur, true);
88
+ this.#input.addEventListener('focus', this.#handleInputFocus);
89
+ this.#input.addEventListener('blur', this.#handleInputBlur);
90
+ this.#input.addEventListener('keydown', this.#handleInputKeydown);
91
+ }
92
+ #removeEventHandlers() {
93
+ this.el.removeEventListener('click', this.#handleChipClick);
94
+ document.removeEventListener('keydown', _a.#handleChipsKeydown);
95
+ document.removeEventListener('keyup', _a.#handleChipsKeyup);
96
+ this.el.removeEventListener('blur', _a.#handleChipsBlur, true);
97
+ this.#input.removeEventListener('focus', this.#handleInputFocus);
98
+ this.#input.removeEventListener('blur', this.#handleInputBlur);
99
+ this.#input.removeEventListener('keydown', this.#handleInputKeydown);
100
+ }
101
+ #handleChipClick = (e) => {
102
+ const _chip = e.target.closest('.chip');
103
+ const clickedClose = e.target.classList.contains('close');
104
+ if (_chip) {
105
+ const index = [..._chip.parentNode.children].indexOf(_chip);
106
+ if (clickedClose) {
107
+ this.deleteChip(index);
108
+ this.#input.focus();
109
+ }
110
+ else {
111
+ this.selectChip(index);
112
+ }
113
+ // Default handle click to focus on input
114
+ }
115
+ else {
116
+ this.#input.focus();
117
+ }
118
+ };
119
+ static #handleChipsKeydown(e) {
120
+ _a.#keydown = true;
121
+ const chips = e.target.closest('.chips');
122
+ const chipsKeydown = e.target && chips;
123
+ // Don't handle keydown inputs on input and textarea
124
+ const tag = e.target.tagName;
125
+ if (tag === 'INPUT' || tag === 'TEXTAREA' || !chipsKeydown)
126
+ return;
127
+ const currChips = chips['M_Chips'];
128
+ if (Utils.keys.BACKSPACE.includes(e.key) || Utils.keys.DELETE.includes(e.key)) {
129
+ e.preventDefault();
130
+ let selectIndex = currChips.chipsData.length;
131
+ if (currChips.#selectedChip) {
132
+ const index = gGetIndex(currChips.#selectedChip);
133
+ currChips.deleteChip(index);
134
+ currChips.#selectedChip = null;
135
+ // Make sure selectIndex doesn't go negative
136
+ selectIndex = Math.max(index - 1, 0);
137
+ }
138
+ if (currChips.chipsData.length)
139
+ currChips.selectChip(selectIndex);
140
+ else
141
+ currChips.#input.focus();
142
+ }
143
+ else if (Utils.keys.ARROW_LEFT.includes(e.key)) {
144
+ if (currChips.#selectedChip) {
145
+ const selectIndex = gGetIndex(currChips.#selectedChip) - 1;
146
+ if (selectIndex < 0)
147
+ return;
148
+ currChips.selectChip(selectIndex);
149
+ }
150
+ }
151
+ else if (Utils.keys.ARROW_RIGHT.includes(e.key)) {
152
+ if (currChips.#selectedChip) {
153
+ const selectIndex = gGetIndex(currChips.#selectedChip) + 1;
154
+ if (selectIndex >= currChips.chipsData.length)
155
+ currChips.#input.focus();
156
+ else
157
+ currChips.selectChip(selectIndex);
158
+ }
159
+ }
160
+ }
161
+ static #handleChipsKeyup() {
162
+ _a.#keydown = false;
163
+ }
164
+ static #handleChipsBlur(e) {
165
+ if (!_a.#keydown && document.hidden) {
166
+ const chips = e.target.closest('.chips');
167
+ const currChips = chips['M_Chips'];
168
+ currChips.#selectedChip = null;
169
+ }
170
+ }
171
+ #handleInputFocus = () => {
172
+ this.el.classList.add('focus');
173
+ };
174
+ #handleInputBlur = () => {
175
+ this.el.classList.remove('focus');
176
+ };
177
+ #handleInputKeydown = (e) => {
178
+ _a.#keydown = true;
179
+ if (Utils.keys.ENTER.includes(e.key)) {
180
+ // Override enter if autocompleting.
181
+ if (this.hasAutocomplete && this.autocomplete && this.autocomplete.isOpen) {
182
+ return;
183
+ }
184
+ e.preventDefault();
185
+ if (!this.hasAutocomplete || (this.hasAutocomplete && !this.options.autocompleteOnly)) {
186
+ this.addChip({ id: this.#input.value });
187
+ }
188
+ this.#input.value = '';
189
+ }
190
+ else if ((Utils.keys.BACKSPACE.includes(e.key) || Utils.keys.ARROW_LEFT.includes(e.key)) &&
191
+ this.#input.value === '' &&
192
+ this.chipsData.length) {
193
+ e.preventDefault();
194
+ this.selectChip(this.chipsData.length - 1);
195
+ }
196
+ };
197
+ #renderChip(chip) {
198
+ if (!chip.id)
199
+ return;
200
+ const renderedChip = document.createElement('li');
201
+ renderedChip.classList.add('chip');
202
+ renderedChip.innerText = chip.text || chip.id;
203
+ // attach image if needed
204
+ if (chip.image) {
205
+ const img = document.createElement('img');
206
+ img.setAttribute('src', chip.image);
207
+ renderedChip.insertBefore(img, renderedChip.firstChild);
208
+ }
209
+ if (this.options.allowUserInput) {
210
+ const closeButton = document.createElement('button');
211
+ closeButton.classList.add(this.options.closeIconClass, 'close');
212
+ closeButton.innerText = 'close';
213
+ renderedChip.appendChild(closeButton);
214
+ }
215
+ return renderedChip;
216
+ }
217
+ #renderChips() {
218
+ this.#chips = []; //.remove();
219
+ for (let i = 0; i < this.chipsData.length; i++) {
220
+ const chipElem = this.#renderChip(this.chipsData[i]);
221
+ this.el.appendChild(chipElem);
222
+ this.#chips.push(chipElem);
223
+ }
224
+ }
225
+ #setupAutocomplete() {
226
+ this.options.autocompleteOptions.onAutocomplete = (items) => {
227
+ if (items.length > 0)
228
+ this.addChip({
229
+ id: items[0].id,
230
+ text: items[0].text,
231
+ image: items[0].image
232
+ });
233
+ this.#input.value = '';
234
+ this.#input.focus();
235
+ };
236
+ this.autocomplete = Autocomplete.init(this.#input, this.options.autocompleteOptions);
237
+ }
238
+ #setupInput() {
239
+ this.#input = this.el.querySelector('input');
240
+ if (!this.#input) {
241
+ this.#input = document.createElement('input');
242
+ this.el.append(this.#input);
243
+ }
244
+ this.#input.classList.add('input');
245
+ this.hasAutocomplete = Object.keys(this.options.autocompleteOptions).length > 0;
246
+ // Setup autocomplete if needed
247
+ if (this.hasAutocomplete)
248
+ this.#setupAutocomplete();
249
+ this.#setPlaceholder();
250
+ // Set input id
251
+ if (!this.#input.getAttribute('id'))
252
+ this.#input.setAttribute('id', Utils.guid());
253
+ }
254
+ #setupLabel() {
255
+ this.#label = this.el.querySelector('label');
256
+ if (this.#label)
257
+ this.#label.setAttribute('for', this.#input.getAttribute('id'));
258
+ }
259
+ #setPlaceholder() {
260
+ if (this.chipsData !== undefined && !this.chipsData.length && this.options.placeholder) {
261
+ this.#input.placeholder = this.options.placeholder;
262
+ }
263
+ else if ((this.chipsData === undefined || !!this.chipsData.length) &&
264
+ this.options.secondaryPlaceholder) {
265
+ this.#input.placeholder = this.options.secondaryPlaceholder;
266
+ }
267
+ }
268
+ #isValidAndNotExist(chip) {
269
+ const isValid = !!chip.id;
270
+ const doesNotExist = !this.chipsData.some((item) => item.id == chip.id);
271
+ return isValid && doesNotExist;
272
+ }
273
+ /**
274
+ * Add chip to input.
275
+ * @param chip Chip data object
276
+ */
277
+ addChip(chip) {
278
+ if (!this.#isValidAndNotExist(chip) || this.chipsData.length >= this.options.limit)
279
+ return;
280
+ const renderedChip = this.#renderChip(chip);
281
+ this.#chips.push(renderedChip);
282
+ this.chipsData.push(chip);
283
+ //$(this._input).before(renderedChip);
284
+ this.#input.before(renderedChip);
285
+ this.#setPlaceholder();
286
+ // fire chipAdd callback
287
+ if (typeof this.options.onChipAdd === 'function') {
288
+ this.options.onChipAdd(this.el, renderedChip);
289
+ }
290
+ }
291
+ /**
292
+ * Delete nth chip.
293
+ * @param chipIndex Index of chip
294
+ */
295
+ deleteChip(chipIndex) {
296
+ const chip = this.#chips[chipIndex];
297
+ this.#chips[chipIndex].remove();
298
+ this.#chips.splice(chipIndex, 1);
299
+ this.chipsData.splice(chipIndex, 1);
300
+ this.#setPlaceholder();
301
+ // fire chipDelete callback
302
+ if (typeof this.options.onChipDelete === 'function') {
303
+ this.options.onChipDelete(this.el, chip);
304
+ }
305
+ }
306
+ /**
307
+ * Select nth chip.
308
+ * @param chipIndex Index of chip
309
+ */
310
+ selectChip(chipIndex) {
311
+ const chip = this.#chips[chipIndex];
312
+ this.#selectedChip = chip;
313
+ chip.focus();
314
+ // fire chipSelect callback
315
+ if (typeof this.options.onChipSelect === 'function') {
316
+ this.options.onChipSelect(this.el, chip);
317
+ }
318
+ }
319
+ static Init() {
320
+ if (typeof document !== 'undefined')
321
+ // Handle removal of static chips.
322
+ document.addEventListener('DOMContentLoaded', () => {
323
+ const chips = document.querySelectorAll('.chips');
324
+ chips.forEach((el) => {
325
+ // if (el && (el['M_Chips == undefined) return;
326
+ el.addEventListener('click', (e) => {
327
+ if (e.target.classList.contains('close')) {
328
+ const chip = e.target.closest('.chip');
329
+ if (chip)
330
+ chip.remove();
331
+ }
332
+ });
333
+ });
334
+ });
335
+ }
336
+ static {
337
+ this.#keydown = false;
338
+ }
339
+ }
340
+ _a = Chips;
341
+ export { Chips };