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.
@@ -67,7 +67,7 @@ class Settings {
67
67
  this.id = 'ss-' + generateID();
68
68
  this.style = settings.style || '';
69
69
  this.class = settings.class || [];
70
- this.isEnabled = settings.isEnabled !== undefined ? settings.isEnabled : true;
70
+ this.disabled = settings.disabled !== undefined ? settings.disabled : false;
71
71
  this.alwaysOpen = settings.alwaysOpen !== undefined ? settings.alwaysOpen : false;
72
72
  this.showSearch = settings.showSearch !== undefined ? settings.showSearch : true;
73
73
  this.searchPlaceholder = settings.searchPlaceholder || 'Search';
@@ -85,6 +85,8 @@ class Settings {
85
85
  this.minSelected = settings.minSelected || 0;
86
86
  this.maxSelected = settings.maxSelected || 1000;
87
87
  this.timeoutDelay = settings.timeoutDelay || 200;
88
+ this.maxValuesShown = settings.maxValuesShown || 20;
89
+ this.maxValuesMessage = settings.maxValuesMessage || '{number} selected';
88
90
  }
89
91
  }
90
92
 
@@ -301,6 +303,7 @@ class Render {
301
303
  placeholder: 'ss-placeholder',
302
304
  values: 'ss-values',
303
305
  single: 'ss-single',
306
+ max: 'ss-max',
304
307
  value: 'ss-value',
305
308
  valueText: 'ss-value-text',
306
309
  valueDelete: 'ss-value-delete',
@@ -342,6 +345,7 @@ class Render {
342
345
  this.callbacks = callbacks;
343
346
  this.main = this.mainDiv();
344
347
  this.content = this.contentDiv();
348
+ this.updateClassStyles();
345
349
  this.settings.contentLocation.appendChild(this.content.main);
346
350
  }
347
351
  enable() {
@@ -356,24 +360,6 @@ class Render {
356
360
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
357
361
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
358
362
  this.moveContent();
359
- this.renderOptions(this.store.getData());
360
- if (this.settings.contentPosition === 'relative') {
361
- this.moveContentBelow();
362
- }
363
- else if (this.settings.openPosition.toLowerCase() === 'up') {
364
- this.moveContentAbove();
365
- }
366
- else if (this.settings.openPosition.toLowerCase() === 'down') {
367
- this.moveContentBelow();
368
- }
369
- else {
370
- if (this.putContent(this.content.main, this.settings.isOpen) === 'up') {
371
- this.moveContentAbove();
372
- }
373
- else {
374
- this.moveContentBelow();
375
- }
376
- }
377
363
  const selectedOptions = this.store.getSelectedOptions();
378
364
  if (selectedOptions.length) {
379
365
  const selectedId = selectedOptions[selectedOptions.length - 1].id;
@@ -390,20 +376,32 @@ class Render {
390
376
  this.content.main.classList.remove(this.classes.openBelow);
391
377
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
392
378
  }
393
- mainDiv() {
394
- const main = document.createElement('div');
395
- main.tabIndex = 0;
396
- main.style.cssText = this.settings.style !== '' ? this.settings.style : '';
397
- main.className = '';
398
- main.classList.add(this.settings.id);
399
- main.classList.add(this.classes.main);
400
- if (this.settings.class) {
379
+ updateClassStyles() {
380
+ this.main.main.className = '';
381
+ this.main.main.removeAttribute('style');
382
+ this.content.main.className = '';
383
+ this.content.main.removeAttribute('style');
384
+ this.main.main.classList.add(this.classes.main);
385
+ this.content.main.classList.add(this.classes.content);
386
+ if (this.settings.style !== '') {
387
+ this.content.main.style.cssText = this.settings.style;
388
+ }
389
+ if (this.settings.class.length) {
401
390
  for (const c of this.settings.class) {
402
391
  if (c.trim() !== '') {
403
- main.classList.add(c.trim());
392
+ this.main.main.classList.add(c.trim());
393
+ this.content.main.classList.add(c.trim());
404
394
  }
405
395
  }
406
396
  }
397
+ if (this.settings.contentPosition === 'relative') {
398
+ this.content.main.classList.add('ss-' + this.settings.contentPosition);
399
+ }
400
+ }
401
+ mainDiv() {
402
+ const main = document.createElement('div');
403
+ main.dataset.id = this.settings.id;
404
+ main.tabIndex = 0;
407
405
  main.onfocus = () => {
408
406
  if (this.settings.triggerFocus) {
409
407
  this.callbacks.open();
@@ -431,7 +429,7 @@ class Render {
431
429
  }
432
430
  };
433
431
  main.onclick = (e) => {
434
- if (!this.settings.isEnabled) {
432
+ if (this.settings.disabled) {
435
433
  return;
436
434
  }
437
435
  this.settings.isOpen ? this.callbacks.close() : this.callbacks.open();
@@ -446,7 +444,7 @@ class Render {
446
444
  }
447
445
  deselect.onclick = (e) => {
448
446
  e.stopPropagation();
449
- if (!this.settings.isEnabled) {
447
+ if (this.settings.disabled) {
450
448
  return;
451
449
  }
452
450
  let shouldDelete = true;
@@ -456,7 +454,7 @@ class Render {
456
454
  shouldDelete = this.callbacks.beforeChange(after, before) === true;
457
455
  }
458
456
  if (shouldDelete) {
459
- this.callbacks.setSelected(['']);
457
+ this.callbacks.setSelected([''], false);
460
458
  if (this.settings.closeOnSelect) {
461
459
  this.callbacks.close();
462
460
  }
@@ -562,6 +560,19 @@ class Render {
562
560
  placeholder.remove();
563
561
  }
564
562
  }
563
+ if (selectedOptions.length > this.settings.maxValuesShown) {
564
+ const singleValue = document.createElement('div');
565
+ singleValue.classList.add(this.classes.max);
566
+ singleValue.textContent = this.settings.maxValuesMessage.replace('{number}', selectedOptions.length.toString());
567
+ this.main.values.innerHTML = singleValue.outerHTML;
568
+ return;
569
+ }
570
+ else {
571
+ const maxValuesMessage = this.main.values.querySelector('.' + this.classes.max);
572
+ if (maxValuesMessage) {
573
+ maxValuesMessage.remove();
574
+ }
575
+ }
565
576
  let removeNodes = [];
566
577
  for (let i = 0; i < currentNodes.length; i++) {
567
578
  const node = currentNodes[i];
@@ -616,6 +627,9 @@ class Render {
616
627
  deleteDiv.onclick = (e) => {
617
628
  e.preventDefault();
618
629
  e.stopPropagation();
630
+ if (this.settings.disabled) {
631
+ return;
632
+ }
619
633
  let shouldDelete = true;
620
634
  const before = this.store.getSelectedOptions();
621
635
  const after = before.filter((o) => {
@@ -639,7 +653,7 @@ class Render {
639
653
  selectedValues.push(o.value);
640
654
  }
641
655
  }
642
- this.callbacks.setSelected(selectedValues);
656
+ this.callbacks.setSelected(selectedValues, false);
643
657
  if (this.settings.closeOnSelect) {
644
658
  this.callbacks.close();
645
659
  }
@@ -660,21 +674,7 @@ class Render {
660
674
  }
661
675
  contentDiv() {
662
676
  const main = document.createElement('div');
663
- main.classList.add(this.classes.content);
664
677
  main.dataset.id = this.settings.id;
665
- if (this.settings.style !== '') {
666
- main.style.cssText = this.settings.style;
667
- }
668
- if (this.settings.contentPosition === 'relative') {
669
- main.classList.add('ss-' + this.settings.contentPosition);
670
- }
671
- if (this.settings.class.length) {
672
- for (const c of this.settings.class) {
673
- if (c.trim() !== '') {
674
- main.classList.add(c.trim());
675
- }
676
- }
677
- }
678
678
  const search = this.searchDiv();
679
679
  main.appendChild(search.main);
680
680
  const list = this.listDiv();
@@ -687,12 +687,23 @@ class Render {
687
687
  }
688
688
  moveContent() {
689
689
  if (this.settings.contentPosition === 'relative') {
690
+ this.moveContentBelow();
690
691
  return;
691
692
  }
692
- const containerRect = this.main.main.getBoundingClientRect();
693
- this.content.main.style.top = containerRect.top + containerRect.height + window.scrollY + 'px';
694
- this.content.main.style.left = containerRect.left + window.scrollX + 'px';
695
- this.content.main.style.width = containerRect.width + 'px';
693
+ if (this.settings.openPosition === 'down') {
694
+ this.moveContentBelow();
695
+ return;
696
+ }
697
+ else if (this.settings.openPosition === 'up') {
698
+ this.moveContentAbove();
699
+ return;
700
+ }
701
+ if (this.putContent() === 'up') {
702
+ this.moveContentAbove();
703
+ }
704
+ else {
705
+ this.moveContentBelow();
706
+ }
696
707
  }
697
708
  searchDiv() {
698
709
  const main = document.createElement('div');
@@ -775,10 +786,10 @@ class Render {
775
786
  if (this.settings.isMultiple) {
776
787
  let values = this.store.getSelected();
777
788
  values.push(newOption.value);
778
- this.callbacks.setSelected(values);
789
+ this.callbacks.setSelected(values, true);
779
790
  }
780
791
  else {
781
- this.callbacks.setSelected([newOption.value]);
792
+ this.callbacks.setSelected([newOption.value], true);
782
793
  }
783
794
  this.callbacks.search('');
784
795
  if (this.settings.closeOnSelect) {
@@ -903,8 +914,7 @@ class Render {
903
914
  this.content.list.innerHTML = '';
904
915
  if (data.length === 0) {
905
916
  const noResults = document.createElement('div');
906
- noResults.classList.add(this.classes.option);
907
- noResults.classList.add(this.classes.disabled);
917
+ noResults.classList.add(this.classes.search);
908
918
  noResults.innerHTML = this.settings.searchText;
909
919
  this.content.list.appendChild(noResults);
910
920
  return;
@@ -961,12 +971,12 @@ class Render {
961
971
  }
962
972
  return true;
963
973
  });
964
- this.callbacks.setSelected(newSelected);
974
+ this.callbacks.setSelected(newSelected, true);
965
975
  return;
966
976
  }
967
977
  else {
968
978
  const newSelected = currentSelected.concat(d.options.map((o) => o.value));
969
- this.callbacks.setSelected(newSelected);
979
+ this.callbacks.setSelected(newSelected, true);
970
980
  }
971
981
  });
972
982
  optgroupActions.appendChild(selectAll);
@@ -980,7 +990,7 @@ class Render {
980
990
  optgroupClosable.appendChild(optgroupClosableSvg);
981
991
  const optgroupClosableArrow = document.createElementNS('http://www.w3.org/2000/svg', 'path');
982
992
  optgroupClosableSvg.appendChild(optgroupClosableArrow);
983
- if (d.options.some((o) => o.selected)) {
993
+ if (d.options.some((o) => o.selected) || this.content.search.input.value.trim() !== '') {
984
994
  optgroupClosable.classList.add(this.classes.open);
985
995
  optgroupClosableArrow.setAttribute('d', this.classes.arrowOpen);
986
996
  }
@@ -1039,8 +1049,7 @@ class Render {
1039
1049
  optionEl.style.cssText = option.style;
1040
1050
  }
1041
1051
  if (this.settings.searchHighlight && this.content.search.input.value.trim() !== '') {
1042
- const textOrHtml = option.html !== '' ? option.html : option.text;
1043
- optionEl.innerHTML = this.highlightText(textOrHtml, this.content.search.input.value, this.classes.searchHighlighter);
1052
+ optionEl.innerHTML = this.highlightText(option.html !== '' ? option.html : option.text, this.content.search.input.value, this.classes.searchHighlighter);
1044
1053
  }
1045
1054
  else if (option.html !== '') {
1046
1055
  optionEl.innerHTML = option.html;
@@ -1051,7 +1060,10 @@ class Render {
1051
1060
  if (this.settings.showOptionTooltips && optionEl.textContent) {
1052
1061
  optionEl.setAttribute('title', optionEl.textContent);
1053
1062
  }
1054
- if ((option.selected && !this.settings.allowDeselect) || (option.disabled && !this.settings.allowDeselect)) {
1063
+ if (!option.display) {
1064
+ optionEl.classList.add(this.classes.hide);
1065
+ }
1066
+ if (option.disabled) {
1055
1067
  optionEl.classList.add(this.classes.disabled);
1056
1068
  }
1057
1069
  if (option.selected && this.settings.hideSelected) {
@@ -1072,9 +1084,8 @@ class Render {
1072
1084
  if (option.disabled || (option.selected && !this.settings.allowDeselect)) {
1073
1085
  return;
1074
1086
  }
1075
- if (this.settings.isMultiple &&
1076
- Array.isArray(selectedOptions) &&
1077
- this.settings.maxSelected <= selectedOptions.length) {
1087
+ if ((this.settings.isMultiple && this.settings.maxSelected <= selectedOptions.length && !option.selected) ||
1088
+ (this.settings.isMultiple && this.settings.minSelected >= selectedOptions.length && option.selected)) {
1078
1089
  return;
1079
1090
  }
1080
1091
  let shouldUpdate = false;
@@ -1111,7 +1122,7 @@ class Render {
1111
1122
  if (!this.store.getOptionByID(elementID)) {
1112
1123
  this.callbacks.addOption(option);
1113
1124
  }
1114
- this.callbacks.setSelected(after.map((o) => o.value));
1125
+ this.callbacks.setSelected(after.map((o) => o.value), false);
1115
1126
  if (this.settings.closeOnSelect) {
1116
1127
  this.callbacks.close();
1117
1128
  }
@@ -1139,23 +1150,30 @@ class Render {
1139
1150
  return completedString;
1140
1151
  }
1141
1152
  moveContentAbove() {
1142
- let mainHeight = this.main.main.offsetHeight;
1153
+ const mainHeight = this.main.main.offsetHeight;
1143
1154
  const contentHeight = this.content.main.offsetHeight;
1144
- const height = mainHeight + contentHeight - 1;
1145
- this.content.main.style.margin = '-' + height + 'px 0px 0px 0px';
1146
- this.content.main.style.transformOrigin = 'center bottom';
1147
1155
  this.main.main.classList.remove(this.classes.openBelow);
1148
1156
  this.main.main.classList.add(this.classes.openAbove);
1149
1157
  this.content.main.classList.remove(this.classes.openBelow);
1150
1158
  this.content.main.classList.add(this.classes.openAbove);
1159
+ const containerRect = this.main.main.getBoundingClientRect();
1160
+ this.content.main.style.margin = '-' + (mainHeight + contentHeight - 1) + 'px 0px 0px 0px';
1161
+ this.content.main.style.top = containerRect.top + containerRect.height + window.scrollY + 'px';
1162
+ this.content.main.style.left = containerRect.left + window.scrollX + 'px';
1163
+ this.content.main.style.width = containerRect.width + 'px';
1151
1164
  }
1152
1165
  moveContentBelow() {
1153
- this.content.main.style.margin = '-1px 0px 0px 0px';
1154
- this.content.main.style.transformOrigin = 'center top';
1155
1166
  this.main.main.classList.remove(this.classes.openAbove);
1156
1167
  this.main.main.classList.add(this.classes.openBelow);
1157
1168
  this.content.main.classList.remove(this.classes.openAbove);
1158
1169
  this.content.main.classList.add(this.classes.openBelow);
1170
+ const containerRect = this.main.main.getBoundingClientRect();
1171
+ this.content.main.style.margin = '-1px 0px 0px 0px';
1172
+ if (this.settings.contentPosition !== 'relative') {
1173
+ this.content.main.style.top = containerRect.top + containerRect.height + window.scrollY + 'px';
1174
+ this.content.main.style.left = containerRect.left + window.scrollX + 'px';
1175
+ this.content.main.style.width = containerRect.width + 'px';
1176
+ }
1159
1177
  }
1160
1178
  ensureElementInView(container, element) {
1161
1179
  const cTop = container.scrollTop + container.offsetTop;
@@ -1169,16 +1187,18 @@ class Render {
1169
1187
  container.scrollTop += eBottom - cBottom;
1170
1188
  }
1171
1189
  }
1172
- putContent(el, isOpen) {
1173
- const height = el.offsetHeight;
1174
- const rect = el.getBoundingClientRect();
1175
- const elemTop = isOpen ? rect.top : rect.top - height;
1176
- const elemBottom = isOpen ? rect.bottom : rect.bottom + height;
1177
- if (elemTop <= 0) {
1178
- return 'down';
1179
- }
1180
- if (elemBottom >= window.innerHeight) {
1181
- return 'up';
1190
+ putContent() {
1191
+ const mainHeight = this.main.main.offsetHeight;
1192
+ const mainRect = this.main.main.getBoundingClientRect();
1193
+ const contentHeight = this.content.main.offsetHeight;
1194
+ const spaceBelow = window.innerHeight - (mainRect.top + mainHeight);
1195
+ if (spaceBelow <= contentHeight) {
1196
+ if (mainRect.top > contentHeight) {
1197
+ return 'up';
1198
+ }
1199
+ else {
1200
+ return 'down';
1201
+ }
1182
1202
  }
1183
1203
  return 'down';
1184
1204
  }
@@ -1189,16 +1209,17 @@ class Select {
1189
1209
  this.listen = false;
1190
1210
  this.observer = null;
1191
1211
  this.select = select;
1212
+ this.select.addEventListener('change', this.valueChange.bind(this), {
1213
+ passive: true,
1214
+ });
1215
+ this.observer = new MutationObserver(this.observeCall.bind(this));
1216
+ this.changeListen(true);
1192
1217
  }
1193
1218
  enable() {
1194
- this.disconnectObserver();
1195
1219
  this.select.disabled = false;
1196
- this.connectObserver();
1197
1220
  }
1198
1221
  disable() {
1199
- this.disconnectObserver();
1200
1222
  this.select.disabled = true;
1201
- this.connectObserver();
1202
1223
  }
1203
1224
  hideUI() {
1204
1225
  this.select.tabIndex = -1;
@@ -1210,65 +1231,61 @@ class Select {
1210
1231
  this.select.style.display = '';
1211
1232
  this.select.removeAttribute('aria-hidden');
1212
1233
  }
1213
- changeListen(on) {
1214
- this.listen = on;
1215
- if (this.listen) {
1216
- this.connectObserver();
1234
+ changeListen(listen) {
1235
+ this.listen = listen;
1236
+ if (listen) {
1237
+ if (this.observer) {
1238
+ this.observer.observe(this.select, {
1239
+ subtree: true,
1240
+ childList: true,
1241
+ attributes: true,
1242
+ });
1243
+ }
1217
1244
  }
1218
- else {
1219
- this.disconnectObserver();
1245
+ if (!listen) {
1246
+ if (this.observer) {
1247
+ this.observer.disconnect();
1248
+ }
1220
1249
  }
1221
1250
  }
1222
- addSelectChangeListener(func) {
1223
- this.onSelectChange = func;
1224
- this.addObserver();
1225
- this.connectObserver();
1226
- this.changeListen(true);
1227
- }
1228
- removeSelectChangeListener() {
1229
- this.changeListen(false);
1230
- this.onSelectChange = undefined;
1231
- }
1232
- addValueChangeListener(func) {
1233
- this.onValueChange = func;
1234
- this.select.addEventListener('change', this.valueChange.bind(this), {
1235
- passive: true,
1236
- });
1237
- }
1238
- removeValueChangeListener() {
1239
- this.onValueChange = undefined;
1240
- this.select.removeEventListener('change', this.valueChange.bind(this));
1241
- }
1242
1251
  valueChange(ev) {
1243
1252
  if (this.listen && this.onValueChange) {
1244
1253
  this.onValueChange(this.getSelectedValues());
1245
1254
  }
1246
1255
  return true;
1247
1256
  }
1248
- observeWrapper(mutations) {
1249
- if (this.onSelectChange) {
1250
- this.changeListen(false);
1251
- this.onSelectChange(this.getData());
1252
- this.changeListen(true);
1257
+ observeCall(mutations) {
1258
+ if (!this.listen) {
1259
+ return;
1253
1260
  }
1254
- }
1255
- addObserver() {
1256
- if (this.observer) {
1257
- this.disconnectObserver();
1258
- this.observer = null;
1261
+ let classChanged = false;
1262
+ let disabledChanged = false;
1263
+ let optgroupOptionChanged = false;
1264
+ for (const m of mutations) {
1265
+ if (m.target === this.select) {
1266
+ if (m.attributeName === 'disabled') {
1267
+ disabledChanged = true;
1268
+ }
1269
+ if (m.attributeName === 'class') {
1270
+ classChanged = true;
1271
+ }
1272
+ }
1273
+ if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {
1274
+ optgroupOptionChanged = true;
1275
+ }
1259
1276
  }
1260
- this.observer = new MutationObserver(this.observeWrapper.bind(this));
1261
- }
1262
- connectObserver() {
1263
- if (this.observer) {
1264
- this.observer.observe(this.select, {
1265
- childList: true,
1266
- });
1277
+ if (classChanged && this.onClassChange) {
1278
+ this.onClassChange(this.select.className.split(' '));
1267
1279
  }
1268
- }
1269
- disconnectObserver() {
1270
- if (this.observer) {
1271
- this.observer.disconnect();
1280
+ if (disabledChanged && this.onDisabledChange) {
1281
+ this.changeListen(false);
1282
+ this.onDisabledChange(this.select.disabled);
1283
+ this.changeListen(true);
1284
+ }
1285
+ if (optgroupOptionChanged && this.onOptionsChange) {
1286
+ this.changeListen(false);
1287
+ this.onOptionsChange(this.getData());
1288
+ this.changeListen(true);
1272
1289
  }
1273
1290
  }
1274
1291
  getData() {
@@ -1286,7 +1303,7 @@ class Select {
1286
1303
  }
1287
1304
  getDataFromOptgroup(optgroup) {
1288
1305
  let data = {
1289
- id: (optgroup.dataset ? optgroup.dataset.id : false) || '',
1306
+ id: optgroup.id,
1290
1307
  label: optgroup.label,
1291
1308
  selectAll: optgroup.dataset ? optgroup.dataset.selectall === 'true' : false,
1292
1309
  closable: optgroup.dataset ? optgroup.dataset.closable : 'off',
@@ -1302,10 +1319,10 @@ class Select {
1302
1319
  }
1303
1320
  getDataFromOption(option) {
1304
1321
  return {
1305
- id: (option.dataset ? option.dataset.id : false) || '',
1322
+ id: option.id,
1306
1323
  value: option.value,
1307
1324
  text: option.text,
1308
- html: option.innerHTML,
1325
+ html: option.dataset && option.dataset.html ? option.dataset.html : '',
1309
1326
  selected: option.selected,
1310
1327
  display: option.style.display === 'none' ? false : true,
1311
1328
  disabled: option.disabled,
@@ -1341,6 +1358,7 @@ class Select {
1341
1358
  return values;
1342
1359
  }
1343
1360
  setSelected(value) {
1361
+ this.changeListen(false);
1344
1362
  const options = this.select.childNodes;
1345
1363
  for (const o of options) {
1346
1364
  if (o.nodeName === 'OPTGROUP') {
@@ -1358,11 +1376,12 @@ class Select {
1358
1376
  option.selected = value.includes(option.value);
1359
1377
  }
1360
1378
  }
1379
+ this.changeListen(true);
1361
1380
  }
1362
1381
  updateSelect(id, style, classes) {
1363
1382
  this.changeListen(false);
1364
1383
  if (id) {
1365
- this.select.id = id;
1384
+ this.select.dataset.id = id;
1366
1385
  }
1367
1386
  if (style) {
1368
1387
  this.select.style.cssText = style;
@@ -1410,8 +1429,12 @@ class Select {
1410
1429
  }
1411
1430
  createOption(info) {
1412
1431
  const optionEl = document.createElement('option');
1413
- optionEl.value = info.value !== '' ? info.value : info.text;
1414
- optionEl.innerHTML = info.html || info.text;
1432
+ optionEl.id = info.id;
1433
+ optionEl.value = info.value;
1434
+ optionEl.innerHTML = info.text;
1435
+ if (info.html !== '') {
1436
+ optionEl.setAttribute('data-html', info.html);
1437
+ }
1415
1438
  if (info.selected) {
1416
1439
  optionEl.selected = info.selected;
1417
1440
  }
@@ -1441,15 +1464,19 @@ class Select {
1441
1464
  }
1442
1465
  destroy() {
1443
1466
  this.changeListen(false);
1444
- this.disconnectObserver();
1445
- this.removeSelectChangeListener();
1446
- this.removeValueChangeListener();
1467
+ this.select.removeEventListener('change', this.valueChange.bind(this));
1468
+ if (this.observer) {
1469
+ this.observer.disconnect();
1470
+ this.observer = null;
1471
+ }
1472
+ delete this.select.dataset.id;
1447
1473
  this.showUI();
1448
1474
  }
1449
1475
  }
1450
1476
 
1451
1477
  class SlimSelect {
1452
1478
  constructor(config) {
1479
+ var _a;
1453
1480
  this.events = {
1454
1481
  search: undefined,
1455
1482
  searchFilter: (opt, search) => {
@@ -1473,23 +1500,7 @@ class SlimSelect {
1473
1500
  if (!this.settings.isOpen) {
1474
1501
  return;
1475
1502
  }
1476
- if (this.settings.openPosition === 'down') {
1477
- this.render.moveContentBelow();
1478
- return;
1479
- }
1480
- else if (this.settings.openPosition === 'up') {
1481
- this.render.moveContentAbove();
1482
- return;
1483
- }
1484
- if (this.settings.contentPosition === 'relative') {
1485
- this.render.moveContentBelow();
1486
- }
1487
- else if (this.render.putContent(this.render.content.main, this.settings.isOpen) === 'up') {
1488
- this.render.moveContentAbove();
1489
- }
1490
- else {
1491
- this.render.moveContentBelow();
1492
- }
1503
+ this.render.moveContent();
1493
1504
  });
1494
1505
  this.documentClick = (e) => {
1495
1506
  if (!this.settings.isOpen) {
@@ -1521,18 +1532,31 @@ class SlimSelect {
1521
1532
  this.events[key] = config.events[key];
1522
1533
  }
1523
1534
  }
1535
+ this.settings.disabled = ((_a = config.settings) === null || _a === void 0 ? void 0 : _a.disabled) ? config.settings.disabled : this.selectEl.disabled;
1524
1536
  this.settings.isMultiple = this.selectEl.multiple;
1525
1537
  this.settings.style = this.selectEl.style.cssText;
1526
1538
  this.settings.class = this.selectEl.className.split(' ');
1527
1539
  this.select = new Select(this.selectEl);
1528
1540
  this.select.updateSelect(this.settings.id, this.settings.style, this.settings.class);
1529
1541
  this.select.hideUI();
1530
- this.select.addSelectChangeListener((data) => {
1531
- this.setData(data);
1532
- });
1533
- this.select.addValueChangeListener((values) => {
1542
+ this.select.onValueChange = (values) => {
1534
1543
  this.setSelected(values);
1535
- });
1544
+ };
1545
+ this.select.onClassChange = (classes) => {
1546
+ this.settings.class = classes;
1547
+ this.render.updateClassStyles();
1548
+ };
1549
+ this.select.onDisabledChange = (disabled) => {
1550
+ if (disabled) {
1551
+ this.disable();
1552
+ }
1553
+ else {
1554
+ this.enable();
1555
+ }
1556
+ };
1557
+ this.select.onOptionsChange = (data) => {
1558
+ this.setData(data);
1559
+ };
1536
1560
  this.store = new Store(this.settings.isMultiple ? 'multiple' : 'single', config.data ? config.data : this.select.getData());
1537
1561
  if (config.data) {
1538
1562
  this.select.updateOptions(this.store.getData());
@@ -1558,7 +1582,7 @@ class SlimSelect {
1558
1582
  if (this.settings.openPosition === 'auto') {
1559
1583
  window.addEventListener('scroll', this.windowScroll, false);
1560
1584
  }
1561
- if (!this.settings.isEnabled) {
1585
+ if (this.settings.disabled) {
1562
1586
  this.disable();
1563
1587
  }
1564
1588
  if (this.settings.alwaysOpen) {
@@ -1567,12 +1591,12 @@ class SlimSelect {
1567
1591
  this.selectEl.slim = this;
1568
1592
  }
1569
1593
  enable() {
1570
- this.settings.isEnabled = true;
1594
+ this.settings.disabled = false;
1571
1595
  this.select.enable();
1572
1596
  this.render.enable();
1573
1597
  }
1574
1598
  disable() {
1575
- this.settings.isEnabled = false;
1599
+ this.settings.disabled = true;
1576
1600
  this.select.disable();
1577
1601
  this.render.disable();
1578
1602
  }
@@ -1600,14 +1624,19 @@ class SlimSelect {
1600
1624
  getSelected() {
1601
1625
  return this.store.getSelected();
1602
1626
  }
1603
- setSelected(value) {
1627
+ setSelected(value, runAfterChange = true) {
1604
1628
  const selected = this.store.getSelected();
1605
1629
  this.store.setSelectedBy('value', Array.isArray(value) ? value : [value]);
1606
1630
  const data = this.store.getData();
1607
1631
  this.select.updateOptions(data);
1608
1632
  this.render.renderValues();
1609
- this.render.renderOptions(data);
1610
- if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1633
+ if (this.render.content.search.input.value !== '') {
1634
+ this.search(this.render.content.search.input.value);
1635
+ }
1636
+ else {
1637
+ this.render.renderOptions(data);
1638
+ }
1639
+ if (runAfterChange && this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1611
1640
  this.events.afterChange(this.store.getSelectedOptions());
1612
1641
  }
1613
1642
  }
@@ -1623,7 +1652,7 @@ class SlimSelect {
1623
1652
  }
1624
1653
  }
1625
1654
  open() {
1626
- if (!this.settings.isEnabled || this.settings.isOpen) {
1655
+ if (this.settings.disabled || this.settings.isOpen) {
1627
1656
  return;
1628
1657
  }
1629
1658
  if (this.events.beforeOpen) {
@@ -1639,10 +1668,12 @@ class SlimSelect {
1639
1668
  }
1640
1669
  this.settings.isOpen = true;
1641
1670
  }, this.settings.timeoutDelay);
1642
- if (this.settings.intervalMove) {
1643
- clearInterval(this.settings.intervalMove);
1671
+ if (this.settings.contentPosition === 'absolute') {
1672
+ if (this.settings.intervalMove) {
1673
+ clearInterval(this.settings.intervalMove);
1674
+ }
1675
+ this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1644
1676
  }
1645
- this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1646
1677
  }
1647
1678
  close() {
1648
1679
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
@@ -1652,7 +1683,9 @@ class SlimSelect {
1652
1683
  this.events.beforeClose();
1653
1684
  }
1654
1685
  this.render.close();
1655
- this.search('');
1686
+ if (this.render.content.search.input.value !== '') {
1687
+ this.search('');
1688
+ }
1656
1689
  this.render.mainFocus(false);
1657
1690
  setTimeout(() => {
1658
1691
  if (this.events.afterClose) {