slim-select 2.8.1 → 2.9.0

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