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