slim-select 2.3.0 → 2.3.2

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.
package/dist/index.d.ts CHANGED
@@ -33,7 +33,7 @@ export default class SlimSelect {
33
33
  getData(): DataArray;
34
34
  setData(data: DataArrayPartial): void;
35
35
  getSelected(): string[];
36
- setSelected(value: string | string[]): void;
36
+ setSelected(value: string | string[], runAfterChange?: boolean): void;
37
37
  addOption(option: OptionOptional): void;
38
38
  open(): void;
39
39
  close(): void;
package/dist/render.d.ts CHANGED
@@ -4,7 +4,7 @@ export interface Callbacks {
4
4
  open: () => void;
5
5
  close: () => void;
6
6
  addable?: (value: string) => Promise<OptionOptional | string> | OptionOptional | string;
7
- setSelected: (value: string[]) => void;
7
+ setSelected: (value: string[], runAfterChange: boolean) => void;
8
8
  addOption: (option: Option) => void;
9
9
  search: (search: string) => void;
10
10
  beforeChange?: (newVal: Option[], oldVal: Option[]) => boolean | void;
@@ -90,6 +90,7 @@ export default class Render {
90
90
  disable(): void;
91
91
  open(): void;
92
92
  close(): void;
93
+ updateClassStyles(): void;
93
94
  mainDiv(): Main;
94
95
  mainFocus(trigger: boolean): void;
95
96
  placeholder(): HTMLDivElement;
package/dist/select.d.ts CHANGED
@@ -2,6 +2,7 @@ import { DataArray, DataArrayPartial, Optgroup, OptgroupOptional, Option } from
2
2
  export default class Select {
3
3
  select: HTMLSelectElement;
4
4
  onValueChange?: (value: string[]) => void;
5
+ onClassChange?: (classes: string[]) => void;
5
6
  onDisabledChange?: (disabled: boolean) => void;
6
7
  onOptionsChange?: (data: DataArrayPartial) => void;
7
8
  listen: boolean;
@@ -78,7 +78,7 @@ class Settings {
78
78
  this.contentLocation = settings.contentLocation || document.body;
79
79
  this.contentPosition = settings.contentPosition || 'absolute';
80
80
  this.openPosition = settings.openPosition || 'auto';
81
- this.placeholderText = settings.placeholderText || 'Select Value';
81
+ this.placeholderText = settings.placeholderText !== undefined ? settings.placeholderText : 'Select Value';
82
82
  this.allowDeselect = settings.allowDeselect !== undefined ? settings.allowDeselect : false;
83
83
  this.hideSelected = settings.hideSelected !== undefined ? settings.hideSelected : false;
84
84
  this.showOptionTooltips = settings.showOptionTooltips !== undefined ? settings.showOptionTooltips : false;
@@ -345,6 +345,7 @@ class Render {
345
345
  this.callbacks = callbacks;
346
346
  this.main = this.mainDiv();
347
347
  this.content = this.contentDiv();
348
+ this.updateClassStyles();
348
349
  this.settings.contentLocation.appendChild(this.content.main);
349
350
  }
350
351
  enable() {
@@ -359,8 +360,6 @@ class Render {
359
360
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
360
361
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
361
362
  this.moveContent();
362
- this.renderOptions(this.store.getData());
363
- this.moveContent();
364
363
  const selectedOptions = this.store.getSelectedOptions();
365
364
  if (selectedOptions.length) {
366
365
  const selectedId = selectedOptions[selectedOptions.length - 1].id;
@@ -377,20 +376,32 @@ class Render {
377
376
  this.content.main.classList.remove(this.classes.openBelow);
378
377
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
379
378
  }
380
- mainDiv() {
381
- const main = document.createElement('div');
382
- main.tabIndex = 0;
383
- main.style.cssText = this.settings.style !== '' ? this.settings.style : '';
384
- main.className = '';
385
- main.classList.add(this.settings.id);
386
- main.classList.add(this.classes.main);
387
- 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) {
388
390
  for (const c of this.settings.class) {
389
391
  if (c.trim() !== '') {
390
- main.classList.add(c.trim());
392
+ this.main.main.classList.add(c.trim());
393
+ this.content.main.classList.add(c.trim());
391
394
  }
392
395
  }
393
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;
394
405
  main.onfocus = () => {
395
406
  if (this.settings.triggerFocus) {
396
407
  this.callbacks.open();
@@ -443,7 +454,7 @@ class Render {
443
454
  shouldDelete = this.callbacks.beforeChange(after, before) === true;
444
455
  }
445
456
  if (shouldDelete) {
446
- this.callbacks.setSelected(['']);
457
+ this.callbacks.setSelected([''], false);
447
458
  if (this.settings.closeOnSelect) {
448
459
  this.callbacks.close();
449
460
  }
@@ -642,7 +653,7 @@ class Render {
642
653
  selectedValues.push(o.value);
643
654
  }
644
655
  }
645
- this.callbacks.setSelected(selectedValues);
656
+ this.callbacks.setSelected(selectedValues, false);
646
657
  if (this.settings.closeOnSelect) {
647
658
  this.callbacks.close();
648
659
  }
@@ -663,21 +674,7 @@ class Render {
663
674
  }
664
675
  contentDiv() {
665
676
  const main = document.createElement('div');
666
- main.classList.add(this.classes.content);
667
677
  main.dataset.id = this.settings.id;
668
- if (this.settings.style !== '') {
669
- main.style.cssText = this.settings.style;
670
- }
671
- if (this.settings.contentPosition === 'relative') {
672
- main.classList.add('ss-' + this.settings.contentPosition);
673
- }
674
- if (this.settings.class.length) {
675
- for (const c of this.settings.class) {
676
- if (c.trim() !== '') {
677
- main.classList.add(c.trim());
678
- }
679
- }
680
- }
681
678
  const search = this.searchDiv();
682
679
  main.appendChild(search.main);
683
680
  const list = this.listDiv();
@@ -789,10 +786,10 @@ class Render {
789
786
  if (this.settings.isMultiple) {
790
787
  let values = this.store.getSelected();
791
788
  values.push(newOption.value);
792
- this.callbacks.setSelected(values);
789
+ this.callbacks.setSelected(values, true);
793
790
  }
794
791
  else {
795
- this.callbacks.setSelected([newOption.value]);
792
+ this.callbacks.setSelected([newOption.value], true);
796
793
  }
797
794
  this.callbacks.search('');
798
795
  if (this.settings.closeOnSelect) {
@@ -974,12 +971,12 @@ class Render {
974
971
  }
975
972
  return true;
976
973
  });
977
- this.callbacks.setSelected(newSelected);
974
+ this.callbacks.setSelected(newSelected, true);
978
975
  return;
979
976
  }
980
977
  else {
981
978
  const newSelected = currentSelected.concat(d.options.map((o) => o.value));
982
- this.callbacks.setSelected(newSelected);
979
+ this.callbacks.setSelected(newSelected, true);
983
980
  }
984
981
  });
985
982
  optgroupActions.appendChild(selectAll);
@@ -1063,6 +1060,9 @@ class Render {
1063
1060
  if (this.settings.showOptionTooltips && optionEl.textContent) {
1064
1061
  optionEl.setAttribute('title', optionEl.textContent);
1065
1062
  }
1063
+ if (!option.display) {
1064
+ optionEl.classList.add(this.classes.hide);
1065
+ }
1066
1066
  if (option.disabled) {
1067
1067
  optionEl.classList.add(this.classes.disabled);
1068
1068
  }
@@ -1122,7 +1122,7 @@ class Render {
1122
1122
  if (!this.store.getOptionByID(elementID)) {
1123
1123
  this.callbacks.addOption(option);
1124
1124
  }
1125
- this.callbacks.setSelected(after.map((o) => o.value));
1125
+ this.callbacks.setSelected(after.map((o) => o.value), false);
1126
1126
  if (this.settings.closeOnSelect) {
1127
1127
  this.callbacks.close();
1128
1128
  }
@@ -1258,6 +1258,7 @@ class Select {
1258
1258
  if (!this.listen) {
1259
1259
  return;
1260
1260
  }
1261
+ let classChanged = false;
1261
1262
  let disabledChanged = false;
1262
1263
  let optgroupOptionChanged = false;
1263
1264
  for (const m of mutations) {
@@ -1265,11 +1266,17 @@ class Select {
1265
1266
  if (m.attributeName === 'disabled') {
1266
1267
  disabledChanged = true;
1267
1268
  }
1269
+ if (m.attributeName === 'class') {
1270
+ classChanged = true;
1271
+ }
1268
1272
  }
1269
1273
  if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {
1270
1274
  optgroupOptionChanged = true;
1271
1275
  }
1272
1276
  }
1277
+ if (classChanged && this.onClassChange) {
1278
+ this.onClassChange(this.select.className.split(' '));
1279
+ }
1273
1280
  if (disabledChanged && this.onDisabledChange) {
1274
1281
  this.changeListen(false);
1275
1282
  this.onDisabledChange(this.select.disabled);
@@ -1374,7 +1381,7 @@ class Select {
1374
1381
  updateSelect(id, style, classes) {
1375
1382
  this.changeListen(false);
1376
1383
  if (id) {
1377
- this.select.id = id;
1384
+ this.select.dataset.id = id;
1378
1385
  }
1379
1386
  if (style) {
1380
1387
  this.select.style.cssText = style;
@@ -1462,6 +1469,7 @@ class Select {
1462
1469
  this.observer.disconnect();
1463
1470
  this.observer = null;
1464
1471
  }
1472
+ delete this.select.dataset.id;
1465
1473
  this.showUI();
1466
1474
  }
1467
1475
  }
@@ -1519,8 +1527,15 @@ class SlimSelect {
1519
1527
  this.destroy();
1520
1528
  }
1521
1529
  this.settings = new Settings(config.settings);
1530
+ const debounceEvents = ['afterChange', 'beforeOpen', 'afterOpen', 'beforeClose', 'afterClose'];
1522
1531
  for (const key in config.events) {
1523
- if (config.events.hasOwnProperty(key)) {
1532
+ if (!config.events.hasOwnProperty(key)) {
1533
+ continue;
1534
+ }
1535
+ if (debounceEvents.indexOf(key) !== -1) {
1536
+ this.events[key] = debounce(config.events[key], 100);
1537
+ }
1538
+ else {
1524
1539
  this.events[key] = config.events[key];
1525
1540
  }
1526
1541
  }
@@ -1534,6 +1549,10 @@ class SlimSelect {
1534
1549
  this.select.onValueChange = (values) => {
1535
1550
  this.setSelected(values);
1536
1551
  };
1552
+ this.select.onClassChange = (classes) => {
1553
+ this.settings.class = classes;
1554
+ this.render.updateClassStyles();
1555
+ };
1537
1556
  this.select.onDisabledChange = (disabled) => {
1538
1557
  if (disabled) {
1539
1558
  this.disable();
@@ -1612,7 +1631,7 @@ class SlimSelect {
1612
1631
  getSelected() {
1613
1632
  return this.store.getSelected();
1614
1633
  }
1615
- setSelected(value) {
1634
+ setSelected(value, runAfterChange = true) {
1616
1635
  const selected = this.store.getSelected();
1617
1636
  this.store.setSelectedBy('value', Array.isArray(value) ? value : [value]);
1618
1637
  const data = this.store.getData();
@@ -1624,7 +1643,7 @@ class SlimSelect {
1624
1643
  else {
1625
1644
  this.render.renderOptions(data);
1626
1645
  }
1627
- if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1646
+ if (runAfterChange && this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1628
1647
  this.events.afterChange(this.store.getSelectedOptions());
1629
1648
  }
1630
1649
  }
@@ -1671,7 +1690,9 @@ class SlimSelect {
1671
1690
  this.events.beforeClose();
1672
1691
  }
1673
1692
  this.render.close();
1674
- this.search('');
1693
+ if (this.render.content.search.input.value !== '') {
1694
+ this.search('');
1695
+ }
1675
1696
  this.render.mainFocus(false);
1676
1697
  setTimeout(() => {
1677
1698
  if (this.events.afterClose) {
@@ -76,7 +76,7 @@ class Settings {
76
76
  this.contentLocation = settings.contentLocation || document.body;
77
77
  this.contentPosition = settings.contentPosition || 'absolute';
78
78
  this.openPosition = settings.openPosition || 'auto';
79
- this.placeholderText = settings.placeholderText || 'Select Value';
79
+ this.placeholderText = settings.placeholderText !== undefined ? settings.placeholderText : 'Select Value';
80
80
  this.allowDeselect = settings.allowDeselect !== undefined ? settings.allowDeselect : false;
81
81
  this.hideSelected = settings.hideSelected !== undefined ? settings.hideSelected : false;
82
82
  this.showOptionTooltips = settings.showOptionTooltips !== undefined ? settings.showOptionTooltips : false;
@@ -343,6 +343,7 @@ class Render {
343
343
  this.callbacks = callbacks;
344
344
  this.main = this.mainDiv();
345
345
  this.content = this.contentDiv();
346
+ this.updateClassStyles();
346
347
  this.settings.contentLocation.appendChild(this.content.main);
347
348
  }
348
349
  enable() {
@@ -357,8 +358,6 @@ class Render {
357
358
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
358
359
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
359
360
  this.moveContent();
360
- this.renderOptions(this.store.getData());
361
- this.moveContent();
362
361
  const selectedOptions = this.store.getSelectedOptions();
363
362
  if (selectedOptions.length) {
364
363
  const selectedId = selectedOptions[selectedOptions.length - 1].id;
@@ -375,20 +374,32 @@ class Render {
375
374
  this.content.main.classList.remove(this.classes.openBelow);
376
375
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
377
376
  }
378
- mainDiv() {
379
- const main = document.createElement('div');
380
- main.tabIndex = 0;
381
- main.style.cssText = this.settings.style !== '' ? this.settings.style : '';
382
- main.className = '';
383
- main.classList.add(this.settings.id);
384
- main.classList.add(this.classes.main);
385
- 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) {
386
388
  for (const c of this.settings.class) {
387
389
  if (c.trim() !== '') {
388
- main.classList.add(c.trim());
390
+ this.main.main.classList.add(c.trim());
391
+ this.content.main.classList.add(c.trim());
389
392
  }
390
393
  }
391
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;
392
403
  main.onfocus = () => {
393
404
  if (this.settings.triggerFocus) {
394
405
  this.callbacks.open();
@@ -441,7 +452,7 @@ class Render {
441
452
  shouldDelete = this.callbacks.beforeChange(after, before) === true;
442
453
  }
443
454
  if (shouldDelete) {
444
- this.callbacks.setSelected(['']);
455
+ this.callbacks.setSelected([''], false);
445
456
  if (this.settings.closeOnSelect) {
446
457
  this.callbacks.close();
447
458
  }
@@ -640,7 +651,7 @@ class Render {
640
651
  selectedValues.push(o.value);
641
652
  }
642
653
  }
643
- this.callbacks.setSelected(selectedValues);
654
+ this.callbacks.setSelected(selectedValues, false);
644
655
  if (this.settings.closeOnSelect) {
645
656
  this.callbacks.close();
646
657
  }
@@ -661,21 +672,7 @@ class Render {
661
672
  }
662
673
  contentDiv() {
663
674
  const main = document.createElement('div');
664
- main.classList.add(this.classes.content);
665
675
  main.dataset.id = this.settings.id;
666
- if (this.settings.style !== '') {
667
- main.style.cssText = this.settings.style;
668
- }
669
- if (this.settings.contentPosition === 'relative') {
670
- main.classList.add('ss-' + this.settings.contentPosition);
671
- }
672
- if (this.settings.class.length) {
673
- for (const c of this.settings.class) {
674
- if (c.trim() !== '') {
675
- main.classList.add(c.trim());
676
- }
677
- }
678
- }
679
676
  const search = this.searchDiv();
680
677
  main.appendChild(search.main);
681
678
  const list = this.listDiv();
@@ -787,10 +784,10 @@ class Render {
787
784
  if (this.settings.isMultiple) {
788
785
  let values = this.store.getSelected();
789
786
  values.push(newOption.value);
790
- this.callbacks.setSelected(values);
787
+ this.callbacks.setSelected(values, true);
791
788
  }
792
789
  else {
793
- this.callbacks.setSelected([newOption.value]);
790
+ this.callbacks.setSelected([newOption.value], true);
794
791
  }
795
792
  this.callbacks.search('');
796
793
  if (this.settings.closeOnSelect) {
@@ -972,12 +969,12 @@ class Render {
972
969
  }
973
970
  return true;
974
971
  });
975
- this.callbacks.setSelected(newSelected);
972
+ this.callbacks.setSelected(newSelected, true);
976
973
  return;
977
974
  }
978
975
  else {
979
976
  const newSelected = currentSelected.concat(d.options.map((o) => o.value));
980
- this.callbacks.setSelected(newSelected);
977
+ this.callbacks.setSelected(newSelected, true);
981
978
  }
982
979
  });
983
980
  optgroupActions.appendChild(selectAll);
@@ -1061,6 +1058,9 @@ class Render {
1061
1058
  if (this.settings.showOptionTooltips && optionEl.textContent) {
1062
1059
  optionEl.setAttribute('title', optionEl.textContent);
1063
1060
  }
1061
+ if (!option.display) {
1062
+ optionEl.classList.add(this.classes.hide);
1063
+ }
1064
1064
  if (option.disabled) {
1065
1065
  optionEl.classList.add(this.classes.disabled);
1066
1066
  }
@@ -1120,7 +1120,7 @@ class Render {
1120
1120
  if (!this.store.getOptionByID(elementID)) {
1121
1121
  this.callbacks.addOption(option);
1122
1122
  }
1123
- this.callbacks.setSelected(after.map((o) => o.value));
1123
+ this.callbacks.setSelected(after.map((o) => o.value), false);
1124
1124
  if (this.settings.closeOnSelect) {
1125
1125
  this.callbacks.close();
1126
1126
  }
@@ -1256,6 +1256,7 @@ class Select {
1256
1256
  if (!this.listen) {
1257
1257
  return;
1258
1258
  }
1259
+ let classChanged = false;
1259
1260
  let disabledChanged = false;
1260
1261
  let optgroupOptionChanged = false;
1261
1262
  for (const m of mutations) {
@@ -1263,11 +1264,17 @@ class Select {
1263
1264
  if (m.attributeName === 'disabled') {
1264
1265
  disabledChanged = true;
1265
1266
  }
1267
+ if (m.attributeName === 'class') {
1268
+ classChanged = true;
1269
+ }
1266
1270
  }
1267
1271
  if (m.target.nodeName === 'OPTGROUP' || m.target.nodeName === 'OPTION') {
1268
1272
  optgroupOptionChanged = true;
1269
1273
  }
1270
1274
  }
1275
+ if (classChanged && this.onClassChange) {
1276
+ this.onClassChange(this.select.className.split(' '));
1277
+ }
1271
1278
  if (disabledChanged && this.onDisabledChange) {
1272
1279
  this.changeListen(false);
1273
1280
  this.onDisabledChange(this.select.disabled);
@@ -1372,7 +1379,7 @@ class Select {
1372
1379
  updateSelect(id, style, classes) {
1373
1380
  this.changeListen(false);
1374
1381
  if (id) {
1375
- this.select.id = id;
1382
+ this.select.dataset.id = id;
1376
1383
  }
1377
1384
  if (style) {
1378
1385
  this.select.style.cssText = style;
@@ -1460,6 +1467,7 @@ class Select {
1460
1467
  this.observer.disconnect();
1461
1468
  this.observer = null;
1462
1469
  }
1470
+ delete this.select.dataset.id;
1463
1471
  this.showUI();
1464
1472
  }
1465
1473
  }
@@ -1517,8 +1525,15 @@ class SlimSelect {
1517
1525
  this.destroy();
1518
1526
  }
1519
1527
  this.settings = new Settings(config.settings);
1528
+ const debounceEvents = ['afterChange', 'beforeOpen', 'afterOpen', 'beforeClose', 'afterClose'];
1520
1529
  for (const key in config.events) {
1521
- if (config.events.hasOwnProperty(key)) {
1530
+ if (!config.events.hasOwnProperty(key)) {
1531
+ continue;
1532
+ }
1533
+ if (debounceEvents.indexOf(key) !== -1) {
1534
+ this.events[key] = debounce(config.events[key], 100);
1535
+ }
1536
+ else {
1522
1537
  this.events[key] = config.events[key];
1523
1538
  }
1524
1539
  }
@@ -1532,6 +1547,10 @@ class SlimSelect {
1532
1547
  this.select.onValueChange = (values) => {
1533
1548
  this.setSelected(values);
1534
1549
  };
1550
+ this.select.onClassChange = (classes) => {
1551
+ this.settings.class = classes;
1552
+ this.render.updateClassStyles();
1553
+ };
1535
1554
  this.select.onDisabledChange = (disabled) => {
1536
1555
  if (disabled) {
1537
1556
  this.disable();
@@ -1610,7 +1629,7 @@ class SlimSelect {
1610
1629
  getSelected() {
1611
1630
  return this.store.getSelected();
1612
1631
  }
1613
- setSelected(value) {
1632
+ setSelected(value, runAfterChange = true) {
1614
1633
  const selected = this.store.getSelected();
1615
1634
  this.store.setSelectedBy('value', Array.isArray(value) ? value : [value]);
1616
1635
  const data = this.store.getData();
@@ -1622,7 +1641,7 @@ class SlimSelect {
1622
1641
  else {
1623
1642
  this.render.renderOptions(data);
1624
1643
  }
1625
- if (this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1644
+ if (runAfterChange && this.events.afterChange && !isEqual(selected, this.store.getSelected())) {
1626
1645
  this.events.afterChange(this.store.getSelectedOptions());
1627
1646
  }
1628
1647
  }
@@ -1669,7 +1688,9 @@ class SlimSelect {
1669
1688
  this.events.beforeClose();
1670
1689
  }
1671
1690
  this.render.close();
1672
- this.search('');
1691
+ if (this.render.content.search.input.value !== '') {
1692
+ this.search('');
1693
+ }
1673
1694
  this.render.mainFocus(false);
1674
1695
  setTimeout(() => {
1675
1696
  if (this.events.afterClose) {