slim-select 2.13.1 → 3.0.0

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 (55) hide show
  1. package/README.md +184 -43
  2. package/dist/index.d.ts +304 -52
  3. package/dist/react/index.d.ts +304 -0
  4. package/dist/react/index.js +1549 -0
  5. package/dist/react/index.umd.js +22 -0
  6. package/dist/slimselect.cjs.js +1 -2030
  7. package/dist/slimselect.css +1 -1
  8. package/dist/slimselect.css.map +1 -1
  9. package/dist/slimselect.es.js +1224 -2012
  10. package/dist/slimselect.umd.js +1 -2036
  11. package/dist/vue/index.d.ts +304 -0
  12. package/dist/vue/index.js +1341 -0
  13. package/dist/vue/index.umd.js +1 -0
  14. package/index.html +1 -0
  15. package/package.json +58 -36
  16. package/release.js +0 -7
  17. package/src/slim-select/accessibility.test.ts +782 -0
  18. package/src/slim-select/classes.test.ts +7 -6
  19. package/src/slim-select/classes.ts +8 -6
  20. package/src/slim-select/helpers.test.ts +10 -8
  21. package/src/slim-select/index.test.ts +509 -14
  22. package/src/slim-select/index.ts +58 -31
  23. package/src/slim-select/react/index.tsx +9 -0
  24. package/src/slim-select/react/react.tsx +112 -0
  25. package/src/slim-select/render.test.ts +479 -119
  26. package/src/slim-select/render.ts +213 -91
  27. package/src/slim-select/select.test.ts +28 -10
  28. package/src/slim-select/select.ts +35 -12
  29. package/src/slim-select/settings.test.ts +19 -8
  30. package/src/slim-select/settings.ts +2 -4
  31. package/src/slim-select/slimselect.scss +30 -15
  32. package/src/slim-select/store.test.ts +13 -16
  33. package/src/slim-select/store.ts +97 -86
  34. package/src/slim-select/vue/index.ts +9 -0
  35. package/src/slim-select/vue/vue.test.ts +832 -0
  36. package/src/slim-select/{vue.vue → vue/vue.vue} +45 -23
  37. package/tsconfig.json +6 -4
  38. package/{vite.config.mts → vite.config.docs.mts} +10 -0
  39. package/vite.config.lib.mts +42 -0
  40. package/vite.config.react.mts +40 -0
  41. package/vite.config.vue.mts +39 -0
  42. package/vitest.config.ts +29 -0
  43. package/dist/classes.d.ts +0 -43
  44. package/dist/helpers.d.ts +0 -5
  45. package/dist/render.d.ts +0 -81
  46. package/dist/select.d.ts +0 -30
  47. package/dist/settings.d.ts +0 -35
  48. package/dist/slimselect.global.js +0 -2033
  49. package/dist/slimselect.js +0 -2036
  50. package/dist/slimselect.min.js +0 -1
  51. package/dist/slimselect.umd.min.js +0 -1
  52. package/dist/store.d.ts +0 -84
  53. package/jest.config.js +0 -14
  54. package/src/slim-select/rollup.config.mjs +0 -127
  55. package/src/slim-select/tsconfig.json +0 -14
