slim-select 2.3.3 → 2.4.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.
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,7 +36,7 @@ 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;
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(eventType: string | null): void;
96
97
  placeholder(): HTMLDivElement;
97
98
  renderValues(): void;
98
99
  private renderSingleValue;
@@ -101,7 +102,7 @@ export default class Render {
101
102
  contentDiv(): Content;
102
103
  moveContent(): void;
103
104
  searchDiv(): Search;
104
- searchFocus(trigger: boolean): void;
105
+ searchFocus(): void;
105
106
  getOptions(notPlaceholder?: boolean, notDisabled?: boolean, notHidden?: boolean): HTMLDivElement[];
106
107
  highlight(dir: 'up' | 'down'): void;
107
108
  listDiv(): HTMLDivElement;
@@ -6,8 +6,7 @@ export default class Settings {
6
6
  class: string[];
7
7
  isMultiple: boolean;
8
8
  isOpen: boolean;
9
- isWindowFocused: boolean;
10
- triggerFocus: boolean;
9
+ isFullOpen: boolean;
11
10
  intervalMove: NodeJS.Timeout | null;
12
11
  disabled: boolean;
13
12
  alwaysOpen: boolean;
@@ -59,8 +59,7 @@ class Settings {
59
59
  this.class = [];
60
60
  this.isMultiple = false;
61
61
  this.isOpen = false;
62
- this.isWindowFocused = true;
63
- this.triggerFocus = true;
62
+ this.isFullOpen = false;
64
63
  this.intervalMove = null;
65
64
  if (!settings) {
66
65
  settings = {};
@@ -347,6 +346,7 @@ class Render {
347
346
  this.main = this.mainDiv();
348
347
  this.content = this.contentDiv();
349
348
  this.updateClassStyles();
349
+ this.updateAriaAttributes();
350
350
  this.settings.contentLocation.appendChild(this.content.main);
351
351
  }
352
352
  enable() {
@@ -360,6 +360,7 @@ class Render {
360
360
  open() {
361
361
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
362
362
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
363
+ this.main.main.setAttribute('aria-expanded', 'true');
363
364
  this.moveContent();
364
365
  const selectedOptions = this.store.getSelectedOptions();
365
366
  if (selectedOptions.length) {
@@ -373,6 +374,7 @@ class Render {
373
374
  close() {
374
375
  this.main.main.classList.remove(this.classes.openAbove);
375
376
  this.main.main.classList.remove(this.classes.openBelow);
377
+ this.main.main.setAttribute('aria-expanded', 'false');
376
378
  this.content.main.classList.remove(this.classes.openAbove);
377
379
  this.content.main.classList.remove(this.classes.openBelow);
378
380
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -399,15 +401,18 @@ class Render {
399
401
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
400
402
  }
401
403
  }
404
+ updateAriaAttributes() {
405
+ this.main.main.role = 'combobox';
406
+ this.main.main.setAttribute('aria-haspopup', 'listbox');
407
+ this.main.main.setAttribute('aria-controls', this.content.main.id);
408
+ this.main.main.setAttribute('aria-expanded', 'false');
409
+ this.content.main.setAttribute('role', 'listbox');
410
+ }
402
411
  mainDiv() {
403
412
  const main = document.createElement('div');
404
413
  main.dataset.id = this.settings.id;
414
+ main.id = this.settings.id;
405
415
  main.tabIndex = 0;
406
- main.onfocus = () => {
407
- if (this.settings.triggerFocus && this.settings.isWindowFocused) {
408
- this.callbacks.open();
409
- }
410
- };
411
416
  main.onkeydown = (e) => {
412
417
  switch (e.key) {
413
418
  case 'ArrowUp':
@@ -419,6 +424,8 @@ class Render {
419
424
  this.callbacks.close();
420
425
  return true;
421
426
  case 'Enter':
427
+ case ' ':
428
+ this.callbacks.open();
422
429
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
423
430
  if (highlighted) {
424
431
  highlighted.click();
@@ -495,12 +502,10 @@ class Render {
495
502
  },
496
503
  };
497
504
  }
498
- mainFocus(trigger) {
499
- if (!trigger) {
500
- this.settings.triggerFocus = false;
505
+ mainFocus(eventType) {
506
+ if (eventType !== 'click') {
507
+ this.main.main.focus({ preventScroll: true });
501
508
  }
502
- this.main.main.focus({ preventScroll: true });
503
- this.settings.triggerFocus = true;
504
509
  }
505
510
  placeholder() {
506
511
  const placeholderOption = this.store.filter((o) => o.placeholder, false);
@@ -676,6 +681,7 @@ class Render {
676
681
  contentDiv() {
677
682
  const main = document.createElement('div');
678
683
  main.dataset.id = this.settings.id;
684
+ main.id = this.settings.id;
679
685
  const search = this.searchDiv();
680
686
  main.appendChild(search.main);
681
687
  const list = this.listDiv();
@@ -733,7 +739,6 @@ class Render {
733
739
  switch (e.key) {
734
740
  case 'ArrowUp':
735
741
  case 'ArrowDown':
736
- this.callbacks.open();
737
742
  e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up');
738
743
  return false;
739
744
  case 'Tab':
@@ -743,6 +748,7 @@ class Render {
743
748
  this.callbacks.close();
744
749
  return false;
745
750
  case 'Enter':
751
+ case ' ':
746
752
  if (this.callbacks.addable && e.ctrlKey) {
747
753
  addable.click();
748
754
  }
@@ -755,12 +761,6 @@ class Render {
755
761
  return false;
756
762
  }
757
763
  };
758
- input.onfocus = () => {
759
- if (this.settings.isOpen) {
760
- return;
761
- }
762
- this.callbacks.open();
763
- };
764
764
  main.appendChild(input);
765
765
  if (this.callbacks.addable) {
766
766
  addable.classList.add(this.classes.addable);
@@ -833,12 +833,8 @@ class Render {
833
833
  }
834
834
  return searchReturn;
835
835
  }
836
- searchFocus(trigger) {
837
- if (!trigger) {
838
- this.settings.triggerFocus = false;
839
- }
836
+ searchFocus() {
840
837
  this.content.search.input.focus();
841
- this.settings.triggerFocus = true;
842
838
  }
843
839
  getOptions(notPlaceholder = false, notDisabled = false, notHidden = false) {
844
840
  let query = '.' + this.classes.option;
@@ -894,7 +890,6 @@ class Render {
894
890
  listDiv() {
895
891
  const options = document.createElement('div');
896
892
  options.classList.add(this.classes.list);
897
- options.setAttribute('role', 'listbox');
898
893
  return options;
899
894
  }
900
895
  renderError(error) {
@@ -1039,6 +1034,7 @@ class Render {
1039
1034
  }
1040
1035
  const optionEl = document.createElement('div');
1041
1036
  optionEl.dataset.id = option.id;
1037
+ optionEl.id = option.id;
1042
1038
  optionEl.classList.add(this.classes.option);
1043
1039
  optionEl.setAttribute('role', 'option');
1044
1040
  if (option.class) {
@@ -1072,9 +1068,12 @@ class Render {
1072
1068
  }
1073
1069
  if (option.selected) {
1074
1070
  optionEl.classList.add(this.classes.selected);
1071
+ optionEl.setAttribute('aria-selected', 'true');
1072
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1075
1073
  }
1076
1074
  else {
1077
1075
  optionEl.classList.remove(this.classes.selected);
1076
+ optionEl.setAttribute('aria-selected', 'false');
1078
1077
  }
1079
1078
  optionEl.addEventListener('click', (e) => {
1080
1079
  e.preventDefault();
@@ -1492,13 +1491,13 @@ class SlimSelect {
1492
1491
  afterClose: undefined,
1493
1492
  };
1494
1493
  this.windowResize = debounce(() => {
1495
- if (!this.settings.isOpen) {
1494
+ if (!this.settings.isOpen && !this.settings.isFullOpen) {
1496
1495
  return;
1497
1496
  }
1498
1497
  this.render.moveContent();
1499
1498
  });
1500
1499
  this.windowScroll = debounce(() => {
1501
- if (!this.settings.isOpen) {
1500
+ if (!this.settings.isOpen && !this.settings.isFullOpen) {
1502
1501
  return;
1503
1502
  }
1504
1503
  this.render.moveContent();
@@ -1508,19 +1507,13 @@ class SlimSelect {
1508
1507
  return;
1509
1508
  }
1510
1509
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1511
- this.close();
1510
+ this.close(e.type);
1512
1511
  }
1513
1512
  };
1514
1513
  this.windowVisibilityChange = () => {
1515
1514
  if (document.hidden) {
1516
- this.settings.isWindowFocused = false;
1517
1515
  this.close();
1518
1516
  }
1519
- else {
1520
- setTimeout(() => {
1521
- this.settings.isWindowFocused = true;
1522
- }, 20);
1523
- }
1524
1517
  };
1525
1518
  this.selectEl = (typeof config.select === 'string' ? document.querySelector(config.select) : config.select);
1526
1519
  if (!this.selectEl) {
@@ -1593,6 +1586,14 @@ class SlimSelect {
1593
1586
  this.render = new Render(this.settings, this.store, callbacks);
1594
1587
  this.render.renderValues();
1595
1588
  this.render.renderOptions(this.store.getData());
1589
+ const selectAriaLabel = this.selectEl.getAttribute('aria-label');
1590
+ const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby');
1591
+ if (selectAriaLabel) {
1592
+ this.render.main.main.setAttribute('aria-label', selectAriaLabel);
1593
+ }
1594
+ else if (selectAriaLabelledBy) {
1595
+ this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy);
1596
+ }
1596
1597
  if (this.selectEl.parentNode) {
1597
1598
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1598
1599
  }
@@ -1682,13 +1683,16 @@ class SlimSelect {
1682
1683
  }
1683
1684
  this.render.open();
1684
1685
  if (this.settings.showSearch) {
1685
- this.render.searchFocus(false);
1686
+ this.render.searchFocus();
1686
1687
  }
1688
+ this.settings.isOpen = true;
1687
1689
  setTimeout(() => {
1688
1690
  if (this.events.afterOpen) {
1689
1691
  this.events.afterOpen();
1690
1692
  }
1691
- this.settings.isOpen = true;
1693
+ if (this.settings.isOpen) {
1694
+ this.settings.isFullOpen = true;
1695
+ }
1692
1696
  }, this.settings.timeoutDelay);
1693
1697
  if (this.settings.contentPosition === 'absolute') {
1694
1698
  if (this.settings.intervalMove) {
@@ -1697,7 +1701,7 @@ class SlimSelect {
1697
1701
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1698
1702
  }
1699
1703
  }
1700
- close() {
1704
+ close(eventType = null) {
1701
1705
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1702
1706
  return;
1703
1707
  }
@@ -1708,12 +1712,13 @@ class SlimSelect {
1708
1712
  if (this.render.content.search.input.value !== '') {
1709
1713
  this.search('');
1710
1714
  }
1711
- this.render.mainFocus(false);
1715
+ this.render.mainFocus(eventType);
1716
+ this.settings.isOpen = false;
1717
+ this.settings.isFullOpen = false;
1712
1718
  setTimeout(() => {
1713
1719
  if (this.events.afterClose) {
1714
1720
  this.events.afterClose();
1715
1721
  }
1716
- this.settings.isOpen = false;
1717
1722
  }, this.settings.timeoutDelay);
1718
1723
  if (this.settings.intervalMove) {
1719
1724
  clearInterval(this.settings.intervalMove);
@@ -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,8 +57,7 @@ class Settings {
57
57
  this.class = [];
58
58
  this.isMultiple = false;
59
59
  this.isOpen = false;
60
- this.isWindowFocused = true;
61
- this.triggerFocus = true;
60
+ this.isFullOpen = false;
62
61
  this.intervalMove = null;
63
62
  if (!settings) {
64
63
  settings = {};
@@ -345,6 +344,7 @@ class Render {
345
344
  this.main = this.mainDiv();
346
345
  this.content = this.contentDiv();
347
346
  this.updateClassStyles();
347
+ this.updateAriaAttributes();
348
348
  this.settings.contentLocation.appendChild(this.content.main);
349
349
  }
350
350
  enable() {
@@ -358,6 +358,7 @@ class Render {
358
358
  open() {
359
359
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
360
360
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
361
+ this.main.main.setAttribute('aria-expanded', 'true');
361
362
  this.moveContent();
362
363
  const selectedOptions = this.store.getSelectedOptions();
363
364
  if (selectedOptions.length) {
@@ -371,6 +372,7 @@ class Render {
371
372
  close() {
372
373
  this.main.main.classList.remove(this.classes.openAbove);
373
374
  this.main.main.classList.remove(this.classes.openBelow);
375
+ this.main.main.setAttribute('aria-expanded', 'false');
374
376
  this.content.main.classList.remove(this.classes.openAbove);
375
377
  this.content.main.classList.remove(this.classes.openBelow);
376
378
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -397,15 +399,18 @@ class Render {
397
399
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
398
400
  }
399
401
  }
402
+ updateAriaAttributes() {
403
+ this.main.main.role = 'combobox';
404
+ this.main.main.setAttribute('aria-haspopup', 'listbox');
405
+ this.main.main.setAttribute('aria-controls', this.content.main.id);
406
+ this.main.main.setAttribute('aria-expanded', 'false');
407
+ this.content.main.setAttribute('role', 'listbox');
408
+ }
400
409
  mainDiv() {
401
410
  const main = document.createElement('div');
402
411
  main.dataset.id = this.settings.id;
412
+ main.id = this.settings.id;
403
413
  main.tabIndex = 0;
404
- main.onfocus = () => {
405
- if (this.settings.triggerFocus && this.settings.isWindowFocused) {
406
- this.callbacks.open();
407
- }
408
- };
409
414
  main.onkeydown = (e) => {
410
415
  switch (e.key) {
411
416
  case 'ArrowUp':
@@ -417,6 +422,8 @@ class Render {
417
422
  this.callbacks.close();
418
423
  return true;
419
424
  case 'Enter':
425
+ case ' ':
426
+ this.callbacks.open();
420
427
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
421
428
  if (highlighted) {
422
429
  highlighted.click();
@@ -493,12 +500,10 @@ class Render {
493
500
  },
494
501
  };
495
502
  }
496
- mainFocus(trigger) {
497
- if (!trigger) {
498
- this.settings.triggerFocus = false;
503
+ mainFocus(eventType) {
504
+ if (eventType !== 'click') {
505
+ this.main.main.focus({ preventScroll: true });
499
506
  }
500
- this.main.main.focus({ preventScroll: true });
501
- this.settings.triggerFocus = true;
502
507
  }
503
508
  placeholder() {
504
509
  const placeholderOption = this.store.filter((o) => o.placeholder, false);
@@ -674,6 +679,7 @@ class Render {
674
679
  contentDiv() {
675
680
  const main = document.createElement('div');
676
681
  main.dataset.id = this.settings.id;
682
+ main.id = this.settings.id;
677
683
  const search = this.searchDiv();
678
684
  main.appendChild(search.main);
679
685
  const list = this.listDiv();
@@ -731,7 +737,6 @@ class Render {
731
737
  switch (e.key) {
732
738
  case 'ArrowUp':
733
739
  case 'ArrowDown':
734
- this.callbacks.open();
735
740
  e.key === 'ArrowDown' ? this.highlight('down') : this.highlight('up');
736
741
  return false;
737
742
  case 'Tab':
@@ -741,6 +746,7 @@ class Render {
741
746
  this.callbacks.close();
742
747
  return false;
743
748
  case 'Enter':
749
+ case ' ':
744
750
  if (this.callbacks.addable && e.ctrlKey) {
745
751
  addable.click();
746
752
  }
@@ -753,12 +759,6 @@ class Render {
753
759
  return false;
754
760
  }
755
761
  };
756
- input.onfocus = () => {
757
- if (this.settings.isOpen) {
758
- return;
759
- }
760
- this.callbacks.open();
761
- };
762
762
  main.appendChild(input);
763
763
  if (this.callbacks.addable) {
764
764
  addable.classList.add(this.classes.addable);
@@ -831,12 +831,8 @@ class Render {
831
831
  }
832
832
  return searchReturn;
833
833
  }
834
- searchFocus(trigger) {
835
- if (!trigger) {
836
- this.settings.triggerFocus = false;
837
- }
834
+ searchFocus() {
838
835
  this.content.search.input.focus();
839
- this.settings.triggerFocus = true;
840
836
  }
841
837
  getOptions(notPlaceholder = false, notDisabled = false, notHidden = false) {
842
838
  let query = '.' + this.classes.option;
@@ -892,7 +888,6 @@ class Render {
892
888
  listDiv() {
893
889
  const options = document.createElement('div');
894
890
  options.classList.add(this.classes.list);
895
- options.setAttribute('role', 'listbox');
896
891
  return options;
897
892
  }
898
893
  renderError(error) {
@@ -1037,6 +1032,7 @@ class Render {
1037
1032
  }
1038
1033
  const optionEl = document.createElement('div');
1039
1034
  optionEl.dataset.id = option.id;
1035
+ optionEl.id = option.id;
1040
1036
  optionEl.classList.add(this.classes.option);
1041
1037
  optionEl.setAttribute('role', 'option');
1042
1038
  if (option.class) {
@@ -1070,9 +1066,12 @@ class Render {
1070
1066
  }
1071
1067
  if (option.selected) {
1072
1068
  optionEl.classList.add(this.classes.selected);
1069
+ optionEl.setAttribute('aria-selected', 'true');
1070
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1073
1071
  }
1074
1072
  else {
1075
1073
  optionEl.classList.remove(this.classes.selected);
1074
+ optionEl.setAttribute('aria-selected', 'false');
1076
1075
  }
1077
1076
  optionEl.addEventListener('click', (e) => {
1078
1077
  e.preventDefault();
@@ -1490,13 +1489,13 @@ class SlimSelect {
1490
1489
  afterClose: undefined,
1491
1490
  };
1492
1491
  this.windowResize = debounce(() => {
1493
- if (!this.settings.isOpen) {
1492
+ if (!this.settings.isOpen && !this.settings.isFullOpen) {
1494
1493
  return;
1495
1494
  }
1496
1495
  this.render.moveContent();
1497
1496
  });
1498
1497
  this.windowScroll = debounce(() => {
1499
- if (!this.settings.isOpen) {
1498
+ if (!this.settings.isOpen && !this.settings.isFullOpen) {
1500
1499
  return;
1501
1500
  }
1502
1501
  this.render.moveContent();
@@ -1506,19 +1505,13 @@ class SlimSelect {
1506
1505
  return;
1507
1506
  }
1508
1507
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1509
- this.close();
1508
+ this.close(e.type);
1510
1509
  }
1511
1510
  };
1512
1511
  this.windowVisibilityChange = () => {
1513
1512
  if (document.hidden) {
1514
- this.settings.isWindowFocused = false;
1515
1513
  this.close();
1516
1514
  }
1517
- else {
1518
- setTimeout(() => {
1519
- this.settings.isWindowFocused = true;
1520
- }, 20);
1521
- }
1522
1515
  };
1523
1516
  this.selectEl = (typeof config.select === 'string' ? document.querySelector(config.select) : config.select);
1524
1517
  if (!this.selectEl) {
@@ -1591,6 +1584,14 @@ class SlimSelect {
1591
1584
  this.render = new Render(this.settings, this.store, callbacks);
1592
1585
  this.render.renderValues();
1593
1586
  this.render.renderOptions(this.store.getData());
1587
+ const selectAriaLabel = this.selectEl.getAttribute('aria-label');
1588
+ const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby');
1589
+ if (selectAriaLabel) {
1590
+ this.render.main.main.setAttribute('aria-label', selectAriaLabel);
1591
+ }
1592
+ else if (selectAriaLabelledBy) {
1593
+ this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy);
1594
+ }
1594
1595
  if (this.selectEl.parentNode) {
1595
1596
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1596
1597
  }
@@ -1680,13 +1681,16 @@ class SlimSelect {
1680
1681
  }
1681
1682
  this.render.open();
1682
1683
  if (this.settings.showSearch) {
1683
- this.render.searchFocus(false);
1684
+ this.render.searchFocus();
1684
1685
  }
1686
+ this.settings.isOpen = true;
1685
1687
  setTimeout(() => {
1686
1688
  if (this.events.afterOpen) {
1687
1689
  this.events.afterOpen();
1688
1690
  }
1689
- this.settings.isOpen = true;
1691
+ if (this.settings.isOpen) {
1692
+ this.settings.isFullOpen = true;
1693
+ }
1690
1694
  }, this.settings.timeoutDelay);
1691
1695
  if (this.settings.contentPosition === 'absolute') {
1692
1696
  if (this.settings.intervalMove) {
@@ -1695,7 +1699,7 @@ class SlimSelect {
1695
1699
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1696
1700
  }
1697
1701
  }
1698
- close() {
1702
+ close(eventType = null) {
1699
1703
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1700
1704
  return;
1701
1705
  }
@@ -1706,12 +1710,13 @@ class SlimSelect {
1706
1710
  if (this.render.content.search.input.value !== '') {
1707
1711
  this.search('');
1708
1712
  }
1709
- this.render.mainFocus(false);
1713
+ this.render.mainFocus(eventType);
1714
+ this.settings.isOpen = false;
1715
+ this.settings.isFullOpen = false;
1710
1716
  setTimeout(() => {
1711
1717
  if (this.events.afterClose) {
1712
1718
  this.events.afterClose();
1713
1719
  }
1714
- this.settings.isOpen = false;
1715
1720
  }, this.settings.timeoutDelay);
1716
1721
  if (this.settings.intervalMove) {
1717
1722
  clearInterval(this.settings.intervalMove);