slim-select 2.10.0 → 2.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.nvmrc CHANGED
@@ -1 +1 @@
1
- v22.11.0
1
+ v24.2.0
package/README.md CHANGED
@@ -61,6 +61,7 @@ npm install slim-select
61
61
 
62
62
  ```javascript
63
63
  import SlimSelect from 'slim-select'
64
+ import 'slim-select/styles' // optional import method
64
65
 
65
66
  new SlimSelect({
66
67
  select: '#selectElement',
package/dist/render.d.ts CHANGED
@@ -42,6 +42,7 @@ export default class Render {
42
42
  settings: Settings;
43
43
  store: Store;
44
44
  callbacks: Callbacks;
45
+ private lastSelectedOption;
45
46
  main: Main;
46
47
  content: Content;
47
48
  classes: CssClasses;
@@ -121,6 +121,7 @@ class Option {
121
121
  this.value = option.value === undefined ? option.text : option.value;
122
122
  this.text = option.text || '';
123
123
  this.html = option.html || '';
124
+ this.defaultSelected = option.defaultSelected !== undefined ? option.defaultSelected : false;
124
125
  this.selected = option.selected !== undefined ? option.selected : false;
125
126
  this.display = option.display !== undefined ? option.display : true;
126
127
  this.disabled = option.disabled !== undefined ? option.disabled : false;
@@ -369,6 +370,7 @@ class Render {
369
370
  this.settings = settings;
370
371
  this.classes = classes;
371
372
  this.callbacks = callbacks;
373
+ this.lastSelectedOption = null;
372
374
  this.main = this.mainDiv();
373
375
  this.content = this.contentDiv();
374
376
  this.updateClassStyles();
@@ -431,9 +433,10 @@ class Render {
431
433
  }
432
434
  }
433
435
  updateAriaAttributes() {
436
+ var _a;
434
437
  this.main.main.role = 'combobox';
435
438
  this.main.main.setAttribute('aria-haspopup', 'listbox');
436
- this.main.main.setAttribute('aria-controls', this.content.main.id);
439
+ this.main.main.setAttribute('aria-controls', (_a = this.content.main.dataset.id) !== null && _a !== void 0 ? _a : '');
437
440
  this.main.main.setAttribute('aria-expanded', 'false');
438
441
  this.content.main.setAttribute('role', 'listbox');
439
442
  }
@@ -692,6 +695,7 @@ class Render {
692
695
  if (!option.mandatory) {
693
696
  const deleteDiv = document.createElement('div');
694
697
  deleteDiv.classList.add(this.classes.valueDelete);
698
+ deleteDiv.setAttribute('tabindex', '0');
695
699
  deleteDiv.onclick = (e) => {
696
700
  e.preventDefault();
697
701
  e.stopPropagation();
@@ -738,6 +742,11 @@ class Render {
738
742
  deleteSvg.appendChild(deletePath);
739
743
  deleteDiv.appendChild(deleteSvg);
740
744
  value.appendChild(deleteDiv);
745
+ deleteDiv.onkeydown = (e) => {
746
+ if (e.key === 'Enter') {
747
+ deleteDiv.click();
748
+ }
749
+ };
741
750
  }
742
751
  return value;
743
752
  }
@@ -1025,6 +1034,7 @@ class Render {
1025
1034
  }), true);
1026
1035
  }
1027
1036
  }
1037
+ const fragment = document.createDocumentFragment();
1028
1038
  for (const d of data) {
1029
1039
  if (d instanceof Optgroup) {
1030
1040
  const optgroupEl = document.createElement('div');
@@ -1133,13 +1143,14 @@ class Render {
1133
1143
  optgroupEl.appendChild(optgroupLabel);
1134
1144
  for (const o of d.options) {
1135
1145
  optgroupEl.appendChild(this.option(o));
1146
+ fragment.appendChild(optgroupEl);
1136
1147
  }
1137
- this.content.list.appendChild(optgroupEl);
1138
1148
  }
1139
1149
  if (d instanceof Option) {
1140
- this.content.list.appendChild(this.option(d));
1150
+ fragment.appendChild(this.option(d));
1141
1151
  }
1142
1152
  }
1153
+ this.content.list.appendChild(fragment);
1143
1154
  }
1144
1155
  option(option) {
1145
1156
  if (option.placeholder) {
@@ -1212,6 +1223,24 @@ class Render {
1212
1223
  }
1213
1224
  else {
1214
1225
  after = before.concat(option);
1226
+ if (!this.settings.closeOnSelect) {
1227
+ if (e.shiftKey && this.lastSelectedOption) {
1228
+ const options = this.store.getDataOptions();
1229
+ let lastClickedOptionIndex = options.findIndex((o) => o.id === this.lastSelectedOption.id);
1230
+ let currentOptionIndex = options.findIndex((o) => o.id === option.id);
1231
+ if (lastClickedOptionIndex >= 0 && currentOptionIndex >= 0) {
1232
+ const startIndex = Math.min(lastClickedOptionIndex, currentOptionIndex);
1233
+ const endIndex = Math.max(lastClickedOptionIndex, currentOptionIndex);
1234
+ const afterRange = options.slice(startIndex, endIndex + 1);
1235
+ if (afterRange.length > 0 && afterRange.length < this.settings.maxSelected) {
1236
+ after = before.concat(afterRange.filter((a) => !before.find((b) => b.id === a.id)));
1237
+ }
1238
+ }
1239
+ }
1240
+ else if (!option.selected) {
1241
+ this.lastSelectedOption = option;
1242
+ }
1243
+ }
1215
1244
  }
1216
1245
  }
1217
1246
  if (!this.settings.isMultiple) {
@@ -1473,6 +1502,7 @@ class Select {
1473
1502
  value: option.value,
1474
1503
  text: option.text,
1475
1504
  html: option.dataset && option.dataset.html ? option.dataset.html : '',
1505
+ defaultSelected: option.defaultSelected,
1476
1506
  selected: option.selected,
1477
1507
  display: option.style.display !== 'none',
1478
1508
  disabled: option.disabled,
@@ -1609,9 +1639,8 @@ class Select {
1609
1639
  if (info.html !== '') {
1610
1640
  optionEl.setAttribute('data-html', info.html);
1611
1641
  }
1612
- if (info.selected) {
1613
- optionEl.selected = info.selected;
1614
- }
1642
+ optionEl.defaultSelected = info.defaultSelected;
1643
+ optionEl.selected = info.selected;
1615
1644
  if (info.disabled) {
1616
1645
  optionEl.disabled = true;
1617
1646
  }
@@ -119,6 +119,7 @@ class Option {
119
119
  this.value = option.value === undefined ? option.text : option.value;
120
120
  this.text = option.text || '';
121
121
  this.html = option.html || '';
122
+ this.defaultSelected = option.defaultSelected !== undefined ? option.defaultSelected : false;
122
123
  this.selected = option.selected !== undefined ? option.selected : false;
123
124
  this.display = option.display !== undefined ? option.display : true;
124
125
  this.disabled = option.disabled !== undefined ? option.disabled : false;
@@ -367,6 +368,7 @@ class Render {
367
368
  this.settings = settings;
368
369
  this.classes = classes;
369
370
  this.callbacks = callbacks;
371
+ this.lastSelectedOption = null;
370
372
  this.main = this.mainDiv();
371
373
  this.content = this.contentDiv();
372
374
  this.updateClassStyles();
@@ -429,9 +431,10 @@ class Render {
429
431
  }
430
432
  }
431
433
  updateAriaAttributes() {
434
+ var _a;
432
435
  this.main.main.role = 'combobox';
433
436
  this.main.main.setAttribute('aria-haspopup', 'listbox');
434
- this.main.main.setAttribute('aria-controls', this.content.main.id);
437
+ this.main.main.setAttribute('aria-controls', (_a = this.content.main.dataset.id) !== null && _a !== void 0 ? _a : '');
435
438
  this.main.main.setAttribute('aria-expanded', 'false');
436
439
  this.content.main.setAttribute('role', 'listbox');
437
440
  }
@@ -690,6 +693,7 @@ class Render {
690
693
  if (!option.mandatory) {
691
694
  const deleteDiv = document.createElement('div');
692
695
  deleteDiv.classList.add(this.classes.valueDelete);
696
+ deleteDiv.setAttribute('tabindex', '0');
693
697
  deleteDiv.onclick = (e) => {
694
698
  e.preventDefault();
695
699
  e.stopPropagation();
@@ -736,6 +740,11 @@ class Render {
736
740
  deleteSvg.appendChild(deletePath);
737
741
  deleteDiv.appendChild(deleteSvg);
738
742
  value.appendChild(deleteDiv);
743
+ deleteDiv.onkeydown = (e) => {
744
+ if (e.key === 'Enter') {
745
+ deleteDiv.click();
746
+ }
747
+ };
739
748
  }
740
749
  return value;
741
750
  }
@@ -1023,6 +1032,7 @@ class Render {
1023
1032
  }), true);
1024
1033
  }
1025
1034
  }
1035
+ const fragment = document.createDocumentFragment();
1026
1036
  for (const d of data) {
1027
1037
  if (d instanceof Optgroup) {
1028
1038
  const optgroupEl = document.createElement('div');
@@ -1131,13 +1141,14 @@ class Render {
1131
1141
  optgroupEl.appendChild(optgroupLabel);
1132
1142
  for (const o of d.options) {
1133
1143
  optgroupEl.appendChild(this.option(o));
1144
+ fragment.appendChild(optgroupEl);
1134
1145
  }
1135
- this.content.list.appendChild(optgroupEl);
1136
1146
  }
1137
1147
  if (d instanceof Option) {
1138
- this.content.list.appendChild(this.option(d));
1148
+ fragment.appendChild(this.option(d));
1139
1149
  }
1140
1150
  }
1151
+ this.content.list.appendChild(fragment);
1141
1152
  }
1142
1153
  option(option) {
1143
1154
  if (option.placeholder) {
@@ -1210,6 +1221,24 @@ class Render {
1210
1221
  }
1211
1222
  else {
1212
1223
  after = before.concat(option);
1224
+ if (!this.settings.closeOnSelect) {
1225
+ if (e.shiftKey && this.lastSelectedOption) {
1226
+ const options = this.store.getDataOptions();
1227
+ let lastClickedOptionIndex = options.findIndex((o) => o.id === this.lastSelectedOption.id);
1228
+ let currentOptionIndex = options.findIndex((o) => o.id === option.id);
1229
+ if (lastClickedOptionIndex >= 0 && currentOptionIndex >= 0) {
1230
+ const startIndex = Math.min(lastClickedOptionIndex, currentOptionIndex);
1231
+ const endIndex = Math.max(lastClickedOptionIndex, currentOptionIndex);
1232
+ const afterRange = options.slice(startIndex, endIndex + 1);
1233
+ if (afterRange.length > 0 && afterRange.length < this.settings.maxSelected) {
1234
+ after = before.concat(afterRange.filter((a) => !before.find((b) => b.id === a.id)));
1235
+ }
1236
+ }
1237
+ }
1238
+ else if (!option.selected) {
1239
+ this.lastSelectedOption = option;
1240
+ }
1241
+ }
1213
1242
  }
1214
1243
  }
1215
1244
  if (!this.settings.isMultiple) {
@@ -1471,6 +1500,7 @@ class Select {
1471
1500
  value: option.value,
1472
1501
  text: option.text,
1473
1502
  html: option.dataset && option.dataset.html ? option.dataset.html : '',
1503
+ defaultSelected: option.defaultSelected,
1474
1504
  selected: option.selected,
1475
1505
  display: option.style.display !== 'none',
1476
1506
  disabled: option.disabled,
@@ -1607,9 +1637,8 @@ class Select {
1607
1637
  if (info.html !== '') {
1608
1638
  optionEl.setAttribute('data-html', info.html);
1609
1639
  }
1610
- if (info.selected) {
1611
- optionEl.selected = info.selected;
1612
- }
1640
+ optionEl.defaultSelected = info.defaultSelected;
1641
+ optionEl.selected = info.selected;
1613
1642
  if (info.disabled) {
1614
1643
  optionEl.disabled = true;
1615
1644
  }
@@ -122,6 +122,7 @@ var SlimSelect = (function () {
122
122
  this.value = option.value === undefined ? option.text : option.value;
123
123
  this.text = option.text || '';
124
124
  this.html = option.html || '';
125
+ this.defaultSelected = option.defaultSelected !== undefined ? option.defaultSelected : false;
125
126
  this.selected = option.selected !== undefined ? option.selected : false;
126
127
  this.display = option.display !== undefined ? option.display : true;
127
128
  this.disabled = option.disabled !== undefined ? option.disabled : false;
@@ -370,6 +371,7 @@ var SlimSelect = (function () {
370
371
  this.settings = settings;
371
372
  this.classes = classes;
372
373
  this.callbacks = callbacks;
374
+ this.lastSelectedOption = null;
373
375
  this.main = this.mainDiv();
374
376
  this.content = this.contentDiv();
375
377
  this.updateClassStyles();
@@ -432,9 +434,10 @@ var SlimSelect = (function () {
432
434
  }
433
435
  }
434
436
  updateAriaAttributes() {
437
+ var _a;
435
438
  this.main.main.role = 'combobox';
436
439
  this.main.main.setAttribute('aria-haspopup', 'listbox');
437
- this.main.main.setAttribute('aria-controls', this.content.main.id);
440
+ this.main.main.setAttribute('aria-controls', (_a = this.content.main.dataset.id) !== null && _a !== void 0 ? _a : '');
438
441
  this.main.main.setAttribute('aria-expanded', 'false');
439
442
  this.content.main.setAttribute('role', 'listbox');
440
443
  }
@@ -693,6 +696,7 @@ var SlimSelect = (function () {
693
696
  if (!option.mandatory) {
694
697
  const deleteDiv = document.createElement('div');
695
698
  deleteDiv.classList.add(this.classes.valueDelete);
699
+ deleteDiv.setAttribute('tabindex', '0');
696
700
  deleteDiv.onclick = (e) => {
697
701
  e.preventDefault();
698
702
  e.stopPropagation();
@@ -739,6 +743,11 @@ var SlimSelect = (function () {
739
743
  deleteSvg.appendChild(deletePath);
740
744
  deleteDiv.appendChild(deleteSvg);
741
745
  value.appendChild(deleteDiv);
746
+ deleteDiv.onkeydown = (e) => {
747
+ if (e.key === 'Enter') {
748
+ deleteDiv.click();
749
+ }
750
+ };
742
751
  }
743
752
  return value;
744
753
  }
@@ -1026,6 +1035,7 @@ var SlimSelect = (function () {
1026
1035
  }), true);
1027
1036
  }
1028
1037
  }
1038
+ const fragment = document.createDocumentFragment();
1029
1039
  for (const d of data) {
1030
1040
  if (d instanceof Optgroup) {
1031
1041
  const optgroupEl = document.createElement('div');
@@ -1134,13 +1144,14 @@ var SlimSelect = (function () {
1134
1144
  optgroupEl.appendChild(optgroupLabel);
1135
1145
  for (const o of d.options) {
1136
1146
  optgroupEl.appendChild(this.option(o));
1147
+ fragment.appendChild(optgroupEl);
1137
1148
  }
1138
- this.content.list.appendChild(optgroupEl);
1139
1149
  }
1140
1150
  if (d instanceof Option) {
1141
- this.content.list.appendChild(this.option(d));
1151
+ fragment.appendChild(this.option(d));
1142
1152
  }
1143
1153
  }
1154
+ this.content.list.appendChild(fragment);
1144
1155
  }
1145
1156
  option(option) {
1146
1157
  if (option.placeholder) {
@@ -1213,6 +1224,24 @@ var SlimSelect = (function () {
1213
1224
  }
1214
1225
  else {
1215
1226
  after = before.concat(option);
1227
+ if (!this.settings.closeOnSelect) {
1228
+ if (e.shiftKey && this.lastSelectedOption) {
1229
+ const options = this.store.getDataOptions();
1230
+ let lastClickedOptionIndex = options.findIndex((o) => o.id === this.lastSelectedOption.id);
1231
+ let currentOptionIndex = options.findIndex((o) => o.id === option.id);
1232
+ if (lastClickedOptionIndex >= 0 && currentOptionIndex >= 0) {
1233
+ const startIndex = Math.min(lastClickedOptionIndex, currentOptionIndex);
1234
+ const endIndex = Math.max(lastClickedOptionIndex, currentOptionIndex);
1235
+ const afterRange = options.slice(startIndex, endIndex + 1);
1236
+ if (afterRange.length > 0 && afterRange.length < this.settings.maxSelected) {
1237
+ after = before.concat(afterRange.filter((a) => !before.find((b) => b.id === a.id)));
1238
+ }
1239
+ }
1240
+ }
1241
+ else if (!option.selected) {
1242
+ this.lastSelectedOption = option;
1243
+ }
1244
+ }
1216
1245
  }
1217
1246
  }
1218
1247
  if (!this.settings.isMultiple) {
@@ -1474,6 +1503,7 @@ var SlimSelect = (function () {
1474
1503
  value: option.value,
1475
1504
  text: option.text,
1476
1505
  html: option.dataset && option.dataset.html ? option.dataset.html : '',
1506
+ defaultSelected: option.defaultSelected,
1477
1507
  selected: option.selected,
1478
1508
  display: option.style.display !== 'none',
1479
1509
  disabled: option.disabled,
@@ -1610,9 +1640,8 @@ var SlimSelect = (function () {
1610
1640
  if (info.html !== '') {
1611
1641
  optionEl.setAttribute('data-html', info.html);
1612
1642
  }
1613
- if (info.selected) {
1614
- optionEl.selected = info.selected;
1615
- }
1643
+ optionEl.defaultSelected = info.defaultSelected;
1644
+ optionEl.selected = info.selected;
1616
1645
  if (info.disabled) {
1617
1646
  optionEl.disabled = true;
1618
1647
  }
@@ -125,6 +125,7 @@
125
125
  this.value = option.value === undefined ? option.text : option.value;
126
126
  this.text = option.text || '';
127
127
  this.html = option.html || '';
128
+ this.defaultSelected = option.defaultSelected !== undefined ? option.defaultSelected : false;
128
129
  this.selected = option.selected !== undefined ? option.selected : false;
129
130
  this.display = option.display !== undefined ? option.display : true;
130
131
  this.disabled = option.disabled !== undefined ? option.disabled : false;
@@ -373,6 +374,7 @@
373
374
  this.settings = settings;
374
375
  this.classes = classes;
375
376
  this.callbacks = callbacks;
377
+ this.lastSelectedOption = null;
376
378
  this.main = this.mainDiv();
377
379
  this.content = this.contentDiv();
378
380
  this.updateClassStyles();
@@ -435,9 +437,10 @@
435
437
  }
436
438
  }
437
439
  updateAriaAttributes() {
440
+ var _a;
438
441
  this.main.main.role = 'combobox';
439
442
  this.main.main.setAttribute('aria-haspopup', 'listbox');
440
- this.main.main.setAttribute('aria-controls', this.content.main.id);
443
+ this.main.main.setAttribute('aria-controls', (_a = this.content.main.dataset.id) !== null && _a !== void 0 ? _a : '');
441
444
  this.main.main.setAttribute('aria-expanded', 'false');
442
445
  this.content.main.setAttribute('role', 'listbox');
443
446
  }
@@ -696,6 +699,7 @@
696
699
  if (!option.mandatory) {
697
700
  const deleteDiv = document.createElement('div');
698
701
  deleteDiv.classList.add(this.classes.valueDelete);
702
+ deleteDiv.setAttribute('tabindex', '0');
699
703
  deleteDiv.onclick = (e) => {
700
704
  e.preventDefault();
701
705
  e.stopPropagation();
@@ -742,6 +746,11 @@
742
746
  deleteSvg.appendChild(deletePath);
743
747
  deleteDiv.appendChild(deleteSvg);
744
748
  value.appendChild(deleteDiv);
749
+ deleteDiv.onkeydown = (e) => {
750
+ if (e.key === 'Enter') {
751
+ deleteDiv.click();
752
+ }
753
+ };
745
754
  }
746
755
  return value;
747
756
  }
@@ -1029,6 +1038,7 @@
1029
1038
  }), true);
1030
1039
  }
1031
1040
  }
1041
+ const fragment = document.createDocumentFragment();
1032
1042
  for (const d of data) {
1033
1043
  if (d instanceof Optgroup) {
1034
1044
  const optgroupEl = document.createElement('div');
@@ -1137,13 +1147,14 @@
1137
1147
  optgroupEl.appendChild(optgroupLabel);
1138
1148
  for (const o of d.options) {
1139
1149
  optgroupEl.appendChild(this.option(o));
1150
+ fragment.appendChild(optgroupEl);
1140
1151
  }
1141
- this.content.list.appendChild(optgroupEl);
1142
1152
  }
1143
1153
  if (d instanceof Option) {
1144
- this.content.list.appendChild(this.option(d));
1154
+ fragment.appendChild(this.option(d));
1145
1155
  }
1146
1156
  }
1157
+ this.content.list.appendChild(fragment);
1147
1158
  }
1148
1159
  option(option) {
1149
1160
  if (option.placeholder) {
@@ -1216,6 +1227,24 @@
1216
1227
  }
1217
1228
  else {
1218
1229
  after = before.concat(option);
1230
+ if (!this.settings.closeOnSelect) {
1231
+ if (e.shiftKey && this.lastSelectedOption) {
1232
+ const options = this.store.getDataOptions();
1233
+ let lastClickedOptionIndex = options.findIndex((o) => o.id === this.lastSelectedOption.id);
1234
+ let currentOptionIndex = options.findIndex((o) => o.id === option.id);
1235
+ if (lastClickedOptionIndex >= 0 && currentOptionIndex >= 0) {
1236
+ const startIndex = Math.min(lastClickedOptionIndex, currentOptionIndex);
1237
+ const endIndex = Math.max(lastClickedOptionIndex, currentOptionIndex);
1238
+ const afterRange = options.slice(startIndex, endIndex + 1);
1239
+ if (afterRange.length > 0 && afterRange.length < this.settings.maxSelected) {
1240
+ after = before.concat(afterRange.filter((a) => !before.find((b) => b.id === a.id)));
1241
+ }
1242
+ }
1243
+ }
1244
+ else if (!option.selected) {
1245
+ this.lastSelectedOption = option;
1246
+ }
1247
+ }
1219
1248
  }
1220
1249
  }
1221
1250
  if (!this.settings.isMultiple) {
@@ -1477,6 +1506,7 @@
1477
1506
  value: option.value,
1478
1507
  text: option.text,
1479
1508
  html: option.dataset && option.dataset.html ? option.dataset.html : '',
1509
+ defaultSelected: option.defaultSelected,
1480
1510
  selected: option.selected,
1481
1511
  display: option.style.display !== 'none',
1482
1512
  disabled: option.disabled,
@@ -1613,9 +1643,8 @@
1613
1643
  if (info.html !== '') {
1614
1644
  optionEl.setAttribute('data-html', info.html);
1615
1645
  }
1616
- if (info.selected) {
1617
- optionEl.selected = info.selected;
1618
- }
1646
+ optionEl.defaultSelected = info.defaultSelected;
1647
+ optionEl.selected = info.selected;
1619
1648
  if (info.disabled) {
1620
1649
  optionEl.disabled = true;
1621
1650
  }