@@ -1,2036 +1 @@
1
- (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3
- typeof define === 'function' && define.amd ? define(factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.SlimSelect = factory());
5
- })(this, (function () { 'use strict';
6
-
7
- class CssClasses {
8
- constructor(classes) {
9
- if (!classes) {
10
- classes = {};
11
- }
12
- this.main = classes.main || 'ss-main';
13
- this.placeholder = classes.placeholder || 'ss-placeholder';
14
- this.values = classes.values || 'ss-values';
15
- this.single = classes.single || 'ss-single';
16
- this.max = classes.max || 'ss-max';
17
- this.value = classes.value || 'ss-value';
18
- this.valueText = classes.valueText || 'ss-value-text';
19
- this.valueDelete = classes.valueDelete || 'ss-value-delete';
20
- this.valueOut = classes.valueOut || 'ss-value-out';
21
- this.deselect = classes.deselect || 'ss-deselect';
22
- this.deselectPath = classes.deselectPath || 'M10,10 L90,90 M10,90 L90,10';
23
- this.arrow = classes.arrow || 'ss-arrow';
24
- this.arrowClose = classes.arrowClose || 'M10,30 L50,70 L90,30';
25
- this.arrowOpen = classes.arrowOpen || 'M10,70 L50,30 L90,70';
26
- this.content = classes.content || 'ss-content';
27
- this.openAbove = classes.openAbove || 'ss-open-above';
28
- this.openBelow = classes.openBelow || 'ss-open-below';
29
- this.search = classes.search || 'ss-search';
30
- this.searchHighlighter = classes.searchHighlighter || 'ss-search-highlight';
31
- this.searching = classes.searching || 'ss-searching';
32
- this.addable = classes.addable || 'ss-addable';
33
- this.addablePath = classes.addablePath || 'M50,10 L50,90 M10,50 L90,50';
34
- this.list = classes.list || 'ss-list';
35
- this.optgroup = classes.optgroup || 'ss-optgroup';
36
- this.optgroupLabel = classes.optgroupLabel || 'ss-optgroup-label';
37
- this.optgroupLabelText = classes.optgroupLabelText || 'ss-optgroup-label-text';
38
- this.optgroupActions = classes.optgroupActions || 'ss-optgroup-actions';
39
- this.optgroupSelectAll = classes.optgroupSelectAll || 'ss-selectall';
40
- this.optgroupSelectAllBox = classes.optgroupSelectAllBox || 'M60,10 L10,10 L10,90 L90,90 L90,50';
41
- this.optgroupSelectAllCheck = classes.optgroupSelectAllCheck || 'M30,45 L50,70 L90,10';
42
- this.optgroupClosable = classes.optgroupClosable || 'ss-closable';
43
- this.option = classes.option || 'ss-option';
44
- this.optionDelete = classes.optionDelete || 'M10,10 L90,90 M10,90 L90,10';
45
- this.highlighted = classes.highlighted || 'ss-highlighted';
46
- this.open = classes.open || 'ss-open';
47
- this.close = classes.close || 'ss-close';
48
- this.selected = classes.selected || 'ss-selected';
49
- this.error = classes.error || 'ss-error';
50
- this.disabled = classes.disabled || 'ss-disabled';
51
- this.hide = classes.hide || 'ss-hide';
52
- }
53
- }
54
-
55
- function generateID() {
56
- return Math.random().toString(36).substring(2, 10);
57
- }
58
- function hasClassInTree(element, className) {
59
- function hasClass(e, c) {
60
- if (c && e && e.classList && e.classList.contains(c)) {
61
- return e;
62
- }
63
- if (c && e && e.dataset && e.dataset.id && e.dataset.id === className) {
64
- return e;
65
- }
66
- return null;
67
- }
68
- function parentByClass(e, c) {
69
- if (!e || e === document) {
70
- return null;
71
- }
72
- else if (hasClass(e, c)) {
73
- return e;
74
- }
75
- else {
76
- return parentByClass(e.parentNode, c);
77
- }
78
- }
79
- return hasClass(element, className) || parentByClass(element, className);
80
- }
81
- function debounce(func, wait = 50, immediate = false) {
82
- let timeout;
83
- return function (...args) {
84
- const context = self;
85
- const later = () => {
86
- timeout = null;
87
- if (!immediate) {
88
- func.apply(context, args);
89
- }
90
- };
91
- const callNow = immediate && !timeout;
92
- clearTimeout(timeout);
93
- timeout = setTimeout(later, wait);
94
- if (callNow) {
95
- func.apply(context, args);
96
- }
97
- };
98
- }
99
- function isEqual(a, b) {
100
- return JSON.stringify(a) === JSON.stringify(b);
101
- }
102
- function kebabCase(str) {
103
- const result = str.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g, (match) => '-' + match.toLowerCase());
104
- return str[0] === str[0].toUpperCase() ? result.substring(1) : result;
105
- }
106
-
107
- class Optgroup {
108
- constructor(optgroup) {
109
- this.id = !optgroup.id || optgroup.id === '' ? generateID() : optgroup.id;
110
- this.label = optgroup.label || '';
111
- this.selectAll = optgroup.selectAll === undefined ? false : optgroup.selectAll;
112
- this.selectAllText = optgroup.selectAllText || 'Select All';
113
- this.closable = optgroup.closable || 'off';
114
- this.options = [];
115
- if (optgroup.options) {
116
- for (const o of optgroup.options) {
117
- this.options.push(new Option(o));
118
- }
119
- }
120
- }
121
- }
122
- class Option {
123
- constructor(option) {
124
- this.id = !option.id || option.id === '' ? generateID() : option.id;
125
- this.value = option.value === undefined ? option.text : option.value;
126
- this.text = option.text || '';
127
- this.html = option.html || '';
128
- this.defaultSelected = option.defaultSelected !== undefined ? option.defaultSelected : false;
129
- this.selected = option.selected !== undefined ? option.selected : false;
130
- this.display = option.display !== undefined ? option.display : true;
131
- this.disabled = option.disabled !== undefined ? option.disabled : false;
132
- this.mandatory = option.mandatory !== undefined ? option.mandatory : false;
133
- this.placeholder = option.placeholder !== undefined ? option.placeholder : false;
134
- this.class = option.class || '';
135
- this.style = option.style || '';
136
- this.data = option.data || {};
137
- }
138
- }
139
- class Store {
140
- constructor(type, data) {
141
- this.selectType = 'single';
142
- this.data = [];
143
- this.selectedOrder = [];
144
- this.selectType = type;
145
- this.setData(data);
146
- }
147
- validateDataArray(data) {
148
- if (!Array.isArray(data)) {
149
- return new Error('Data must be an array');
150
- }
151
- for (let dataObj of data) {
152
- if (dataObj instanceof Optgroup || 'label' in dataObj) {
153
- if (!('label' in dataObj)) {
154
- return new Error('Optgroup must have a label');
155
- }
156
- if ('options' in dataObj && dataObj.options) {
157
- for (let option of dataObj.options) {
158
- const validationError = this.validateOption(option);
159
- if (validationError) {
160
- return validationError;
161
- }
162
- }
163
- }
164
- }
165
- else if (dataObj instanceof Option || 'text' in dataObj) {
166
- const validationError = this.validateOption(dataObj);
167
- if (validationError) {
168
- return validationError;
169
- }
170
- }
171
- else {
172
- return new Error('Data object must be a valid optgroup or option');
173
- }
174
- }
175
- return null;
176
- }
177
- validateOption(option) {
178
- if (!('text' in option)) {
179
- return new Error('Option must have a text');
180
- }
181
- return null;
182
- }
183
- partialToFullData(data) {
184
- let dataFinal = [];
185
- data.forEach((dataObj) => {
186
- if (dataObj instanceof Optgroup || 'label' in dataObj) {
187
- let optOptions = [];
188
- if ('options' in dataObj && dataObj.options) {
189
- dataObj.options.forEach((option) => {
190
- optOptions.push(new Option(option));
191
- });
192
- }
193
- if (optOptions.length > 0) {
194
- dataFinal.push(new Optgroup(dataObj));
195
- }
196
- }
197
- if (dataObj instanceof Option || 'text' in dataObj) {
198
- dataFinal.push(new Option(dataObj));
199
- }
200
- });
201
- return dataFinal;
202
- }
203
- setData(data) {
204
- this.data = this.partialToFullData(data);
205
- if (this.selectType === 'single') {
206
- this.setSelectedBy('id', this.getSelected());
207
- }
208
- }
209
- getData() {
210
- return this.filter(null, true);
211
- }
212
- getDataOptions() {
213
- return this.filter(null, false);
214
- }
215
- addOption(option, addToStart = false) {
216
- if (addToStart) {
217
- let data = [new Option(option)];
218
- this.setData(data.concat(this.getData()));
219
- }
220
- else {
221
- this.setData(this.getData().concat(new Option(option)));
222
- }
223
- }
224
- setSelectedBy(selectedType, selectedValues) {
225
- let firstOption = null;
226
- let hasSelected = false;
227
- const selectedObjects = [];
228
- for (let dataObj of this.data) {
229
- if (dataObj instanceof Optgroup) {
230
- for (let option of dataObj.options) {
231
- if (!firstOption) {
232
- firstOption = option;
233
- }
234
- option.selected = hasSelected ? false : selectedValues.includes(option[selectedType]);
235
- if (option.selected) {
236
- selectedObjects.push(option);
237
- if (this.selectType === 'single') {
238
- hasSelected = true;
239
- }
240
- }
241
- }
242
- }
243
- if (dataObj instanceof Option) {
244
- if (!firstOption) {
245
- firstOption = dataObj;
246
- }
247
- dataObj.selected = hasSelected ? false : selectedValues.includes(dataObj[selectedType]);
248
- if (dataObj.selected) {
249
- selectedObjects.push(dataObj);
250
- if (this.selectType === 'single') {
251
- hasSelected = true;
252
- }
253
- }
254
- }
255
- }
256
- if (this.selectType === 'single' && firstOption && !hasSelected) {
257
- firstOption.selected = true;
258
- selectedObjects.push(firstOption);
259
- }
260
- const selectedIds = selectedValues.map((value) => {
261
- var _a;
262
- return ((_a = selectedObjects.find((option) => option[selectedType] === value)) === null || _a === void 0 ? void 0 : _a.id) || '';
263
- });
264
- this.selectedOrder = selectedIds;
265
- }
266
- getSelected() {
267
- return this.getSelectedOptions().map((option) => option.id);
268
- }
269
- getSelectedValues() {
270
- return this.getSelectedOptions().map((option) => option.value);
271
- }
272
- getSelectedOptions() {
273
- return this.filter((opt) => {
274
- return opt.selected;
275
- }, false);
276
- }
277
- getOptgroupByID(id) {
278
- for (let dataObj of this.data) {
279
- if (dataObj instanceof Optgroup && dataObj.id === id) {
280
- return dataObj;
281
- }
282
- }
283
- return null;
284
- }
285
- getOptionByID(id) {
286
- let options = this.filter((opt) => {
287
- return opt.id === id;
288
- }, false);
289
- return options.length ? options[0] : null;
290
- }
291
- getSelectType() {
292
- return this.selectType;
293
- }
294
- getFirstOption() {
295
- let option = null;
296
- for (let dataObj of this.data) {
297
- if (dataObj instanceof Optgroup) {
298
- option = dataObj.options[0];
299
- }
300
- else if (dataObj instanceof Option) {
301
- option = dataObj;
302
- }
303
- if (option) {
304
- break;
305
- }
306
- }
307
- return option;
308
- }
309
- search(search, searchFilter) {
310
- search = search.trim();
311
- if (search === '') {
312
- return this.getData();
313
- }
314
- return this.filter((opt) => {
315
- return searchFilter(opt, search);
316
- }, true);
317
- }
318
- filter(filter, includeOptgroup) {
319
- const dataSearch = [];
320
- this.data.forEach((dataObj) => {
321
- if (dataObj instanceof Optgroup) {
322
- let optOptions = [];
323
- dataObj.options.forEach((option) => {
324
- if (!filter || filter(option)) {
325
- if (!includeOptgroup) {
326
- dataSearch.push(new Option(option));
327
- }
328
- else {
329
- optOptions.push(new Option(option));
330
- }
331
- }
332
- });
333
- if (optOptions.length > 0) {
334
- let optgroup = new Optgroup(dataObj);
335
- optgroup.options = optOptions;
336
- dataSearch.push(optgroup);
337
- }
338
- }
339
- if (dataObj instanceof Option) {
340
- if (!filter || filter(dataObj)) {
341
- dataSearch.push(new Option(dataObj));
342
- }
343
- }
344
- });
345
- return dataSearch;
346
- }
347
- selectedOrderOptions(options) {
348
- const newOrder = [];
349
- this.selectedOrder.forEach((id) => {
350
- const option = options.find((opt) => opt.id === id);
351
- if (option) {
352
- newOrder.push(option);
353
- }
354
- });
355
- options.forEach((option) => {
356
- let isIn = false;
357
- newOrder.forEach((selectedOption) => {
358
- if (option.id === selectedOption.id) {
359
- isIn = true;
360
- return;
361
- }
362
- });
363
- if (!isIn) {
364
- newOrder.push(option);
365
- }
366
- });
367
- return newOrder;
368
- }
369
- }
370
-
371
- class Render {
372
- constructor(settings, classes, store, callbacks) {
373
- this.store = store;
374
- this.settings = settings;
375
- this.classes = classes;
376
- this.callbacks = callbacks;
377
- this.lastSelectedOption = null;
378
- this.main = this.mainDiv();
379
- this.content = this.contentDiv();
380
- this.updateClassStyles();
381
- this.updateAriaAttributes();
382
- if (this.settings.contentLocation) {
383
- this.settings.contentLocation.appendChild(this.content.main);
384
- }
385
- }
386
- enable() {
387
- this.main.main.classList.remove(this.classes.disabled);
388
- this.content.search.input.disabled = false;
389
- }
390
- disable() {
391
- this.main.main.classList.add(this.classes.disabled);
392
- this.content.search.input.disabled = true;
393
- }
394
- open() {
395
- this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
396
- this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
397
- this.main.main.setAttribute('aria-expanded', 'true');
398
- this.moveContent();
399
- const selectedOptions = this.store.getSelectedOptions();
400
- if (selectedOptions.length) {
401
- const selectedId = selectedOptions[selectedOptions.length - 1].id;
402
- const selectedOption = this.content.list.querySelector('[data-id="' + selectedId + '"]');
403
- if (selectedOption) {
404
- this.ensureElementInView(this.content.list, selectedOption);
405
- }
406
- }
407
- }
408
- close() {
409
- this.main.main.classList.remove(this.classes.openAbove);
410
- this.main.main.classList.remove(this.classes.openBelow);
411
- this.main.main.setAttribute('aria-expanded', 'false');
412
- this.content.main.classList.remove(this.classes.openAbove);
413
- this.content.main.classList.remove(this.classes.openBelow);
414
- this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
415
- }
416
- updateClassStyles() {
417
- this.main.main.className = '';
418
- this.main.main.removeAttribute('style');
419
- this.content.main.className = '';
420
- this.content.main.removeAttribute('style');
421
- this.main.main.classList.add(this.classes.main);
422
- this.content.main.classList.add(this.classes.content);
423
- if (this.settings.style !== '') {
424
- this.main.main.style.cssText = this.settings.style;
425
- this.content.main.style.cssText = this.settings.style;
426
- }
427
- if (this.settings.class.length) {
428
- for (const c of this.settings.class) {
429
- if (c.trim() !== '') {
430
- this.main.main.classList.add(c.trim());
431
- this.content.main.classList.add(c.trim());
432
- }
433
- }
434
- }
435
- if (this.settings.contentPosition === 'relative' || this.settings.contentPosition === 'fixed') {
436
- this.content.main.classList.add('ss-' + this.settings.contentPosition);
437
- }
438
- }
439
- updateAriaAttributes() {
440
- var _a;
441
- this.main.main.role = 'combobox';
442
- this.main.main.setAttribute('aria-haspopup', 'listbox');
443
- this.main.main.setAttribute('aria-controls', (_a = this.content.main.dataset.id) !== null && _a !== void 0 ? _a : '');
444
- this.main.main.setAttribute('aria-expanded', 'false');
445
- this.content.main.setAttribute('role', 'listbox');
446
- }
447
- mainDiv() {
448
- var _a;
449
- const main = document.createElement('div');
450
- main.dataset.id = this.settings.id;
451
- main.setAttribute('aria-label', this.settings.ariaLabel);
452
- main.tabIndex = 0;
453
- main.onkeydown = (e) => {
454
- switch (e.key) {
455
- case 'ArrowUp':
456
- case 'ArrowDown':
457
- this.callbacks.open();
458
- e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up');
459
- return false;
460
- case 'Tab':
461
- this.callbacks.close();
462
- return true;
463
- case 'Enter':
464
- case ' ':
465
- this.callbacks.open();
466
- const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
467
- if (highlighted) {
468
- highlighted.click();
469
- }
470
- return false;
471
- case 'Escape':
472
- this.callbacks.close();
473
- return false;
474
- }
475
- if (e.key.length === 1) {
476
- this.callbacks.open();
477
- }
478
- return true;
479
- };
480
- main.onclick = (e) => {
481
- if (this.settings.disabled) {
482
- return;
483
- }
484
- this.settings.isOpen ? this.callbacks.close() : this.callbacks.open();
485
- };
486
- const values = document.createElement('div');
487
- values.classList.add(this.classes.values);
488
- main.appendChild(values);
489
- const deselect = document.createElement('div');
490
- deselect.classList.add(this.classes.deselect);
491
- const selectedOptions = (_a = this.store) === null || _a === void 0 ? void 0 : _a.getSelectedOptions();
492
- if (!this.settings.allowDeselect || (this.settings.isMultiple && selectedOptions && selectedOptions.length <= 0)) {
493
- deselect.classList.add(this.classes.hide);
494
- }
495
- else {
496
- deselect.classList.remove(this.classes.hide);
497
- }
498
- deselect.onclick = (e) => {
499
- e.stopPropagation();
500
- if (this.settings.disabled) {
501
- return;
502
- }
503
- let shouldDelete = true;
504
- const before = this.store.getSelectedOptions();
505
- const after = [];
506
- if (this.callbacks.beforeChange) {
507
- shouldDelete = this.callbacks.beforeChange(after, before) === true;
508
- }
509
- if (shouldDelete) {
510
- if (this.settings.isMultiple) {
511
- this.callbacks.setSelected([], false);
512
- this.updateDeselectAll();
513
- }
514
- else {
515
- const firstOption = this.store.getFirstOption();
516
- const id = firstOption ? firstOption.id : '';
517
- this.callbacks.setSelected(id, false);
518
- }
519
- if (this.settings.closeOnSelect) {
520
- this.callbacks.close();
521
- }
522
- if (this.callbacks.afterChange) {
523
- this.callbacks.afterChange(this.store.getSelectedOptions());
524
- }
525
- }
526
- };
527
- const deselectSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
528
- deselectSvg.setAttribute('viewBox', '0 0 100 100');
529
- const deselectPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
530
- deselectPath.setAttribute('d', this.classes.deselectPath);
531
- deselectSvg.appendChild(deselectPath);
532
- deselect.appendChild(deselectSvg);
533
- main.appendChild(deselect);
534
- const arrow = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
535
- arrow.classList.add(this.classes.arrow);
536
- arrow.setAttribute('viewBox', '0 0 100 100');
537
- const arrowPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
538
- arrowPath.setAttribute('d', this.classes.arrowClose);
539
- if (this.settings.alwaysOpen) {
540
- arrow.classList.add(this.classes.hide);
541
- }
542
- arrow.appendChild(arrowPath);
543
- main.appendChild(arrow);
544
- return {
545
- main: main,
546
- values: values,
547
- deselect: {
548
- main: deselect,
549
- svg: deselectSvg,
550
- path: deselectPath
551
- },
552
- arrow: {
553
- main: arrow,
554
- path: arrowPath
555
- }
556
- };
557
- }
558
- mainFocus(eventType) {
559
- if (eventType !== 'click') {
560
- this.main.main.focus({ preventScroll: true });
561
- }
562
- }
563
- placeholder() {
564
- const placeholderOption = this.store.filter((o) => o.placeholder, false);
565
- let placeholderText = this.settings.placeholderText;
566
- if (placeholderOption.length) {
567
- if (placeholderOption[0].html !== '') {
568
- placeholderText = placeholderOption[0].html;
569
- }
570
- else if (placeholderOption[0].text !== '') {
571
- placeholderText = placeholderOption[0].text;
572
- }
573
- }
574
- const placeholder = document.createElement('div');
575
- placeholder.classList.add(this.classes.placeholder);
576
- placeholder.innerHTML = placeholderText;
577
- return placeholder;
578
- }
579
- renderValues() {
580
- if (!this.settings.isMultiple) {
581
- this.renderSingleValue();
582
- return;
583
- }
584
- this.renderMultipleValues();
585
- this.updateDeselectAll();
586
- }
587
- renderSingleValue() {
588
- const selected = this.store.filter((o) => {
589
- return o.selected && !o.placeholder;
590
- }, false);
591
- const selectedSingle = selected.length > 0 ? selected[0] : null;
592
- if (!selectedSingle) {
593
- this.main.values.innerHTML = this.placeholder().outerHTML;
594
- }
595
- else {
596
- const singleValue = document.createElement('div');
597
- singleValue.classList.add(this.classes.single);
598
- if (selectedSingle.html) {
599
- singleValue.innerHTML = selectedSingle.html;
600
- }
601
- else {
602
- singleValue.innerText = selectedSingle.text;
603
- }
604
- this.main.values.innerHTML = singleValue.outerHTML;
605
- }
606
- if (!this.settings.allowDeselect || !selected.length) {
607
- this.main.deselect.main.classList.add(this.classes.hide);
608
- }
609
- else {
610
- this.main.deselect.main.classList.remove(this.classes.hide);
611
- }
612
- }
613
- renderMultipleValues() {
614
- let currentNodes = this.main.values.childNodes;
615
- let selectedOptions = this.store.filter((opt) => {
616
- return opt.selected && opt.display;
617
- }, false);
618
- if (selectedOptions.length === 0) {
619
- this.main.values.innerHTML = this.placeholder().outerHTML;
620
- return;
621
- }
622
- else {
623
- const placeholder = this.main.values.querySelector('.' + this.classes.placeholder);
624
- if (placeholder) {
625
- placeholder.remove();
626
- }
627
- }
628
- if (selectedOptions.length > this.settings.maxValuesShown) {
629
- const singleValue = document.createElement('div');
630
- singleValue.classList.add(this.classes.max);
631
- singleValue.textContent = this.settings.maxValuesMessage.replace('{number}', selectedOptions.length.toString());
632
- this.main.values.innerHTML = singleValue.outerHTML;
633
- return;
634
- }
635
- else {
636
- const maxValuesMessage = this.main.values.querySelector('.' + this.classes.max);
637
- if (maxValuesMessage) {
638
- maxValuesMessage.remove();
639
- }
640
- }
641
- if (this.settings.keepOrder) {
642
- selectedOptions = this.store.selectedOrderOptions(selectedOptions);
643
- }
644
- let removeNodes = [];
645
- for (let i = 0; i < currentNodes.length; i++) {
646
- const node = currentNodes[i];
647
- const id = node.getAttribute('data-id');
648
- if (id) {
649
- const found = selectedOptions.filter((opt) => {
650
- return opt.id === id;
651
- }, false);
652
- if (!found.length) {
653
- removeNodes.push(node);
654
- }
655
- }
656
- }
657
- for (const n of removeNodes) {
658
- n.classList.add(this.classes.valueOut);
659
- setTimeout(() => {
660
- if (this.main.values.hasChildNodes() && this.main.values.contains(n)) {
661
- this.main.values.removeChild(n);
662
- }
663
- }, 100);
664
- }
665
- currentNodes = this.main.values.childNodes;
666
- for (let d = 0; d < selectedOptions.length; d++) {
667
- let shouldAdd = true;
668
- for (let i = 0; i < currentNodes.length; i++) {
669
- if (selectedOptions[d].id === String(currentNodes[i].dataset.id)) {
670
- shouldAdd = false;
671
- }
672
- }
673
- if (shouldAdd) {
674
- if (this.settings.keepOrder) {
675
- this.main.values.appendChild(this.multipleValue(selectedOptions[d]));
676
- }
677
- else {
678
- if (currentNodes.length === 0) {
679
- this.main.values.appendChild(this.multipleValue(selectedOptions[d]));
680
- }
681
- else if (d === 0) {
682
- this.main.values.insertBefore(this.multipleValue(selectedOptions[d]), currentNodes[d]);
683
- }
684
- else {
685
- currentNodes[d - 1].insertAdjacentElement('afterend', this.multipleValue(selectedOptions[d]));
686
- }
687
- }
688
- }
689
- }
690
- }
691
- multipleValue(option) {
692
- const value = document.createElement('div');
693
- value.classList.add(this.classes.value);
694
- value.dataset.id = option.id;
695
- const text = document.createElement('div');
696
- text.classList.add(this.classes.valueText);
697
- text.textContent = option.text;
698
- value.appendChild(text);
699
- if (!option.mandatory) {
700
- const deleteDiv = document.createElement('div');
701
- deleteDiv.classList.add(this.classes.valueDelete);
702
- deleteDiv.setAttribute('tabindex', '0');
703
- deleteDiv.onclick = (e) => {
704
- e.preventDefault();
705
- e.stopPropagation();
706
- if (this.settings.disabled) {
707
- return;
708
- }
709
- let shouldDelete = true;
710
- const before = this.store.getSelectedOptions();
711
- const after = before.filter((o) => {
712
- return o.selected && o.id !== option.id;
713
- }, true);
714
- if (this.settings.minSelected && after.length < this.settings.minSelected) {
715
- return;
716
- }
717
- if (this.callbacks.beforeChange) {
718
- shouldDelete = this.callbacks.beforeChange(after, before) === true;
719
- }
720
- if (shouldDelete) {
721
- let selectedIds = [];
722
- for (const o of after) {
723
- if (o instanceof Optgroup) {
724
- for (const c of o.options) {
725
- selectedIds.push(c.id);
726
- }
727
- }
728
- if (o instanceof Option) {
729
- selectedIds.push(o.id);
730
- }
731
- }
732
- this.callbacks.setSelected(selectedIds, false);
733
- if (this.settings.closeOnSelect) {
734
- this.callbacks.close();
735
- }
736
- if (this.callbacks.afterChange) {
737
- this.callbacks.afterChange(after);
738
- }
739
- this.updateDeselectAll();
740
- }
741
- };
742
- const deleteSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
743
- deleteSvg.setAttribute('viewBox', '0 0 100 100');
744
- const deletePath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
745
- deletePath.setAttribute('d', this.classes.optionDelete);
746
- deleteSvg.appendChild(deletePath);
747
- deleteDiv.appendChild(deleteSvg);
748
- value.appendChild(deleteDiv);
749
- deleteDiv.onkeydown = (e) => {
750
- if (e.key === 'Enter') {
751
- deleteDiv.click();
752
- }
753
- };
754
- }
755
- return value;
756
- }
757
- contentDiv() {
758
- const main = document.createElement('div');
759
- main.dataset.id = this.settings.id;
760
- const search = this.searchDiv();
761
- main.appendChild(search.main);
762
- const list = this.listDiv();
763
- main.appendChild(list);
764
- return {
765
- main: main,
766
- search: search,
767
- list: list
768
- };
769
- }
770
- moveContent() {
771
- if (this.settings.contentPosition === 'relative') {
772
- this.moveContentBelow();
773
- return;
774
- }
775
- if (this.settings.openPosition === 'down') {
776
- this.moveContentBelow();
777
- return;
778
- }
779
- else if (this.settings.openPosition === 'up') {
780
- this.moveContentAbove();
781
- return;
782
- }
783
- if (this.putContent() === 'up') {
784
- this.moveContentAbove();
785
- }
786
- else {
787
- this.moveContentBelow();
788
- }
789
- }
790
- searchDiv() {
791
- const main = document.createElement('div');
792
- const input = document.createElement('input');
793
- const addable = document.createElement('div');
794
- main.classList.add(this.classes.search);
795
- const searchReturn = {
796
- main,
797
- input
798
- };
799
- if (!this.settings.showSearch) {
800
- main.classList.add(this.classes.hide);
801
- input.readOnly = true;
802
- }
803
- input.type = 'search';
804
- input.placeholder = this.settings.searchPlaceholder;
805
- input.tabIndex = -1;
806
- input.setAttribute('aria-label', this.settings.searchPlaceholder);
807
- input.setAttribute('autocapitalize', 'off');
808
- input.setAttribute('autocomplete', 'off');
809
- input.setAttribute('autocorrect', 'off');
810
- input.oninput = debounce((e) => {
811
- this.callbacks.search(e.target.value);
812
- }, 100);
813
- input.onkeydown = (e) => {
814
- switch (e.key) {
815
- case 'ArrowUp':
816
- case 'ArrowDown':
817
- e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up');
818
- return false;
819
- case 'Tab':
820
- this.callbacks.close();
821
- return true;
822
- case 'Escape':
823
- this.callbacks.close();
824
- return false;
825
- case ' ':
826
- const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
827
- if (highlighted) {
828
- highlighted.click();
829
- return false;
830
- }
831
- return true;
832
- case 'Enter':
833
- if (this.callbacks.addable) {
834
- addable.click();
835
- return false;
836
- }
837
- else {
838
- const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
839
- if (highlighted) {
840
- highlighted.click();
841
- return false;
842
- }
843
- }
844
- return true;
845
- }
846
- return true;
847
- };
848
- main.appendChild(input);
849
- if (this.callbacks.addable) {
850
- addable.classList.add(this.classes.addable);
851
- const plus = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
852
- plus.setAttribute('viewBox', '0 0 100 100');
853
- const plusPath = document.createElementNS('http://www.w3.org/2000/svg', 'path');
854
- plusPath.setAttribute('d', this.classes.addablePath);
855
- plus.appendChild(plusPath);
856
- addable.appendChild(plus);
857
- addable.onclick = (e) => {
858
- e.preventDefault();
859
- e.stopPropagation();
860
- if (!this.callbacks.addable) {
861
- return;
862
- }
863
- const inputValue = this.content.search.input.value.trim();
864
- if (inputValue === '') {
865
- this.content.search.input.focus();
866
- return;
867
- }
868
- const runFinish = (oo) => {
869
- let newOption = new Option(oo);
870
- this.callbacks.addOption(newOption);
871
- if (this.settings.isMultiple) {
872
- let ids = this.store.getSelected();
873
- ids.push(newOption.id);
874
- this.callbacks.setSelected(ids, true);
875
- }
876
- else {
877
- this.callbacks.setSelected([newOption.id], true);
878
- }
879
- this.callbacks.search('');
880
- if (this.settings.closeOnSelect) {
881
- setTimeout(() => {
882
- this.callbacks.close();
883
- }, 100);
884
- }
885
- };
886
- const addableValue = this.callbacks.addable(inputValue);
887
- if (addableValue === false || addableValue === undefined || addableValue === null) {
888
- return;
889
- }
890
- if (addableValue instanceof Promise) {
891
- addableValue.then((value) => {
892
- if (typeof value === 'string') {
893
- runFinish({
894
- text: value,
895
- value: value
896
- });
897
- }
898
- else if (addableValue instanceof Error) {
899
- this.renderError(addableValue.message);
900
- }
901
- else {
902
- runFinish(value);
903
- }
904
- });
905
- }
906
- else if (typeof addableValue === 'string') {
907
- runFinish({
908
- text: addableValue,
909
- value: addableValue
910
- });
911
- }
912
- else if (addableValue instanceof Error) {
913
- this.renderError(addableValue.message);
914
- }
915
- else {
916
- runFinish(addableValue);
917
- }
918
- return;
919
- };
920
- main.appendChild(addable);
921
- searchReturn.addable = {
922
- main: addable,
923
- svg: plus,
924
- path: plusPath
925
- };
926
- }
927
- return searchReturn;
928
- }
929
- searchFocus() {
930
- this.content.search.input.focus();
931
- }
932
- getOptions(notPlaceholder = false, notDisabled = false, notHidden = false) {
933
- let query = '.' + this.classes.option;
934
- if (notPlaceholder) {
935
- query += ':not(.' + this.classes.placeholder + ')';
936
- }
937
- if (notDisabled) {
938
- query += ':not(.' + this.classes.disabled + ')';
939
- }
940
- if (notHidden) {
941
- query += ':not(.' + this.classes.hide + ')';
942
- }
943
- return Array.from(this.content.list.querySelectorAll(query));
944
- }
945
- highlight(dir) {
946
- const options = this.getOptions(true, true, true);
947
- if (options.length === 0) {
948
- return;
949
- }
950
- if (options.length === 1) {
951
- if (!options[0].classList.contains(this.classes.highlighted)) {
952
- options[0].classList.add(this.classes.highlighted);
953
- return;
954
- }
955
- }
956
- let highlighted = false;
957
- for (const o of options) {
958
- if (o.classList.contains(this.classes.highlighted)) {
959
- highlighted = true;
960
- }
961
- }
962
- if (!highlighted) {
963
- for (const o of options) {
964
- if (o.classList.contains(this.classes.selected)) {
965
- o.classList.add(this.classes.highlighted);
966
- break;
967
- }
968
- }
969
- }
970
- for (let i = 0; i < options.length; i++) {
971
- if (options[i].classList.contains(this.classes.highlighted)) {
972
- const prevOption = options[i];
973
- prevOption.classList.remove(this.classes.highlighted);
974
- const prevParent = prevOption.parentElement;
975
- if (prevParent && prevParent.classList.contains(this.classes.open)) {
976
- const optgroupLabel = prevParent.querySelector('.' + this.classes.optgroupLabel);
977
- if (optgroupLabel) {
978
- optgroupLabel.click();
979
- }
980
- }
981
- let selectOption = options[dir === 'down' ? (i + 1 < options.length ? i + 1 : 0) : i - 1 >= 0 ? i - 1 : options.length - 1];
982
- selectOption.classList.add(this.classes.highlighted);
983
- this.ensureElementInView(this.content.list, selectOption);
984
- const selectParent = selectOption.parentElement;
985
- if (selectParent && selectParent.classList.contains(this.classes.close)) {
986
- const optgroupLabel = selectParent.querySelector('.' + this.classes.optgroupLabel);
987
- if (optgroupLabel) {
988
- optgroupLabel.click();
989
- }
990
- }
991
- return;
992
- }
993
- }
994
- options[dir === 'down' ? 0 : options.length - 1].classList.add(this.classes.highlighted);
995
- this.ensureElementInView(this.content.list, options[dir === 'down' ? 0 : options.length - 1]);
996
- }
997
- listDiv() {
998
- const options = document.createElement('div');
999
- options.classList.add(this.classes.list);
1000
- return options;
1001
- }
1002
- renderError(error) {
1003
- this.content.list.innerHTML = '';
1004
- const errorDiv = document.createElement('div');
1005
- errorDiv.classList.add(this.classes.error);
1006
- errorDiv.textContent = error;
1007
- this.content.list.appendChild(errorDiv);
1008
- }
1009
- renderSearching() {
1010
- this.content.list.innerHTML = '';
1011
- const searchingDiv = document.createElement('div');
1012
- searchingDiv.classList.add(this.classes.searching);
1013
- searchingDiv.textContent = this.settings.searchingText;
1014
- this.content.list.appendChild(searchingDiv);
1015
- }
1016
- renderOptions(data) {
1017
- this.content.list.innerHTML = '';
1018
- if (data.length === 0) {
1019
- const noResults = document.createElement('div');
1020
- noResults.classList.add(this.classes.search);
1021
- if (this.callbacks.addable) {
1022
- noResults.innerHTML = this.settings.addableText.replace('{value}', this.content.search.input.value);
1023
- }
1024
- else {
1025
- noResults.innerHTML = this.settings.searchText;
1026
- }
1027
- this.content.list.appendChild(noResults);
1028
- return;
1029
- }
1030
- if (this.settings.allowDeselect && !this.settings.isMultiple) {
1031
- const placeholderOption = this.store.filter((o) => o.placeholder, false);
1032
- if (!placeholderOption.length) {
1033
- this.store.addOption(new Option({
1034
- text: '',
1035
- value: '',
1036
- selected: false,
1037
- placeholder: true
1038
- }), true);
1039
- }
1040
- }
1041
- const fragment = document.createDocumentFragment();
1042
- for (const d of data) {
1043
- if (d instanceof Optgroup) {
1044
- const optgroupEl = document.createElement('div');
1045
- optgroupEl.classList.add(this.classes.optgroup);
1046
- const optgroupLabel = document.createElement('div');
1047
- optgroupLabel.classList.add(this.classes.optgroupLabel);
1048
- optgroupEl.appendChild(optgroupLabel);
1049
- const optgroupLabelText = document.createElement('div');
1050
- optgroupLabelText.classList.add(this.classes.optgroupLabelText);
1051
- optgroupLabelText.textContent = d.label;
1052
- optgroupLabel.appendChild(optgroupLabelText);
1053
- const optgroupActions = document.createElement('div');
1054
- optgroupActions.classList.add(this.classes.optgroupActions);
1055
- optgroupLabel.appendChild(optgroupActions);
1056
- if (this.settings.isMultiple && d.selectAll) {
1057
- const selectAll = document.createElement('div');
1058
- selectAll.classList.add(this.classes.optgroupSelectAll);
1059
- let allSelected = true;
1060
- for (const o of d.options) {
1061
- if (!o.selected) {
1062
- allSelected = false;
1063
- break;
1064
- }
1065
- }
1066
- if (allSelected) {
1067
- selectAll.classList.add(this.classes.selected);
1068
- }
1069
- const selectAllText = document.createElement('span');
1070
- selectAllText.textContent = d.selectAllText;
1071
- selectAll.appendChild(selectAllText);
1072
- const selectAllSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
1073
- selectAllSvg.setAttribute('viewBox', '0 0 100 100');
1074
- selectAll.appendChild(selectAllSvg);
1075
- const selectAllBox = document.createElementNS('http://www.w3.org/2000/svg', 'path');
1076
- selectAllBox.setAttribute('d', this.classes.optgroupSelectAllBox);
1077
- selectAllSvg.appendChild(selectAllBox);
1078
- const selectAllCheck = document.createElementNS('http://www.w3.org/2000/svg', 'path');
1079
- selectAllCheck.setAttribute('d', this.classes.optgroupSelectAllCheck);
1080
- selectAllSvg.appendChild(selectAllCheck);
1081
- selectAll.addEventListener('click', (e) => {
1082
- e.preventDefault();
1083
- e.stopPropagation();
1084
- const currentSelected = this.store.getSelected();
1085
- if (allSelected) {
1086
- const newSelected = currentSelected.filter((s) => {
1087
- for (const o of d.options) {
1088
- if (s === o.id) {
1089
- return false;
1090
- }
1091
- }
1092
- return true;
1093
- });
1094
- this.callbacks.setSelected(newSelected, true);
1095
- return;
1096
- }
1097
- else {
1098
- const newSelected = currentSelected.concat(d.options.map((o) => o.id));
1099
- for (const o of d.options) {
1100
- if (!this.store.getOptionByID(o.id)) {
1101
- this.callbacks.addOption(o);
1102
- }
1103
- }
1104
- this.callbacks.setSelected(newSelected, true);
1105
- return;
1106
- }
1107
- });
1108
- optgroupActions.appendChild(selectAll);
1109
- }
1110
- if (d.closable !== 'off') {
1111
- const optgroupClosable = document.createElement('div');
1112
- optgroupClosable.classList.add(this.classes.optgroupClosable);
1113
- const optgroupClosableSvg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
1114
- optgroupClosableSvg.setAttribute('viewBox', '0 0 100 100');
1115
- optgroupClosableSvg.classList.add(this.classes.arrow);
1116
- optgroupClosable.appendChild(optgroupClosableSvg);
1117
- const optgroupClosableArrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
1118
- optgroupClosableSvg.appendChild(optgroupClosableArrow);
1119
- if (d.options.some((o) => o.selected) || this.content.search.input.value.trim() !== '') {
1120
- optgroupClosable.classList.add(this.classes.open);
1121
- optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen);
1122
- }
1123
- else if (d.closable === 'open') {
1124
- optgroupEl.classList.add(this.classes.open);
1125
- optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen);
1126
- }
1127
- else if (d.closable === 'close') {
1128
- optgroupEl.classList.add(this.classes.close);
1129
- optgroupClosableArrow.setAttribute('d', this.classes.arrowClose);
1130
- }
1131
- optgroupLabel.addEventListener('click', (e) => {
1132
- e.preventDefault();
1133
- e.stopPropagation();
1134
- if (optgroupEl.classList.contains(this.classes.close)) {
1135
- optgroupEl.classList.remove(this.classes.close);
1136
- optgroupEl.classList.add(this.classes.open);
1137
- optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen);
1138
- }
1139
- else {
1140
- optgroupEl.classList.remove(this.classes.open);
1141
- optgroupEl.classList.add(this.classes.close);
1142
- optgroupClosableArrow.setAttribute('d', this.classes.arrowClose);
1143
- }
1144
- });
1145
- optgroupActions.appendChild(optgroupClosable);
1146
- }
1147
- optgroupEl.appendChild(optgroupLabel);
1148
- for (const o of d.options) {
1149
- optgroupEl.appendChild(this.option(o));
1150
- fragment.appendChild(optgroupEl);
1151
- }
1152
- }
1153
- if (d instanceof Option) {
1154
- fragment.appendChild(this.option(d));
1155
- }
1156
- }
1157
- this.content.list.appendChild(fragment);
1158
- }
1159
- option(option) {
1160
- if (option.placeholder) {
1161
- const placeholder = document.createElement('div');
1162
- placeholder.classList.add(this.classes.option);
1163
- placeholder.classList.add(this.classes.hide);
1164
- return placeholder;
1165
- }
1166
- const optionEl = document.createElement('div');
1167
- optionEl.dataset.id = option.id;
1168
- optionEl.classList.add(this.classes.option);
1169
- optionEl.setAttribute('role', 'option');
1170
- if (option.class) {
1171
- option.class.split(' ').forEach((dataClass) => {
1172
- optionEl.classList.add(dataClass);
1173
- });
1174
- }
1175
- if (option.style) {
1176
- optionEl.style.cssText = option.style;
1177
- }
1178
- if (this.settings.searchHighlight && this.content.search.input.value.trim() !== '') {
1179
- optionEl.innerHTML = this.highlightText(option.html !== '' ? option.html : option.text, this.content.search.input.value, this.classes.searchHighlighter);
1180
- }
1181
- else if (option.html !== '') {
1182
- optionEl.innerHTML = option.html;
1183
- }
1184
- else {
1185
- optionEl.textContent = option.text;
1186
- }
1187
- if (this.settings.showOptionTooltips && optionEl.textContent) {
1188
- optionEl.setAttribute('title', optionEl.textContent);
1189
- }
1190
- if (!option.display) {
1191
- optionEl.classList.add(this.classes.hide);
1192
- }
1193
- if (option.disabled) {
1194
- optionEl.classList.add(this.classes.disabled);
1195
- }
1196
- if (option.selected && this.settings.hideSelected) {
1197
- optionEl.classList.add(this.classes.hide);
1198
- }
1199
- if (option.selected) {
1200
- optionEl.classList.add(this.classes.selected);
1201
- optionEl.setAttribute('aria-selected', 'true');
1202
- this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1203
- }
1204
- else {
1205
- optionEl.classList.remove(this.classes.selected);
1206
- optionEl.setAttribute('aria-selected', 'false');
1207
- }
1208
- optionEl.addEventListener('click', (e) => {
1209
- e.preventDefault();
1210
- e.stopPropagation();
1211
- const selectedOptions = this.store.getSelected();
1212
- const element = e.currentTarget;
1213
- const elementID = String(element.dataset.id);
1214
- if (option.disabled || (option.selected && !this.settings.allowDeselect)) {
1215
- return;
1216
- }
1217
- if ((this.settings.isMultiple && this.settings.maxSelected <= selectedOptions.length && !option.selected) ||
1218
- (this.settings.isMultiple && this.settings.minSelected >= selectedOptions.length && option.selected)) {
1219
- return;
1220
- }
1221
- let shouldUpdate = false;
1222
- const before = this.store.getSelectedOptions();
1223
- let after = [];
1224
- if (this.settings.isMultiple) {
1225
- if (option.selected) {
1226
- after = before.filter((o) => o.id !== elementID);
1227
- }
1228
- else {
1229
- after = before.concat(option);
1230
- if (!this.settings.closeOnSelect) {
1231
- if (e.shiftKey && this.lastSelectedOption) {
1232
- const options = this.store.getDataOptions();
1233
- let lastClickedOptionIndex = options.findIndex((o) => o.id === this.lastSelectedOption.id);
1234
- let currentOptionIndex = options.findIndex((o) => o.id === option.id);
1235
- if (lastClickedOptionIndex >= 0 && currentOptionIndex >= 0) {
1236
- const startIndex = Math.min(lastClickedOptionIndex, currentOptionIndex);
1237
- const endIndex = Math.max(lastClickedOptionIndex, currentOptionIndex);
1238
- const afterRange = options.slice(startIndex, endIndex + 1);
1239
- if (afterRange.length > 0 && afterRange.length < this.settings.maxSelected) {
1240
- after = before.concat(afterRange.filter((a) => !before.find((b) => b.id === a.id)));
1241
- }
1242
- }
1243
- }
1244
- else if (!option.selected) {
1245
- this.lastSelectedOption = option;
1246
- }
1247
- }
1248
- }
1249
- }
1250
- if (!this.settings.isMultiple) {
1251
- if (option.selected) {
1252
- after = [];
1253
- }
1254
- else {
1255
- after = [option];
1256
- }
1257
- }
1258
- if (!this.callbacks.beforeChange) {
1259
- shouldUpdate = true;
1260
- }
1261
- if (this.callbacks.beforeChange) {
1262
- if (this.callbacks.beforeChange(after, before) === false) {
1263
- shouldUpdate = false;
1264
- }
1265
- else {
1266
- shouldUpdate = true;
1267
- }
1268
- }
1269
- if (shouldUpdate) {
1270
- if (!this.store.getOptionByID(elementID)) {
1271
- this.callbacks.addOption(option);
1272
- }
1273
- this.callbacks.setSelected(after.map((o) => o.id), false);
1274
- if (this.settings.closeOnSelect) {
1275
- this.callbacks.close();
1276
- }
1277
- if (this.callbacks.afterChange) {
1278
- this.callbacks.afterChange(after);
1279
- }
1280
- }
1281
- });
1282
- return optionEl;
1283
- }
1284
- destroy() {
1285
- this.main.main.remove();
1286
- this.content.main.remove();
1287
- }
1288
- highlightText(str, search, className) {
1289
- let completedString = str;
1290
- const regex = new RegExp('(?![^<]*>)(' + search.trim() + ')(?![^<]*>[^<>]*</)', 'i');
1291
- if (!str.match(regex)) {
1292
- return str;
1293
- }
1294
- const matchStartPosition = str.match(regex).index;
1295
- const matchEndPosition = matchStartPosition + str.match(regex)[0].toString().length;
1296
- const originalTextFoundByRegex = str.substring(matchStartPosition, matchEndPosition);
1297
- completedString = completedString.replace(regex, `<mark class="${className}">${originalTextFoundByRegex}</mark>`);
1298
- return completedString;
1299
- }
1300
- moveContentAbove() {
1301
- const mainHeight = this.main.main.offsetHeight;
1302
- const contentHeight = this.content.main.offsetHeight;
1303
- this.main.main.classList.remove(this.classes.openBelow);
1304
- this.main.main.classList.add(this.classes.openAbove);
1305
- this.content.main.classList.remove(this.classes.openBelow);
1306
- this.content.main.classList.add(this.classes.openAbove);
1307
- const containerRect = this.main.main.getBoundingClientRect();
1308
- this.content.main.style.margin = '-' + (mainHeight + contentHeight - 1) + 'px 0px 0px 0px';
1309
- this.content.main.style.top =
1310
- containerRect.top + containerRect.height + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollY) + 'px';
1311
- this.content.main.style.left =
1312
- containerRect.left + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollX) + 'px';
1313
- this.content.main.style.width = containerRect.width + 'px';
1314
- }
1315
- moveContentBelow() {
1316
- this.main.main.classList.remove(this.classes.openAbove);
1317
- this.main.main.classList.add(this.classes.openBelow);
1318
- this.content.main.classList.remove(this.classes.openAbove);
1319
- this.content.main.classList.add(this.classes.openBelow);
1320
- const containerRect = this.main.main.getBoundingClientRect();
1321
- this.content.main.style.margin = '-1px 0px 0px 0px';
1322
- if (this.settings.contentPosition !== 'relative') {
1323
- this.content.main.style.top =
1324
- containerRect.top +
1325
- containerRect.height +
1326
- (this.settings.contentPosition === 'fixed' ? 0 : window.scrollY) +
1327
- 'px';
1328
- this.content.main.style.left =
1329
- containerRect.left + (this.settings.contentPosition === 'fixed' ? 0 : window.scrollX) + 'px';
1330
- this.content.main.style.width = containerRect.width + 'px';
1331
- }
1332
- }
1333
- ensureElementInView(container, element) {
1334
- const cTop = container.scrollTop + container.offsetTop;
1335
- const cBottom = cTop + container.clientHeight;
1336
- const eTop = element.offsetTop;
1337
- const eBottom = eTop + element.clientHeight;
1338
- if (eTop < cTop) {
1339
- container.scrollTop -= cTop - eTop;
1340
- }
1341
- else if (eBottom > cBottom) {
1342
- container.scrollTop += eBottom - cBottom;
1343
- }
1344
- }
1345
- putContent() {
1346
- const mainHeight = this.main.main.offsetHeight;
1347
- const mainRect = this.main.main.getBoundingClientRect();
1348
- const contentHeight = this.content.main.offsetHeight;
1349
- const spaceBelow = window.innerHeight - (mainRect.top + mainHeight);
1350
- if (spaceBelow <= contentHeight) {
1351
- if (mainRect.top > contentHeight) {
1352
- return 'up';
1353
- }
1354
- else {
1355
- return 'down';
1356
- }
1357
- }
1358
- return 'down';
1359
- }
1360
- updateDeselectAll() {
1361
- if (!this.store || !this.settings) {
1362
- return;
1363
- }
1364
- const selected = this.store.getSelectedOptions();
1365
- const hasSelectedItems = selected && selected.length > 0;
1366
- const isMultiple = this.settings.isMultiple;
1367
- const allowDeselect = this.settings.allowDeselect;
1368
- const deselectButton = this.main.deselect.main;
1369
- const hideClass = this.classes.hide;
1370
- if (allowDeselect && !(isMultiple && !hasSelectedItems)) {
1371
- deselectButton.classList.remove(hideClass);
1372
- }
1373
- else {
1374
- deselectButton.classList.add(hideClass);
1375
- }
1376
- }
1377
- }
1378
-
1379
- class Select {
1380
- constructor(select) {
1381
- this.listen = false;
1382
- this.observer = null;
1383
- this.select = select;
1384
- this.valueChange = this.valueChange.bind(this);
1385
- this.select.addEventListener('change', this.valueChange, {
1386
- passive: true
1387
- });
1388
- this.observer = new MutationObserver(this.observeCall.bind(this));
1389
- this.changeListen(true);
1390
- }
1391
- enable() {
1392
- this.select.disabled = false;
1393
- }
1394
- disable() {
1395
- this.select.disabled = true;
1396
- }
1397
- hideUI() {
1398
- this.select.tabIndex = -1;
1399
- this.select.style.display = 'none';
1400
- this.select.setAttribute('aria-hidden', 'true');
1401
- }
1402
- showUI() {
1403
- this.select.removeAttribute('tabindex');
1404
- this.select.style.display = '';
1405
- this.select.removeAttribute('aria-hidden');
1406
- }
1407
- changeListen(listen) {
1408
- this.listen = listen;
1409
- if (listen) {
1410
- if (this.observer) {
1411
- this.observer.observe(this.select, {
1412
- subtree: true,
1413
- childList: true,
1414
- attributes: true
1415
- });
1416
- }
1417
- }
1418
- if (!listen) {
1419
- if (this.observer) {
1420
- this.observer.disconnect();
1421
- }
1422
- }
1423
- }
1424
- valueChange(ev) {
1425
- if (this.listen && this.onValueChange) {
1426
- this.onValueChange(this.getSelectedOptions());
1427
- }
1428
- return true;
1429
- }
1430
- observeCall(mutations) {
1431
- if (!this.listen) {
1432
- return;
1433
- }
1434
- let classChanged = false;
1435
- let disabledChanged = false;
1436
- let optgroupOptionChanged = false;
1437
- for (const m of mutations) {
1438
- if (m.target === this.select) {
1439
- if (m.attributeName === 'disabled') {
1440
- disabledChanged = true;
1441
- }
1442
- if (m.attributeName === 'class') {
1443
- classChanged = true;
1444
- }
1445
- if (m.type === 'childList') {
1446
- for (const n of m.addedNodes) {
1447
- if (n.nodeName === 'OPTION' && n.value === this.select.value) {
1448
- this.select.dispatchEvent(new Event('change'));
1449
- break;
1450
- }
1451
- }
1452
- optgroupOptionChanged = true;
1453
- }
1454
- }
1455
- if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {
1456
- optgroupOptionChanged = true;
1457
- }
1458
- }
1459
- if (classChanged && this.onClassChange) {
1460
- this.onClassChange(this.select.className.split(' '));
1461
- }
1462
- if (disabledChanged && this.onDisabledChange) {
1463
- this.changeListen(false);
1464
- this.onDisabledChange(this.select.disabled);
1465
- this.changeListen(true);
1466
- }
1467
- if (optgroupOptionChanged && this.onOptionsChange) {
1468
- this.changeListen(false);
1469
- this.onOptionsChange(this.getData());
1470
- this.changeListen(true);
1471
- }
1472
- }
1473
- getData() {
1474
- let data = [];
1475
- const nodes = this.select.childNodes;
1476
- for (const n of nodes) {
1477
- if (n.nodeName === 'OPTGROUP') {
1478
- data.push(this.getDataFromOptgroup(n));
1479
- }
1480
- if (n.nodeName === 'OPTION') {
1481
- data.push(this.getDataFromOption(n));
1482
- }
1483
- }
1484
- return data;
1485
- }
1486
- getDataFromOptgroup(optgroup) {
1487
- let data = {
1488
- id: optgroup.id,
1489
- label: optgroup.label,
1490
- selectAll: optgroup.dataset ? optgroup.dataset.selectall === 'true' : false,
1491
- selectAllText: optgroup.dataset ? optgroup.dataset.selectalltext : 'Select all',
1492
- closable: optgroup.dataset ? optgroup.dataset.closable : 'off',
1493
- options: []
1494
- };
1495
- const options = optgroup.childNodes;
1496
- for (const o of options) {
1497
- if (o.nodeName === 'OPTION') {
1498
- data.options.push(this.getDataFromOption(o));
1499
- }
1500
- }
1501
- return data;
1502
- }
1503
- getDataFromOption(option) {
1504
- return {
1505
- id: option.id,
1506
- value: option.value,
1507
- text: option.text,
1508
- html: option.dataset && option.dataset.html ? option.dataset.html : '',
1509
- defaultSelected: option.defaultSelected,
1510
- selected: option.selected,
1511
- display: option.style.display !== 'none',
1512
- disabled: option.disabled,
1513
- mandatory: option.dataset ? option.dataset.mandatory === 'true' : false,
1514
- placeholder: option.dataset.placeholder === 'true',
1515
- class: option.className,
1516
- style: option.style.cssText,
1517
- data: option.dataset
1518
- };
1519
- }
1520
- getSelectedOptions() {
1521
- let options = [];
1522
- const opts = this.select.childNodes;
1523
- for (const o of opts) {
1524
- if (o.nodeName === 'OPTGROUP') {
1525
- const optgroupOptions = o.childNodes;
1526
- for (const oo of optgroupOptions) {
1527
- if (oo.nodeName === 'OPTION') {
1528
- const option = oo;
1529
- if (option.selected) {
1530
- options.push(this.getDataFromOption(option));
1531
- }
1532
- }
1533
- }
1534
- }
1535
- if (o.nodeName === 'OPTION') {
1536
- const option = o;
1537
- if (option.selected) {
1538
- options.push(this.getDataFromOption(option));
1539
- }
1540
- }
1541
- }
1542
- return options;
1543
- }
1544
- getSelectedValues() {
1545
- return this.getSelectedOptions().map((option) => option.value);
1546
- }
1547
- setSelected(ids) {
1548
- this.changeListen(false);
1549
- const options = this.select.childNodes;
1550
- for (const o of options) {
1551
- if (o.nodeName === 'OPTGROUP') {
1552
- const optgroup = o;
1553
- const optgroupOptions = optgroup.childNodes;
1554
- for (const oo of optgroupOptions) {
1555
- if (oo.nodeName === 'OPTION') {
1556
- const option = oo;
1557
- option.selected = ids.includes(option.id);
1558
- }
1559
- }
1560
- }
1561
- if (o.nodeName === 'OPTION') {
1562
- const option = o;
1563
- option.selected = ids.includes(option.id);
1564
- }
1565
- }
1566
- this.changeListen(true);
1567
- }
1568
- setSelectedByValue(values) {
1569
- this.changeListen(false);
1570
- const options = this.select.childNodes;
1571
- for (const o of options) {
1572
- if (o.nodeName === 'OPTGROUP') {
1573
- const optgroup = o;
1574
- const optgroupOptions = optgroup.childNodes;
1575
- for (const oo of optgroupOptions) {
1576
- if (oo.nodeName === 'OPTION') {
1577
- const option = oo;
1578
- option.selected = values.includes(option.value);
1579
- }
1580
- }
1581
- }
1582
- if (o.nodeName === 'OPTION') {
1583
- const option = o;
1584
- option.selected = values.includes(option.value);
1585
- }
1586
- }
1587
- this.changeListen(true);
1588
- }
1589
- updateSelect(id, style, classes) {
1590
- this.changeListen(false);
1591
- if (id) {
1592
- this.select.dataset.id = id;
1593
- }
1594
- if (style) {
1595
- this.select.style.cssText = style;
1596
- }
1597
- if (classes) {
1598
- this.select.className = '';
1599
- classes.forEach((c) => {
1600
- if (c.trim() !== '') {
1601
- this.select.classList.add(c.trim());
1602
- }
1603
- });
1604
- }
1605
- this.changeListen(true);
1606
- }
1607
- updateOptions(data) {
1608
- this.changeListen(false);
1609
- this.select.innerHTML = '';
1610
- for (const d of data) {
1611
- if (d instanceof Optgroup) {
1612
- this.select.appendChild(this.createOptgroup(d));
1613
- }
1614
- if (d instanceof Option) {
1615
- this.select.appendChild(this.createOption(d));
1616
- }
1617
- }
1618
- this.select.dispatchEvent(new Event('change', { bubbles: true }));
1619
- this.changeListen(true);
1620
- }
1621
- createOptgroup(optgroup) {
1622
- const optgroupEl = document.createElement('optgroup');
1623
- optgroupEl.id = optgroup.id;
1624
- optgroupEl.label = optgroup.label;
1625
- if (optgroup.selectAll) {
1626
- optgroupEl.dataset.selectAll = 'true';
1627
- }
1628
- if (optgroup.closable !== 'off') {
1629
- optgroupEl.dataset.closable = optgroup.closable;
1630
- }
1631
- if (optgroup.options) {
1632
- for (const o of optgroup.options) {
1633
- optgroupEl.appendChild(this.createOption(o));
1634
- }
1635
- }
1636
- return optgroupEl;
1637
- }
1638
- createOption(info) {
1639
- const optionEl = document.createElement('option');
1640
- optionEl.id = info.id;
1641
- optionEl.value = info.value;
1642
- optionEl.textContent = info.text;
1643
- if (info.html !== '') {
1644
- optionEl.setAttribute('data-html', info.html);
1645
- }
1646
- optionEl.defaultSelected = info.defaultSelected;
1647
- optionEl.selected = info.selected;
1648
- if (info.disabled) {
1649
- optionEl.disabled = true;
1650
- }
1651
- if (!info.display) {
1652
- optionEl.style.display = 'none';
1653
- }
1654
- if (info.placeholder) {
1655
- optionEl.setAttribute('data-placeholder', 'true');
1656
- }
1657
- if (info.mandatory) {
1658
- optionEl.setAttribute('data-mandatory', 'true');
1659
- }
1660
- if (info.class) {
1661
- info.class.split(' ').forEach((optionClass) => {
1662
- optionEl.classList.add(optionClass);
1663
- });
1664
- }
1665
- if (info.data && typeof info.data === 'object') {
1666
- Object.keys(info.data).forEach((key) => {
1667
- optionEl.setAttribute('data-' + kebabCase(key), info.data[key]);
1668
- });
1669
- }
1670
- return optionEl;
1671
- }
1672
- destroy() {
1673
- this.changeListen(false);
1674
- this.select.removeEventListener('change', this.valueChange);
1675
- if (this.observer) {
1676
- this.observer.disconnect();
1677
- this.observer = null;
1678
- }
1679
- delete this.select.dataset.id;
1680
- this.showUI();
1681
- }
1682
- }
1683
-
1684
- class Settings {
1685
- constructor(settings) {
1686
- this.id = '';
1687
- this.style = '';
1688
- this.class = [];
1689
- this.isMultiple = false;
1690
- this.isOpen = false;
1691
- this.isFullOpen = false;
1692
- this.intervalMove = null;
1693
- if (!settings) {
1694
- settings = {};
1695
- }
1696
- this.id = 'ss-' + generateID();
1697
- this.style = settings.style || '';
1698
- this.class = settings.class || [];
1699
- this.disabled = settings.disabled !== undefined ? settings.disabled : false;
1700
- this.alwaysOpen = settings.alwaysOpen !== undefined ? settings.alwaysOpen : false;
1701
- this.showSearch = settings.showSearch !== undefined ? settings.showSearch : true;
1702
- this.focusSearch = settings.focusSearch !== undefined ? settings.focusSearch : true;
1703
- this.ariaLabel = settings.ariaLabel || 'Combobox';
1704
- this.searchPlaceholder = settings.searchPlaceholder || 'Search';
1705
- this.searchText = settings.searchText || 'No Results';
1706
- this.searchingText = settings.searchingText || 'Searching...';
1707
- this.searchHighlight = settings.searchHighlight !== undefined ? settings.searchHighlight : false;
1708
- this.closeOnSelect = settings.closeOnSelect !== undefined ? settings.closeOnSelect : true;
1709
- this.contentLocation = settings.contentLocation || document.body;
1710
- this.contentPosition = settings.contentPosition || 'absolute';
1711
- this.openPosition = settings.openPosition || 'auto';
1712
- this.placeholderText = settings.placeholderText !== undefined ? settings.placeholderText : 'Select Value';
1713
- this.allowDeselect = settings.allowDeselect !== undefined ? settings.allowDeselect : false;
1714
- this.hideSelected = settings.hideSelected !== undefined ? settings.hideSelected : false;
1715
- this.keepOrder = settings.keepOrder !== undefined ? settings.keepOrder : false;
1716
- this.showOptionTooltips = settings.showOptionTooltips !== undefined ? settings.showOptionTooltips : false;
1717
- this.minSelected = settings.minSelected || 0;
1718
- this.maxSelected = settings.maxSelected || 1000;
1719
- this.timeoutDelay = settings.timeoutDelay || 200;
1720
- this.maxValuesShown = settings.maxValuesShown || 20;
1721
- this.maxValuesMessage = settings.maxValuesMessage || '{number} selected';
1722
- this.addableText = settings.addableText || 'Press "Enter" to add {value}';
1723
- }
1724
- }
1725
-
1726
- class SlimSelect {
1727
- constructor(config) {
1728
- var _a;
1729
- this.events = {
1730
- search: undefined,
1731
- searchFilter: (opt, search) => {
1732
- return opt.text.toLowerCase().indexOf(search.toLowerCase()) !== -1;
1733
- },
1734
- addable: undefined,
1735
- beforeChange: undefined,
1736
- afterChange: undefined,
1737
- beforeOpen: undefined,
1738
- afterOpen: undefined,
1739
- beforeClose: undefined,
1740
- afterClose: undefined
1741
- };
1742
- this.windowResize = debounce(() => {
1743
- if (!this.settings.isOpen && !this.settings.isFullOpen) {
1744
- return;
1745
- }
1746
- this.render.moveContent();
1747
- });
1748
- this.windowScroll = debounce(() => {
1749
- if (!this.settings.isOpen && !this.settings.isFullOpen) {
1750
- return;
1751
- }
1752
- this.render.moveContent();
1753
- });
1754
- this.documentClick = (e) => {
1755
- if (!this.settings.isOpen) {
1756
- return;
1757
- }
1758
- if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1759
- this.close(e.type);
1760
- }
1761
- };
1762
- this.windowVisibilityChange = () => {
1763
- if (document.hidden) {
1764
- this.close();
1765
- }
1766
- };
1767
- this.selectEl = (typeof config.select === 'string' ? document.querySelector(config.select) : config.select);
1768
- if (!this.selectEl) {
1769
- if (config.events && config.events.error) {
1770
- config.events.error(new Error('Could not find select element'));
1771
- }
1772
- return;
1773
- }
1774
- if (this.selectEl.tagName !== 'SELECT') {
1775
- if (config.events && config.events.error) {
1776
- config.events.error(new Error('Element isnt of type select'));
1777
- }
1778
- return;
1779
- }
1780
- if (this.selectEl.dataset.ssid) {
1781
- this.destroy();
1782
- }
1783
- this.settings = new Settings(config.settings);
1784
- this.cssClasses = new CssClasses(config.cssClasses);
1785
- const debounceEvents = ['afterChange', 'beforeOpen', 'afterOpen', 'beforeClose', 'afterClose'];
1786
- for (const key in config.events) {
1787
- if (!config.events.hasOwnProperty(key)) {
1788
- continue;
1789
- }
1790
- if (debounceEvents.indexOf(key) !== -1) {
1791
- this.events[key] = debounce(config.events[key], 100);
1792
- }
1793
- else {
1794
- this.events[key] = config.events[key];
1795
- }
1796
- }
1797
- this.settings.disabled = ((_a = config.settings) === null || _a === void 0 ? void 0 : _a.disabled) ? config.settings.disabled : this.selectEl.disabled;
1798
- this.settings.isMultiple = this.selectEl.multiple;
1799
- this.settings.style = this.selectEl.style.cssText;
1800
- this.settings.class = this.selectEl.className.split(' ');
1801
- this.select = new Select(this.selectEl);
1802
- this.select.updateSelect(this.settings.id, this.settings.style, this.settings.class);
1803
- this.select.hideUI();
1804
- this.select.onValueChange = (options) => {
1805
- this.setSelected(options.map((option) => option.id));
1806
- };
1807
- this.select.onClassChange = (classes) => {
1808
- this.settings.class = classes;
1809
- this.render.updateClassStyles();
1810
- };
1811
- this.select.onDisabledChange = (disabled) => {
1812
- if (disabled) {
1813
- this.disable();
1814
- }
1815
- else {
1816
- this.enable();
1817
- }
1818
- };
1819
- this.select.onOptionsChange = (data) => {
1820
- this.setData(data);
1821
- };
1822
- this.store = new Store(this.settings.isMultiple ? 'multiple' : 'single', config.data ? config.data : this.select.getData());
1823
- if (config.data) {
1824
- this.select.updateOptions(this.store.getData());
1825
- }
1826
- const renderCallbacks = {
1827
- open: this.open.bind(this),
1828
- close: this.close.bind(this),
1829
- addable: this.events.addable ? this.events.addable : undefined,
1830
- setSelected: this.setSelected.bind(this),
1831
- addOption: this.addOption.bind(this),
1832
- search: this.search.bind(this),
1833
- beforeChange: this.events.beforeChange,
1834
- afterChange: this.events.afterChange
1835
- };
1836
- this.render = new Render(this.settings, this.cssClasses, this.store, renderCallbacks);
1837
- this.render.renderValues();
1838
- this.render.renderOptions(this.store.getData());
1839
- const selectAriaLabel = this.selectEl.getAttribute('aria-label');
1840
- const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby');
1841
- if (selectAriaLabel) {
1842
- this.render.main.main.setAttribute('aria-label', selectAriaLabel);
1843
- }
1844
- else if (selectAriaLabelledBy) {
1845
- this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy);
1846
- }
1847
- if (this.selectEl.parentNode) {
1848
- this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1849
- }
1850
- window.addEventListener('resize', this.windowResize, false);
1851
- if (this.settings.openPosition === 'auto') {
1852
- window.addEventListener('scroll', this.windowScroll, false);
1853
- }
1854
- document.addEventListener('visibilitychange', this.windowVisibilityChange);
1855
- if (this.settings.disabled) {
1856
- this.disable();
1857
- }
1858
- if (this.settings.alwaysOpen) {
1859
- this.open();
1860
- }
1861
- this.selectEl.slim = this;
1862
- }
1863
- enable() {
1864
- this.settings.disabled = false;
1865
- this.select.enable();
1866
- this.render.enable();
1867
- }
1868
- disable() {
1869
- this.settings.disabled = true;
1870
- this.select.disable();
1871
- this.render.disable();
1872
- }
1873
- getData() {
1874
- return this.store.getData();
1875
- }
1876
- setData(data) {
1877
- const selected = this.store.getSelected();
1878
- const err = this.store.validateDataArray(data);
1879
- if (err) {
1880
- if (this.events.error) {
1881
- this.events.error(err);
1882
- }
1883
- return;
1884
- }
1885
- this.store.setData(data);
1886
- const dataClean = this.store.getData();
1887
- this.select.updateOptions(dataClean);
1888
- this.render.renderValues();
1889
- this.render.renderOptions(dataClean);
1890
- if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1891
- this.events.afterChange(this.store.getSelectedOptions());
1892
- }
1893
- }
1894
- getSelected() {
1895
- let options = this.store.getSelectedOptions();
1896
- if (this.settings.keepOrder) {
1897
- options = this.store.selectedOrderOptions(options);
1898
- }
1899
- return options.map((option) => option.value);
1900
- }
1901
- setSelected(values, runAfterChange = true) {
1902
- const selected = this.store.getSelected();
1903
- const options = this.store.getDataOptions();
1904
- values = Array.isArray(values) ? values : [values];
1905
- const ids = [];
1906
- for (const value of values) {
1907
- if (options.find((option) => option.id == value)) {
1908
- ids.push(value);
1909
- continue;
1910
- }
1911
- for (const option of options.filter((option) => option.value == value)) {
1912
- ids.push(option.id);
1913
- }
1914
- }
1915
- this.store.setSelectedBy('id', ids);
1916
- const data = this.store.getData();
1917
- this.select.updateOptions(data);
1918
- this.render.renderValues();
1919
- if (this.render.content.search.input.value !== '') {
1920
- this.search(this.render.content.search.input.value);
1921
- }
1922
- else {
1923
- this.render.renderOptions(data);
1924
- }
1925
- if (runAfterChange && this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1926
- this.events.afterChange(this.store.getSelectedOptions());
1927
- }
1928
- }
1929
- addOption(option) {
1930
- const selected = this.store.getSelected();
1931
- if (!this.store.getDataOptions().some((o) => { var _a; return o.value === ((_a = option.value) !== null && _a !== void 0 ? _a : option.text); })) {
1932
- this.store.addOption(option);
1933
- }
1934
- const data = this.store.getData();
1935
- this.select.updateOptions(data);
1936
- this.render.renderValues();
1937
- this.render.renderOptions(data);
1938
- if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1939
- this.events.afterChange(this.store.getSelectedOptions());
1940
- }
1941
- }
1942
- open() {
1943
- if (this.settings.disabled || this.settings.isOpen) {
1944
- return;
1945
- }
1946
- if (this.events.beforeOpen) {
1947
- this.events.beforeOpen();
1948
- }
1949
- this.render.open();
1950
- if (this.settings.showSearch && this.settings.focusSearch) {
1951
- this.render.searchFocus();
1952
- }
1953
- this.settings.isOpen = true;
1954
- setTimeout(() => {
1955
- if (this.events.afterOpen) {
1956
- this.events.afterOpen();
1957
- }
1958
- if (this.settings.isOpen) {
1959
- this.settings.isFullOpen = true;
1960
- }
1961
- document.addEventListener('click', this.documentClick);
1962
- }, this.settings.timeoutDelay);
1963
- if (this.settings.contentPosition === 'absolute') {
1964
- if (this.settings.intervalMove) {
1965
- clearInterval(this.settings.intervalMove);
1966
- }
1967
- this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1968
- }
1969
- }
1970
- close(eventType = null) {
1971
- if (!this.settings.isOpen || this.settings.alwaysOpen) {
1972
- return;
1973
- }
1974
- if (this.events.beforeClose) {
1975
- this.events.beforeClose();
1976
- }
1977
- this.render.close();
1978
- if (this.render.content.search.input.value !== '') {
1979
- this.search('');
1980
- }
1981
- this.render.mainFocus(eventType);
1982
- this.settings.isOpen = false;
1983
- this.settings.isFullOpen = false;
1984
- setTimeout(() => {
1985
- if (this.events.afterClose) {
1986
- this.events.afterClose();
1987
- }
1988
- document.removeEventListener('click', this.documentClick);
1989
- }, this.settings.timeoutDelay);
1990
- if (this.settings.intervalMove) {
1991
- clearInterval(this.settings.intervalMove);
1992
- }
1993
- }
1994
- search(value) {
1995
- if (this.render.content.search.input.value !== value) {
1996
- this.render.content.search.input.value = value;
1997
- }
1998
- if (!this.events.search) {
1999
- this.render.renderOptions(value === '' ? this.store.getData() : this.store.search(value, this.events.searchFilter));
2000
- return;
2001
- }
2002
- this.render.renderSearching();
2003
- const searchResp = this.events.search(value, this.store.getSelectedOptions());
2004
- if (searchResp instanceof Promise) {
2005
- searchResp
2006
- .then((data) => {
2007
- this.render.renderOptions(this.store.partialToFullData(data));
2008
- })
2009
- .catch((err) => {
2010
- this.render.renderError(typeof err === 'string' ? err : err.message);
2011
- });
2012
- return;
2013
- }
2014
- else if (Array.isArray(searchResp)) {
2015
- this.render.renderOptions(this.store.partialToFullData(searchResp));
2016
- }
2017
- else {
2018
- this.render.renderError('Search event must return a promise or an array of data');
2019
- }
2020
- }
2021
- destroy() {
2022
- document.removeEventListener('click', this.documentClick);
2023
- window.removeEventListener('resize', this.windowResize, false);
2024
- if (this.settings.openPosition === 'auto') {
2025
- window.removeEventListener('scroll', this.windowScroll, false);
2026
- }
2027
- document.removeEventListener('visibilitychange', this.windowVisibilityChange);
2028
- this.store.setData([]);
2029
- this.render.destroy();
2030
- this.select.destroy();
2031
- }
2032
- }
2033
-
2034
- return SlimSelect;
2035
-
2036
- }));
1
+ (function(m,S){typeof exports=="object"&&typeof module<"u"?S(exports):typeof define=="function"&&define.amd?define(["exports"],S):(m=typeof globalThis<"u"?globalThis:m||self,S(m.SlimSelect={}))})(this,function(m){"use strict";class S{main;placeholder;values;single;max;value;valueText;valueDelete;valueOut;deselect;deselectPath;arrow;arrowClose;arrowOpen;content;contentOpen;dirAbove;dirBelow;search;searchHighlighter;searching;addable;addablePath;list;optgroup;optgroupLabel;optgroupLabelText;optgroupActions;optgroupSelectAll;optgroupSelectAllBox;optgroupSelectAllCheck;optgroupClosable;option;optionDelete;highlighted;mainOpen;close;selected;error;disabled;hide;constructor(e){e||(e={}),this.main=e.main||"ss-main",this.placeholder=e.placeholder||"ss-placeholder",this.values=e.values||"ss-values",this.single=e.single||"ss-single",this.max=e.max||"ss-max",this.value=e.value||"ss-value",this.valueText=e.valueText||"ss-value-text",this.valueDelete=e.valueDelete||"ss-value-delete",this.valueOut=e.valueOut||"ss-value-out",this.deselect=e.deselect||"ss-deselect",this.deselectPath=e.deselectPath||"M10,10 L90,90 M10,90 L90,10",this.arrow=e.arrow||"ss-arrow",this.arrowClose=e.arrowClose||"M10,30 L50,70 L90,30",this.arrowOpen=e.arrowOpen||"M10,70 L50,30 L90,70",this.content=e.content||"ss-content",this.contentOpen=e.contentOpen||"ss-open",this.dirAbove=e.dirAbove||"ss-dir-above",this.dirBelow=e.dirBelow||"ss-dir-below",this.search=e.search||"ss-search",this.searchHighlighter=e.searchHighlighter||"ss-search-highlight",this.searching=e.searching||"ss-searching",this.addable=e.addable||"ss-addable",this.addablePath=e.addablePath||"M50,10 L50,90 M10,50 L90,50",this.list=e.list||"ss-list",this.optgroup=e.optgroup||"ss-optgroup",this.optgroupLabel=e.optgroupLabel||"ss-optgroup-label",this.optgroupLabelText=e.optgroupLabelText||"ss-optgroup-label-text",this.optgroupActions=e.optgroupActions||"ss-optgroup-actions",this.optgroupSelectAll=e.optgroupSelectAll||"ss-selectall",this.optgroupSelectAllBox=e.optgroupSelectAllBox||"M60,10 L10,10 L10,90 L90,90 L90,50",this.optgroupSelectAllCheck=e.optgroupSelectAllCheck||"M30,45 L50,70 L90,10",this.optgroupClosable=e.optgroupClosable||"ss-closable",this.option=e.option||"ss-option",this.optionDelete=e.optionDelete||"M10,10 L90,90 M10,90 L90,10",this.highlighted=e.highlighted||"ss-highlighted",this.mainOpen=e.mainOpen||"ss-open",this.close=e.close||"ss-close",this.selected=e.selected||"ss-selected",this.error=e.error||"ss-error",this.disabled=e.disabled||"ss-disabled",this.hide=e.hide||"ss-hide"}}function y(){return Math.random().toString(36).substring(2,10)}function N(p,e){function t(i,l){return l&&i&&i.classList&&i.classList.contains(l)||l&&i&&i.dataset&&i.dataset.id&&i.dataset.id===e?i:null}function s(i,l){return!i||i===document?null:t(i,l)?i:s(i.parentNode,l)}return t(p,e)||s(p,e)}function L(p,e=50,t=!1){let s;return function(...i){const l=self,a=()=>{s=null,t||p.apply(l,i)},n=t&&!s;clearTimeout(s),s=setTimeout(a,e),n&&p.apply(l,i)}}function x(p,e){return JSON.stringify(p)===JSON.stringify(e)}function M(p){const e=p.replace(/[A-Z\u00C0-\u00D6\u00D8-\u00DE]/g,t=>"-"+t.toLowerCase());return p[0]===p[0].toUpperCase()?e.substring(1):e}class u{id;value;text;html;defaultSelected;selected;display;disabled;placeholder;class;style;data;mandatory;constructor(e){this.id=!e.id||e.id===""?y():e.id,this.value=e.value===void 0?e.text||"":e.value||"",this.text=e.text||"",this.html=e.html||"",this.defaultSelected=e.defaultSelected!==void 0?e.defaultSelected:!1,this.selected=e.selected!==void 0?e.selected:!1,this.display=e.display!==void 0?e.display:!0,this.disabled=e.disabled!==void 0?e.disabled:!1,this.mandatory=e.mandatory!==void 0?e.mandatory:!1,this.placeholder=e.placeholder!==void 0?e.placeholder:!1,this.class=e.class||"",this.style=e.style||"",this.data=e.data||{}}}class g{id;label;selectAll;selectAllText;closable;options;constructor(e){if(this.id=!e.id||e.id===""?y():e.id,this.label=e.label||"",this.selectAll=e.selectAll===void 0?!1:e.selectAll,this.selectAllText=e.selectAllText||"Select All",this.closable=e.closable||"off",this.options=[],e.options)for(const t of e.options)this.options.push(new u(t))}}class A{selectType="single";data=[];selectedOrder=[];constructor(e,t){this.selectType=e,this.setData(t)}validateDataArray(e){if(!Array.isArray(e))return new Error("Data must be an array");for(let t of e)if(t)if(t instanceof g||"label"in t){if(!("label"in t))return new Error("Optgroup must have a label");if("options"in t&&t.options)for(let s of t.options){const i=this.validateOption(s);if(i)return i}}else if(t instanceof u||"text"in t){const s=this.validateOption(t);if(s)return s}else return new Error("Data object must be a valid optgroup or option");return null}validateOption(e){return"text"in e?null:new Error("Option must have a text")}partialToFullData(e){let t=[];return e.forEach(s=>{if(s){if(s instanceof g||"label"in s){let i=[];"options"in s&&s.options&&s.options.forEach(l=>{i.push(new u(l))}),i.length>0&&t.push(new g(s))}(s instanceof u||"text"in s)&&t.push(new u(s))}}),t}setData(e,t=!1){const s=this.partialToFullData(e);if(t){const i=this.getSelectedOptions(),l=[];i.forEach(a=>{let n=!1;for(const o of s){if(o instanceof u&&o.id===a.id){n=!0;break}if(o instanceof g){for(const c of o.options)if(c.id===a.id){n=!0;break}}}n||l.push(a)}),this.data=[...l,...s]}else this.data=s;this.selectType==="single"&&this.setSelectedBy("id",this.getSelected())}getData(){return this.filter(null,!0)}getDataOptions(){return this.filter(null,!1)}addOption(e,t=!1){if(t){let s=[new u(e)];this.setData(s.concat(this.getData()))}else this.setData(this.getData().concat(new u(e)))}setSelectedBy(e,t){let s=null,i=!1;const l=[];for(let n of this.data){if(n instanceof g)for(let o of n.options){s||(s=o);let c=o[e]||"";o.selected=i?!1:t.includes(c),o.selected&&(l.push(o),this.selectType==="single"&&(i=!0))}n instanceof u&&(s||(s=n),n.selected=i?!1:t.includes(n[e]),n.selected&&(l.push(n),this.selectType==="single"&&(i=!0)))}this.selectType==="single"&&s&&!i&&(s.selected=!0,l.push(s));const a=t.map(n=>l.find(o=>o[e]===n)?.id||"");this.selectedOrder=a}getSelected(){return this.getSelectedOptions().map(e=>e.id)}getSelectedValues(){return this.getSelectedOptions().map(e=>e.value)}getSelectedOptions(){return this.filter(e=>e.selected,!1)}getOptgroupByID(e){for(let t of this.data)if(t instanceof g&&t.id===e)return t;return null}getOptionByID(e){let t=this.filter(s=>s.id===e,!1);return t.length?t[0]:null}getSelectType(){return this.selectType}getFirstOption(){let e=null;for(let t of this.data)if(t instanceof g?e=t.options[0]:t instanceof u&&(e=t),e)break;return e}search(e,t){return e=e.trim(),e===""?this.getData():this.filter(s=>t(s,e),!0)}filter(e,t){const s=[];return this.data.forEach(i=>{if(i instanceof g){let l=[];if(i.options.forEach(n=>{(!e||e(n))&&(t?l.push(new u(n)):s.push(new u(n)))}),l.length>0){let n=new g(i);n.options=l,s.push(n)}}i instanceof u&&(!e||e(i))&&s.push(new u(i))}),s}selectedOrderOptions(e){const t=[];return this.selectedOrder.forEach(s=>{const i=e.find(l=>l.id===s);i&&t.push(i)}),e.forEach(s=>{let i=!1;t.forEach(l=>{if(s.id===l.id){i=!0;return}}),i||t.push(s)}),t}}class E{settings;store;callbacks;lastSelectedOption;main;content;classes;constructor(e,t,s,i){this.store=s,this.settings=e,this.classes=t,this.callbacks=i,this.lastSelectedOption=null,this.main=this.mainDiv(),this.content=this.contentDiv(),this.updateClassStyles(),this.updateAriaAttributes(),this.settings.contentLocation&&this.settings.contentLocation.appendChild(this.content.main)}enable(){this.main.main.classList.remove(this.classes.disabled),this.main.main.setAttribute("aria-disabled","false"),this.content.search.input.disabled=!1}disable(){this.main.main.classList.add(this.classes.disabled),this.main.main.setAttribute("aria-disabled","true"),this.content.search.input.disabled=!0}open(){this.main.arrow.path.setAttribute("d",this.classes.arrowOpen),this.main.main.setAttribute("aria-expanded","true");const t=this.settings.openPosition==="up"?this.classes.dirAbove:this.classes.dirBelow;this.main.main.classList.add(t),this.content.main.classList.add(t),this.content.main.classList.add(this.classes.contentOpen),this.content.search.input.removeAttribute("aria-hidden"),this.moveContent();const s=this.store.getSelectedOptions();if(s.length){const i=s[s.length-1].id,l=this.content.list.querySelector('[data-id="'+i+'"]');l&&this.ensureElementInView(this.content.list,l)}}close(){this.main.main.setAttribute("aria-expanded","false"),this.main.arrow.path.setAttribute("d",this.classes.arrowClose),this.content.main.classList.remove(this.classes.contentOpen),this.content.search.input.setAttribute("aria-hidden","true"),this.main.main.removeAttribute("aria-activedescendant")}updateClassStyles(){if(this.main.main.className="",this.main.main.removeAttribute("style"),this.content.main.className="",this.content.main.removeAttribute("style"),this.main.main.classList.add(this.classes.main),this.content.main.classList.add(this.classes.content),this.settings.style!==""&&(this.main.main.style.cssText=this.settings.style,this.content.main.style.cssText=this.settings.style),this.settings.class.length)for(const e of this.settings.class)e.trim()!==""&&(this.main.main.classList.add(e.trim()),this.content.main.classList.add(e.trim()));(this.settings.contentPosition==="relative"||this.settings.contentPosition==="fixed")&&this.content.main.classList.add("ss-"+this.settings.contentPosition)}updateAriaAttributes(){const e=this.content.list.id;this.main.main.role="combobox",this.main.main.setAttribute("aria-haspopup","listbox"),this.main.main.setAttribute("aria-controls",e),this.main.main.setAttribute("aria-expanded","false"),this.content.list.setAttribute("role","listbox"),this.content.list.setAttribute("aria-label",this.settings.ariaLabel+" listbox"),this.settings.isMultiple&&this.content.list.setAttribute("aria-multiselectable","true"),this.content.search.input.setAttribute("aria-controls",e)}mainDiv(){const e=document.createElement("div");e.dataset.id=this.settings.id,e.setAttribute("aria-label",this.settings.ariaLabel),e.tabIndex=0,e.onkeydown=c=>{switch(c.key){case"ArrowUp":case"ArrowDown":return this.callbacks.open(),c.key==="ArrowDown"?this.highlight("down"):this.highlight("up"),!1;case"Tab":return this.callbacks.close(),!0;case"Enter":case" ":this.callbacks.open();const r=this.content.list.querySelector("."+this.classes.highlighted);return r&&r.click(),!1;case"Escape":return this.callbacks.close(),!1}return c.key.length===1&&this.callbacks.open(),!0},e.onclick=c=>{this.settings.disabled||(this.settings.isOpen?this.callbacks.close():this.callbacks.open())};const t=document.createElement("div");t.classList.add(this.classes.values),e.appendChild(t);const s=document.createElement("div");s.classList.add(this.classes.deselect);const i=this.store?.getSelectedOptions();!this.settings.allowDeselect||this.settings.isMultiple&&i&&i.length<=0?s.classList.add(this.classes.hide):s.classList.remove(this.classes.hide),s.onclick=c=>{if(c.stopPropagation(),this.settings.disabled)return;let r=!0;const h=this.store.getSelectedOptions(),f=[];if(this.callbacks.beforeChange&&(r=this.callbacks.beforeChange(f,h)===!0),r){if(this.settings.isMultiple)this.callbacks.setSelected([],!1),this.updateDeselectAll();else{const d=this.store.getFirstOption(),b=d?d.id:"";this.callbacks.setSelected(b,!1)}this.settings.closeOnSelect&&this.callbacks.close(),this.callbacks.afterChange&&this.callbacks.afterChange(this.store.getSelectedOptions())}};const l=document.createElementNS("http://www.w3.org/2000/svg","svg");l.setAttribute("viewBox","0 0 100 100");const a=document.createElementNS("http://www.w3.org/2000/svg","path");a.setAttribute("d",this.classes.deselectPath),l.appendChild(a),s.appendChild(l),e.appendChild(s);const n=document.createElementNS("http://www.w3.org/2000/svg","svg");n.classList.add(this.classes.arrow),n.setAttribute("viewBox","0 0 100 100");const o=document.createElementNS("http://www.w3.org/2000/svg","path");return o.setAttribute("d",this.classes.arrowClose),this.settings.alwaysOpen&&n.classList.add(this.classes.hide),n.appendChild(o),e.appendChild(n),{main:e,values:t,deselect:{main:s,svg:l,path:a},arrow:{main:n,path:o}}}mainFocus(e){e!=="click"&&this.main.main.focus({preventScroll:!0})}placeholder(){const e=this.store.filter(i=>i.placeholder,!1);let t=this.settings.placeholderText;e.length&&(e[0].html!==""?t=e[0].html:e[0].text!==""&&(t=e[0].text));const s=document.createElement("div");return s.classList.add(this.classes.placeholder),s.innerHTML=t,s}renderValues(){if(!this.settings.isMultiple){this.renderSingleValue();return}this.renderMultipleValues(),this.updateDeselectAll()}renderSingleValue(){const e=this.store.filter(s=>s.selected&&!s.placeholder,!1),t=e.length>0?e[0]:null;if(!t)this.main.values.innerHTML=this.placeholder().outerHTML;else{const s=document.createElement("div");s.classList.add(this.classes.single),t.html?s.innerHTML=t.html:s.innerText=t.text,this.main.values.innerHTML=s.outerHTML}!this.settings.allowDeselect||!e.length?this.main.deselect.main.classList.add(this.classes.hide):this.main.deselect.main.classList.remove(this.classes.hide)}renderMultipleValues(){let e=this.main.values.childNodes,t=this.store.filter(i=>i.selected&&i.display,!1);if(t.length===0){this.main.values.innerHTML=this.placeholder().outerHTML;return}else{const i=this.main.values.querySelector("."+this.classes.placeholder);i&&i.remove()}if(t.length>this.settings.maxValuesShown){const i=document.createElement("div");i.classList.add(this.classes.max),i.textContent=this.settings.maxValuesMessage.replace("{number}",t.length.toString()),this.main.values.innerHTML=i.outerHTML;return}else{const i=this.main.values.querySelector("."+this.classes.max);i&&i.remove()}this.settings.keepOrder&&(t=this.store.selectedOrderOptions(t));let s=[];for(let i=0;i<e.length;i++){const l=e[i],a=l.getAttribute("data-id");a&&(t.filter(o=>o.id===a,!1).length||s.push(l))}for(const i of s)i.classList.add(this.classes.valueOut),setTimeout(()=>{this.main.values.hasChildNodes()&&this.main.values.contains(i)&&this.main.values.removeChild(i)},100);e=this.main.values.childNodes;for(let i=0;i<t.length;i++){let l=!0;for(let a=0;a<e.length;a++)t[i].id===String(e[a].dataset.id)&&(l=!1);l&&(this.settings.keepOrder?this.main.values.appendChild(this.multipleValue(t[i])):e.length===0?this.main.values.appendChild(this.multipleValue(t[i])):i===0?this.main.values.insertBefore(this.multipleValue(t[i]),e[i]):e[i-1].insertAdjacentElement("afterend",this.multipleValue(t[i])))}}multipleValue(e){const t=document.createElement("div");t.classList.add(this.classes.value),t.dataset.id=e.id;const s=document.createElement("div");if(s.classList.add(this.classes.valueText),s.textContent=e.text,t.appendChild(s),!e.mandatory){const i=document.createElement("div");i.classList.add(this.classes.valueDelete),i.setAttribute("tabindex","0"),i.onclick=n=>{if(n.preventDefault(),n.stopPropagation(),this.settings.disabled)return;let o=!0;const c=this.store.getSelectedOptions(),r=c.filter(h=>h.selected&&h.id!==e.id,!0);if(!(this.settings.minSelected&&r.length<this.settings.minSelected)&&(this.callbacks.beforeChange&&(o=this.callbacks.beforeChange(r,c)===!0),o)){let h=[];for(const f of r){if(f instanceof g)for(const d of f.options)d.id&&h.push(d.id);f instanceof u&&h.push(f.id)}this.callbacks.setSelected(h,!1),this.settings.closeOnSelect&&this.callbacks.close(),this.callbacks.afterChange&&this.callbacks.afterChange(r),this.updateDeselectAll()}};const l=document.createElementNS("http://www.w3.org/2000/svg","svg");l.setAttribute("viewBox","0 0 100 100");const a=document.createElementNS("http://www.w3.org/2000/svg","path");a.setAttribute("d",this.classes.optionDelete),l.appendChild(a),i.appendChild(l),t.appendChild(i),i.onkeydown=n=>{n.key==="Enter"&&i.click()}}return t}contentDiv(){const e=document.createElement("div");e.dataset.id=this.settings.id;const t=this.searchDiv();e.appendChild(t.main);const s=this.listDiv();return e.appendChild(s),{main:e,search:t,list:s}}moveContent(){if(this.settings.contentPosition==="relative"){this.moveContentBelow();return}if(this.settings.openPosition==="down"){this.moveContentBelow();return}else if(this.settings.openPosition==="up"){this.moveContentAbove();return}this.putContent()==="up"?this.moveContentAbove():this.moveContentBelow()}searchDiv(){const e=document.createElement("div"),t=document.createElement("input"),s=document.createElement("div");e.classList.add(this.classes.search);const i={main:e,input:t};if(this.settings.showSearch||(e.classList.add(this.classes.hide),t.readOnly=!0),t.type="search",t.placeholder=this.settings.searchPlaceholder,t.tabIndex=-1,t.setAttribute("aria-label",this.settings.searchPlaceholder),t.setAttribute("aria-autocomplete","list"),t.setAttribute("autocapitalize","off"),t.setAttribute("autocomplete","off"),t.setAttribute("autocorrect","off"),t.setAttribute("aria-hidden","true"),t.oninput=L(l=>{this.callbacks.search(l.target.value)},100),t.onkeydown=l=>{switch(l.key){case"ArrowUp":case"ArrowDown":return l.key==="ArrowDown"?this.highlight("down"):this.highlight("up"),!1;case"Tab":return this.callbacks.close(),!0;case"Escape":return this.callbacks.close(),!1;case" ":const a=this.content.list.querySelector("."+this.classes.highlighted);return a?(a.click(),!1):!0;case"Enter":const n=this.content.list.querySelector("."+this.classes.highlighted);return n?(n.click(),!1):this.callbacks.addable?(s.click(),!1):!0}return!0},e.appendChild(t),this.callbacks.addable){s.classList.add(this.classes.addable);const l=document.createElementNS("http://www.w3.org/2000/svg","svg");l.setAttribute("viewBox","0 0 100 100");const a=document.createElementNS("http://www.w3.org/2000/svg","path");a.setAttribute("d",this.classes.addablePath),l.appendChild(a),s.appendChild(l),s.onclick=n=>{if(n.preventDefault(),n.stopPropagation(),!this.callbacks.addable)return;const o=this.content.search.input.value.trim();if(o===""){this.content.search.input.focus();return}const c=h=>{let f=new u(h);if(this.callbacks.addOption(f),this.settings.isMultiple){let d=this.store.getSelected();d.push(f.id),this.callbacks.setSelected(d,!0)}else this.callbacks.setSelected([f.id],!0);this.callbacks.search(""),this.settings.closeOnSelect&&setTimeout(()=>{this.callbacks.close()},100)},r=this.callbacks.addable(o);r===!1||r===void 0||r===null||(r instanceof Promise?r.then(h=>{typeof h=="string"?c({text:h,value:h}):r instanceof Error?this.renderError(r.message):c(h)}):typeof r=="string"?c({text:r,value:r}):r instanceof Error?this.renderError(r.message):c(r))},e.appendChild(s),i.addable={main:s,svg:l,path:a}}return i}searchFocus(){this.content.search.input.focus()}clearSearch(){this.content.search.input.value=""}getOptions(e=!1,t=!1,s=!1){let i="."+this.classes.option;return e&&(i+=":not(."+this.classes.placeholder+")"),t&&(i+=":not(."+this.classes.disabled+")"),s&&(i+=":not(."+this.classes.hide+")"),Array.from(this.content.list.querySelectorAll(i))}highlight(e){const t=this.getOptions(!0,!0,!0);if(t.length===0)return;if(t.length===1&&!t[0].classList.contains(this.classes.highlighted)){t[0].classList.add(this.classes.highlighted);return}let s=!1;for(const l of t)l.classList.contains(this.classes.highlighted)&&(s=!0);if(!s){for(const l of t)if(l.classList.contains(this.classes.selected)){l.classList.add(this.classes.highlighted);break}}for(let l=0;l<t.length;l++)if(t[l].classList.contains(this.classes.highlighted)){const a=t[l];a.classList.remove(this.classes.highlighted);const n=a.parentElement;if(n&&n.classList.contains(this.classes.mainOpen)){const r=n.querySelector("."+this.classes.optgroupLabel);r&&r.click()}let o=t[e==="down"?l+1<t.length?l+1:0:l-1>=0?l-1:t.length-1];o.classList.add(this.classes.highlighted),this.ensureElementInView(this.content.list,o),o.id&&this.main.main.setAttribute("aria-activedescendant",o.id);const c=o.parentElement;if(c&&c.classList.contains(this.classes.close)){const r=c.querySelector("."+this.classes.optgroupLabel);r&&r.click()}return}const i=t[e==="down"?0:t.length-1];i.classList.add(this.classes.highlighted),i.id&&this.main.main.setAttribute("aria-activedescendant",i.id),this.ensureElementInView(this.content.list,i)}listDiv(){const e=document.createElement("div");e.classList.add(this.classes.list);const t=this.settings.id+"-list";return e.id=t,e.dataset.id=t,e}renderError(e){this.content.list.innerHTML="";const t=document.createElement("div");t.classList.add(this.classes.error),t.textContent=e,this.content.list.appendChild(t)}renderSearching(){this.content.list.innerHTML="";const e=document.createElement("div");e.classList.add(this.classes.searching),e.textContent=this.settings.searchingText,this.content.list.appendChild(e)}renderOptions(e){if(this.content.list.innerHTML="",e.length===0){const s=document.createElement("div");s.classList.add(this.classes.search),this.callbacks.addable?s.innerHTML=this.settings.addableText.replace("{value}",this.content.search.input.value):s.innerHTML=this.settings.searchText,this.content.list.appendChild(s);return}this.settings.allowDeselect&&!this.settings.isMultiple&&(this.store.filter(i=>i.placeholder,!1).length||this.store.addOption(new u({text:"",value:"",selected:!1,placeholder:!0}),!0));const t=document.createDocumentFragment();for(const s of e){if(s instanceof g){const i=document.createElement("div");i.classList.add(this.classes.optgroup);const l=document.createElement("div");l.classList.add(this.classes.optgroupLabel),i.appendChild(l);const a=document.createElement("div");a.classList.add(this.classes.optgroupLabelText),a.textContent=s.label,l.appendChild(a);const n=document.createElement("div");if(n.classList.add(this.classes.optgroupActions),l.appendChild(n),this.settings.isMultiple&&s.selectAll){const o=document.createElement("div");o.classList.add(this.classes.optgroupSelectAll);let c=!0;for(const b of s.options)if(!b.selected){c=!1;break}c&&o.classList.add(this.classes.selected);const r=document.createElement("span");r.textContent=s.selectAllText,o.appendChild(r);const h=document.createElementNS("http://www.w3.org/2000/svg","svg");h.setAttribute("viewBox","0 0 100 100"),o.appendChild(h);const f=document.createElementNS("http://www.w3.org/2000/svg","path");f.setAttribute("d",this.classes.optgroupSelectAllBox),h.appendChild(f);const d=document.createElementNS("http://www.w3.org/2000/svg","path");d.setAttribute("d",this.classes.optgroupSelectAllCheck),h.appendChild(d),o.addEventListener("click",b=>{b.preventDefault(),b.stopPropagation();const v=this.store.getSelected();if(c){const O=v.filter(C=>{for(const w of s.options)if(C===w.id)return!1;return!0});this.callbacks.setSelected(O,!0);return}else{let O=s.options.map(w=>w.id).filter(w=>w!==void 0);const C=v.concat(O);for(const w of s.options)w.id&&!this.store.getOptionByID(w.id)&&this.callbacks.addOption(new u(w));this.callbacks.setSelected(C,!0);return}}),n.appendChild(o)}if(s.closable!=="off"){const o=document.createElement("div");o.classList.add(this.classes.optgroupClosable);const c=document.createElementNS("http://www.w3.org/2000/svg","svg");c.setAttribute("viewBox","0 0 100 100"),c.classList.add(this.classes.arrow),o.appendChild(c);const r=document.createElementNS("http://www.w3.org/2000/svg","path");c.appendChild(r),s.options.some(h=>h.selected)||this.content.search.input.value.trim()!==""?(o.classList.add(this.classes.mainOpen),r.setAttribute("d",this.classes.arrowOpen)):s.closable==="open"?(i.classList.add(this.classes.mainOpen),r.setAttribute("d",this.classes.arrowOpen)):s.closable==="close"&&(i.classList.add(this.classes.close),r.setAttribute("d",this.classes.arrowClose)),l.addEventListener("click",h=>{h.preventDefault(),h.stopPropagation(),i.classList.contains(this.classes.close)?(i.classList.remove(this.classes.close),i.classList.add(this.classes.mainOpen),r.setAttribute("d",this.classes.arrowOpen)):(i.classList.remove(this.classes.mainOpen),i.classList.add(this.classes.close),r.setAttribute("d",this.classes.arrowClose))}),n.appendChild(o)}i.appendChild(l);for(const o of s.options)i.appendChild(this.option(new u(o))),t.appendChild(i)}s instanceof u&&t.appendChild(this.option(s))}this.content.list.appendChild(t)}option(e){if(e.placeholder){const s=document.createElement("div");return s.classList.add(this.classes.option),s.classList.add(this.classes.hide),s}const t=document.createElement("div");return t.dataset.id=e.id,t.id=this.settings.id+"-"+e.id,t.classList.add(this.classes.option),t.setAttribute("role","option"),e.class&&e.class.split(" ").forEach(s=>{t.classList.add(s)}),e.style&&(t.style.cssText=e.style),this.settings.searchHighlight&&this.content.search.input.value.trim()!==""?t.innerHTML=this.highlightText(e.html!==""?e.html:e.text,this.content.search.input.value,this.classes.searchHighlighter):e.html!==""?t.innerHTML=e.html:t.textContent=e.text,this.settings.showOptionTooltips&&t.textContent&&t.setAttribute("title",t.textContent),e.display||t.classList.add(this.classes.hide),e.disabled&&t.classList.add(this.classes.disabled),e.selected&&this.settings.hideSelected&&t.classList.add(this.classes.hide),e.selected?(t.classList.add(this.classes.selected),t.setAttribute("aria-selected","true"),this.main.main.setAttribute("aria-activedescendant",t.id)):(t.classList.remove(this.classes.selected),t.setAttribute("aria-selected","false")),t.addEventListener("click",s=>{s.preventDefault(),s.stopPropagation();const i=this.store.getSelected(),l=s.currentTarget,a=String(l.dataset.id),n=s.ctrlKey||s.metaKey;if(e.disabled||!this.settings.isMultiple&&e.selected&&!this.settings.allowDeselect||this.settings.isMultiple&&this.settings.maxSelected<=i.length&&!e.selected||this.settings.isMultiple&&this.settings.minSelected>=i.length&&e.selected&&!n)return;let o=!1;const c=this.store.getSelectedOptions();let r=[];if(this.settings.isMultiple){const h=c.some(d=>d.id===a);if(s.shiftKey&&this.lastSelectedOption){const d=this.store.getDataOptions(),b=d.findIndex(O=>O.id===this.lastSelectedOption.id),v=d.findIndex(O=>O.id===e.id);if(b>=0&&v>=0){const O=Math.min(b,v),C=Math.max(b,v),k=d.slice(O,C+1).filter(I=>!c.find(B=>B.id===I.id));c.length+k.length<=this.settings.maxSelected?r=c.concat(k):r=c}else r=c}else n?(h?r=c.filter(d=>d.id!==a):r=c.concat(e),this.lastSelectedOption=e):(h?r=c.filter(d=>d.id!==a):r=c.concat(e),this.lastSelectedOption=e)}if(this.settings.isMultiple||(e.selected?r=[]:r=[e]),this.callbacks.beforeChange||(o=!0),this.callbacks.beforeChange&&(this.callbacks.beforeChange(r,c)===!1?o=!1:o=!0),o){this.store.getOptionByID(a)||this.callbacks.addOption(e),this.callbacks.setSelected(r.map(d=>d.id),!1);const h=s.ctrlKey||s.metaKey||s.shiftKey;this.settings.closeOnSelect&&!(this.settings.isMultiple&&h)&&this.callbacks.close(),this.callbacks.afterChange&&this.callbacks.afterChange(r)}}),t}destroy(){this.main.main.remove(),this.content.main.remove()}highlightText(e,t,s){const i=t.trim();if(i==="")return e;const l=i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),a=document.createElement("div");a.innerHTML=e;const n=o=>{if(o.nodeType===Node.TEXT_NODE){const c=o.textContent||"",r=new RegExp("("+l+")","i");if(r.test(c)){const h=document.createElement("span");c.split(r).forEach((d,b)=>{if(d&&r.test(d)){const v=document.createElement("mark");v.className=s,v.textContent=d,h.appendChild(v)}else d&&h.appendChild(document.createTextNode(d))}),o.parentNode?.replaceChild(h,o)}}else o.nodeType===Node.ELEMENT_NODE&&Array.from(o.childNodes).forEach(c=>n(c))};return Array.from(a.childNodes).forEach(o=>n(o)),a.innerHTML}moveContentAbove(){const e=this.main.main.offsetHeight,t=this.content.main.offsetHeight;this.main.main.classList.remove(this.classes.dirBelow),this.main.main.classList.add(this.classes.dirAbove),this.content.main.classList.remove(this.classes.dirBelow),this.content.main.classList.add(this.classes.dirAbove);const s=this.main.main.getBoundingClientRect();this.content.main.style.margin="-"+(e+t-1)+"px 0px 0px 0px",this.content.main.style.top=s.top+s.height+(this.settings.contentPosition==="fixed"?0:window.scrollY)+"px",this.content.main.style.left=s.left+(this.settings.contentPosition==="fixed"?0:window.scrollX)+"px",this.content.main.style.width=s.width+"px"}moveContentBelow(){this.main.main.classList.remove(this.classes.dirAbove),this.main.main.classList.add(this.classes.dirBelow),this.content.main.classList.remove(this.classes.dirAbove),this.content.main.classList.add(this.classes.dirBelow);const e=this.main.main.getBoundingClientRect();this.content.main.style.margin="-1px 0px 0px 0px",this.settings.contentPosition!=="relative"&&(this.content.main.style.top=e.top+e.height+(this.settings.contentPosition==="fixed"?0:window.scrollY)+"px",this.content.main.style.left=e.left+(this.settings.contentPosition==="fixed"?0:window.scrollX)+"px",this.content.main.style.width=e.width+"px")}ensureElementInView(e,t){const s=e.scrollTop+e.offsetTop,i=s+e.clientHeight,l=t.offsetTop,a=l+t.clientHeight;l<s?e.scrollTop-=s-l:a>i&&(e.scrollTop+=a-i)}putContent(){const e=this.main.main.offsetHeight,t=this.main.main.getBoundingClientRect(),s=this.content.main.offsetHeight;return window.innerHeight-(t.top+e)<=s&&t.top>s?"up":"down"}updateDeselectAll(){if(!this.store||!this.settings)return;const e=this.store.getSelectedOptions(),t=e&&e.length>0,s=this.settings.isMultiple,i=this.settings.allowDeselect,l=this.main.deselect.main,a=this.classes.hide;i&&!(s&&!t)?l.classList.remove(a):l.classList.add(a)}}class T{select;onValueChange;onClassChange;onDisabledChange;onOptionsChange;listen=!1;observer=null;constructor(e){this.select=e,this.valueChange=this.valueChange.bind(this),this.select.addEventListener("change",this.valueChange,{passive:!0}),this.observer=new MutationObserver(this.observeCall.bind(this)),this.changeListen(!0)}enable(){this.select.disabled=!1}disable(){this.select.disabled=!0}hideUI(){this.select.tabIndex=-1,this.select.style.position="absolute",this.select.style.width="1px",this.select.style.height="1px",this.select.style.opacity="0",this.select.style.overflow="hidden",this.select.style.pointerEvents="none",this.select.style.margin="0",this.select.style.padding="0",this.select.style.borderWidth="0",this.select.style.clip="rect(0 0 0 0)",this.select.setAttribute("aria-hidden","true")}showUI(){this.select.removeAttribute("tabindex"),this.select.style.position="",this.select.style.width="",this.select.style.height="",this.select.style.opacity="",this.select.style.overflow="",this.select.style.pointerEvents="",this.select.style.margin="",this.select.style.padding="",this.select.style.borderWidth="",this.select.style.clip="",this.select.removeAttribute("aria-hidden")}changeListen(e){this.listen=e,e&&this.observer&&this.observer.observe(this.select,{subtree:!0,childList:!0,attributes:!0}),e||this.observer&&this.observer.disconnect()}valueChange(e){return this.listen&&this.onValueChange&&this.onValueChange(this.getSelectedOptions()),!0}observeCall(e){if(!this.listen)return;let t=!1,s=!1,i=!1;for(const l of e){if(l.target===this.select&&(l.attributeName==="disabled"&&(s=!0),l.attributeName==="class"&&(t=!0),l.type==="childList")){for(const a of Array.from(l.addedNodes))if(a.nodeName==="OPTION"&&a.value===this.select.value){this.select.dispatchEvent(new Event("change"));break}i=!0}(l.target.nodeName==="OPTGROUP"||l.target.nodeName==="OPTION")&&(i=!0)}t&&this.onClassChange&&this.onClassChange(this.select.className.split(" ")),s&&this.onDisabledChange&&(this.changeListen(!1),this.onDisabledChange(this.select.disabled),this.changeListen(!0)),i&&this.onOptionsChange&&(this.changeListen(!1),this.onOptionsChange(this.getData()),this.changeListen(!0))}getData(){let e=[];const t=this.select.childNodes;for(const s of t)s.nodeName==="OPTGROUP"&&e.push(this.getDataFromOptgroup(s)),s.nodeName==="OPTION"&&e.push(this.getDataFromOption(s));return e}getDataFromOptgroup(e){let t={id:e.id,label:e.label,selectAll:e.dataset?e.dataset.selectall==="true":!1,selectAllText:e.dataset?e.dataset.selectalltext:"Select all",closable:e.dataset?e.dataset.closable:"off",options:[]};const s=e.childNodes;for(const i of s)i.nodeName==="OPTION"&&t.options.push(this.getDataFromOption(i));return t}getDataFromOption(e){return{id:e.id,value:e.value,text:e.text,html:e.dataset&&e.dataset.html?e.dataset.html:"",defaultSelected:e.defaultSelected,selected:e.selected,display:e.style.display!=="none",disabled:e.disabled,mandatory:e.dataset?e.dataset.mandatory==="true":!1,placeholder:e.dataset.placeholder==="true",class:e.className,style:e.style.cssText,data:e.dataset}}getSelectedOptions(){let e=[];const t=this.select.childNodes;for(const s of t){if(s.nodeName==="OPTGROUP"){const i=s.childNodes;for(const l of i)if(l.nodeName==="OPTION"){const a=l;a.selected&&e.push(this.getDataFromOption(a))}}if(s.nodeName==="OPTION"){const i=s;i.selected&&e.push(this.getDataFromOption(i))}}return e}getSelectedValues(){return this.getSelectedOptions().map(e=>e.value)}setSelected(e){this.changeListen(!1);const t=this.select.childNodes;for(const s of t){if(s.nodeName==="OPTGROUP"){const l=s.childNodes;for(const a of l)if(a.nodeName==="OPTION"){const n=a;n.selected=e.includes(n.id)}}if(s.nodeName==="OPTION"){const i=s;i.selected=e.includes(i.id)}}this.changeListen(!0)}setSelectedByValue(e){this.changeListen(!1);const t=this.select.childNodes;for(const s of t){if(s.nodeName==="OPTGROUP"){const l=s.childNodes;for(const a of l)if(a.nodeName==="OPTION"){const n=a;n.selected=e.includes(n.value)}}if(s.nodeName==="OPTION"){const i=s;i.selected=e.includes(i.value)}}this.changeListen(!0)}updateSelect(e,t,s){this.changeListen(!1),e&&(this.select.dataset.id=e),t&&(this.select.style.cssText=t),s&&(this.select.className="",s.forEach(i=>{i.trim()!==""&&this.select.classList.add(i.trim())})),this.changeListen(!0)}updateOptions(e){this.changeListen(!1),this.select.innerHTML="";for(const t of e)t instanceof g&&this.select.appendChild(this.createOptgroup(t)),t instanceof u&&this.select.appendChild(this.createOption(t));this.select.dispatchEvent(new Event("change",{bubbles:!0})),this.changeListen(!0)}createOptgroup(e){const t=document.createElement("optgroup");if(t.id=e.id,t.label=e.label,e.selectAll&&(t.dataset.selectAll="true"),e.closable!=="off"&&(t.dataset.closable=e.closable),e.options)for(const s of e.options)t.appendChild(this.createOption(s));return t}createOption(e){const t=document.createElement("option");return t.id=e.id,t.value=e.value,t.textContent=e.text,e.html!==""&&t.setAttribute("data-html",e.html),t.defaultSelected=e.defaultSelected,t.selected=e.selected,e.disabled&&(t.disabled=!0),e.display||(t.style.display="none"),e.placeholder&&t.setAttribute("data-placeholder","true"),e.mandatory&&t.setAttribute("data-mandatory","true"),e.class&&e.class.split(" ").forEach(s=>{t.classList.add(s)}),e.data&&typeof e.data=="object"&&Object.keys(e.data).forEach(s=>{t.setAttribute("data-"+M(s),e.data[s])}),t}destroy(){this.changeListen(!1),this.select.removeEventListener("change",this.valueChange),this.observer&&(this.observer.disconnect(),this.observer=null),delete this.select.dataset.id,this.showUI()}}class D{id="";style="";class=[];isMultiple=!1;isOpen=!1;isFullOpen=!1;intervalMove=null;disabled;alwaysOpen;showSearch;focusSearch;ariaLabel;searchPlaceholder;searchText;searchingText;searchHighlight;closeOnSelect;contentLocation;contentPosition;openPosition;placeholderText;allowDeselect;hideSelected;keepOrder;showOptionTooltips;minSelected;maxSelected;timeoutDelay;maxValuesShown;maxValuesMessage;addableText;constructor(e){e||(e={}),this.id="ss-"+y(),this.style=e.style||"",this.class=e.class||[],this.disabled=e.disabled!==void 0?e.disabled:!1,this.alwaysOpen=e.alwaysOpen!==void 0?e.alwaysOpen:!1,this.showSearch=e.showSearch!==void 0?e.showSearch:!0,this.focusSearch=e.focusSearch!==void 0?e.focusSearch:!0,this.ariaLabel=e.ariaLabel||"Combobox",this.searchPlaceholder=e.searchPlaceholder||"Search",this.searchText=e.searchText||"No Results",this.searchingText=e.searchingText||"Searching...",this.searchHighlight=e.searchHighlight!==void 0?e.searchHighlight:!1,this.closeOnSelect=e.closeOnSelect!==void 0?e.closeOnSelect:!0,this.contentLocation=e.contentLocation||document.body,this.contentPosition=e.contentPosition||"absolute",this.openPosition=e.openPosition||"auto",this.placeholderText=e.placeholderText!==void 0?e.placeholderText:"Select Value",this.allowDeselect=e.allowDeselect!==void 0?e.allowDeselect:!1,this.hideSelected=e.hideSelected!==void 0?e.hideSelected:!1,this.keepOrder=e.keepOrder!==void 0?e.keepOrder:!1,this.showOptionTooltips=e.showOptionTooltips!==void 0?e.showOptionTooltips:!1,this.minSelected=e.minSelected||0,this.maxSelected=e.maxSelected||1e3,this.timeoutDelay=e.timeoutDelay||200,this.maxValuesShown=e.maxValuesShown||20,this.maxValuesMessage=e.maxValuesMessage||"{number} selected",this.addableText=e.addableText||'Press "Enter" to add {value}'}}class P{selectEl;settings;cssClasses;select;store;render;openTimeout=null;closeTimeout=null;events={search:void 0,searchFilter:(e,t)=>e.text.toLowerCase().indexOf(t.toLowerCase())!==-1,addable:void 0,beforeChange:void 0,afterChange:void 0,beforeOpen:void 0,afterOpen:void 0,beforeClose:void 0,afterClose:void 0};constructor(e){if(this.selectEl=typeof e.select=="string"?document.querySelector(e.select):e.select,!this.selectEl){e.events&&e.events.error&&e.events.error(new Error("Could not find select element"));return}if(this.selectEl.tagName!=="SELECT"){e.events&&e.events.error&&e.events.error(new Error("Element isnt of type select"));return}this.selectEl.dataset.ssid&&this.destroy(),this.settings=new D(e.settings),this.cssClasses=new S(e.cssClasses);const t=["beforeOpen","afterOpen","beforeClose","afterClose"];for(const n in e.events)e.events.hasOwnProperty(n)&&(t.indexOf(n)!==-1?this.events[n]=L(e.events[n],100):this.events[n]=e.events[n]);this.settings.disabled=e.settings?.disabled?e.settings.disabled:this.selectEl.disabled,this.settings.isMultiple=this.selectEl.multiple,this.settings.style=this.selectEl.style.cssText,this.settings.class=this.selectEl.className.split(" "),this.select=new T(this.selectEl),this.select.updateSelect(this.settings.id,this.settings.style,this.settings.class),this.select.hideUI(),this.select.onValueChange=n=>{this.setSelected(n.map(o=>o.id))},this.select.onClassChange=n=>{this.settings.class=n,this.render.updateClassStyles()},this.select.onDisabledChange=n=>{n?this.disable():this.enable()},this.select.onOptionsChange=n=>{this.setData(n)};const s=e.data?e.data:this.select.getData();this.store=new A(this.settings.isMultiple?"multiple":"single",s),e.data&&this.select.updateOptions(this.store.getData());const i={open:this.open.bind(this),close:this.close.bind(this),addable:this.events.addable?this.events.addable:void 0,setSelected:this.setSelected.bind(this),addOption:this.addOption.bind(this),search:this.search.bind(this),beforeChange:this.events.beforeChange,afterChange:this.events.afterChange};this.render=new E(this.settings,this.cssClasses,this.store,i),this.render.renderValues(),this.render.renderOptions(this.store.getData());const l=this.selectEl.getAttribute("aria-label"),a=this.selectEl.getAttribute("aria-labelledby");l?this.render.main.main.setAttribute("aria-label",l):a&&this.render.main.main.setAttribute("aria-labelledby",a),this.selectEl.parentNode&&this.selectEl.parentNode.insertBefore(this.render.main.main,this.selectEl.nextSibling),window.addEventListener("resize",this.windowResize,!1),this.settings.openPosition==="auto"&&window.addEventListener("scroll",this.windowScroll,!1),document.addEventListener("visibilitychange",this.windowVisibilityChange),this.settings.disabled&&this.disable(),this.settings.alwaysOpen&&this.open(),this.selectEl.slim=this}enable(){this.settings.disabled=!1,this.select.enable(),this.render.enable()}disable(){this.settings.disabled=!0,this.select.disable(),this.render.disable()}getData(){return this.store.getData()}setData(e){const t=this.store.getSelected(),s=this.store.validateDataArray(e);if(s){this.events.error&&this.events.error(s);return}this.store.setData(e);const i=this.store.getData();this.select.updateOptions(i),this.render.renderValues(),this.render.renderOptions(i),this.events.afterChange&&!x(t,this.store.getSelected())&&this.events.afterChange(this.store.getSelectedOptions())}getSelected(){let e=this.store.getSelectedOptions();return this.settings.keepOrder&&(e=this.store.selectedOrderOptions(e)),e.map(t=>t.value)}setSelected(e,t=!0){const s=this.store.getSelected(),i=this.store.getDataOptions();e=Array.isArray(e)?e:[e];const l=[];for(const n of e){if(i.find(o=>o.id==n)){l.push(n);continue}for(const o of i.filter(c=>c.value==n))l.push(o.id)}this.store.setSelectedBy("id",l);const a=this.store.getData();this.select.updateOptions(a),this.render.renderValues(),this.render.content.search.input.value!==""?this.search(this.render.content.search.input.value):this.render.renderOptions(a),t&&this.events.afterChange&&!x(s,this.store.getSelected())&&this.events.afterChange(this.store.getSelectedOptions())}addOption(e){const t=this.store.getSelected();this.store.getDataOptions().some(i=>i.value===(e.value??e.text))||this.store.addOption(e);const s=this.store.getData();this.select.updateOptions(s),this.render.renderValues(),this.render.renderOptions(s),this.events.afterChange&&!x(t,this.store.getSelected())&&this.events.afterChange(this.store.getSelectedOptions())}open(){this.settings.disabled||this.settings.isOpen||(this.events.beforeOpen&&this.events.beforeOpen(),this.render.open(),this.settings.showSearch&&this.settings.focusSearch&&this.render.searchFocus(),this.settings.isOpen=!0,this.openTimeout=setTimeout(()=>{this.events.afterOpen&&this.events.afterOpen(),this.settings.isOpen&&(this.settings.isFullOpen=!0),document.addEventListener("click",this.documentClick)},this.settings.timeoutDelay),this.settings.contentPosition==="absolute"&&(this.settings.intervalMove&&clearInterval(this.settings.intervalMove),this.settings.intervalMove=setInterval(this.render.moveContent.bind(this.render),500)))}close(e=null){!this.settings.isOpen||this.settings.alwaysOpen||(this.events.beforeClose&&this.events.beforeClose(),this.render.close(),this.render.clearSearch(),this.render.mainFocus(e),this.settings.isOpen=!1,this.settings.isFullOpen=!1,this.closeTimeout=setTimeout(()=>{this.events.afterClose&&this.events.afterClose(),document.removeEventListener("click",this.documentClick)},this.settings.timeoutDelay),this.settings.intervalMove&&clearInterval(this.settings.intervalMove))}search(e){if(this.render.content.search.input.value!==e&&(this.render.content.search.input.value=e),!this.events.search){const s=e===""?this.store.getData():this.store.search(e,this.events.searchFilter);this.render.renderOptions(s);return}this.render.renderSearching();const t=this.events.search(e,this.store.getSelectedOptions());if(t instanceof Promise){t.then(s=>{this.store.setData(s,!0),this.select.updateOptions(this.store.getData()),this.render.renderOptions(this.store.getData())}).catch(s=>{this.render.renderError(typeof s=="string"?s:s.message)});return}else Array.isArray(t)?(this.store.setData(t,!0),this.select.updateOptions(this.store.getData()),this.render.renderOptions(this.store.getData())):this.render.renderError("Search event must return a promise or an array of data")}destroy(){this.openTimeout&&(clearTimeout(this.openTimeout),this.openTimeout=null),this.closeTimeout&&(clearTimeout(this.closeTimeout),this.closeTimeout=null),this.settings.intervalMove&&(clearInterval(this.settings.intervalMove),this.settings.intervalMove=null),document.removeEventListener("click",this.documentClick),window.removeEventListener("resize",this.windowResize,!1),this.settings.openPosition==="auto"&&window.removeEventListener("scroll",this.windowScroll,!1),document.removeEventListener("visibilitychange",this.windowVisibilityChange),this.store.setData([]),this.render.destroy(),this.select.destroy()}windowResize=L(()=>{!this.settings.isOpen&&!this.settings.isFullOpen||this.render.moveContent()});windowScroll=L(()=>{!this.settings.isOpen&&!this.settings.isFullOpen||this.render.moveContent()});documentClick=e=>{this.settings.isOpen&&e.target&&!N(e.target,this.settings.id)&&this.close(e.type)};windowVisibilityChange=()=>{document.hidden&&this.close()}}m.Optgroup=g,m.Option=u,m.Render=E,m.Select=T,m.Settings=D,m.Store=A,m.default=P,Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})});