slim-select 2.2.3 → 2.3.1

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.
@@ -69,7 +69,7 @@ class Settings {
69
69
  this.id = 'ss-' + generateID();
70
70
  this.style = settings.style || '';
71
71
  this.class = settings.class || [];
72
- this.isEnabled = settings.isEnabled !== undefined ? settings.isEnabled : true;
72
+ this.disabled = settings.disabled !== undefined ? settings.disabled : false;
73
73
  this.alwaysOpen = settings.alwaysOpen !== undefined ? settings.alwaysOpen : false;
74
74
  this.showSearch = settings.showSearch !== undefined ? settings.showSearch : true;
75
75
  this.searchPlaceholder = settings.searchPlaceholder || 'Search';
@@ -87,6 +87,8 @@ class Settings {
87
87
  this.minSelected = settings.minSelected || 0;
88
88
  this.maxSelected = settings.maxSelected || 1000;
89
89
  this.timeoutDelay = settings.timeoutDelay || 200;
90
+ this.maxValuesShown = settings.maxValuesShown || 20;
91
+ this.maxValuesMessage = settings.maxValuesMessage || '{number} selected';
90
92
  }
91
93
  }
92
94
 
@@ -303,6 +305,7 @@ class Render {
303
305
  placeholder: 'ss-placeholder',
304
306
  values: 'ss-values',
305
307
  single: 'ss-single',
308
+ max: 'ss-max',
306
309
  value: 'ss-value',
307
310
  valueText: 'ss-value-text',
308
311
  valueDelete: 'ss-value-delete',
@@ -344,6 +347,7 @@ class Render {
344
347
  this.callbacks = callbacks;
345
348
  this.main = this.mainDiv();
346
349
  this.content = this.contentDiv();
350
+ this.updateClassStyles();
347
351
  this.settings.contentLocation.appendChild(this.content.main);
348
352
  }
349
353
  enable() {
@@ -358,24 +362,6 @@ class Render {
358
362
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
359
363
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
360
364
  this.moveContent();
361
- this.renderOptions(this.store.getData());
362
- if (this.settings.contentPosition === 'relative') {
363
- this.moveContentBelow();
364
- }
365
- else if (this.settings.openPosition.toLowerCase() === 'up') {
366
- this.moveContentAbove();
367
- }
368
- else if (this.settings.openPosition.toLowerCase() === 'down') {
369
- this.moveContentBelow();
370
- }
371
- else {
372
- if (this.putContent(this.content.main, this.settings.isOpen) === 'up') {
373
- this.moveContentAbove();
374
- }
375
- else {
376
- this.moveContentBelow();
377
- }
378
- }
379
365
  const selectedOptions = this.store.getSelectedOptions();
380
366
  if (selectedOptions.length) {
381
367
  const selectedId = selectedOptions[selectedOptions.length - 1].id;
@@ -392,20 +378,32 @@ class Render {
392
378
  this.content.main.classList.remove(this.classes.openBelow);
393
379
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
394
380
  }
395
- mainDiv() {
396
- const main = document.createElement('div');
397
- main.tabIndex = 0;
398
- main.style.cssText = this.settings.style !== '' ? this.settings.style : '';
399
- main.className = '';
400
- main.classList.add(this.settings.id);
401
- main.classList.add(this.classes.main);
402
- if (this.settings.class) {
381
+ updateClassStyles() {
382
+ this.main.main.className = '';
383
+ this.main.main.removeAttribute('style');
384
+ this.content.main.className = '';
385
+ this.content.main.removeAttribute('style');
386
+ this.main.main.classList.add(this.classes.main);
387
+ this.content.main.classList.add(this.classes.content);
388
+ if (this.settings.style !== '') {
389
+ this.content.main.style.cssText = this.settings.style;
390
+ }
391
+ if (this.settings.class.length) {
403
392
  for (const c of this.settings.class) {
404
393
  if (c.trim() !== '') {
405
- main.classList.add(c.trim());
394
+ this.main.main.classList.add(c.trim());
395
+ this.content.main.classList.add(c.trim());
406
396
  }
407
397
  }
408
398
  }
399
+ if (this.settings.contentPosition === 'relative') {
400
+ this.content.main.classList.add('ss-' + this.settings.contentPosition);
401
+ }
402
+ }
403
+ mainDiv() {
404
+ const main = document.createElement('div');
405
+ main.dataset.id = this.settings.id;
406
+ main.tabIndex = 0;
409
407
  main.onfocus = () => {
410
408
  if (this.settings.triggerFocus) {
411
409
  this.callbacks.open();
@@ -433,7 +431,7 @@ class Render {
433
431
  }
434
432
  };
435
433
  main.onclick = (e) => {
436
- if (!this.settings.isEnabled) {
434
+ if (this.settings.disabled) {
437
435
  return;
438
436
  }
439
437
  this.settings.isOpen ? this.callbacks.close() : this.callbacks.open();
@@ -448,7 +446,7 @@ class Render {
448
446
  }
449
447
  deselect.onclick = (e) => {
450
448
  e.stopPropagation();
451
- if (!this.settings.isEnabled) {
449
+ if (this.settings.disabled) {
452
450
  return;
453
451
  }
454
452
  let shouldDelete = true;
@@ -458,7 +456,7 @@ class Render {
458
456
  shouldDelete = this.callbacks.beforeChange(after, before) === true;
459
457
  }
460
458
  if (shouldDelete) {
461
- this.callbacks.setSelected(['']);
459
+ this.callbacks.setSelected([''], false);
462
460
  if (this.settings.closeOnSelect) {
463
461
  this.callbacks.close();
464
462
  }
@@ -564,6 +562,19 @@ class Render {
564
562
  placeholder.remove();
565
563
  }
566
564
  }
565
+ if (selectedOptions.length > this.settings.maxValuesShown) {
566
+ const singleValue = document.createElement('div');
567
+ singleValue.classList.add(this.classes.max);
568
+ singleValue.textContent = this.settings.maxValuesMessage.replace('{number}', selectedOptions.length.toString());
569
+ this.main.values.innerHTML = singleValue.outerHTML;
570
+ return;
571
+ }
572
+ else {
573
+ const maxValuesMessage = this.main.values.querySelector('.' + this.classes.max);
574
+ if (maxValuesMessage) {
575
+ maxValuesMessage.remove();
576
+ }
577
+ }
567
578
  let removeNodes = [];
568
579
  for (let i = 0; i < currentNodes.length; i++) {
569
580
  const node = currentNodes[i];
@@ -618,6 +629,9 @@ class Render {
618
629
  deleteDiv.onclick = (e) => {
619
630
  e.preventDefault();
620
631
  e.stopPropagation();
632
+ if (this.settings.disabled) {
633
+ return;
634
+ }
621
635
  let shouldDelete = true;
622
636
  const before = this.store.getSelectedOptions();
623
637
  const after = before.filter((o) => {
@@ -641,7 +655,7 @@ class Render {
641
655
  selectedValues.push(o.value);
642
656
  }
643
657
  }
644
- this.callbacks.setSelected(selectedValues);
658
+ this.callbacks.setSelected(selectedValues, false);
645
659
  if (this.settings.closeOnSelect) {
646
660
  this.callbacks.close();
647
661
  }
@@ -662,21 +676,7 @@ class Render {
662
676
  }
663
677
  contentDiv() {
664
678
  const main = document.createElement('div');
665
- main.classList.add(this.classes.content);
666
679
  main.dataset.id = this.settings.id;
667
- if (this.settings.style !== '') {
668
- main.style.cssText = this.settings.style;
669
- }
670
- if (this.settings.contentPosition === 'relative') {
671
- main.classList.add('ss-' + this.settings.contentPosition);
672
- }
673
- if (this.settings.class.length) {
674
- for (const c of this.settings.class) {
675
- if (c.trim() !== '') {
676
- main.classList.add(c.trim());
677
- }
678
- }
679
- }
680
680
  const search = this.searchDiv();
681
681
  main.appendChild(search.main);
682
682
  const list = this.listDiv();
@@ -689,12 +689,23 @@ class Render {
689
689
  }
690
690
  moveContent() {
691
691
  if (this.settings.contentPosition === 'relative') {
692
+ this.moveContentBelow();
692
693
  return;
693
694
  }
694
- const containerRect = this.main.main.getBoundingClientRect();
695
- this.content.main.style.top = containerRect.top + containerRect.height + window.scrollY + 'px';
696
- this.content.main.style.left = containerRect.left + window.scrollX + 'px';
697
- this.content.main.style.width = containerRect.width + 'px';
695
+ if (this.settings.openPosition === 'down') {
696
+ this.moveContentBelow();
697
+ return;
698
+ }
699
+ else if (this.settings.openPosition === 'up') {
700
+ this.moveContentAbove();
701
+ return;
702
+ }
703
+ if (this.putContent() === 'up') {
704
+ this.moveContentAbove();
705
+ }
706
+ else {
707
+ this.moveContentBelow();
708
+ }
698
709
  }
699
710
  searchDiv() {
700
711
  const main = document.createElement('div');
@@ -777,10 +788,10 @@ class Render {
777
788
  if (this.settings.isMultiple) {
778
789
  let values = this.store.getSelected();
779
790
  values.push(newOption.value);
780
- this.callbacks.setSelected(values);
791
+ this.callbacks.setSelected(values, true);
781
792
  }
782
793
  else {
783
- this.callbacks.setSelected([newOption.value]);
794
+ this.callbacks.setSelected([newOption.value], true);
784
795
  }
785
796
  this.callbacks.search('');
786
797
  if (this.settings.closeOnSelect) {
@@ -905,8 +916,7 @@ class Render {
905
916
  this.content.list.innerHTML = '';
906
917
  if (data.length === 0) {
907
918
  const noResults = document.createElement('div');
908
- noResults.classList.add(this.classes.option);
909
- noResults.classList.add(this.classes.disabled);
919
+ noResults.classList.add(this.classes.search);
910
920
  noResults.innerHTML = this.settings.searchText;
911
921
  this.content.list.appendChild(noResults);
912
922
  return;
@@ -963,12 +973,12 @@ class Render {
963
973
  }
964
974
  return true;
965
975
  });
966
- this.callbacks.setSelected(newSelected);
976
+ this.callbacks.setSelected(newSelected, true);
967
977
  return;
968
978
  }
969
979
  else {
970
980
  const newSelected = currentSelected.concat(d.options.map((o) => o.value));
971
- this.callbacks.setSelected(newSelected);
981
+ this.callbacks.setSelected(newSelected, true);
972
982
  }
973
983
  });
974
984
  optgroupActions.appendChild(selectAll);
@@ -982,7 +992,7 @@ class Render {
982
992
  optgroupClosable.appendChild(optgroupClosableSvg);
983
993
  const optgroupClosableArrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
984
994
  optgroupClosableSvg.appendChild(optgroupClosableArrow);
985
- if (d.options.some((o) => o.selected)) {
995
+ if (d.options.some((o) => o.selected) || this.content.search.input.value.trim() !== '') {
986
996
  optgroupClosable.classList.add(this.classes.open);
987
997
  optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen);
988
998
  }
@@ -1041,8 +1051,7 @@ class Render {
1041
1051
  optionEl.style.cssText = option.style;
1042
1052
  }
1043
1053
  if (this.settings.searchHighlight && this.content.search.input.value.trim() !== '') {
1044
- const textOrHtml = option.html !== '' ? option.html : option.text;
1045
- optionEl.innerHTML = this.highlightText(textOrHtml, this.content.search.input.value, this.classes.searchHighlighter);
1054
+ optionEl.innerHTML = this.highlightText(option.html !== '' ? option.html : option.text, this.content.search.input.value, this.classes.searchHighlighter);
1046
1055
  }
1047
1056
  else if (option.html !== '') {
1048
1057
  optionEl.innerHTML = option.html;
@@ -1053,7 +1062,10 @@ class Render {
1053
1062
  if (this.settings.showOptionTooltips && optionEl.textContent) {
1054
1063
  optionEl.setAttribute('title', optionEl.textContent);
1055
1064
  }
1056
- if ((option.selected && !this.settings.allowDeselect) || (option.disabled && !this.settings.allowDeselect)) {
1065
+ if (!option.display) {
1066
+ optionEl.classList.add(this.classes.hide);
1067
+ }
1068
+ if (option.disabled) {
1057
1069
  optionEl.classList.add(this.classes.disabled);
1058
1070
  }
1059
1071
  if (option.selected && this.settings.hideSelected) {
@@ -1074,9 +1086,8 @@ class Render {
1074
1086
  if (option.disabled || (option.selected && !this.settings.allowDeselect)) {
1075
1087
  return;
1076
1088
  }
1077
- if (this.settings.isMultiple &&
1078
- Array.isArray(selectedOptions) &&
1079
- this.settings.maxSelected <= selectedOptions.length) {
1089
+ if ((this.settings.isMultiple && this.settings.maxSelected <= selectedOptions.length && !option.selected) ||
1090
+ (this.settings.isMultiple && this.settings.minSelected >= selectedOptions.length && option.selected)) {
1080
1091
  return;
1081
1092
  }
1082
1093
  let shouldUpdate = false;
@@ -1113,7 +1124,7 @@ class Render {
1113
1124
  if (!this.store.getOptionByID(elementID)) {
1114
1125
  this.callbacks.addOption(option);
1115
1126
  }
1116
- this.callbacks.setSelected(after.map((o) => o.value));
1127
+ this.callbacks.setSelected(after.map((o) => o.value), false);
1117
1128
  if (this.settings.closeOnSelect) {
1118
1129
  this.callbacks.close();
1119
1130
  }
@@ -1141,23 +1152,30 @@ class Render {
1141
1152
  return completedString;
1142
1153
  }
1143
1154
  moveContentAbove() {
1144
- let mainHeight = this.main.main.offsetHeight;
1155
+ const mainHeight = this.main.main.offsetHeight;
1145
1156
  const contentHeight = this.content.main.offsetHeight;
1146
- const height = mainHeight + contentHeight - 1;
1147
- this.content.main.style.margin = '-' + height + 'px 0px 0px 0px';
1148
- this.content.main.style.transformOrigin = 'center bottom';
1149
1157
  this.main.main.classList.remove(this.classes.openBelow);
1150
1158
  this.main.main.classList.add(this.classes.openAbove);
1151
1159
  this.content.main.classList.remove(this.classes.openBelow);
1152
1160
  this.content.main.classList.add(this.classes.openAbove);
1161
+ const containerRect = this.main.main.getBoundingClientRect();
1162
+ this.content.main.style.margin = '-' + (mainHeight + contentHeight - 1) + 'px 0px 0px 0px';
1163
+ this.content.main.style.top = containerRect.top + containerRect.height + window.scrollY + 'px';
1164
+ this.content.main.style.left = containerRect.left + window.scrollX + 'px';
1165
+ this.content.main.style.width = containerRect.width + 'px';
1153
1166
  }
1154
1167
  moveContentBelow() {
1155
- this.content.main.style.margin = '-1px 0px 0px 0px';
1156
- this.content.main.style.transformOrigin = 'center top';
1157
1168
  this.main.main.classList.remove(this.classes.openAbove);
1158
1169
  this.main.main.classList.add(this.classes.openBelow);
1159
1170
  this.content.main.classList.remove(this.classes.openAbove);
1160
1171
  this.content.main.classList.add(this.classes.openBelow);
1172
+ const containerRect = this.main.main.getBoundingClientRect();
1173
+ this.content.main.style.margin = '-1px 0px 0px 0px';
1174
+ if (this.settings.contentPosition !== 'relative') {
1175
+ this.content.main.style.top = containerRect.top + containerRect.height + window.scrollY + 'px';
1176
+ this.content.main.style.left = containerRect.left + window.scrollX + 'px';
1177
+ this.content.main.style.width = containerRect.width + 'px';
1178
+ }
1161
1179
  }
1162
1180
  ensureElementInView(container, element) {
1163
1181
  const cTop = container.scrollTop + container.offsetTop;
@@ -1171,16 +1189,18 @@ class Render {
1171
1189
  container.scrollTop += eBottom - cBottom;
1172
1190
  }
1173
1191
  }
1174
- putContent(el, isOpen) {
1175
- const height = el.offsetHeight;
1176
- const rect = el.getBoundingClientRect();
1177
- const elemTop = isOpen ? rect.top : rect.top - height;
1178
- const elemBottom = isOpen ? rect.bottom : rect.bottom + height;
1179
- if (elemTop <= 0) {
1180
- return 'down';
1181
- }
1182
- if (elemBottom >= window.innerHeight) {
1183
- return 'up';
1192
+ putContent() {
1193
+ const mainHeight = this.main.main.offsetHeight;
1194
+ const mainRect = this.main.main.getBoundingClientRect();
1195
+ const contentHeight = this.content.main.offsetHeight;
1196
+ const spaceBelow = window.innerHeight - (mainRect.top + mainHeight);
1197
+ if (spaceBelow <= contentHeight) {
1198
+ if (mainRect.top > contentHeight) {
1199
+ return 'up';
1200
+ }
1201
+ else {
1202
+ return 'down';
1203
+ }
1184
1204
  }
1185
1205
  return 'down';
1186
1206
  }
@@ -1191,16 +1211,17 @@ class Select {
1191
1211
  this.listen = false;
1192
1212
  this.observer = null;
1193
1213
  this.select = select;
1214
+ this.select.addEventListener('change', this.valueChange.bind(this), {
1215
+ passive: true,
1216
+ });
1217
+ this.observer = new MutationObserver(this.observeCall.bind(this));
1218
+ this.changeListen(true);
1194
1219
  }
1195
1220
  enable() {
1196
- this.disconnectObserver();
1197
1221
  this.select.disabled = false;
1198
- this.connectObserver();
1199
1222
  }
1200
1223
  disable() {
1201
- this.disconnectObserver();
1202
1224
  this.select.disabled = true;
1203
- this.connectObserver();
1204
1225
  }
1205
1226
  hideUI() {
1206
1227
  this.select.tabIndex = -1;
@@ -1212,65 +1233,61 @@ class Select {
1212
1233
  this.select.style.display = '';
1213
1234
  this.select.removeAttribute('aria-hidden');
1214
1235
  }
1215
- changeListen(on) {
1216
- this.listen = on;
1217
- if (this.listen) {
1218
- this.connectObserver();
1236
+ changeListen(listen) {
1237
+ this.listen = listen;
1238
+ if (listen) {
1239
+ if (this.observer) {
1240
+ this.observer.observe(this.select, {
1241
+ subtree: true,
1242
+ childList: true,
1243
+ attributes: true,
1244
+ });
1245
+ }
1219
1246
  }
1220
- else {
1221
- this.disconnectObserver();
1247
+ if (!listen) {
1248
+ if (this.observer) {
1249
+ this.observer.disconnect();
1250
+ }
1222
1251
  }
1223
1252
  }
1224
- addSelectChangeListener(func) {
1225
- this.onSelectChange = func;
1226
- this.addObserver();
1227
- this.connectObserver();
1228
- this.changeListen(true);
1229
- }
1230
- removeSelectChangeListener() {
1231
- this.changeListen(false);
1232
- this.onSelectChange = undefined;
1233
- }
1234
- addValueChangeListener(func) {
1235
- this.onValueChange = func;
1236
- this.select.addEventListener('change', this.valueChange.bind(this), {
1237
- passive: true,
1238
- });
1239
- }
1240
- removeValueChangeListener() {
1241
- this.onValueChange = undefined;
1242
- this.select.removeEventListener('change', this.valueChange.bind(this));
1243
- }
1244
1253
  valueChange(ev) {
1245
1254
  if (this.listen && this.onValueChange) {
1246
1255
  this.onValueChange(this.getSelectedValues());
1247
1256
  }
1248
1257
  return true;
1249
1258
  }
1250
- observeWrapper(mutations) {
1251
- if (this.onSelectChange) {
1252
- this.changeListen(false);
1253
- this.onSelectChange(this.getData());
1254
- this.changeListen(true);
1259
+ observeCall(mutations) {
1260
+ if (!this.listen) {
1261
+ return;
1255
1262
  }
1256
- }
1257
- addObserver() {
1258
- if (this.observer) {
1259
- this.disconnectObserver();
1260
- this.observer = null;
1263
+ let classChanged = false;
1264
+ let disabledChanged = false;
1265
+ let optgroupOptionChanged = false;
1266
+ for (const m of mutations) {
1267
+ if (m.target === this.select) {
1268
+ if (m.attributeName === 'disabled') {
1269
+ disabledChanged = true;
1270
+ }
1271
+ if (m.attributeName === 'class') {
1272
+ classChanged = true;
1273
+ }
1274
+ }
1275
+ if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {
1276
+ optgroupOptionChanged = true;
1277
+ }
1261
1278
  }
1262
- this.observer = new MutationObserver(this.observeWrapper.bind(this));
1263
- }
1264
- connectObserver() {
1265
- if (this.observer) {
1266
- this.observer.observe(this.select, {
1267
- childList: true,
1268
- });
1279
+ if (classChanged && this.onClassChange) {
1280
+ this.onClassChange(this.select.className.split(' '));
1269
1281
  }
1270
- }
1271
- disconnectObserver() {
1272
- if (this.observer) {
1273
- this.observer.disconnect();
1282
+ if (disabledChanged && this.onDisabledChange) {
1283
+ this.changeListen(false);
1284
+ this.onDisabledChange(this.select.disabled);
1285
+ this.changeListen(true);
1286
+ }
1287
+ if (optgroupOptionChanged && this.onOptionsChange) {
1288
+ this.changeListen(false);
1289
+ this.onOptionsChange(this.getData());
1290
+ this.changeListen(true);
1274
1291
  }
1275
1292
  }
1276
1293
  getData() {
@@ -1288,7 +1305,7 @@ class Select {
1288
1305
  }
1289
1306
  getDataFromOptgroup(optgroup) {
1290
1307
  let data = {
1291
- id: (optgroup.dataset ? optgroup.dataset.id : false) || '',
1308
+ id: optgroup.id,
1292
1309
  label: optgroup.label,
1293
1310
  selectAll: optgroup.dataset ? optgroup.dataset.selectall === 'true' : false,
1294
1311
  closable: optgroup.dataset ? optgroup.dataset.closable : 'off',
@@ -1304,10 +1321,10 @@ class Select {
1304
1321
  }
1305
1322
  getDataFromOption(option) {
1306
1323
  return {
1307
- id: (option.dataset ? option.dataset.id : false) || '',
1324
+ id: option.id,
1308
1325
  value: option.value,
1309
1326
  text: option.text,
1310
- html: option.innerHTML,
1327
+ html: option.dataset && option.dataset.html ? option.dataset.html : '',
1311
1328
  selected: option.selected,
1312
1329
  display: option.style.display === 'none' ? false : true,
1313
1330
  disabled: option.disabled,
@@ -1343,6 +1360,7 @@ class Select {
1343
1360
  return values;
1344
1361
  }
1345
1362
  setSelected(value) {
1363
+ this.changeListen(false);
1346
1364
  const options = this.select.childNodes;
1347
1365
  for (const o of options) {
1348
1366
  if (o.nodeName === 'OPTGROUP') {
@@ -1360,11 +1378,12 @@ class Select {
1360
1378
  option.selected = value.includes(option.value);
1361
1379
  }
1362
1380
  }
1381
+ this.changeListen(true);
1363
1382
  }
1364
1383
  updateSelect(id, style, classes) {
1365
1384
  this.changeListen(false);
1366
1385
  if (id) {
1367
- this.select.id = id;
1386
+ this.select.dataset.id = id;
1368
1387
  }
1369
1388
  if (style) {
1370
1389
  this.select.style.cssText = style;
@@ -1412,8 +1431,12 @@ class Select {
1412
1431
  }
1413
1432
  createOption(info) {
1414
1433
  const optionEl = document.createElement('option');
1415
- optionEl.value = info.value !== '' ? info.value : info.text;
1416
- optionEl.innerHTML = info.html || info.text;
1434
+ optionEl.id = info.id;
1435
+ optionEl.value = info.value;
1436
+ optionEl.innerHTML = info.text;
1437
+ if (info.html !== '') {
1438
+ optionEl.setAttribute('data-html', info.html);
1439
+ }
1417
1440
  if (info.selected) {
1418
1441
  optionEl.selected = info.selected;
1419
1442
  }
@@ -1443,15 +1466,19 @@ class Select {
1443
1466
  }
1444
1467
  destroy() {
1445
1468
  this.changeListen(false);
1446
- this.disconnectObserver();
1447
- this.removeSelectChangeListener();
1448
- this.removeValueChangeListener();
1469
+ this.select.removeEventListener('change', this.valueChange.bind(this));
1470
+ if (this.observer) {
1471
+ this.observer.disconnect();
1472
+ this.observer = null;
1473
+ }
1474
+ delete this.select.dataset.id;
1449
1475
  this.showUI();
1450
1476
  }
1451
1477
  }
1452
1478
 
1453
1479
  class SlimSelect {
1454
1480
  constructor(config) {
1481
+ var _a;
1455
1482
  this.events = {
1456
1483
  search: undefined,
1457
1484
  searchFilter: (opt, search) => {
@@ -1475,23 +1502,7 @@ class SlimSelect {
1475
1502
  if (!this.settings.isOpen) {
1476
1503
  return;
1477
1504
  }
1478
- if (this.settings.openPosition === 'down') {
1479
- this.render.moveContentBelow();
1480
- return;
1481
- }
1482
- else if (this.settings.openPosition === 'up') {
1483
- this.render.moveContentAbove();
1484
- return;
1485
- }
1486
- if (this.settings.contentPosition === 'relative') {
1487
- this.render.moveContentBelow();
1488
- }
1489
- else if (this.render.putContent(this.render.content.main, this.settings.isOpen) === 'up') {
1490
- this.render.moveContentAbove();
1491
- }
1492
- else {
1493
- this.render.moveContentBelow();
1494
- }
1505
+ this.render.moveContent();
1495
1506
  });
1496
1507
  this.documentClick = (e) => {
1497
1508
  if (!this.settings.isOpen) {
@@ -1523,18 +1534,31 @@ class SlimSelect {
1523
1534
  this.events[key] = config.events[key];
1524
1535
  }
1525
1536
  }
1537
+ this.settings.disabled = ((_a = config.settings) === null || _a === void 0 ? void 0 : _a.disabled) ? config.settings.disabled : this.selectEl.disabled;
1526
1538
  this.settings.isMultiple = this.selectEl.multiple;
1527
1539
  this.settings.style = this.selectEl.style.cssText;
1528
1540
  this.settings.class = this.selectEl.className.split(' ');
1529
1541
  this.select = new Select(this.selectEl);
1530
1542
  this.select.updateSelect(this.settings.id, this.settings.style, this.settings.class);
1531
1543
  this.select.hideUI();
1532
- this.select.addSelectChangeListener((data) => {
1533
- this.setData(data);
1534
- });
1535
- this.select.addValueChangeListener((values) => {
1544
+ this.select.onValueChange = (values) => {
1536
1545
  this.setSelected(values);
1537
- });
1546
+ };
1547
+ this.select.onClassChange = (classes) => {
1548
+ this.settings.class = classes;
1549
+ this.render.updateClassStyles();
1550
+ };
1551
+ this.select.onDisabledChange = (disabled) => {
1552
+ if (disabled) {
1553
+ this.disable();
1554
+ }
1555
+ else {
1556
+ this.enable();
1557
+ }
1558
+ };
1559
+ this.select.onOptionsChange = (data) => {
1560
+ this.setData(data);
1561
+ };
1538
1562
  this.store = new Store(this.settings.isMultiple ? 'multiple' : 'single', config.data ? config.data : this.select.getData());
1539
1563
  if (config.data) {
1540
1564
  this.select.updateOptions(this.store.getData());
@@ -1560,7 +1584,7 @@ class SlimSelect {
1560
1584
  if (this.settings.openPosition === 'auto') {
1561
1585
  window.addEventListener('scroll', this.windowScroll, false);
1562
1586
  }
1563
- if (!this.settings.isEnabled) {
1587
+ if (this.settings.disabled) {
1564
1588
  this.disable();
1565
1589
  }
1566
1590
  if (this.settings.alwaysOpen) {
@@ -1569,12 +1593,12 @@ class SlimSelect {
1569
1593
  this.selectEl.slim = this;
1570
1594
  }
1571
1595
  enable() {
1572
- this.settings.isEnabled = true;
1596
+ this.settings.disabled = false;
1573
1597
  this.select.enable();
1574
1598
  this.render.enable();
1575
1599
  }
1576
1600
  disable() {
1577
- this.settings.isEnabled = false;
1601
+ this.settings.disabled = true;
1578
1602
  this.select.disable();
1579
1603
  this.render.disable();
1580
1604
  }
@@ -1602,14 +1626,19 @@ class SlimSelect {
1602
1626
  getSelected() {
1603
1627
  return this.store.getSelected();
1604
1628
  }
1605
- setSelected(value) {
1629
+ setSelected(value, runAfterChange = true) {
1606
1630
  const selected = this.store.getSelected();
1607
1631
  this.store.setSelectedBy('value', Array.isArray(value) ? value : [value]);
1608
1632
  const data = this.store.getData();
1609
1633
  this.select.updateOptions(data);
1610
1634
  this.render.renderValues();
1611
- this.render.renderOptions(data);
1612
- if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1635
+ if (this.render.content.search.input.value !== '') {
1636
+ this.search(this.render.content.search.input.value);
1637
+ }
1638
+ else {
1639
+ this.render.renderOptions(data);
1640
+ }
1641
+ if (runAfterChange && this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1613
1642
  this.events.afterChange(this.store.getSelectedOptions());
1614
1643
  }
1615
1644
  }
@@ -1625,7 +1654,7 @@ class SlimSelect {
1625
1654
  }
1626
1655
  }
1627
1656
  open() {
1628
- if (!this.settings.isEnabled || this.settings.isOpen) {
1657
+ if (this.settings.disabled || this.settings.isOpen) {
1629
1658
  return;
1630
1659
  }
1631
1660
  if (this.events.beforeOpen) {
@@ -1641,10 +1670,12 @@ class SlimSelect {
1641
1670
  }
1642
1671
  this.settings.isOpen = true;
1643
1672
  }, this.settings.timeoutDelay);
1644
- if (this.settings.intervalMove) {
1645
- clearInterval(this.settings.intervalMove);
1673
+ if (this.settings.contentPosition === 'absolute') {
1674
+ if (this.settings.intervalMove) {
1675
+ clearInterval(this.settings.intervalMove);
1676
+ }
1677
+ this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1646
1678
  }
1647
- this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1648
1679
  }
1649
1680
  close() {
1650
1681
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
@@ -1654,7 +1685,9 @@ class SlimSelect {
1654
1685
  this.events.beforeClose();
1655
1686
  }
1656
1687
  this.render.close();
1657
- this.search('');
1688
+ if (this.render.content.search.input.value !== '') {
1689
+ this.search('');
1690
+ }
1658
1691
  this.render.mainFocus(false);
1659
1692
  setTimeout(() => {
1660
1693
  if (this.events.afterClose) {
@@ -1760,7 +1793,7 @@ var script = vue.defineComponent({
1760
1793
  this.slim = new SlimSelect(config);
1761
1794
  let selected = this.$props.multiple ? this.slim.getSelected() : this.slim.getSelected()[0];
1762
1795
  if (this.value !== selected) {
1763
- this.value = selected;
1796
+ this.slim.setSelected(this.value);
1764
1797
  }
1765
1798
  },
1766
1799
  beforeUnmount() {
@@ -1769,6 +1802,13 @@ var script = vue.defineComponent({
1769
1802
  }
1770
1803
  },
1771
1804
  watch: {
1805
+ modelValue: {
1806
+ handler: function (newVal) {
1807
+ var _a;
1808
+ (_a = this.slim) === null || _a === void 0 ? void 0 : _a.setSelected(this.getCleanValue(newVal));
1809
+ },
1810
+ immediate: true,
1811
+ },
1772
1812
  data: {
1773
1813
  handler: function (newData) {
1774
1814
  if (this.slim) {
@@ -1781,18 +1821,7 @@ var script = vue.defineComponent({
1781
1821
  computed: {
1782
1822
  value: {
1783
1823
  get() {
1784
- const multi = this.$props.multiple;
1785
- const val = this.$props.modelValue;
1786
- if (val === undefined) {
1787
- return multi ? [] : '';
1788
- }
1789
- if (multi && typeof val === 'string') {
1790
- return [val];
1791
- }
1792
- if (!multi && Array.isArray(val)) {
1793
- return val[0];
1794
- }
1795
- return multi ? [] : '';
1824
+ return this.getCleanValue(this.$props.modelValue);
1796
1825
  },
1797
1826
  set(value) {
1798
1827
  this.$emit('update:modelValue', value);
@@ -1803,6 +1832,16 @@ var script = vue.defineComponent({
1803
1832
  getSlimSelect() {
1804
1833
  return this.slim;
1805
1834
  },
1835
+ getCleanValue(val) {
1836
+ const multi = this.$props.multiple;
1837
+ if (typeof val === 'string') {
1838
+ return multi ? [val] : val;
1839
+ }
1840
+ if (Array.isArray(val)) {
1841
+ return multi ? val : val[0];
1842
+ }
1843
+ return multi ? [] : '';
1844
+ },
1806
1845
  },
1807
1846
  });
1808
1847