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