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