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.
@@ -348,6 +348,7 @@ var SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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 SlimSelectVue = (function (vue) {
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();
@@ -349,6 +349,7 @@ class Render {
349
349
  this.main = this.mainDiv();
350
350
  this.content = this.contentDiv();
351
351
  this.updateClassStyles();
352
+ this.updateAriaAttributes();
352
353
  this.settings.contentLocation.appendChild(this.content.main);
353
354
  }
354
355
  enable() {
@@ -362,6 +363,7 @@ class Render {
362
363
  open() {
363
364
  this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
364
365
  this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
366
+ this.main.main.setAttribute('aria-expanded', 'true');
365
367
  this.moveContent();
366
368
  const selectedOptions = this.store.getSelectedOptions();
367
369
  if (selectedOptions.length) {
@@ -375,6 +377,7 @@ class Render {
375
377
  close() {
376
378
  this.main.main.classList.remove(this.classes.openAbove);
377
379
  this.main.main.classList.remove(this.classes.openBelow);
380
+ this.main.main.setAttribute('aria-expanded', 'false');
378
381
  this.content.main.classList.remove(this.classes.openAbove);
379
382
  this.content.main.classList.remove(this.classes.openBelow);
380
383
  this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
@@ -401,15 +404,18 @@ class Render {
401
404
  this.content.main.classList.add('ss-' + this.settings.contentPosition);
402
405
  }
403
406
  }
407
+ updateAriaAttributes() {
408
+ this.main.main.role = 'combobox';
409
+ this.main.main.setAttribute('aria-haspopup', 'listbox');
410
+ this.main.main.setAttribute('aria-controls', this.content.main.id);
411
+ this.main.main.setAttribute('aria-expanded', 'false');
412
+ this.content.main.setAttribute('role', 'listbox');
413
+ }
404
414
  mainDiv() {
405
415
  const main = document.createElement('div');
406
416
  main.dataset.id = this.settings.id;
417
+ main.id = this.settings.id;
407
418
  main.tabIndex = 0;
408
- main.onfocus = () => {
409
- if (this.settings.triggerFocus && this.settings.isWindowFocused) {
410
- this.callbacks.open();
411
- }
412
- };
413
419
  main.onkeydown = (e) => {
414
420
  switch (e.key) {
415
421
  case 'ArrowUp':
@@ -421,6 +427,8 @@ class Render {
421
427
  this.callbacks.close();
422
428
  return true;
423
429
  case 'Enter':
430
+ case ' ':
431
+ this.callbacks.open();
424
432
  const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
425
433
  if (highlighted) {
426
434
  highlighted.click();
@@ -497,11 +505,13 @@ class Render {
497
505
  },
498
506
  };
499
507
  }
500
- mainFocus(trigger) {
508
+ mainFocus(trigger, eventType) {
501
509
  if (!trigger) {
502
510
  this.settings.triggerFocus = false;
503
511
  }
504
- this.main.main.focus({ preventScroll: true });
512
+ if (eventType !== 'click') {
513
+ this.main.main.focus({ preventScroll: true });
514
+ }
505
515
  this.settings.triggerFocus = true;
506
516
  }
507
517
  placeholder() {
@@ -678,6 +688,7 @@ class Render {
678
688
  contentDiv() {
679
689
  const main = document.createElement('div');
680
690
  main.dataset.id = this.settings.id;
691
+ main.id = this.settings.id;
681
692
  const search = this.searchDiv();
682
693
  main.appendChild(search.main);
683
694
  const list = this.listDiv();
@@ -745,6 +756,7 @@ class Render {
745
756
  this.callbacks.close();
746
757
  return false;
747
758
  case 'Enter':
759
+ case ' ':
748
760
  if (this.callbacks.addable && e.ctrlKey) {
749
761
  addable.click();
750
762
  }
@@ -896,7 +908,6 @@ class Render {
896
908
  listDiv() {
897
909
  const options = document.createElement('div');
898
910
  options.classList.add(this.classes.list);
899
- options.setAttribute('role', 'listbox');
900
911
  return options;
901
912
  }
902
913
  renderError(error) {
@@ -1041,6 +1052,7 @@ class Render {
1041
1052
  }
1042
1053
  const optionEl = document.createElement('div');
1043
1054
  optionEl.dataset.id = option.id;
1055
+ optionEl.id = option.id;
1044
1056
  optionEl.classList.add(this.classes.option);
1045
1057
  optionEl.setAttribute('role', 'option');
1046
1058
  if (option.class) {
@@ -1074,9 +1086,12 @@ class Render {
1074
1086
  }
1075
1087
  if (option.selected) {
1076
1088
  optionEl.classList.add(this.classes.selected);
1089
+ optionEl.setAttribute('aria-selected', 'true');
1090
+ this.main.main.setAttribute('aria-activedescendant', optionEl.id);
1077
1091
  }
1078
1092
  else {
1079
1093
  optionEl.classList.remove(this.classes.selected);
1094
+ optionEl.setAttribute('aria-selected', 'false');
1080
1095
  }
1081
1096
  optionEl.addEventListener('click', (e) => {
1082
1097
  e.preventDefault();
@@ -1510,7 +1525,7 @@ class SlimSelect {
1510
1525
  return;
1511
1526
  }
1512
1527
  if (e.target && !hasClassInTree(e.target, this.settings.id)) {
1513
- this.close();
1528
+ this.close(e.type);
1514
1529
  }
1515
1530
  };
1516
1531
  this.windowVisibilityChange = () => {
@@ -1595,6 +1610,14 @@ class SlimSelect {
1595
1610
  this.render = new Render(this.settings, this.store, callbacks);
1596
1611
  this.render.renderValues();
1597
1612
  this.render.renderOptions(this.store.getData());
1613
+ const selectAriaLabel = this.selectEl.getAttribute('aria-label');
1614
+ const selectAriaLabelledBy = this.selectEl.getAttribute('aria-labelledby');
1615
+ if (selectAriaLabel) {
1616
+ this.render.main.main.setAttribute('aria-label', selectAriaLabel);
1617
+ }
1618
+ else if (selectAriaLabelledBy) {
1619
+ this.render.main.main.setAttribute('aria-labelledby', selectAriaLabelledBy);
1620
+ }
1598
1621
  if (this.selectEl.parentNode) {
1599
1622
  this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
1600
1623
  }
@@ -1699,7 +1722,7 @@ class SlimSelect {
1699
1722
  this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
1700
1723
  }
1701
1724
  }
1702
- close() {
1725
+ close(eventType = null) {
1703
1726
  if (!this.settings.isOpen || this.settings.alwaysOpen) {
1704
1727
  return;
1705
1728
  }
@@ -1710,7 +1733,7 @@ class SlimSelect {
1710
1733
  if (this.render.content.search.input.value !== '') {
1711
1734
  this.search('');
1712
1735
  }
1713
- this.render.mainFocus(false);
1736
+ this.render.mainFocus(false, eventType);
1714
1737
  setTimeout(() => {
1715
1738
  if (this.events.afterClose) {
1716
1739
  this.events.afterClose();
@@ -243,8 +243,9 @@ declare const _default: import("vue").DefineComponent<{
243
243
  open: () => void;
244
244
  close: () => void;
245
245
  updateClassStyles: () => void;
246
+ updateAriaAttributes: () => void;
246
247
  mainDiv: () => import("../slim-select/render").Main;
247
- mainFocus: (trigger: boolean) => void;
248
+ mainFocus: (trigger: boolean, eventType: string | null) => void;
248
249
  placeholder: () => HTMLDivElement;
249
250
  renderValues: () => void;
250
251
  multipleValue: (option: Option) => HTMLDivElement;
@@ -285,7 +286,7 @@ declare const _default: import("vue").DefineComponent<{
285
286
  setSelected: (value: string | string[], runAfterChange?: boolean) => void;
286
287
  addOption: (option: import("../slim-select/store").OptionOptional) => void;
287
288
  open: () => void;
288
- close: () => void;
289
+ close: (eventType?: string | null) => void;
289
290
  search: (value: string) => void;
290
291
  destroy: () => void;
291
292
  } | null;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@slim-select/vue",
3
3
  "private": false,
4
- "version": "1.3.3",
4
+ "version": "1.4.0",
5
5
  "description": "Vue integration",
6
6
  "repository": {
7
7
  "type": "git",
@@ -16,6 +16,7 @@
16
16
  "bugs": {
17
17
  "url": "https://github.com/brianvoe/slim-select/issues"
18
18
  },
19
+ "type": "module",
19
20
  "main": "dist/slimselectvue.ssr.js",
20
21
  "browser": "dist/slimselect.global.js",
21
22
  "module": "dist/slimselectvue.es.js",