slim-select 2.3.2 → 2.4.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/dist/helpers.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export declare function generateID(): string;
2
2
  export declare function hasClassInTree(element: HTMLElement, className: string): any;
3
- export declare function debounce(func: (...params: any[]) => void, wait?: number, immediate?: boolean): () => void;
3
+ export declare function debounce<T extends (...args: any[]) => void>(func: T, wait?: number, immediate?: boolean): () => void;
4
4
  export declare function isEqual(a: any, b: any): boolean;
5
5
  export declare function kebabCase(str: string): string;
package/dist/index.d.ts CHANGED
@@ -36,10 +36,11 @@ export default class SlimSelect {
36
36
  setSelected(value: string | string[], runAfterChange?: boolean): void;
37
37
  addOption(option: OptionOptional): void;
38
38
  open(): void;
39
- close(): void;
39
+ close(eventType?: string | null): void;
40
40
  search(value: string): void;
41
41
  destroy(): void;
42
42
  private windowResize;
43
43
  private windowScroll;
44
44
  private documentClick;
45
+ private windowVisibilityChange;
45
46
  }
package/dist/render.d.ts CHANGED
@@ -91,8 +91,9 @@ export default class Render {
91
91
  open(): void;
92
92
  close(): void;
93
93
  updateClassStyles(): void;
94
+ updateAriaAttributes(): void;
94
95
  mainDiv(): Main;
95
- mainFocus(trigger: boolean): void;
96
+ mainFocus(trigger: boolean, eventType: string | null): void;
96
97
  placeholder(): HTMLDivElement;
97
98
  renderValues(): void;
98
99
  private renderSingleValue;
@@ -6,6 +6,7 @@ export default class Settings {
6
6
  class: string[];
7
7
  isMultiple: boolean;
8
8
  isOpen: boolean;
9
+ isWindowFocused: boolean;
9
10
  triggerFocus: boolean;
10
11
  intervalMove: NodeJS.Timeout | null;
11
12
  disabled: boolean;
@@ -59,6 +59,7 @@ class Settings {
59
59
  this.class = [];
60
60
  this.isMultiple = false;
61
61
  this.isOpen = false;
62
+ this.isWindowFocused = true;
62
63
  this.triggerFocus = true;
63
64
  this.intervalMove = null;
64
65
  if (!settings) {
@@ -346,6 +347,7 @@ class Render {
346
347
  this.main = this.mainDiv();
347
348
  this.content = this.contentDiv();
348
349
  this.updateClassStyles();
350
+ this.updateAriaAttributes();
349
351
  this.settings.contentLocation.appendChild(this.content.main);
350
352
  }
351
353
  enable() {
@@ -359,6 +361,7 @@ class Render {
359
361
  open() {
360
362
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
361
363
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
364
+ this.main.main.setAttribute('aria-expanded', 'true');
362
365
  this.moveContent();
363
366
  const selectedOptions = this.store.getSelectedOptions();
364
367
  if (selectedOptions.length) {
@@ -372,6 +375,7 @@ class Render {
372
375
  close() {
373
376
  this.main.main.classList.remove(this.classes.openAbove);
374
377
  this.main.main.classList.remove(this.classes.openBelow);
378
+ this.main.main.setAttribute('aria-expanded', 'false');
375
379
  this.content.main.classList.remove(this.classes.openAbove);
376
380
  this.content.main.classList.remove(this.classes.openBelow);
377
381
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -398,15 +402,18 @@ class Render {
398
402
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
399
403
  }
400
404
  }
405
+ updateAriaAttributes() {
406
+ this.main.main.role = 'combobox';
407
+ this.main.main.setAttribute('aria-haspopup', 'listbox');
408
+ this.main.main.setAttribute('aria-controls', this.content.main.id);
409
+ this.main.main.setAttribute('aria-expanded', 'false');
410
+ this.content.main.setAttribute('role', 'listbox');
411
+ }
401
412
  mainDiv() {
402
413
  const main = document.createElement('div');
403
414
  main.dataset.id = this.settings.id;
415
+ main.id = this.settings.id;
404
416
  main.tabIndex = 0;
405
- main.onfocus = () => {
406
- if (this.settings.triggerFocus) {
407
- this.callbacks.open();
408
- }
409
- };
410
417
  main.onkeydown = (e) => {
411
418
  switch (e.key) {
412
419
  case 'ArrowUp':
@@ -418,6 +425,8 @@ class Render {
418
425
  this.callbacks.close();
419
426
  return true;
420
427
  case 'Enter':
428
+ case ' ':
429
+ this.callbacks.open();
421
430
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
422
431
  if (highlighted) {
423
432
  highlighted.click();
@@ -494,11 +503,13 @@ class Render {
494
503
  },
495
504
  };
496
505
  }
497
- mainFocus(trigger) {
506
+ mainFocus(trigger, eventType) {
498
507
  if (!trigger) {
499
508
  this.settings.triggerFocus = false;
500
509
  }
501
- this.main.main.focus({ preventScroll: true });
510
+ if (eventType !== 'click') {
511
+ this.main.main.focus({ preventScroll: true });
512
+ }
502
513
  this.settings.triggerFocus = true;
503
514
  }
504
515
  placeholder() {
@@ -675,6 +686,7 @@ class Render {
675
686
  contentDiv() {
676
687
  const main = document.createElement('div');
677
688
  main.dataset.id = this.settings.id;
689
+ main.id = this.settings.id;
678
690
  const search = this.searchDiv();
679
691
  main.appendChild(search.main);
680
692
  const list = this.listDiv();
@@ -742,6 +754,7 @@ class Render {
742
754
  this.callbacks.close();
743
755
  return false;
744
756
  case 'Enter':
757
+ case ' ':
745
758
  if (this.callbacks.addable && e.ctrlKey) {
746
759
  addable.click();
747
760
  }
@@ -893,7 +906,6 @@ class Render {
893
906
  listDiv() {
894
907
  const options = document.createElement('div');
895
908
  options.classList.add(this.classes.list);
896
- options.setAttribute('role', 'listbox');
897
909
  return options;
898
910
  }
899
911
  renderError(error) {
@@ -1038,6 +1050,7 @@ class Render {
1038
1050
  }
1039
1051
  const optionEl = document.createElement('div');
1040
1052
  optionEl.dataset.id = option.id;
1053
+ optionEl.id = option.id;
1041
1054
  optionEl.classList.add(this.classes.option);
1042
1055
  optionEl.setAttribute('role', 'option');
1043
1056
  if (option.class) {
@@ -1071,9 +1084,12 @@ class Render {
1071
1084
  }
1072
1085
  if (option.selected) {
1073
1086
  optionEl.classList.add(this.classes.selected);
1087
+ optionEl.setAttribute('aria-selected', 'true');
1088
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1074
1089
  }
1075
1090
  else {
1076
1091
  optionEl.classList.remove(this.classes.selected);
1092
+ optionEl.setAttribute('aria-selected', 'false');
1077
1093
  }
1078
1094
  optionEl.addEventListener('click', (e) => {
1079
1095
  e.preventDefault();
@@ -1507,8 +1523,19 @@ class SlimSelect {
1507
1523
  return;
1508
1524
  }
1509
1525
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1526
+ this.close(e.type);
1527
+ }
1528
+ };
1529
+ this.windowVisibilityChange = () => {
1530
+ if (document.hidden) {
1531
+ this.settings.isWindowFocused = false;
1510
1532
  this.close();
1511
1533
  }
1534
+ else {
1535
+ setTimeout(() => {
1536
+ this.settings.isWindowFocused = true;
1537
+ }, 20);
1538
+ }
1512
1539
  };
1513
1540
  this.selectEl = (typeof config.select === 'string' ? document.querySelector(config.select) : config.select);
1514
1541
  if (!this.selectEl) {
@@ -1581,6 +1608,14 @@ class SlimSelect {
1581
1608
  this.render = new Render(this.settings, this.store, callbacks);
1582
1609
  this.render.renderValues();
1583
1610
  this.render.renderOptions(this.store.getData());
1611
+ const selectAriaLabel = this.selectEl.getAttribute('aria-label');
1612
+ const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby');
1613
+ if (selectAriaLabel) {
1614
+ this.render.main.main.setAttribute('aria-label', selectAriaLabel);
1615
+ }
1616
+ else if (selectAriaLabelledBy) {
1617
+ this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy);
1618
+ }
1584
1619
  if (this.selectEl.parentNode) {
1585
1620
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1586
1621
  }
@@ -1589,6 +1624,7 @@ class SlimSelect {
1589
1624
  if (this.settings.openPosition === 'auto') {
1590
1625
  window.addEventListener('scroll', this.windowScroll, false);
1591
1626
  }
1627
+ document.addEventListener('visibilitychange', this.windowVisibilityChange);
1592
1628
  if (this.settings.disabled) {
1593
1629
  this.disable();
1594
1630
  }
@@ -1649,7 +1685,9 @@ class SlimSelect {
1649
1685
  }
1650
1686
  addOption(option) {
1651
1687
  const selected = this.store.getSelected();
1652
- this.store.addOption(option);
1688
+ if (!this.store.getDataOptions().some((o) => { var _a; return o.value === ((_a = option.value) !== null && _a !== void 0 ? _a : option.text); })) {
1689
+ this.store.addOption(option);
1690
+ }
1653
1691
  const data = this.store.getData();
1654
1692
  this.select.updateOptions(data);
1655
1693
  this.render.renderValues();
@@ -1682,7 +1720,7 @@ class SlimSelect {
1682
1720
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1683
1721
  }
1684
1722
  }
1685
- close() {
1723
+ close(eventType = null) {
1686
1724
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1687
1725
  return;
1688
1726
  }
@@ -1693,7 +1731,7 @@ class SlimSelect {
1693
1731
  if (this.render.content.search.input.value !== '') {
1694
1732
  this.search('');
1695
1733
  }
1696
- this.render.mainFocus(false);
1734
+ this.render.mainFocus(false, eventType);
1697
1735
  setTimeout(() => {
1698
1736
  if (this.events.afterClose) {
1699
1737
  this.events.afterClose();
@@ -1737,6 +1775,7 @@ class SlimSelect {
1737
1775
  if (this.settings.openPosition === 'auto') {
1738
1776
  window.removeEventListener('scroll', this.windowScroll, false);
1739
1777
  }
1778
+ document.removeEventListener('visibilitychange', this.windowVisibilityChange);
1740
1779
  this.store.setData([]);
1741
1780
  this.render.destroy();
1742
1781
  this.select.destroy();
@@ -1 +1 @@
1
- :root{--ss-primary-color: #5897fb;--ss-bg-color: #ffffff;--ss-font-color: #4d4d4d;--ss-font-placeholder-color: #8d8d8d;--ss-disabled-color: #dcdee2;--ss-border-color: #dcdee2;--ss-highlight-color: #fffb8c;--ss-success-color: #00b755;--ss-error-color: #dc3545;--ss-main-height: 30px;--ss-content-height: 300px;--ss-spacing-l: 7px;--ss-spacing-m: 5px;--ss-spacing-s: 3px;--ss-animation-timing: 0.2s;--ss-border-radius: 4px}@keyframes ss-valueIn{0%{transform:scale(0);opacity:0}100%{transform:scale(1);opacity:1}}@keyframes ss-valueOut{0%{transform:scale(1);opacity:1}100%{transform:scale(0);opacity:0}}.ss-hide{display:none !important}.ss-main{display:flex;flex-direction:row;position:relative;user-select:none;color:var(--ss-font-color);min-height:var(--ss-main-height);width:100%;padding:var(--ss-spacing-s);cursor:pointer;border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius);background-color:var(--ss-bg-color);outline:0;box-sizing:border-box;transition:background-color var(--ss-animation-timing)}.ss-main:focus{box-shadow:0 0 5px var(--ss-primary-color)}.ss-main.ss-disabled{background-color:var(--ss-disabled-color);cursor:not-allowed}.ss-main.ss-disabled .ss-values .ss-disabled{color:var(--ss-font-color)}.ss-main.ss-disabled .ss-values .ss-value .ss-value-delete{cursor:not-allowed}.ss-main.ss-open-above{border-top-left-radius:0px;border-top-right-radius:0px}.ss-main.ss-open-below{border-bottom-left-radius:0px;border-bottom-right-radius:0px}.ss-main .ss-values{display:inline-flex;flex-wrap:wrap;gap:var(--ss-spacing-m);flex:1 1 100%}.ss-main .ss-values .ss-placeholder{display:flex;padding:var(--ss-spacing-s) var(--ss-spacing-m) var(--ss-spacing-s) var(--ss-spacing-m);margin:auto 0px auto 0px;line-height:1em;align-items:center;width:100%;color:var(--ss-font-placeholder-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ss-main .ss-values .ss-max{display:flex;user-select:none;align-items:center;width:fit-content;font-size:12px;color:var(--ss-bg-color);line-height:1;padding:var(--ss-spacing-s) var(--ss-spacing-m);background-color:var(--ss-primary-color);border-radius:var(--ss-border-radius)}.ss-main .ss-values .ss-single{display:flex;margin:auto 0px auto var(--ss-spacing-s)}.ss-main .ss-values .ss-value{display:flex;user-select:none;align-items:center;width:fit-content;background-color:var(--ss-primary-color);border-radius:var(--ss-border-radius);animation-name:ss-valueIn;animation-duration:var(--ss-animation-timing);animation-timing-function:ease-out;animation-fill-mode:both}.ss-main .ss-values .ss-value.ss-value-out{animation-name:ss-valueOut;animation-duration:var(--ss-animation-timing);animation-timing-function:ease-out}.ss-main .ss-values .ss-value .ss-value-text{font-size:12px;color:var(--ss-bg-color);line-height:1;padding:var(--ss-spacing-s) var(--ss-spacing-m)}.ss-main .ss-values .ss-value .ss-value-delete{display:flex;align-items:center;height:var(--ss-spacing-l);width:var(--ss-spacing-l);padding:var(--ss-spacing-s) var(--ss-spacing-m);cursor:pointer;border-left:solid 1px var(--ss-bg-color)}.ss-main .ss-values .ss-value .ss-value-delete svg{height:var(--ss-spacing-l);width:var(--ss-spacing-l)}.ss-main .ss-values .ss-value .ss-value-delete svg path{fill:none;stroke:var(--ss-bg-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round}.ss-main .ss-deselect{display:flex;align-self:center;justify-content:flex-end;flex:0 1 auto;width:8px;height:8px;margin:0 var(--ss-spacing-m) 0 var(--ss-spacing-m)}.ss-main .ss-deselect svg{width:8px;height:8px}.ss-main .ss-deselect svg path{fill:none;stroke:var(--ss-font-color);stroke-width:20;stroke-linecap:round;stroke-linejoin:round}.ss-main .ss-arrow{display:flex;align-items:center;justify-content:flex-end;flex:0 1 auto;width:12px;height:12px;margin:auto var(--ss-spacing-m) auto var(--ss-spacing-m)}.ss-main .ss-arrow path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round;transition-timing-function:ease-out;transition:var(--ss-animation-timing)}.ss-content{position:absolute;display:flex;height:auto;flex-direction:column;width:auto;max-height:var(--ss-content-height);box-sizing:border-box;border:solid 1px var(--ss-border-color);background-color:var(--ss-bg-color);transition:transform var(--ss-animation-timing),opacity var(--ss-animation-timing);opacity:0;transform:scaleY(0);transform-origin:center top;overflow:hidden;z-index:10000}.ss-content.ss-relative{position:relative;height:100%}.ss-content.ss-open-above{flex-direction:column-reverse;opacity:1;transform:scaleY(1);transform-origin:center bottom;border-top-left-radius:var(--ss-border-radius);border-top-right-radius:var(--ss-border-radius)}.ss-content.ss-open-below{opacity:1;transform:scaleY(1);transform-origin:center top;border-bottom-left-radius:var(--ss-border-radius);border-bottom-right-radius:var(--ss-border-radius)}.ss-content .ss-search{flex:0 1 auto;display:flex;flex-direction:row;padding:var(--ss-spacing-l) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l)}.ss-content .ss-search input{display:inline-flex;font-size:inherit;line-height:inherit;flex:1 1 auto;width:100%;min-width:0px;padding:var(--ss-spacing-m) var(--ss-spacing-l);margin:0;border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius);background-color:var(--ss-bg-color);outline:0;text-align:left;box-sizing:border-box}.ss-content .ss-search input::placeholder{color:var(--ss-font-placeholder-color);vertical-align:middle}.ss-content .ss-search input:focus{box-shadow:0 0 5px var(--ss-primary-color)}.ss-content .ss-search .ss-addable{display:inline-flex;justify-content:center;align-items:center;cursor:pointer;flex:0 0 auto;height:auto;margin:0 0 0 var(--ss-spacing-m);border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius)}.ss-content .ss-search .ss-addable svg{display:flex;align-items:center;justify-content:flex-end;flex:0 1 auto;width:12px;height:12px;margin:auto var(--ss-spacing-m) auto var(--ss-spacing-m)}.ss-content .ss-search .ss-addable svg path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round}.ss-content .ss-list{flex:1 1 auto;height:auto;overflow-x:hidden;overflow-y:auto}.ss-content .ss-list .ss-error{color:var(--ss-error-color);padding:var(--ss-spacing-l)}.ss-content .ss-list .ss-searching{color:var(--ss-font-color);padding:var(--ss-spacing-l)}.ss-content .ss-list .ss-optgroup.ss-close .ss-option{display:none !important}.ss-content .ss-list .ss-optgroup .ss-optgroup-label{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:var(--ss-spacing-m) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-label-text{flex:1 1 auto;font-weight:bold;color:var(--ss-font-color)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label:has(.ss-arrow){cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions{flex:0 1 auto;display:flex;flex-direction:row;align-items:center;justify-content:center;gap:var(--ss-spacing-m)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall{flex:0 0 auto;display:flex;flex-direction:row;cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall:hover{opacity:.5}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall.ss-selected svg path{stroke:var(--ss-error-color)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall span{flex:0 1 auto;display:flex;align-items:center;justify-content:center;font-size:60%;text-align:center;padding:0 var(--ss-spacing-s) 0 0}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg{flex:0 1 auto;width:13px;height:13px}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg path{fill:none;stroke:var(--ss-success-color);stroke-linecap:round;stroke-linejoin:round}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg:first-child{stroke-width:5}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg:last-child{stroke-width:11}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable{flex:0 1 auto;display:flex;flex-direction:row;cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable .ss-arrow{flex:1 1 auto;width:10px;height:10px}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable .ss-arrow path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round;transition-timing-function:ease-out;transition:var(--ss-animation-timing)}.ss-content .ss-list .ss-optgroup .ss-option{padding:var(--ss-spacing-s) var(--ss-spacing-s) var(--ss-spacing-s) calc(var(--ss-spacing-l)*3)}.ss-content .ss-list .ss-option{display:flex;padding:var(--ss-spacing-m) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l);color:var(--ss-font-color);cursor:pointer;user-select:none}.ss-content .ss-list .ss-option:hover{color:var(--ss-bg-color);background-color:var(--ss-primary-color)}.ss-content .ss-list .ss-option.ss-highlighted,.ss-content .ss-list .ss-option:not(.ss-disabled).ss-selected{color:var(--ss-bg-color);background-color:var(--ss-primary-color)}.ss-content .ss-list .ss-option.ss-disabled{cursor:not-allowed;background-color:var(--ss-disabled-color)}.ss-content .ss-list .ss-option.ss-disabled:hover{color:var(--ss-font-color)}.ss-content .ss-list .ss-option .ss-search-highlight{background-color:var(--ss-highlight-color)}/*# sourceMappingURL=slimselect.css.map */
1
+ :root{--ss-primary-color: #5897fb;--ss-bg-color: #ffffff;--ss-font-color: #4d4d4d;--ss-font-placeholder-color: #8d8d8d;--ss-disabled-color: #dcdee2;--ss-border-color: #dcdee2;--ss-highlight-color: #fffb8c;--ss-success-color: #00b755;--ss-error-color: #dc3545;--ss-main-height: 30px;--ss-content-height: 300px;--ss-spacing-l: 7px;--ss-spacing-m: 5px;--ss-spacing-s: 3px;--ss-animation-timing: 0.2s;--ss-border-radius: 4px}@keyframes ss-valueIn{0%{transform:scale(0);opacity:0}100%{transform:scale(1);opacity:1}}@keyframes ss-valueOut{0%{transform:scale(1);opacity:1}100%{transform:scale(0);opacity:0}}.ss-hide{display:none !important}.ss-main{display:flex;flex-direction:row;position:relative;user-select:none;color:var(--ss-font-color);min-height:var(--ss-main-height);width:100%;padding:var(--ss-spacing-s);cursor:pointer;border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius);background-color:var(--ss-bg-color);outline:0;box-sizing:border-box;transition:background-color var(--ss-animation-timing);overflow:hidden}.ss-main:focus{box-shadow:0 0 5px var(--ss-primary-color)}.ss-main.ss-disabled{background-color:var(--ss-disabled-color);cursor:not-allowed}.ss-main.ss-disabled .ss-values .ss-disabled{color:var(--ss-font-color)}.ss-main.ss-disabled .ss-values .ss-value .ss-value-delete{cursor:not-allowed}.ss-main.ss-open-above{border-top-left-radius:0px;border-top-right-radius:0px}.ss-main.ss-open-below{border-bottom-left-radius:0px;border-bottom-right-radius:0px}.ss-main .ss-values{display:inline-flex;flex-wrap:wrap;gap:var(--ss-spacing-m);flex:1 1 100%}.ss-main .ss-values .ss-placeholder{display:flex;padding:var(--ss-spacing-s) var(--ss-spacing-m) var(--ss-spacing-s) var(--ss-spacing-m);margin:auto 0px auto 0px;line-height:1em;align-items:center;width:100%;color:var(--ss-font-placeholder-color);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ss-main .ss-values .ss-max{display:flex;user-select:none;align-items:center;width:fit-content;font-size:12px;color:var(--ss-bg-color);line-height:1;padding:var(--ss-spacing-s) var(--ss-spacing-m);background-color:var(--ss-primary-color);border-radius:var(--ss-border-radius)}.ss-main .ss-values .ss-single{display:flex;margin:auto 0px auto var(--ss-spacing-s)}.ss-main .ss-values .ss-value{display:flex;user-select:none;align-items:center;width:fit-content;background-color:var(--ss-primary-color);border-radius:var(--ss-border-radius);animation-name:ss-valueIn;animation-duration:var(--ss-animation-timing);animation-timing-function:ease-out;animation-fill-mode:both}.ss-main .ss-values .ss-value.ss-value-out{animation-name:ss-valueOut;animation-duration:var(--ss-animation-timing);animation-timing-function:ease-out}.ss-main .ss-values .ss-value .ss-value-text{font-size:12px;color:var(--ss-bg-color);line-height:1;padding:var(--ss-spacing-s) var(--ss-spacing-m)}.ss-main .ss-values .ss-value .ss-value-delete{display:flex;align-items:center;height:var(--ss-spacing-l);width:var(--ss-spacing-l);padding:var(--ss-spacing-s) var(--ss-spacing-m);cursor:pointer;border-left:solid 1px var(--ss-bg-color)}.ss-main .ss-values .ss-value .ss-value-delete svg{height:var(--ss-spacing-l);width:var(--ss-spacing-l)}.ss-main .ss-values .ss-value .ss-value-delete svg path{fill:none;stroke:var(--ss-bg-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round}.ss-main .ss-deselect{display:flex;align-self:center;justify-content:flex-end;flex:0 1 auto;width:8px;height:8px;margin:0 var(--ss-spacing-m) 0 var(--ss-spacing-m)}.ss-main .ss-deselect svg{width:8px;height:8px}.ss-main .ss-deselect svg path{fill:none;stroke:var(--ss-font-color);stroke-width:20;stroke-linecap:round;stroke-linejoin:round}.ss-main .ss-arrow{display:flex;align-items:center;justify-content:flex-end;flex:0 1 auto;width:12px;height:12px;margin:auto var(--ss-spacing-m) auto var(--ss-spacing-m)}.ss-main .ss-arrow path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round;transition-timing-function:ease-out;transition:var(--ss-animation-timing)}.ss-content{position:absolute;display:flex;height:auto;flex-direction:column;width:auto;max-height:var(--ss-content-height);box-sizing:border-box;border:solid 1px var(--ss-border-color);background-color:var(--ss-bg-color);transition:transform var(--ss-animation-timing),opacity var(--ss-animation-timing);opacity:0;transform:scaleY(0);transform-origin:center top;overflow:hidden;z-index:10000}.ss-content.ss-relative{position:relative;height:100%}.ss-content.ss-open-above{flex-direction:column-reverse;opacity:1;transform:scaleY(1);transform-origin:center bottom;border-top-left-radius:var(--ss-border-radius);border-top-right-radius:var(--ss-border-radius)}.ss-content.ss-open-below{opacity:1;transform:scaleY(1);transform-origin:center top;border-bottom-left-radius:var(--ss-border-radius);border-bottom-right-radius:var(--ss-border-radius)}.ss-content .ss-search{flex:0 1 auto;display:flex;flex-direction:row;padding:var(--ss-spacing-l) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l)}.ss-content .ss-search input{display:inline-flex;font-size:inherit;line-height:inherit;flex:1 1 auto;width:100%;min-width:0px;padding:var(--ss-spacing-m) var(--ss-spacing-l);margin:0;border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius);background-color:var(--ss-bg-color);outline:0;text-align:left;box-sizing:border-box}.ss-content .ss-search input::placeholder{color:var(--ss-font-placeholder-color);vertical-align:middle}.ss-content .ss-search input:focus{box-shadow:0 0 5px var(--ss-primary-color)}.ss-content .ss-search .ss-addable{display:inline-flex;justify-content:center;align-items:center;cursor:pointer;flex:0 0 auto;height:auto;margin:0 0 0 var(--ss-spacing-m);border:1px solid var(--ss-border-color);border-radius:var(--ss-border-radius)}.ss-content .ss-search .ss-addable svg{display:flex;align-items:center;justify-content:flex-end;flex:0 1 auto;width:12px;height:12px;margin:auto var(--ss-spacing-m) auto var(--ss-spacing-m)}.ss-content .ss-search .ss-addable svg path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round}.ss-content .ss-list{flex:1 1 auto;height:auto;overflow-x:hidden;overflow-y:auto}.ss-content .ss-list .ss-error{color:var(--ss-error-color);padding:var(--ss-spacing-l)}.ss-content .ss-list .ss-searching{color:var(--ss-font-color);padding:var(--ss-spacing-l)}.ss-content .ss-list .ss-optgroup.ss-close .ss-option{display:none !important}.ss-content .ss-list .ss-optgroup .ss-optgroup-label{display:flex;flex-direction:row;align-items:center;justify-content:space-between;padding:var(--ss-spacing-m) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-label-text{flex:1 1 auto;font-weight:bold;color:var(--ss-font-color)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label:has(.ss-arrow){cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions{flex:0 1 auto;display:flex;flex-direction:row;align-items:center;justify-content:center;gap:var(--ss-spacing-m)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall{flex:0 0 auto;display:flex;flex-direction:row;cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall:hover{opacity:.5}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall.ss-selected svg path{stroke:var(--ss-error-color)}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall span{flex:0 1 auto;display:flex;align-items:center;justify-content:center;font-size:60%;text-align:center;padding:0 var(--ss-spacing-s) 0 0}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg{flex:0 1 auto;width:13px;height:13px}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg path{fill:none;stroke:var(--ss-success-color);stroke-linecap:round;stroke-linejoin:round}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg:first-child{stroke-width:5}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-selectall svg:last-child{stroke-width:11}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable{flex:0 1 auto;display:flex;flex-direction:row;cursor:pointer}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable .ss-arrow{flex:1 1 auto;width:10px;height:10px}.ss-content .ss-list .ss-optgroup .ss-optgroup-label .ss-optgroup-actions .ss-closable .ss-arrow path{fill:none;stroke:var(--ss-font-color);stroke-width:18;stroke-linecap:round;stroke-linejoin:round;transition-timing-function:ease-out;transition:var(--ss-animation-timing)}.ss-content .ss-list .ss-optgroup .ss-option{padding:var(--ss-spacing-s) var(--ss-spacing-s) var(--ss-spacing-s) calc(var(--ss-spacing-l)*3)}.ss-content .ss-list .ss-option{display:flex;padding:var(--ss-spacing-m) var(--ss-spacing-l) var(--ss-spacing-m) var(--ss-spacing-l);color:var(--ss-font-color);cursor:pointer;user-select:none}.ss-content .ss-list .ss-option:hover{color:var(--ss-bg-color);background-color:var(--ss-primary-color)}.ss-content .ss-list .ss-option.ss-highlighted,.ss-content .ss-list .ss-option:not(.ss-disabled).ss-selected{color:var(--ss-bg-color);background-color:var(--ss-primary-color)}.ss-content .ss-list .ss-option.ss-disabled{cursor:not-allowed;background-color:var(--ss-disabled-color)}.ss-content .ss-list .ss-option.ss-disabled:hover{color:var(--ss-font-color)}.ss-content .ss-list .ss-option .ss-search-highlight{background-color:var(--ss-highlight-color)}/*# sourceMappingURL=slimselect.css.map */
@@ -1 +1 @@
1
- {"version":3,"sourceRoot":"","sources":["../src/slim-select/slimselect.scss"],"names":[],"mappings":"AAAA,MAEE,4BACA,uBACA,yBACA,qCACA,6BACA,2BACA,8BACA,4BACA,0BAGA,uBACA,2BAGA,oBACA,oBACA,oBAGA,4BACA,wBAIF,sBACE,GACE,mBACA,UAEF,KACE,mBACA,WAGJ,uBACE,GACE,mBACA,UAEF,KACE,mBACA,WAKJ,SACE,wBAIF,SACE,aACA,mBACA,kBACA,iBACA,2BACA,iCACA,WACA,4BACA,eACA,wCACA,sCACA,oCACA,UACA,sBACA,uDAEA,eACE,2CAGF,qBACE,0CACA,mBAGE,6CACE,2BAIA,2DACE,mBAMR,uBACE,2BACA,4BAEF,uBACE,8BACA,+BAGF,oBACE,oBACA,eACA,wBACA,cAEA,oCACE,aACA,wFACA,yBACA,gBACA,mBACA,WACA,uCACA,gBACA,uBACA,mBAIF,4BACE,aACA,iBACA,mBACA,kBACA,eACA,yBACA,cACA,gDACA,yCACA,sCAIF,+BACE,aACA,yCAIF,8BACE,aACA,iBACA,mBACA,kBACA,yCACA,sCACA,0BACA,8CACA,mCACA,yBAEA,2CACE,2BACA,8CACA,mCAGF,6CACE,eACA,yBACA,cACA,gDAGF,+CACE,aACA,mBACA,2BACA,0BACA,gDACA,eACA,yCAEA,mDACE,2BACA,0BAEA,wDACE,UACA,0BACA,gBACA,qBACA,sBAOV,sBACE,aACA,kBACA,yBACA,cACA,UACA,WACA,mDAEA,0BACE,UACA,WAEA,+BACE,UACA,4BACA,gBACA,qBACA,sBAKN,mBACE,aACA,mBACA,yBACA,cACA,WACA,YACA,yDAEA,wBACE,UACA,4BACA,gBACA,qBACA,sBACA,oCACA,sCAMN,YACE,kBACA,aACA,YACA,sBACA,WACA,oCACA,sBACA,wCACA,oCACA,mFACA,UACA,oBACA,4BACA,gBACA,cAEA,wBACE,kBACA,YAGF,0BACE,8BACA,UACA,oBACA,+BACA,+CACA,gDAGF,0BACE,UACA,oBACA,4BACA,kDACA,mDAGF,uBACE,cACA,aACA,mBACA,wFAEA,6BACE,oBACA,kBACA,oBACA,cACA,WACA,cACA,gDACA,SACA,wCACA,sCACA,oCACA,UACA,gBACA,sBAEA,0CACE,uCACA,sBAGF,mCACE,2CAIJ,mCACE,oBACA,uBACA,mBACA,eACA,cACA,YACA,iCACA,wCACA,sCAEA,uCACE,aACA,mBACA,yBACA,cACA,WACA,YACA,yDAEA,4CACE,UACA,4BACA,gBACA,qBACA,sBAMR,qBACE,cACA,YACA,kBACA,gBAEA,+BACE,4BACA,4BAGF,mCACE,2BACA,4BAYE,sDACE,wBAIJ,qDACE,aACA,mBACA,mBACA,8BACA,wFAEA,6EACE,cACA,iBACA,2BAIF,oEACE,eAGF,0EACE,cACA,aACA,mBACA,mBACA,uBACA,wBAEA,wFACE,cACA,aACA,mBACA,eAEA,8FACE,WAKE,6GACE,6BAKN,6FACE,cACA,aACA,mBACA,uBACA,cACA,kBACA,kCAGF,4FACE,cACA,WACA,YAEA,iGACE,UACA,+BACA,qBACA,sBAGF,wGACE,eAEF,uGACE,gBAKN,uFACE,cACA,aACA,mBACA,eAEA,iGACE,cACA,WACA,YAEA,sGACE,UACA,4BACA,gBACA,qBACA,sBACA,oCACA,sCAOV,6CACE,gGAIJ,gCACE,aACA,wFACA,2BACA,eACA,iBAEA,sCACE,yBACA,yCAGF,6GAEE,yBACA,yCAGF,4CACE,mBACA,0CAEA,kDACE,2BAKJ,qDACE","file":"slimselect.css"}
1
+ {"version":3,"sourceRoot":"","sources":["../src/slim-select/slimselect.scss"],"names":[],"mappings":"AAAA,MAEE,4BACA,uBACA,yBACA,qCACA,6BACA,2BACA,8BACA,4BACA,0BAGA,uBACA,2BAGA,oBACA,oBACA,oBAGA,4BACA,wBAIF,sBACE,GACE,mBACA,UAEF,KACE,mBACA,WAGJ,uBACE,GACE,mBACA,UAEF,KACE,mBACA,WAKJ,SACE,wBAIF,SACE,aACA,mBACA,kBACA,iBACA,2BACA,iCACA,WACA,4BACA,eACA,wCACA,sCACA,oCACA,UACA,sBACA,uDACA,gBAEA,eACE,2CAGF,qBACE,0CACA,mBAGE,6CACE,2BAIA,2DACE,mBAMR,uBACE,2BACA,4BAEF,uBACE,8BACA,+BAGF,oBACE,oBACA,eACA,wBACA,cAEA,oCACE,aACA,wFACA,yBACA,gBACA,mBACA,WACA,uCACA,gBACA,uBACA,mBAIF,4BACE,aACA,iBACA,mBACA,kBACA,eACA,yBACA,cACA,gDACA,yCACA,sCAIF,+BACE,aACA,yCAIF,8BACE,aACA,iBACA,mBACA,kBACA,yCACA,sCACA,0BACA,8CACA,mCACA,yBAEA,2CACE,2BACA,8CACA,mCAGF,6CACE,eACA,yBACA,cACA,gDAGF,+CACE,aACA,mBACA,2BACA,0BACA,gDACA,eACA,yCAEA,mDACE,2BACA,0BAEA,wDACE,UACA,0BACA,gBACA,qBACA,sBAOV,sBACE,aACA,kBACA,yBACA,cACA,UACA,WACA,mDAEA,0BACE,UACA,WAEA,+BACE,UACA,4BACA,gBACA,qBACA,sBAKN,mBACE,aACA,mBACA,yBACA,cACA,WACA,YACA,yDAEA,wBACE,UACA,4BACA,gBACA,qBACA,sBACA,oCACA,sCAMN,YACE,kBACA,aACA,YACA,sBACA,WACA,oCACA,sBACA,wCACA,oCACA,mFACA,UACA,oBACA,4BACA,gBACA,cAEA,wBACE,kBACA,YAGF,0BACE,8BACA,UACA,oBACA,+BACA,+CACA,gDAGF,0BACE,UACA,oBACA,4BACA,kDACA,mDAGF,uBACE,cACA,aACA,mBACA,wFAEA,6BACE,oBACA,kBACA,oBACA,cACA,WACA,cACA,gDACA,SACA,wCACA,sCACA,oCACA,UACA,gBACA,sBAEA,0CACE,uCACA,sBAGF,mCACE,2CAIJ,mCACE,oBACA,uBACA,mBACA,eACA,cACA,YACA,iCACA,wCACA,sCAEA,uCACE,aACA,mBACA,yBACA,cACA,WACA,YACA,yDAEA,4CACE,UACA,4BACA,gBACA,qBACA,sBAMR,qBACE,cACA,YACA,kBACA,gBAEA,+BACE,4BACA,4BAGF,mCACE,2BACA,4BAYE,sDACE,wBAIJ,qDACE,aACA,mBACA,mBACA,8BACA,wFAEA,6EACE,cACA,iBACA,2BAIF,oEACE,eAGF,0EACE,cACA,aACA,mBACA,mBACA,uBACA,wBAEA,wFACE,cACA,aACA,mBACA,eAEA,8FACE,WAKE,6GACE,6BAKN,6FACE,cACA,aACA,mBACA,uBACA,cACA,kBACA,kCAGF,4FACE,cACA,WACA,YAEA,iGACE,UACA,+BACA,qBACA,sBAGF,wGACE,eAEF,uGACE,gBAKN,uFACE,cACA,aACA,mBACA,eAEA,iGACE,cACA,WACA,YAEA,sGACE,UACA,4BACA,gBACA,qBACA,sBACA,oCACA,sCAOV,6CACE,gGAIJ,gCACE,aACA,wFACA,2BACA,eACA,iBAEA,sCACE,yBACA,yCAGF,6GAEE,yBACA,yCAGF,4CACE,mBACA,0CAEA,kDACE,2BAKJ,qDACE","file":"slimselect.css"}
@@ -57,6 +57,7 @@ class Settings {
57
57
  this.class = [];
58
58
  this.isMultiple = false;
59
59
  this.isOpen = false;
60
+ this.isWindowFocused = true;
60
61
  this.triggerFocus = true;
61
62
  this.intervalMove = null;
62
63
  if (!settings) {
@@ -344,6 +345,7 @@ class Render {
344
345
  this.main = this.mainDiv();
345
346
  this.content = this.contentDiv();
346
347
  this.updateClassStyles();
348
+ this.updateAriaAttributes();
347
349
  this.settings.contentLocation.appendChild(this.content.main);
348
350
  }
349
351
  enable() {
@@ -357,6 +359,7 @@ class Render {
357
359
  open() {
358
360
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
359
361
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
362
+ this.main.main.setAttribute('aria-expanded', 'true');
360
363
  this.moveContent();
361
364
  const selectedOptions = this.store.getSelectedOptions();
362
365
  if (selectedOptions.length) {
@@ -370,6 +373,7 @@ class Render {
370
373
  close() {
371
374
  this.main.main.classList.remove(this.classes.openAbove);
372
375
  this.main.main.classList.remove(this.classes.openBelow);
376
+ this.main.main.setAttribute('aria-expanded', 'false');
373
377
  this.content.main.classList.remove(this.classes.openAbove);
374
378
  this.content.main.classList.remove(this.classes.openBelow);
375
379
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -396,15 +400,18 @@ class Render {
396
400
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
397
401
  }
398
402
  }
403
+ updateAriaAttributes() {
404
+ this.main.main.role = 'combobox';
405
+ this.main.main.setAttribute('aria-haspopup', 'listbox');
406
+ this.main.main.setAttribute('aria-controls', this.content.main.id);
407
+ this.main.main.setAttribute('aria-expanded', 'false');
408
+ this.content.main.setAttribute('role', 'listbox');
409
+ }
399
410
  mainDiv() {
400
411
  const main = document.createElement('div');
401
412
  main.dataset.id = this.settings.id;
413
+ main.id = this.settings.id;
402
414
  main.tabIndex = 0;
403
- main.onfocus = () => {
404
- if (this.settings.triggerFocus) {
405
- this.callbacks.open();
406
- }
407
- };
408
415
  main.onkeydown = (e) => {
409
416
  switch (e.key) {
410
417
  case 'ArrowUp':
@@ -416,6 +423,8 @@ class Render {
416
423
  this.callbacks.close();
417
424
  return true;
418
425
  case 'Enter':
426
+ case ' ':
427
+ this.callbacks.open();
419
428
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
420
429
  if (highlighted) {
421
430
  highlighted.click();
@@ -492,11 +501,13 @@ class Render {
492
501
  },
493
502
  };
494
503
  }
495
- mainFocus(trigger) {
504
+ mainFocus(trigger, eventType) {
496
505
  if (!trigger) {
497
506
  this.settings.triggerFocus = false;
498
507
  }
499
- this.main.main.focus({ preventScroll: true });
508
+ if (eventType !== 'click') {
509
+ this.main.main.focus({ preventScroll: true });
510
+ }
500
511
  this.settings.triggerFocus = true;
501
512
  }
502
513
  placeholder() {
@@ -673,6 +684,7 @@ class Render {
673
684
  contentDiv() {
674
685
  const main = document.createElement('div');
675
686
  main.dataset.id = this.settings.id;
687
+ main.id = this.settings.id;
676
688
  const search = this.searchDiv();
677
689
  main.appendChild(search.main);
678
690
  const list = this.listDiv();
@@ -740,6 +752,7 @@ class Render {
740
752
  this.callbacks.close();
741
753
  return false;
742
754
  case 'Enter':
755
+ case ' ':
743
756
  if (this.callbacks.addable && e.ctrlKey) {
744
757
  addable.click();
745
758
  }
@@ -891,7 +904,6 @@ class Render {
891
904
  listDiv() {
892
905
  const options = document.createElement('div');
893
906
  options.classList.add(this.classes.list);
894
- options.setAttribute('role', 'listbox');
895
907
  return options;
896
908
  }
897
909
  renderError(error) {
@@ -1036,6 +1048,7 @@ class Render {
1036
1048
  }
1037
1049
  const optionEl = document.createElement('div');
1038
1050
  optionEl.dataset.id = option.id;
1051
+ optionEl.id = option.id;
1039
1052
  optionEl.classList.add(this.classes.option);
1040
1053
  optionEl.setAttribute('role', 'option');
1041
1054
  if (option.class) {
@@ -1069,9 +1082,12 @@ class Render {
1069
1082
  }
1070
1083
  if (option.selected) {
1071
1084
  optionEl.classList.add(this.classes.selected);
1085
+ optionEl.setAttribute('aria-selected', 'true');
1086
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1072
1087
  }
1073
1088
  else {
1074
1089
  optionEl.classList.remove(this.classes.selected);
1090
+ optionEl.setAttribute('aria-selected', 'false');
1075
1091
  }
1076
1092
  optionEl.addEventListener('click', (e) => {
1077
1093
  e.preventDefault();
@@ -1505,8 +1521,19 @@ class SlimSelect {
1505
1521
  return;
1506
1522
  }
1507
1523
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1524
+ this.close(e.type);
1525
+ }
1526
+ };
1527
+ this.windowVisibilityChange = () => {
1528
+ if (document.hidden) {
1529
+ this.settings.isWindowFocused = false;
1508
1530
  this.close();
1509
1531
  }
1532
+ else {
1533
+ setTimeout(() => {
1534
+ this.settings.isWindowFocused = true;
1535
+ }, 20);
1536
+ }
1510
1537
  };
1511
1538
  this.selectEl = (typeof config.select === 'string' ? document.querySelector(config.select) : config.select);
1512
1539
  if (!this.selectEl) {
@@ -1579,6 +1606,14 @@ class SlimSelect {
1579
1606
  this.render = new Render(this.settings, this.store, callbacks);
1580
1607
  this.render.renderValues();
1581
1608
  this.render.renderOptions(this.store.getData());
1609
+ const selectAriaLabel = this.selectEl.getAttribute('aria-label');
1610
+ const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby');
1611
+ if (selectAriaLabel) {
1612
+ this.render.main.main.setAttribute('aria-label', selectAriaLabel);
1613
+ }
1614
+ else if (selectAriaLabelledBy) {
1615
+ this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy);
1616
+ }
1582
1617
  if (this.selectEl.parentNode) {
1583
1618
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1584
1619
  }
@@ -1587,6 +1622,7 @@ class SlimSelect {
1587
1622
  if (this.settings.openPosition === 'auto') {
1588
1623
  window.addEventListener('scroll', this.windowScroll, false);
1589
1624
  }
1625
+ document.addEventListener('visibilitychange', this.windowVisibilityChange);
1590
1626
  if (this.settings.disabled) {
1591
1627
  this.disable();
1592
1628
  }
@@ -1647,7 +1683,9 @@ class SlimSelect {
1647
1683
  }
1648
1684
  addOption(option) {
1649
1685
  const selected = this.store.getSelected();
1650
- this.store.addOption(option);
1686
+ if (!this.store.getDataOptions().some((o) => { var _a; return o.value === ((_a = option.value) !== null && _a !== void 0 ? _a : option.text); })) {
1687
+ this.store.addOption(option);
1688
+ }
1651
1689
  const data = this.store.getData();
1652
1690
  this.select.updateOptions(data);
1653
1691
  this.render.renderValues();
@@ -1680,7 +1718,7 @@ class SlimSelect {
1680
1718
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1681
1719
  }
1682
1720
  }
1683
- close() {
1721
+ close(eventType = null) {
1684
1722
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1685
1723
  return;
1686
1724
  }
@@ -1691,7 +1729,7 @@ class SlimSelect {
1691
1729
  if (this.render.content.search.input.value !== '') {
1692
1730
  this.search('');
1693
1731
  }
1694
- this.render.mainFocus(false);
1732
+ this.render.mainFocus(false, eventType);
1695
1733
  setTimeout(() => {
1696
1734
  if (this.events.afterClose) {
1697
1735
  this.events.afterClose();
@@ -1735,6 +1773,7 @@ class SlimSelect {
1735
1773
  if (this.settings.openPosition === 'auto') {
1736
1774
  window.removeEventListener('scroll', this.windowScroll, false);
1737
1775
  }
1776
+ document.removeEventListener('visibilitychange', this.windowVisibilityChange);
1738
1777
  this.store.setData([]);
1739
1778
  this.render.destroy();
1740
1779
  this.select.destroy();