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