slim-select 2.3.2 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/helpers.d.ts +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/render.d.ts +2 -1
- package/dist/settings.d.ts +1 -0
- package/dist/slimselect.cjs.js +50 -11
- package/dist/slimselect.css +1 -1
- package/dist/slimselect.css.map +1 -1
- package/dist/slimselect.es.js +50 -11
- package/dist/slimselect.global.js +50 -11
- package/dist/slimselect.js +50 -11
- package/dist/slimselect.min.js +1 -1
- package/dist/slimselect.umd.js +50 -11
- package/dist/slimselect.umd.min.js +1 -1
- package/package.json +14 -13
- package/src/slim-select/helpers.ts +12 -2
- package/src/slim-select/index.ts +32 -4
- package/src/slim-select/render.ts +28 -10
- package/src/slim-select/settings.ts +1 -0
- package/src/slim-select/slimselect.scss +1 -0
- package/src/vue/dist/slim-select/helpers.d.ts +1 -1
- package/src/vue/dist/slim-select/index.d.ts +2 -1
- package/src/vue/dist/slim-select/render.d.ts +2 -1
- package/src/vue/dist/slim-select/settings.d.ts +1 -0
- package/src/vue/dist/slimselectvue.es.js +50 -11
- package/src/vue/dist/slimselectvue.global.js +50 -11
- package/src/vue/dist/slimselectvue.ssr.js +50 -11
- package/src/vue/dist/vue/slimselect.vue.d.ts +5 -2
- package/src/vue/package.json +2 -1
|
@@ -61,6 +61,7 @@ class Settings {
|
|
|
61
61
|
this.class = [];
|
|
62
62
|
this.isMultiple = false;
|
|
63
63
|
this.isOpen = false;
|
|
64
|
+
this.isWindowFocused = true;
|
|
64
65
|
this.triggerFocus = true;
|
|
65
66
|
this.intervalMove = null;
|
|
66
67
|
if (!settings) {
|
|
@@ -348,6 +349,7 @@ class Render {
|
|
|
348
349
|
this.main = this.mainDiv();
|
|
349
350
|
this.content = this.contentDiv();
|
|
350
351
|
this.updateClassStyles();
|
|
352
|
+
this.updateAriaAttributes();
|
|
351
353
|
this.settings.contentLocation.appendChild(this.content.main);
|
|
352
354
|
}
|
|
353
355
|
enable() {
|
|
@@ -361,6 +363,7 @@ class Render {
|
|
|
361
363
|
open() {
|
|
362
364
|
this.main.arrow.path.setAttribute('d', this.classes.arrowOpen);
|
|
363
365
|
this.main.main.classList.add(this.settings.openPosition === 'up' ? this.classes.openAbove : this.classes.openBelow);
|
|
366
|
+
this.main.main.setAttribute('aria-expanded', 'true');
|
|
364
367
|
this.moveContent();
|
|
365
368
|
const selectedOptions = this.store.getSelectedOptions();
|
|
366
369
|
if (selectedOptions.length) {
|
|
@@ -374,6 +377,7 @@ class Render {
|
|
|
374
377
|
close() {
|
|
375
378
|
this.main.main.classList.remove(this.classes.openAbove);
|
|
376
379
|
this.main.main.classList.remove(this.classes.openBelow);
|
|
380
|
+
this.main.main.setAttribute('aria-expanded', 'false');
|
|
377
381
|
this.content.main.classList.remove(this.classes.openAbove);
|
|
378
382
|
this.content.main.classList.remove(this.classes.openBelow);
|
|
379
383
|
this.main.arrow.path.setAttribute('d', this.classes.arrowClose);
|
|
@@ -400,15 +404,18 @@ class Render {
|
|
|
400
404
|
this.content.main.classList.add('ss-' + this.settings.contentPosition);
|
|
401
405
|
}
|
|
402
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
|
+
}
|
|
403
414
|
mainDiv() {
|
|
404
415
|
const main = document.createElement('div');
|
|
405
416
|
main.dataset.id = this.settings.id;
|
|
417
|
+
main.id = this.settings.id;
|
|
406
418
|
main.tabIndex = 0;
|
|
407
|
-
main.onfocus = () => {
|
|
408
|
-
if (this.settings.triggerFocus) {
|
|
409
|
-
this.callbacks.open();
|
|
410
|
-
}
|
|
411
|
-
};
|
|
412
419
|
main.onkeydown = (e) => {
|
|
413
420
|
switch (e.key) {
|
|
414
421
|
case 'ArrowUp':
|
|
@@ -420,6 +427,8 @@ class Render {
|
|
|
420
427
|
this.callbacks.close();
|
|
421
428
|
return true;
|
|
422
429
|
case 'Enter':
|
|
430
|
+
case ' ':
|
|
431
|
+
this.callbacks.open();
|
|
423
432
|
const highlighted = this.content.list.querySelector('.' + this.classes.highlighted);
|
|
424
433
|
if (highlighted) {
|
|
425
434
|
highlighted.click();
|
|
@@ -496,11 +505,13 @@ class Render {
|
|
|
496
505
|
},
|
|
497
506
|
};
|
|
498
507
|
}
|
|
499
|
-
mainFocus(trigger) {
|
|
508
|
+
mainFocus(trigger, eventType) {
|
|
500
509
|
if (!trigger) {
|
|
501
510
|
this.settings.triggerFocus = false;
|
|
502
511
|
}
|
|
503
|
-
|
|
512
|
+
if (eventType !== 'click') {
|
|
513
|
+
this.main.main.focus({ preventScroll: true });
|
|
514
|
+
}
|
|
504
515
|
this.settings.triggerFocus = true;
|
|
505
516
|
}
|
|
506
517
|
placeholder() {
|
|
@@ -677,6 +688,7 @@ class Render {
|
|
|
677
688
|
contentDiv() {
|
|
678
689
|
const main = document.createElement('div');
|
|
679
690
|
main.dataset.id = this.settings.id;
|
|
691
|
+
main.id = this.settings.id;
|
|
680
692
|
const search = this.searchDiv();
|
|
681
693
|
main.appendChild(search.main);
|
|
682
694
|
const list = this.listDiv();
|
|
@@ -744,6 +756,7 @@ class Render {
|
|
|
744
756
|
this.callbacks.close();
|
|
745
757
|
return false;
|
|
746
758
|
case 'Enter':
|
|
759
|
+
case ' ':
|
|
747
760
|
if (this.callbacks.addable && e.ctrlKey) {
|
|
748
761
|
addable.click();
|
|
749
762
|
}
|
|
@@ -895,7 +908,6 @@ class Render {
|
|
|
895
908
|
listDiv() {
|
|
896
909
|
const options = document.createElement('div');
|
|
897
910
|
options.classList.add(this.classes.list);
|
|
898
|
-
options.setAttribute('role', 'listbox');
|
|
899
911
|
return options;
|
|
900
912
|
}
|
|
901
913
|
renderError(error) {
|
|
@@ -1040,6 +1052,7 @@ class Render {
|
|
|
1040
1052
|
}
|
|
1041
1053
|
const optionEl = document.createElement('div');
|
|
1042
1054
|
optionEl.dataset.id = option.id;
|
|
1055
|
+
optionEl.id = option.id;
|
|
1043
1056
|
optionEl.classList.add(this.classes.option);
|
|
1044
1057
|
optionEl.setAttribute('role', 'option');
|
|
1045
1058
|
if (option.class) {
|
|
@@ -1073,9 +1086,12 @@ class Render {
|
|
|
1073
1086
|
}
|
|
1074
1087
|
if (option.selected) {
|
|
1075
1088
|
optionEl.classList.add(this.classes.selected);
|
|
1089
|
+
optionEl.setAttribute('aria-selected', 'true');
|
|
1090
|
+
this.main.main.setAttribute('aria-activedescendant', optionEl.id);
|
|
1076
1091
|
}
|
|
1077
1092
|
else {
|
|
1078
1093
|
optionEl.classList.remove(this.classes.selected);
|
|
1094
|
+
optionEl.setAttribute('aria-selected', 'false');
|
|
1079
1095
|
}
|
|
1080
1096
|
optionEl.addEventListener('click', (e) => {
|
|
1081
1097
|
e.preventDefault();
|
|
@@ -1509,8 +1525,19 @@ class SlimSelect {
|
|
|
1509
1525
|
return;
|
|
1510
1526
|
}
|
|
1511
1527
|
if (e.target && !hasClassInTree(e.target, this.settings.id)) {
|
|
1528
|
+
this.close(e.type);
|
|
1529
|
+
}
|
|
1530
|
+
};
|
|
1531
|
+
this.windowVisibilityChange = () => {
|
|
1532
|
+
if (document.hidden) {
|
|
1533
|
+
this.settings.isWindowFocused = false;
|
|
1512
1534
|
this.close();
|
|
1513
1535
|
}
|
|
1536
|
+
else {
|
|
1537
|
+
setTimeout(() => {
|
|
1538
|
+
this.settings.isWindowFocused = true;
|
|
1539
|
+
}, 20);
|
|
1540
|
+
}
|
|
1514
1541
|
};
|
|
1515
1542
|
this.selectEl = (typeof config.select === 'string' ? document.querySelector(config.select) : config.select);
|
|
1516
1543
|
if (!this.selectEl) {
|
|
@@ -1583,6 +1610,14 @@ class SlimSelect {
|
|
|
1583
1610
|
this.render = new Render(this.settings, this.store, callbacks);
|
|
1584
1611
|
this.render.renderValues();
|
|
1585
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
|
+
}
|
|
1586
1621
|
if (this.selectEl.parentNode) {
|
|
1587
1622
|
this.selectEl.parentNode.insertBefore(this.render.main.main, this.selectEl.nextSibling);
|
|
1588
1623
|
}
|
|
@@ -1591,6 +1626,7 @@ class SlimSelect {
|
|
|
1591
1626
|
if (this.settings.openPosition === 'auto') {
|
|
1592
1627
|
window.addEventListener('scroll', this.windowScroll, false);
|
|
1593
1628
|
}
|
|
1629
|
+
document.addEventListener('visibilitychange', this.windowVisibilityChange);
|
|
1594
1630
|
if (this.settings.disabled) {
|
|
1595
1631
|
this.disable();
|
|
1596
1632
|
}
|
|
@@ -1651,7 +1687,9 @@ class SlimSelect {
|
|
|
1651
1687
|
}
|
|
1652
1688
|
addOption(option) {
|
|
1653
1689
|
const selected = this.store.getSelected();
|
|
1654
|
-
this.store.
|
|
1690
|
+
if (!this.store.getDataOptions().some((o) => { var _a; return o.value === ((_a = option.value) !== null && _a !== void 0 ? _a : option.text); })) {
|
|
1691
|
+
this.store.addOption(option);
|
|
1692
|
+
}
|
|
1655
1693
|
const data = this.store.getData();
|
|
1656
1694
|
this.select.updateOptions(data);
|
|
1657
1695
|
this.render.renderValues();
|
|
@@ -1684,7 +1722,7 @@ class SlimSelect {
|
|
|
1684
1722
|
this.settings.intervalMove = setInterval(this.render.moveContent.bind(this.render), 500);
|
|
1685
1723
|
}
|
|
1686
1724
|
}
|
|
1687
|
-
close() {
|
|
1725
|
+
close(eventType = null) {
|
|
1688
1726
|
if (!this.settings.isOpen || this.settings.alwaysOpen) {
|
|
1689
1727
|
return;
|
|
1690
1728
|
}
|
|
@@ -1695,7 +1733,7 @@ class SlimSelect {
|
|
|
1695
1733
|
if (this.render.content.search.input.value !== '') {
|
|
1696
1734
|
this.search('');
|
|
1697
1735
|
}
|
|
1698
|
-
this.render.mainFocus(false);
|
|
1736
|
+
this.render.mainFocus(false, eventType);
|
|
1699
1737
|
setTimeout(() => {
|
|
1700
1738
|
if (this.events.afterClose) {
|
|
1701
1739
|
this.events.afterClose();
|
|
@@ -1739,6 +1777,7 @@ class SlimSelect {
|
|
|
1739
1777
|
if (this.settings.openPosition === 'auto') {
|
|
1740
1778
|
window.removeEventListener('scroll', this.windowScroll, false);
|
|
1741
1779
|
}
|
|
1780
|
+
document.removeEventListener('visibilitychange', this.windowVisibilityChange);
|
|
1742
1781
|
this.store.setData([]);
|
|
1743
1782
|
this.render.destroy();
|
|
1744
1783
|
this.select.destroy();
|
|
@@ -35,6 +35,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
35
35
|
class: string[];
|
|
36
36
|
isMultiple: boolean;
|
|
37
37
|
isOpen: boolean;
|
|
38
|
+
isWindowFocused: boolean;
|
|
38
39
|
triggerFocus: boolean;
|
|
39
40
|
intervalMove: {
|
|
40
41
|
hasRef: () => boolean;
|
|
@@ -112,6 +113,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
112
113
|
class: string[];
|
|
113
114
|
isMultiple: boolean;
|
|
114
115
|
isOpen: boolean;
|
|
116
|
+
isWindowFocused: boolean;
|
|
115
117
|
triggerFocus: boolean;
|
|
116
118
|
intervalMove: {
|
|
117
119
|
hasRef: () => boolean;
|
|
@@ -241,8 +243,9 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
241
243
|
open: () => void;
|
|
242
244
|
close: () => void;
|
|
243
245
|
updateClassStyles: () => void;
|
|
246
|
+
updateAriaAttributes: () => void;
|
|
244
247
|
mainDiv: () => import("../slim-select/render").Main;
|
|
245
|
-
mainFocus: (trigger: boolean) => void;
|
|
248
|
+
mainFocus: (trigger: boolean, eventType: string | null) => void;
|
|
246
249
|
placeholder: () => HTMLDivElement;
|
|
247
250
|
renderValues: () => void;
|
|
248
251
|
multipleValue: (option: Option) => HTMLDivElement;
|
|
@@ -283,7 +286,7 @@ declare const _default: import("vue").DefineComponent<{
|
|
|
283
286
|
setSelected: (value: string | string[], runAfterChange?: boolean) => void;
|
|
284
287
|
addOption: (option: import("../slim-select/store").OptionOptional) => void;
|
|
285
288
|
open: () => void;
|
|
286
|
-
close: () => void;
|
|
289
|
+
close: (eventType?: string | null) => void;
|
|
287
290
|
search: (value: string) => void;
|
|
288
291
|
destroy: () => void;
|
|
289
292
|
} | null;
|
package/src/vue/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slim-select/vue",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.
|
|
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",
|