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