slim-select 2.3.3 → 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,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(trigger: boolean, eventType: string | null): void;
96
97
  placeholder(): HTMLDivElement;
97
98
  renderValues(): void;
98
99
  private renderSingleValue;
@@ -347,6 +347,7 @@ class Render {
347
347
  this.main = this.mainDiv();
348
348
  this.content = this.contentDiv();
349
349
  this.updateClassStyles();
350
+ this.updateAriaAttributes();
350
351
  this.settings.contentLocation.appendChild(this.content.main);
351
352
  }
352
353
  enable() {
@@ -360,6 +361,7 @@ class Render {
360
361
  open() {
361
362
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
362
363
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
364
+ this.main.main.setAttribute('aria-expanded', 'true');
363
365
  this.moveContent();
364
366
  const selectedOptions = this.store.getSelectedOptions();
365
367
  if (selectedOptions.length) {
@@ -373,6 +375,7 @@ class Render {
373
375
  close() {
374
376
  this.main.main.classList.remove(this.classes.openAbove);
375
377
  this.main.main.classList.remove(this.classes.openBelow);
378
+ this.main.main.setAttribute('aria-expanded', 'false');
376
379
  this.content.main.classList.remove(this.classes.openAbove);
377
380
  this.content.main.classList.remove(this.classes.openBelow);
378
381
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -399,15 +402,18 @@ class Render {
399
402
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
400
403
  }
401
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
+ }
402
412
  mainDiv() {
403
413
  const main = document.createElement('div');
404
414
  main.dataset.id = this.settings.id;
415
+ main.id = this.settings.id;
405
416
  main.tabIndex = 0;
406
- main.onfocus = () => {
407
- if (this.settings.triggerFocus && this.settings.isWindowFocused) {
408
- this.callbacks.open();
409
- }
410
- };
411
417
  main.onkeydown = (e) => {
412
418
  switch (e.key) {
413
419
  case 'ArrowUp':
@@ -419,6 +425,8 @@ class Render {
419
425
  this.callbacks.close();
420
426
  return true;
421
427
  case 'Enter':
428
+ case ' ':
429
+ this.callbacks.open();
422
430
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
423
431
  if (highlighted) {
424
432
  highlighted.click();
@@ -495,11 +503,13 @@ class Render {
495
503
  },
496
504
  };
497
505
  }
498
- mainFocus(trigger) {
506
+ mainFocus(trigger, eventType) {
499
507
  if (!trigger) {
500
508
  this.settings.triggerFocus = false;
501
509
  }
502
- this.main.main.focus({ preventScroll: true });
510
+ if (eventType !== 'click') {
511
+ this.main.main.focus({ preventScroll: true });
512
+ }
503
513
  this.settings.triggerFocus = true;
504
514
  }
505
515
  placeholder() {
@@ -676,6 +686,7 @@ class Render {
676
686
  contentDiv() {
677
687
  const main = document.createElement('div');
678
688
  main.dataset.id = this.settings.id;
689
+ main.id = this.settings.id;
679
690
  const search = this.searchDiv();
680
691
  main.appendChild(search.main);
681
692
  const list = this.listDiv();
@@ -743,6 +754,7 @@ class Render {
743
754
  this.callbacks.close();
744
755
  return false;
745
756
  case 'Enter':
757
+ case ' ':
746
758
  if (this.callbacks.addable && e.ctrlKey) {
747
759
  addable.click();
748
760
  }
@@ -894,7 +906,6 @@ class Render {
894
906
  listDiv() {
895
907
  const options = document.createElement('div');
896
908
  options.classList.add(this.classes.list);
897
- options.setAttribute('role', 'listbox');
898
909
  return options;
899
910
  }
900
911
  renderError(error) {
@@ -1039,6 +1050,7 @@ class Render {
1039
1050
  }
1040
1051
  const optionEl = document.createElement('div');
1041
1052
  optionEl.dataset.id = option.id;
1053
+ optionEl.id = option.id;
1042
1054
  optionEl.classList.add(this.classes.option);
1043
1055
  optionEl.setAttribute('role', 'option');
1044
1056
  if (option.class) {
@@ -1072,9 +1084,12 @@ class Render {
1072
1084
  }
1073
1085
  if (option.selected) {
1074
1086
  optionEl.classList.add(this.classes.selected);
1087
+ optionEl.setAttribute('aria-selected', 'true');
1088
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1075
1089
  }
1076
1090
  else {
1077
1091
  optionEl.classList.remove(this.classes.selected);
1092
+ optionEl.setAttribute('aria-selected', 'false');
1078
1093
  }
1079
1094
  optionEl.addEventListener('click', (e) => {
1080
1095
  e.preventDefault();
@@ -1508,7 +1523,7 @@ class SlimSelect {
1508
1523
  return;
1509
1524
  }
1510
1525
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1511
- this.close();
1526
+ this.close(e.type);
1512
1527
  }
1513
1528
  };
1514
1529
  this.windowVisibilityChange = () => {
@@ -1593,6 +1608,14 @@ class SlimSelect {
1593
1608
  this.render = new Render(this.settings, this.store, callbacks);
1594
1609
  this.render.renderValues();
1595
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
+ }
1596
1619
  if (this.selectEl.parentNode) {
1597
1620
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1598
1621
  }
@@ -1697,7 +1720,7 @@ class SlimSelect {
1697
1720
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1698
1721
  }
1699
1722
  }
1700
- close() {
1723
+ close(eventType = null) {
1701
1724
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1702
1725
  return;
1703
1726
  }
@@ -1708,7 +1731,7 @@ class SlimSelect {
1708
1731
  if (this.render.content.search.input.value !== '') {
1709
1732
  this.search('');
1710
1733
  }
1711
- this.render.mainFocus(false);
1734
+ this.render.mainFocus(false, eventType);
1712
1735
  setTimeout(() => {
1713
1736
  if (this.events.afterClose) {
1714
1737
  this.events.afterClose();
@@ -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"}
@@ -345,6 +345,7 @@ class Render {
345
345
  this.main = this.mainDiv();
346
346
  this.content = this.contentDiv();
347
347
  this.updateClassStyles();
348
+ this.updateAriaAttributes();
348
349
  this.settings.contentLocation.appendChild(this.content.main);
349
350
  }
350
351
  enable() {
@@ -358,6 +359,7 @@ class Render {
358
359
  open() {
359
360
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
360
361
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
362
+ this.main.main.setAttribute('aria-expanded', 'true');
361
363
  this.moveContent();
362
364
  const selectedOptions = this.store.getSelectedOptions();
363
365
  if (selectedOptions.length) {
@@ -371,6 +373,7 @@ class Render {
371
373
  close() {
372
374
  this.main.main.classList.remove(this.classes.openAbove);
373
375
  this.main.main.classList.remove(this.classes.openBelow);
376
+ this.main.main.setAttribute('aria-expanded', 'false');
374
377
  this.content.main.classList.remove(this.classes.openAbove);
375
378
  this.content.main.classList.remove(this.classes.openBelow);
376
379
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -397,15 +400,18 @@ class Render {
397
400
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
398
401
  }
399
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
+ }
400
410
  mainDiv() {
401
411
  const main = document.createElement('div');
402
412
  main.dataset.id = this.settings.id;
413
+ main.id = this.settings.id;
403
414
  main.tabIndex = 0;
404
- main.onfocus = () => {
405
- if (this.settings.triggerFocus && this.settings.isWindowFocused) {
406
- this.callbacks.open();
407
- }
408
- };
409
415
  main.onkeydown = (e) => {
410
416
  switch (e.key) {
411
417
  case 'ArrowUp':
@@ -417,6 +423,8 @@ class Render {
417
423
  this.callbacks.close();
418
424
  return true;
419
425
  case 'Enter':
426
+ case ' ':
427
+ this.callbacks.open();
420
428
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
421
429
  if (highlighted) {
422
430
  highlighted.click();
@@ -493,11 +501,13 @@ class Render {
493
501
  },
494
502
  };
495
503
  }
496
- mainFocus(trigger) {
504
+ mainFocus(trigger, eventType) {
497
505
  if (!trigger) {
498
506
  this.settings.triggerFocus = false;
499
507
  }
500
- this.main.main.focus({ preventScroll: true });
508
+ if (eventType !== 'click') {
509
+ this.main.main.focus({ preventScroll: true });
510
+ }
501
511
  this.settings.triggerFocus = true;
502
512
  }
503
513
  placeholder() {
@@ -674,6 +684,7 @@ class Render {
674
684
  contentDiv() {
675
685
  const main = document.createElement('div');
676
686
  main.dataset.id = this.settings.id;
687
+ main.id = this.settings.id;
677
688
  const search = this.searchDiv();
678
689
  main.appendChild(search.main);
679
690
  const list = this.listDiv();
@@ -741,6 +752,7 @@ class Render {
741
752
  this.callbacks.close();
742
753
  return false;
743
754
  case 'Enter':
755
+ case ' ':
744
756
  if (this.callbacks.addable && e.ctrlKey) {
745
757
  addable.click();
746
758
  }
@@ -892,7 +904,6 @@ class Render {
892
904
  listDiv() {
893
905
  const options = document.createElement('div');
894
906
  options.classList.add(this.classes.list);
895
- options.setAttribute('role', 'listbox');
896
907
  return options;
897
908
  }
898
909
  renderError(error) {
@@ -1037,6 +1048,7 @@ class Render {
1037
1048
  }
1038
1049
  const optionEl = document.createElement('div');
1039
1050
  optionEl.dataset.id = option.id;
1051
+ optionEl.id = option.id;
1040
1052
  optionEl.classList.add(this.classes.option);
1041
1053
  optionEl.setAttribute('role', 'option');
1042
1054
  if (option.class) {
@@ -1070,9 +1082,12 @@ class Render {
1070
1082
  }
1071
1083
  if (option.selected) {
1072
1084
  optionEl.classList.add(this.classes.selected);
1085
+ optionEl.setAttribute('aria-selected', 'true');
1086
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1073
1087
  }
1074
1088
  else {
1075
1089
  optionEl.classList.remove(this.classes.selected);
1090
+ optionEl.setAttribute('aria-selected', 'false');
1076
1091
  }
1077
1092
  optionEl.addEventListener('click', (e) => {
1078
1093
  e.preventDefault();
@@ -1506,7 +1521,7 @@ class SlimSelect {
1506
1521
  return;
1507
1522
  }
1508
1523
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1509
- this.close();
1524
+ this.close(e.type);
1510
1525
  }
1511
1526
  };
1512
1527
  this.windowVisibilityChange = () => {
@@ -1591,6 +1606,14 @@ class SlimSelect {
1591
1606
  this.render = new Render(this.settings, this.store, callbacks);
1592
1607
  this.render.renderValues();
1593
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
+ }
1594
1617
  if (this.selectEl.parentNode) {
1595
1618
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1596
1619
  }
@@ -1695,7 +1718,7 @@ class SlimSelect {
1695
1718
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1696
1719
  }
1697
1720
  }
1698
- close() {
1721
+ close(eventType = null) {
1699
1722
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1700
1723
  return;
1701
1724
  }
@@ -1706,7 +1729,7 @@ class SlimSelect {
1706
1729
  if (this.render.content.search.input.value !== '') {
1707
1730
  this.search('');
1708
1731
  }
1709
- this.render.mainFocus(false);
1732
+ this.render.mainFocus(false, eventType);
1710
1733
  setTimeout(() => {
1711
1734
  if (this.events.afterClose) {
1712
1735
  this.events.afterClose();
@@ -348,6 +348,7 @@ var SlimSelect = (function () {
348
348
  this.main = this.mainDiv();
349
349
  this.content = this.contentDiv();
350
350
  this.updateClassStyles();
351
+ this.updateAriaAttributes();
351
352
  this.settings.contentLocation.appendChild(this.content.main);
352
353
  }
353
354
  enable() {
@@ -361,6 +362,7 @@ var SlimSelect = (function () {
361
362
  open() {
362
363
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
363
364
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
365
+ this.main.main.setAttribute('aria-expanded', 'true');
364
366
  this.moveContent();
365
367
  const selectedOptions = this.store.getSelectedOptions();
366
368
  if (selectedOptions.length) {
@@ -374,6 +376,7 @@ var SlimSelect = (function () {
374
376
  close() {
375
377
  this.main.main.classList.remove(this.classes.openAbove);
376
378
  this.main.main.classList.remove(this.classes.openBelow);
379
+ this.main.main.setAttribute('aria-expanded', 'false');
377
380
  this.content.main.classList.remove(this.classes.openAbove);
378
381
  this.content.main.classList.remove(this.classes.openBelow);
379
382
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -400,15 +403,18 @@ var SlimSelect = (function () {
400
403
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
401
404
  }
402
405
  }
406
+ updateAriaAttributes() {
407
+ this.main.main.role = 'combobox';
408
+ this.main.main.setAttribute('aria-haspopup', 'listbox');
409
+ this.main.main.setAttribute('aria-controls', this.content.main.id);
410
+ this.main.main.setAttribute('aria-expanded', 'false');
411
+ this.content.main.setAttribute('role', 'listbox');
412
+ }
403
413
  mainDiv() {
404
414
  const main = document.createElement('div');
405
415
  main.dataset.id = this.settings.id;
416
+ main.id = this.settings.id;
406
417
  main.tabIndex = 0;
407
- main.onfocus = () => {
408
- if (this.settings.triggerFocus && this.settings.isWindowFocused) {
409
- this.callbacks.open();
410
- }
411
- };
412
418
  main.onkeydown = (e) => {
413
419
  switch (e.key) {
414
420
  case 'ArrowUp':
@@ -420,6 +426,8 @@ var SlimSelect = (function () {
420
426
  this.callbacks.close();
421
427
  return true;
422
428
  case 'Enter':
429
+ case ' ':
430
+ this.callbacks.open();
423
431
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
424
432
  if (highlighted) {
425
433
  highlighted.click();
@@ -496,11 +504,13 @@ var SlimSelect = (function () {
496
504
  },
497
505
  };
498
506
  }
499
- mainFocus(trigger) {
507
+ mainFocus(trigger, eventType) {
500
508
  if (!trigger) {
501
509
  this.settings.triggerFocus = false;
502
510
  }
503
- this.main.main.focus({ preventScroll: true });
511
+ if (eventType !== 'click') {
512
+ this.main.main.focus({ preventScroll: true });
513
+ }
504
514
  this.settings.triggerFocus = true;
505
515
  }
506
516
  placeholder() {
@@ -677,6 +687,7 @@ var SlimSelect = (function () {
677
687
  contentDiv() {
678
688
  const main = document.createElement('div');
679
689
  main.dataset.id = this.settings.id;
690
+ main.id = this.settings.id;
680
691
  const search = this.searchDiv();
681
692
  main.appendChild(search.main);
682
693
  const list = this.listDiv();
@@ -744,6 +755,7 @@ var SlimSelect = (function () {
744
755
  this.callbacks.close();
745
756
  return false;
746
757
  case 'Enter':
758
+ case ' ':
747
759
  if (this.callbacks.addable && e.ctrlKey) {
748
760
  addable.click();
749
761
  }
@@ -895,7 +907,6 @@ var SlimSelect = (function () {
895
907
  listDiv() {
896
908
  const options = document.createElement('div');
897
909
  options.classList.add(this.classes.list);
898
- options.setAttribute('role', 'listbox');
899
910
  return options;
900
911
  }
901
912
  renderError(error) {
@@ -1040,6 +1051,7 @@ var SlimSelect = (function () {
1040
1051
  }
1041
1052
  const optionEl = document.createElement('div');
1042
1053
  optionEl.dataset.id = option.id;
1054
+ optionEl.id = option.id;
1043
1055
  optionEl.classList.add(this.classes.option);
1044
1056
  optionEl.setAttribute('role', 'option');
1045
1057
  if (option.class) {
@@ -1073,9 +1085,12 @@ var SlimSelect = (function () {
1073
1085
  }
1074
1086
  if (option.selected) {
1075
1087
  optionEl.classList.add(this.classes.selected);
1088
+ optionEl.setAttribute('aria-selected', 'true');
1089
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1076
1090
  }
1077
1091
  else {
1078
1092
  optionEl.classList.remove(this.classes.selected);
1093
+ optionEl.setAttribute('aria-selected', 'false');
1079
1094
  }
1080
1095
  optionEl.addEventListener('click', (e) => {
1081
1096
  e.preventDefault();
@@ -1509,7 +1524,7 @@ var SlimSelect = (function () {
1509
1524
  return;
1510
1525
  }
1511
1526
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1512
- this.close();
1527
+ this.close(e.type);
1513
1528
  }
1514
1529
  };
1515
1530
  this.windowVisibilityChange = () => {
@@ -1594,6 +1609,14 @@ var SlimSelect = (function () {
1594
1609
  this.render = new Render(this.settings, this.store, callbacks);
1595
1610
  this.render.renderValues();
1596
1611
  this.render.renderOptions(this.store.getData());
1612
+ const selectAriaLabel = this.selectEl.getAttribute('aria-label');
1613
+ const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby');
1614
+ if (selectAriaLabel) {
1615
+ this.render.main.main.setAttribute('aria-label', selectAriaLabel);
1616
+ }
1617
+ else if (selectAriaLabelledBy) {
1618
+ this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy);
1619
+ }
1597
1620
  if (this.selectEl.parentNode) {
1598
1621
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1599
1622
  }
@@ -1698,7 +1721,7 @@ var SlimSelect = (function () {
1698
1721
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1699
1722
  }
1700
1723
  }
1701
- close() {
1724
+ close(eventType = null) {
1702
1725
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1703
1726
  return;
1704
1727
  }
@@ -1709,7 +1732,7 @@ var SlimSelect = (function () {
1709
1732
  if (this.render.content.search.input.value !== '') {
1710
1733
  this.search('');
1711
1734
  }
1712
- this.render.mainFocus(false);
1735
+ this.render.mainFocus(false, eventType);
1713
1736
  setTimeout(() => {
1714
1737
  if (this.events.afterClose) {
1715
1738
  this.events.afterClose();