@getflip/swirl-components 0.95.1 → 0.95.2
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/components.json +1 -1
- package/dist/cjs/swirl-action-list_3.cjs.entry.js +10 -20
- package/dist/cjs/swirl-app-layout_7.cjs.entry.js +20 -9
- package/dist/cjs/swirl-autocomplete.cjs.entry.js +10 -2
- package/dist/cjs/swirl-option-list_2.cjs.entry.js +5 -3
- package/dist/cjs/swirl-select.cjs.entry.js +4 -2
- package/dist/collection/components/swirl-action-list/swirl-action-list.js +10 -20
- package/dist/collection/components/swirl-autocomplete/swirl-autocomplete.js +10 -2
- package/dist/collection/components/swirl-option-list/swirl-option-list.js +5 -3
- package/dist/collection/components/swirl-resource-list/swirl-resource-list.js +20 -9
- package/dist/collection/components/swirl-resource-list/swirl-resource-list.spec.js +8 -9
- package/dist/collection/components/swirl-select/swirl-select.js +4 -2
- package/dist/components/swirl-action-list2.js +10 -20
- package/dist/components/swirl-autocomplete.js +10 -2
- package/dist/components/swirl-option-list2.js +5 -3
- package/dist/components/swirl-resource-list2.js +20 -9
- package/dist/components/swirl-select.js +4 -2
- package/dist/esm/swirl-action-list_3.entry.js +10 -20
- package/dist/esm/swirl-app-layout_7.entry.js +20 -9
- package/dist/esm/swirl-autocomplete.entry.js +10 -2
- package/dist/esm/swirl-option-list_2.entry.js +5 -3
- package/dist/esm/swirl-select.entry.js +4 -2
- package/dist/swirl-components/{p-89898ac6.entry.js → p-057b650a.entry.js} +1 -1
- package/dist/swirl-components/p-0e6c2f2b.entry.js +1 -0
- package/dist/swirl-components/p-59408f77.entry.js +1 -0
- package/dist/swirl-components/p-6f07c958.entry.js +1 -0
- package/dist/swirl-components/{p-1d1edae3.entry.js → p-8a00faee.entry.js} +1 -1
- package/dist/swirl-components/swirl-components.esm.js +1 -1
- package/dist/types/components/swirl-action-list/swirl-action-list.d.ts +1 -6
- package/dist/types/components/swirl-select/swirl-select.d.ts +2 -0
- package/package.json +1 -1
- package/dist/swirl-components/p-0067f11b.entry.js +0 -1
- package/dist/swirl-components/p-56fa872b.entry.js +0 -1
- package/dist/swirl-components/p-bf258885.entry.js +0 -1
package/components.json
CHANGED
|
@@ -22,35 +22,25 @@ const SwirlActionList = class {
|
|
|
22
22
|
}
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
this.
|
|
27
|
-
this.observeSlotChanges();
|
|
28
|
-
}
|
|
29
|
-
disconnectedCallback() {
|
|
30
|
-
this.observer?.disconnect();
|
|
31
|
-
}
|
|
32
|
-
observeSlotChanges() {
|
|
33
|
-
this.observer = new MutationObserver(() => {
|
|
34
|
-
this.updateItems();
|
|
35
|
-
});
|
|
36
|
-
this.observer.observe(this.el, { childList: true });
|
|
37
|
-
}
|
|
38
|
-
updateItems() {
|
|
39
|
-
this.items = utils.querySelectorAllDeep(this.el, '[role="menuitem"]');
|
|
25
|
+
getItems() {
|
|
26
|
+
return utils.querySelectorAllDeep(this.el, '[role="menuitem"]');
|
|
40
27
|
}
|
|
41
28
|
focusNextItem() {
|
|
29
|
+
const items = this.getItems();
|
|
42
30
|
const activeItemIndex = this.getActiveItemIndex();
|
|
43
|
-
const newIndex = (activeItemIndex + 1) %
|
|
44
|
-
|
|
31
|
+
const newIndex = (activeItemIndex + 1) % items.length;
|
|
32
|
+
items[newIndex].focus();
|
|
45
33
|
}
|
|
46
34
|
focusPreviousItem() {
|
|
35
|
+
const items = this.getItems();
|
|
47
36
|
const activeItemIndex = this.getActiveItemIndex();
|
|
48
|
-
const newIndex = activeItemIndex === 0 ?
|
|
49
|
-
|
|
37
|
+
const newIndex = activeItemIndex === 0 ? items.length - 1 : activeItemIndex - 1;
|
|
38
|
+
items[newIndex]?.focus();
|
|
50
39
|
}
|
|
51
40
|
getActiveItemIndex() {
|
|
41
|
+
const items = this.getItems();
|
|
52
42
|
const activeElement = utils.getActiveElement();
|
|
53
|
-
return
|
|
43
|
+
return items.findIndex((item) => item === activeElement ||
|
|
54
44
|
item === activeElement?.querySelector('[role="menuitem"]'));
|
|
55
45
|
}
|
|
56
46
|
render() {
|
|
@@ -315,7 +315,7 @@ const SwirlResourceList = class {
|
|
|
315
315
|
this.draggingStartIndex = undefined;
|
|
316
316
|
};
|
|
317
317
|
this.onKeyDown = (event) => {
|
|
318
|
-
if (event.
|
|
318
|
+
if (event.code === "ArrowDown") {
|
|
319
319
|
event.preventDefault();
|
|
320
320
|
if (!Boolean(this.dragging)) {
|
|
321
321
|
this.focusItemAtIndex((this.focusedIndex + 1) % this.items.length);
|
|
@@ -324,7 +324,7 @@ const SwirlResourceList = class {
|
|
|
324
324
|
this.moveDraggedItemDown();
|
|
325
325
|
}
|
|
326
326
|
}
|
|
327
|
-
else if (event.
|
|
327
|
+
else if (event.code === "ArrowUp") {
|
|
328
328
|
event.preventDefault();
|
|
329
329
|
if (!Boolean(this.dragging)) {
|
|
330
330
|
const prevIndex = this.focusedIndex === 0
|
|
@@ -336,7 +336,7 @@ const SwirlResourceList = class {
|
|
|
336
336
|
this.moveDraggedItemUp();
|
|
337
337
|
}
|
|
338
338
|
}
|
|
339
|
-
else if (event.
|
|
339
|
+
else if (event.code === "Space" || event.code === "Enter") {
|
|
340
340
|
const target = event.composedPath()[0];
|
|
341
341
|
if (Boolean(this.dragging) &&
|
|
342
342
|
!target?.classList.contains("resource-list-item__drag-handle")) {
|
|
@@ -344,11 +344,11 @@ const SwirlResourceList = class {
|
|
|
344
344
|
this.stopDrag(this.dragging);
|
|
345
345
|
}
|
|
346
346
|
}
|
|
347
|
-
else if (event.
|
|
347
|
+
else if (event.code === "Home") {
|
|
348
348
|
event.preventDefault();
|
|
349
349
|
this.focusItemAtIndex(0);
|
|
350
350
|
}
|
|
351
|
-
else if (event.
|
|
351
|
+
else if (event.code === "End") {
|
|
352
352
|
event.preventDefault();
|
|
353
353
|
this.focusItemAtIndex(this.items.length - 1);
|
|
354
354
|
}
|
|
@@ -376,7 +376,11 @@ const SwirlResourceList = class {
|
|
|
376
376
|
this.setItemAllowDragState();
|
|
377
377
|
this.setupDragDrop();
|
|
378
378
|
});
|
|
379
|
-
this.observer.observe(this.el, {
|
|
379
|
+
this.observer.observe(this.el, {
|
|
380
|
+
childList: true,
|
|
381
|
+
characterData: true,
|
|
382
|
+
subtree: true,
|
|
383
|
+
});
|
|
380
384
|
}
|
|
381
385
|
watchAllowDrag() {
|
|
382
386
|
this.setItemAllowDragState();
|
|
@@ -391,9 +395,12 @@ const SwirlResourceList = class {
|
|
|
391
395
|
return this.items.map((i) => i).findIndex((i) => i === item);
|
|
392
396
|
}
|
|
393
397
|
removeItemsFromTabOrder() {
|
|
394
|
-
this.items.forEach((item) =>
|
|
395
|
-
?.querySelector(".resource-list-item__content, .resource-list-file-item")
|
|
396
|
-
?.
|
|
398
|
+
this.items.forEach((item) => {
|
|
399
|
+
const focusableEl = item?.querySelector(".resource-list-item__content, .resource-list-file-item");
|
|
400
|
+
const dragHandle = item?.querySelector(".resource-list-item__drag-handle");
|
|
401
|
+
focusableEl?.setAttribute("tabIndex", "-1");
|
|
402
|
+
dragHandle?.setAttribute("tabIndex", "-1");
|
|
403
|
+
});
|
|
397
404
|
}
|
|
398
405
|
setItemAllowDragState() {
|
|
399
406
|
if (this.allowDrag) {
|
|
@@ -434,6 +441,10 @@ const SwirlResourceList = class {
|
|
|
434
441
|
return;
|
|
435
442
|
}
|
|
436
443
|
const interactiveElement = item.querySelector(".resource-list-item__content, .resource-list-file-item");
|
|
444
|
+
const dragHandle = item.querySelector(".resource-list-item__drag-handle");
|
|
445
|
+
if (Boolean(dragHandle)) {
|
|
446
|
+
dragHandle.setAttribute("tabIndex", "0");
|
|
447
|
+
}
|
|
437
448
|
if (!Boolean(interactiveElement)) {
|
|
438
449
|
return;
|
|
439
450
|
}
|
|
@@ -41,8 +41,16 @@ const SwirlAutocomplete = class {
|
|
|
41
41
|
!this.value.some((item) => item.id === suggestion.id)),
|
|
42
42
|
];
|
|
43
43
|
this.valueChange.emit(this.value);
|
|
44
|
-
this.inputEl.
|
|
45
|
-
|
|
44
|
+
this.inputEl.value = "";
|
|
45
|
+
const input = this.inputEl.querySelector("input");
|
|
46
|
+
if (Boolean(input)) {
|
|
47
|
+
input.value = "";
|
|
48
|
+
queueMicrotask(() => {
|
|
49
|
+
input.focus();
|
|
50
|
+
this.close();
|
|
51
|
+
});
|
|
52
|
+
this.updateSuggestions(input.value);
|
|
53
|
+
}
|
|
46
54
|
}
|
|
47
55
|
else {
|
|
48
56
|
if (Boolean(event.detail[0])) {
|
|
@@ -305,9 +305,11 @@ const SwirlOptionList = class {
|
|
|
305
305
|
this.focusItem(newIndex);
|
|
306
306
|
}
|
|
307
307
|
getActiveItemIndex() {
|
|
308
|
-
return this.
|
|
309
|
-
|
|
310
|
-
|
|
308
|
+
return Boolean(this.focusedItem)
|
|
309
|
+
? this.items
|
|
310
|
+
.map((item) => item.querySelector('[role="option"]'))
|
|
311
|
+
.findIndex((item) => item === this.focusedItem)
|
|
312
|
+
: 0;
|
|
311
313
|
}
|
|
312
314
|
getItemIndex(item) {
|
|
313
315
|
return this.items.map((i) => i).findIndex((i) => i === item);
|
|
@@ -32,9 +32,11 @@ const SwirlSelect = class {
|
|
|
32
32
|
this.onOpen = (event) => {
|
|
33
33
|
this.placement = event.detail.position?.placement;
|
|
34
34
|
this.open = true;
|
|
35
|
+
this.optionList.querySelector('[tabIndex="0"]')?.focus();
|
|
35
36
|
};
|
|
36
37
|
this.onClose = () => {
|
|
37
38
|
this.open = false;
|
|
39
|
+
this.input.focus();
|
|
38
40
|
};
|
|
39
41
|
this.onKeyDown = (event) => {
|
|
40
42
|
if (event.code === "Space" || event.code === "Enter") {
|
|
@@ -87,11 +89,11 @@ const SwirlSelect = class {
|
|
|
87
89
|
"select--inline": this.inline,
|
|
88
90
|
"select--multi": this.multiSelect,
|
|
89
91
|
});
|
|
90
|
-
return (index.h(index.Host, { onKeyDown: this.onKeyDown }, index.h("div", { class: className }, index.h("swirl-popover-trigger", { popover: this.popover, setAriaAttributes: false }, index.h("input", { "aria-describedby": this.swirlAriaDescribedby, "aria-disabled": this.disabled ? "true" : undefined, "aria-invalid": ariaInvalid, class: "select__input", disabled: this.disabled, readOnly: true, type: "text", value: label })), index.h("span", { class: "select__multi-select-values" }, this.value
|
|
92
|
+
return (index.h(index.Host, { onKeyDown: this.onKeyDown }, index.h("div", { class: className }, index.h("swirl-popover-trigger", { popover: this.popover, setAriaAttributes: false }, index.h("input", { "aria-describedby": this.swirlAriaDescribedby, "aria-disabled": this.disabled ? "true" : undefined, "aria-invalid": ariaInvalid, class: "select__input", disabled: this.disabled, readOnly: true, ref: (el) => (this.input = el), type: "text", value: label })), index.h("span", { class: "select__multi-select-values" }, this.value
|
|
91
93
|
?.map((value) => this.options.find((option) => option.value === value))
|
|
92
94
|
?.map((option) => (index.h("swirl-tag", { "aria-hidden": "true", label: option?.label,
|
|
93
95
|
// eslint-disable-next-line react/jsx-no-bind
|
|
94
|
-
onRemove: () => this.unselectOption(option?.value), removable: !this.disabled && this.allowDeselect })))), index.h("span", { class: "select__indicator" }, this.open ? (index.h("swirl-icon-expand-less", null)) : (index.h("swirl-icon-expand-more", null))), index.h("swirl-popover", { animation: "scale-in-y", class: "select__popover", id: `select-options-${this.selectId}`, label: this.label, offset: [0, offset], onPopoverClose: this.onClose, onPopoverOpen: this.onOpen, ref: (el) => (this.popover = el), useContainerWidth: "swirl-form-control" }, index.h("swirl-option-list", { allowDeselect: this.allowDeselect, onValueChange: this.select, multiSelect: this.multiSelect, value: this.value }, index.h("slot", { onSlotchange: this.onSlotChange }))))));
|
|
96
|
+
onRemove: () => this.unselectOption(option?.value), removable: !this.disabled && this.allowDeselect })))), index.h("span", { class: "select__indicator" }, this.open ? (index.h("swirl-icon-expand-less", null)) : (index.h("swirl-icon-expand-more", null))), index.h("swirl-popover", { animation: "scale-in-y", class: "select__popover", id: `select-options-${this.selectId}`, label: this.label, offset: [0, offset], onPopoverClose: this.onClose, onPopoverOpen: this.onOpen, ref: (el) => (this.popover = el), useContainerWidth: "swirl-form-control" }, index.h("swirl-option-list", { allowDeselect: this.allowDeselect, onValueChange: this.select, multiSelect: this.multiSelect, ref: (el) => (this.optionList = el), value: this.value }, index.h("slot", { onSlotchange: this.onSlotChange }))))));
|
|
95
97
|
}
|
|
96
98
|
get el() { return index.getElement(this); }
|
|
97
99
|
};
|
|
@@ -16,35 +16,25 @@ export class SwirlActionList {
|
|
|
16
16
|
}
|
|
17
17
|
};
|
|
18
18
|
}
|
|
19
|
-
|
|
20
|
-
this.
|
|
21
|
-
this.observeSlotChanges();
|
|
22
|
-
}
|
|
23
|
-
disconnectedCallback() {
|
|
24
|
-
this.observer?.disconnect();
|
|
25
|
-
}
|
|
26
|
-
observeSlotChanges() {
|
|
27
|
-
this.observer = new MutationObserver(() => {
|
|
28
|
-
this.updateItems();
|
|
29
|
-
});
|
|
30
|
-
this.observer.observe(this.el, { childList: true });
|
|
31
|
-
}
|
|
32
|
-
updateItems() {
|
|
33
|
-
this.items = querySelectorAllDeep(this.el, '[role="menuitem"]');
|
|
19
|
+
getItems() {
|
|
20
|
+
return querySelectorAllDeep(this.el, '[role="menuitem"]');
|
|
34
21
|
}
|
|
35
22
|
focusNextItem() {
|
|
23
|
+
const items = this.getItems();
|
|
36
24
|
const activeItemIndex = this.getActiveItemIndex();
|
|
37
|
-
const newIndex = (activeItemIndex + 1) %
|
|
38
|
-
|
|
25
|
+
const newIndex = (activeItemIndex + 1) % items.length;
|
|
26
|
+
items[newIndex].focus();
|
|
39
27
|
}
|
|
40
28
|
focusPreviousItem() {
|
|
29
|
+
const items = this.getItems();
|
|
41
30
|
const activeItemIndex = this.getActiveItemIndex();
|
|
42
|
-
const newIndex = activeItemIndex === 0 ?
|
|
43
|
-
|
|
31
|
+
const newIndex = activeItemIndex === 0 ? items.length - 1 : activeItemIndex - 1;
|
|
32
|
+
items[newIndex]?.focus();
|
|
44
33
|
}
|
|
45
34
|
getActiveItemIndex() {
|
|
35
|
+
const items = this.getItems();
|
|
46
36
|
const activeElement = getActiveElement();
|
|
47
|
-
return
|
|
37
|
+
return items.findIndex((item) => item === activeElement ||
|
|
48
38
|
item === activeElement?.querySelector('[role="menuitem"]'));
|
|
49
39
|
}
|
|
50
40
|
render() {
|
|
@@ -32,8 +32,16 @@ export class SwirlAutocomplete {
|
|
|
32
32
|
!this.value.some((item) => item.id === suggestion.id)),
|
|
33
33
|
];
|
|
34
34
|
this.valueChange.emit(this.value);
|
|
35
|
-
this.inputEl.
|
|
36
|
-
|
|
35
|
+
this.inputEl.value = "";
|
|
36
|
+
const input = this.inputEl.querySelector("input");
|
|
37
|
+
if (Boolean(input)) {
|
|
38
|
+
input.value = "";
|
|
39
|
+
queueMicrotask(() => {
|
|
40
|
+
input.focus();
|
|
41
|
+
this.close();
|
|
42
|
+
});
|
|
43
|
+
this.updateSuggestions(input.value);
|
|
44
|
+
}
|
|
37
45
|
}
|
|
38
46
|
else {
|
|
39
47
|
if (Boolean(event.detail[0])) {
|
|
@@ -294,9 +294,11 @@ export class SwirlOptionList {
|
|
|
294
294
|
this.focusItem(newIndex);
|
|
295
295
|
}
|
|
296
296
|
getActiveItemIndex() {
|
|
297
|
-
return this.
|
|
298
|
-
|
|
299
|
-
|
|
297
|
+
return Boolean(this.focusedItem)
|
|
298
|
+
? this.items
|
|
299
|
+
.map((item) => item.querySelector('[role="option"]'))
|
|
300
|
+
.findIndex((item) => item === this.focusedItem)
|
|
301
|
+
: 0;
|
|
300
302
|
}
|
|
301
303
|
getItemIndex(item) {
|
|
302
304
|
return this.items.map((i) => i).findIndex((i) => i === item);
|
|
@@ -29,7 +29,7 @@ export class SwirlResourceList {
|
|
|
29
29
|
this.draggingStartIndex = undefined;
|
|
30
30
|
};
|
|
31
31
|
this.onKeyDown = (event) => {
|
|
32
|
-
if (event.
|
|
32
|
+
if (event.code === "ArrowDown") {
|
|
33
33
|
event.preventDefault();
|
|
34
34
|
if (!Boolean(this.dragging)) {
|
|
35
35
|
this.focusItemAtIndex((this.focusedIndex + 1) % this.items.length);
|
|
@@ -38,7 +38,7 @@ export class SwirlResourceList {
|
|
|
38
38
|
this.moveDraggedItemDown();
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
-
else if (event.
|
|
41
|
+
else if (event.code === "ArrowUp") {
|
|
42
42
|
event.preventDefault();
|
|
43
43
|
if (!Boolean(this.dragging)) {
|
|
44
44
|
const prevIndex = this.focusedIndex === 0
|
|
@@ -50,7 +50,7 @@ export class SwirlResourceList {
|
|
|
50
50
|
this.moveDraggedItemUp();
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
else if (event.
|
|
53
|
+
else if (event.code === "Space" || event.code === "Enter") {
|
|
54
54
|
const target = event.composedPath()[0];
|
|
55
55
|
if (Boolean(this.dragging) &&
|
|
56
56
|
!target?.classList.contains("resource-list-item__drag-handle")) {
|
|
@@ -58,11 +58,11 @@ export class SwirlResourceList {
|
|
|
58
58
|
this.stopDrag(this.dragging);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
else if (event.
|
|
61
|
+
else if (event.code === "Home") {
|
|
62
62
|
event.preventDefault();
|
|
63
63
|
this.focusItemAtIndex(0);
|
|
64
64
|
}
|
|
65
|
-
else if (event.
|
|
65
|
+
else if (event.code === "End") {
|
|
66
66
|
event.preventDefault();
|
|
67
67
|
this.focusItemAtIndex(this.items.length - 1);
|
|
68
68
|
}
|
|
@@ -90,7 +90,11 @@ export class SwirlResourceList {
|
|
|
90
90
|
this.setItemAllowDragState();
|
|
91
91
|
this.setupDragDrop();
|
|
92
92
|
});
|
|
93
|
-
this.observer.observe(this.el, {
|
|
93
|
+
this.observer.observe(this.el, {
|
|
94
|
+
childList: true,
|
|
95
|
+
characterData: true,
|
|
96
|
+
subtree: true,
|
|
97
|
+
});
|
|
94
98
|
}
|
|
95
99
|
watchAllowDrag() {
|
|
96
100
|
this.setItemAllowDragState();
|
|
@@ -105,9 +109,12 @@ export class SwirlResourceList {
|
|
|
105
109
|
return this.items.map((i) => i).findIndex((i) => i === item);
|
|
106
110
|
}
|
|
107
111
|
removeItemsFromTabOrder() {
|
|
108
|
-
this.items.forEach((item) =>
|
|
109
|
-
?.querySelector(".resource-list-item__content, .resource-list-file-item")
|
|
110
|
-
?.
|
|
112
|
+
this.items.forEach((item) => {
|
|
113
|
+
const focusableEl = item?.querySelector(".resource-list-item__content, .resource-list-file-item");
|
|
114
|
+
const dragHandle = item?.querySelector(".resource-list-item__drag-handle");
|
|
115
|
+
focusableEl?.setAttribute("tabIndex", "-1");
|
|
116
|
+
dragHandle?.setAttribute("tabIndex", "-1");
|
|
117
|
+
});
|
|
111
118
|
}
|
|
112
119
|
setItemAllowDragState() {
|
|
113
120
|
if (this.allowDrag) {
|
|
@@ -148,6 +155,10 @@ export class SwirlResourceList {
|
|
|
148
155
|
return;
|
|
149
156
|
}
|
|
150
157
|
const interactiveElement = item.querySelector(".resource-list-item__content, .resource-list-file-item");
|
|
158
|
+
const dragHandle = item.querySelector(".resource-list-item__drag-handle");
|
|
159
|
+
if (Boolean(dragHandle)) {
|
|
160
|
+
dragHandle.setAttribute("tabIndex", "0");
|
|
161
|
+
}
|
|
151
162
|
if (!Boolean(interactiveElement)) {
|
|
152
163
|
return;
|
|
153
164
|
}
|
|
@@ -60,23 +60,21 @@ describe("swirl-resource-list", () => {
|
|
|
60
60
|
});
|
|
61
61
|
const items = Array.from(page.root.querySelectorAll("swirl-resource-list-item"));
|
|
62
62
|
const interactiveElements = items.map((item) => item.querySelector(".resource-list-item__content"));
|
|
63
|
-
// focuses the first element if list is focused
|
|
64
|
-
page.root.children[0].focus();
|
|
65
63
|
expect(interactiveElements[0].getAttribute("tabIndex")).toBe("0");
|
|
66
|
-
// Down arrow
|
|
67
|
-
page.root.dispatchEvent(new KeyboardEvent("keydown", {
|
|
64
|
+
// Down arrow focuses the next element
|
|
65
|
+
page.root.dispatchEvent(new KeyboardEvent("keydown", { code: "ArrowDown" }));
|
|
68
66
|
expect(interactiveElements[0].getAttribute("tabIndex")).toBe("-1");
|
|
69
67
|
expect(interactiveElements[1].getAttribute("tabIndex")).toBe("0");
|
|
70
68
|
// Up arrow focues the next element
|
|
71
|
-
page.root.dispatchEvent(new KeyboardEvent("keydown", {
|
|
69
|
+
page.root.dispatchEvent(new KeyboardEvent("keydown", { code: "ArrowUp" }));
|
|
72
70
|
expect(interactiveElements[0].getAttribute("tabIndex")).toBe("0");
|
|
73
71
|
expect(interactiveElements[1].getAttribute("tabIndex")).toBe("-1");
|
|
74
72
|
// End key focues the first element
|
|
75
|
-
page.root.dispatchEvent(new KeyboardEvent("keydown", {
|
|
73
|
+
page.root.dispatchEvent(new KeyboardEvent("keydown", { code: "End" }));
|
|
76
74
|
expect(interactiveElements[0].getAttribute("tabIndex")).toBe("-1");
|
|
77
75
|
expect(interactiveElements[1].getAttribute("tabIndex")).toBe("0");
|
|
78
76
|
// Home key focues the first element
|
|
79
|
-
page.root.dispatchEvent(new KeyboardEvent("keydown", {
|
|
77
|
+
page.root.dispatchEvent(new KeyboardEvent("keydown", { code: "Home" }));
|
|
80
78
|
expect(interactiveElements[0].getAttribute("tabIndex")).toBe("0");
|
|
81
79
|
expect(interactiveElements[1].getAttribute("tabIndex")).toBe("-1");
|
|
82
80
|
});
|
|
@@ -101,10 +99,11 @@ describe("swirl-resource-list", () => {
|
|
|
101
99
|
.dispatchEvent(new KeyboardEvent("keydown", { code: "Space" }));
|
|
102
100
|
await page.waitForChanges();
|
|
103
101
|
expect(assistiveText.innerHTML).toBe("Item grabbed. Use arrow keys to move item up or down. Use spacebar to save position.");
|
|
104
|
-
|
|
102
|
+
await page.waitForChanges();
|
|
103
|
+
resourceList.dispatchEvent(new KeyboardEvent("keydown", { code: "ArrowDown" }));
|
|
105
104
|
await page.waitForChanges();
|
|
106
105
|
expect(assistiveText.innerHTML).toBe("Current position: 2");
|
|
107
|
-
resourceList.dispatchEvent(new KeyboardEvent("keydown", {
|
|
106
|
+
resourceList.dispatchEvent(new KeyboardEvent("keydown", { code: "ArrowUp" }));
|
|
108
107
|
await page.waitForChanges();
|
|
109
108
|
expect(assistiveText.innerHTML).toBe("Current position: 1");
|
|
110
109
|
});
|
|
@@ -23,9 +23,11 @@ export class SwirlSelect {
|
|
|
23
23
|
this.onOpen = (event) => {
|
|
24
24
|
this.placement = event.detail.position?.placement;
|
|
25
25
|
this.open = true;
|
|
26
|
+
this.optionList.querySelector('[tabIndex="0"]')?.focus();
|
|
26
27
|
};
|
|
27
28
|
this.onClose = () => {
|
|
28
29
|
this.open = false;
|
|
30
|
+
this.input.focus();
|
|
29
31
|
};
|
|
30
32
|
this.onKeyDown = (event) => {
|
|
31
33
|
if (event.code === "Space" || event.code === "Enter") {
|
|
@@ -78,11 +80,11 @@ export class SwirlSelect {
|
|
|
78
80
|
"select--inline": this.inline,
|
|
79
81
|
"select--multi": this.multiSelect,
|
|
80
82
|
});
|
|
81
|
-
return (h(Host, { onKeyDown: this.onKeyDown }, h("div", { class: className }, h("swirl-popover-trigger", { popover: this.popover, setAriaAttributes: false }, h("input", { "aria-describedby": this.swirlAriaDescribedby, "aria-disabled": this.disabled ? "true" : undefined, "aria-invalid": ariaInvalid, class: "select__input", disabled: this.disabled, readOnly: true, type: "text", value: label })), h("span", { class: "select__multi-select-values" }, this.value
|
|
83
|
+
return (h(Host, { onKeyDown: this.onKeyDown }, h("div", { class: className }, h("swirl-popover-trigger", { popover: this.popover, setAriaAttributes: false }, h("input", { "aria-describedby": this.swirlAriaDescribedby, "aria-disabled": this.disabled ? "true" : undefined, "aria-invalid": ariaInvalid, class: "select__input", disabled: this.disabled, readOnly: true, ref: (el) => (this.input = el), type: "text", value: label })), h("span", { class: "select__multi-select-values" }, this.value
|
|
82
84
|
?.map((value) => this.options.find((option) => option.value === value))
|
|
83
85
|
?.map((option) => (h("swirl-tag", { "aria-hidden": "true", label: option?.label,
|
|
84
86
|
// eslint-disable-next-line react/jsx-no-bind
|
|
85
|
-
onRemove: () => this.unselectOption(option?.value), removable: !this.disabled && this.allowDeselect })))), h("span", { class: "select__indicator" }, this.open ? (h("swirl-icon-expand-less", null)) : (h("swirl-icon-expand-more", null))), h("swirl-popover", { animation: "scale-in-y", class: "select__popover", id: `select-options-${this.selectId}`, label: this.label, offset: [0, offset], onPopoverClose: this.onClose, onPopoverOpen: this.onOpen, ref: (el) => (this.popover = el), useContainerWidth: "swirl-form-control" }, h("swirl-option-list", { allowDeselect: this.allowDeselect, onValueChange: this.select, multiSelect: this.multiSelect, value: this.value }, h("slot", { onSlotchange: this.onSlotChange }))))));
|
|
87
|
+
onRemove: () => this.unselectOption(option?.value), removable: !this.disabled && this.allowDeselect })))), h("span", { class: "select__indicator" }, this.open ? (h("swirl-icon-expand-less", null)) : (h("swirl-icon-expand-more", null))), h("swirl-popover", { animation: "scale-in-y", class: "select__popover", id: `select-options-${this.selectId}`, label: this.label, offset: [0, offset], onPopoverClose: this.onClose, onPopoverOpen: this.onOpen, ref: (el) => (this.popover = el), useContainerWidth: "swirl-form-control" }, h("swirl-option-list", { allowDeselect: this.allowDeselect, onValueChange: this.select, multiSelect: this.multiSelect, ref: (el) => (this.optionList = el), value: this.value }, h("slot", { onSlotchange: this.onSlotChange }))))));
|
|
86
88
|
}
|
|
87
89
|
static get is() { return "swirl-select"; }
|
|
88
90
|
static get encapsulation() { return "scoped"; }
|
|
@@ -19,35 +19,25 @@ const SwirlActionList = /*@__PURE__*/ proxyCustomElement(class SwirlActionList e
|
|
|
19
19
|
}
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
this.
|
|
24
|
-
this.observeSlotChanges();
|
|
25
|
-
}
|
|
26
|
-
disconnectedCallback() {
|
|
27
|
-
this.observer?.disconnect();
|
|
28
|
-
}
|
|
29
|
-
observeSlotChanges() {
|
|
30
|
-
this.observer = new MutationObserver(() => {
|
|
31
|
-
this.updateItems();
|
|
32
|
-
});
|
|
33
|
-
this.observer.observe(this.el, { childList: true });
|
|
34
|
-
}
|
|
35
|
-
updateItems() {
|
|
36
|
-
this.items = querySelectorAllDeep(this.el, '[role="menuitem"]');
|
|
22
|
+
getItems() {
|
|
23
|
+
return querySelectorAllDeep(this.el, '[role="menuitem"]');
|
|
37
24
|
}
|
|
38
25
|
focusNextItem() {
|
|
26
|
+
const items = this.getItems();
|
|
39
27
|
const activeItemIndex = this.getActiveItemIndex();
|
|
40
|
-
const newIndex = (activeItemIndex + 1) %
|
|
41
|
-
|
|
28
|
+
const newIndex = (activeItemIndex + 1) % items.length;
|
|
29
|
+
items[newIndex].focus();
|
|
42
30
|
}
|
|
43
31
|
focusPreviousItem() {
|
|
32
|
+
const items = this.getItems();
|
|
44
33
|
const activeItemIndex = this.getActiveItemIndex();
|
|
45
|
-
const newIndex = activeItemIndex === 0 ?
|
|
46
|
-
|
|
34
|
+
const newIndex = activeItemIndex === 0 ? items.length - 1 : activeItemIndex - 1;
|
|
35
|
+
items[newIndex]?.focus();
|
|
47
36
|
}
|
|
48
37
|
getActiveItemIndex() {
|
|
38
|
+
const items = this.getItems();
|
|
49
39
|
const activeElement = getActiveElement();
|
|
50
|
-
return
|
|
40
|
+
return items.findIndex((item) => item === activeElement ||
|
|
51
41
|
item === activeElement?.querySelector('[role="menuitem"]'));
|
|
52
42
|
}
|
|
53
43
|
render() {
|
|
@@ -54,8 +54,16 @@ const SwirlAutocomplete$1 = /*@__PURE__*/ proxyCustomElement(class SwirlAutocomp
|
|
|
54
54
|
!this.value.some((item) => item.id === suggestion.id)),
|
|
55
55
|
];
|
|
56
56
|
this.valueChange.emit(this.value);
|
|
57
|
-
this.inputEl.
|
|
58
|
-
|
|
57
|
+
this.inputEl.value = "";
|
|
58
|
+
const input = this.inputEl.querySelector("input");
|
|
59
|
+
if (Boolean(input)) {
|
|
60
|
+
input.value = "";
|
|
61
|
+
queueMicrotask(() => {
|
|
62
|
+
input.focus();
|
|
63
|
+
this.close();
|
|
64
|
+
});
|
|
65
|
+
this.updateSuggestions(input.value);
|
|
66
|
+
}
|
|
59
67
|
}
|
|
60
68
|
else {
|
|
61
69
|
if (Boolean(event.detail[0])) {
|
|
@@ -302,9 +302,11 @@ const SwirlOptionList = /*@__PURE__*/ proxyCustomElement(class SwirlOptionList e
|
|
|
302
302
|
this.focusItem(newIndex);
|
|
303
303
|
}
|
|
304
304
|
getActiveItemIndex() {
|
|
305
|
-
return this.
|
|
306
|
-
|
|
307
|
-
|
|
305
|
+
return Boolean(this.focusedItem)
|
|
306
|
+
? this.items
|
|
307
|
+
.map((item) => item.querySelector('[role="option"]'))
|
|
308
|
+
.findIndex((item) => item === this.focusedItem)
|
|
309
|
+
: 0;
|
|
308
310
|
}
|
|
309
311
|
getItemIndex(item) {
|
|
310
312
|
return this.items.map((i) => i).findIndex((i) => i === item);
|
|
@@ -37,7 +37,7 @@ const SwirlResourceList = /*@__PURE__*/ proxyCustomElement(class SwirlResourceLi
|
|
|
37
37
|
this.draggingStartIndex = undefined;
|
|
38
38
|
};
|
|
39
39
|
this.onKeyDown = (event) => {
|
|
40
|
-
if (event.
|
|
40
|
+
if (event.code === "ArrowDown") {
|
|
41
41
|
event.preventDefault();
|
|
42
42
|
if (!Boolean(this.dragging)) {
|
|
43
43
|
this.focusItemAtIndex((this.focusedIndex + 1) % this.items.length);
|
|
@@ -46,7 +46,7 @@ const SwirlResourceList = /*@__PURE__*/ proxyCustomElement(class SwirlResourceLi
|
|
|
46
46
|
this.moveDraggedItemDown();
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
-
else if (event.
|
|
49
|
+
else if (event.code === "ArrowUp") {
|
|
50
50
|
event.preventDefault();
|
|
51
51
|
if (!Boolean(this.dragging)) {
|
|
52
52
|
const prevIndex = this.focusedIndex === 0
|
|
@@ -58,7 +58,7 @@ const SwirlResourceList = /*@__PURE__*/ proxyCustomElement(class SwirlResourceLi
|
|
|
58
58
|
this.moveDraggedItemUp();
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
else if (event.
|
|
61
|
+
else if (event.code === "Space" || event.code === "Enter") {
|
|
62
62
|
const target = event.composedPath()[0];
|
|
63
63
|
if (Boolean(this.dragging) &&
|
|
64
64
|
!target?.classList.contains("resource-list-item__drag-handle")) {
|
|
@@ -66,11 +66,11 @@ const SwirlResourceList = /*@__PURE__*/ proxyCustomElement(class SwirlResourceLi
|
|
|
66
66
|
this.stopDrag(this.dragging);
|
|
67
67
|
}
|
|
68
68
|
}
|
|
69
|
-
else if (event.
|
|
69
|
+
else if (event.code === "Home") {
|
|
70
70
|
event.preventDefault();
|
|
71
71
|
this.focusItemAtIndex(0);
|
|
72
72
|
}
|
|
73
|
-
else if (event.
|
|
73
|
+
else if (event.code === "End") {
|
|
74
74
|
event.preventDefault();
|
|
75
75
|
this.focusItemAtIndex(this.items.length - 1);
|
|
76
76
|
}
|
|
@@ -98,7 +98,11 @@ const SwirlResourceList = /*@__PURE__*/ proxyCustomElement(class SwirlResourceLi
|
|
|
98
98
|
this.setItemAllowDragState();
|
|
99
99
|
this.setupDragDrop();
|
|
100
100
|
});
|
|
101
|
-
this.observer.observe(this.el, {
|
|
101
|
+
this.observer.observe(this.el, {
|
|
102
|
+
childList: true,
|
|
103
|
+
characterData: true,
|
|
104
|
+
subtree: true,
|
|
105
|
+
});
|
|
102
106
|
}
|
|
103
107
|
watchAllowDrag() {
|
|
104
108
|
this.setItemAllowDragState();
|
|
@@ -113,9 +117,12 @@ const SwirlResourceList = /*@__PURE__*/ proxyCustomElement(class SwirlResourceLi
|
|
|
113
117
|
return this.items.map((i) => i).findIndex((i) => i === item);
|
|
114
118
|
}
|
|
115
119
|
removeItemsFromTabOrder() {
|
|
116
|
-
this.items.forEach((item) =>
|
|
117
|
-
?.querySelector(".resource-list-item__content, .resource-list-file-item")
|
|
118
|
-
?.
|
|
120
|
+
this.items.forEach((item) => {
|
|
121
|
+
const focusableEl = item?.querySelector(".resource-list-item__content, .resource-list-file-item");
|
|
122
|
+
const dragHandle = item?.querySelector(".resource-list-item__drag-handle");
|
|
123
|
+
focusableEl?.setAttribute("tabIndex", "-1");
|
|
124
|
+
dragHandle?.setAttribute("tabIndex", "-1");
|
|
125
|
+
});
|
|
119
126
|
}
|
|
120
127
|
setItemAllowDragState() {
|
|
121
128
|
if (this.allowDrag) {
|
|
@@ -156,6 +163,10 @@ const SwirlResourceList = /*@__PURE__*/ proxyCustomElement(class SwirlResourceLi
|
|
|
156
163
|
return;
|
|
157
164
|
}
|
|
158
165
|
const interactiveElement = item.querySelector(".resource-list-item__content, .resource-list-file-item");
|
|
166
|
+
const dragHandle = item.querySelector(".resource-list-item__drag-handle");
|
|
167
|
+
if (Boolean(dragHandle)) {
|
|
168
|
+
dragHandle.setAttribute("tabIndex", "0");
|
|
169
|
+
}
|
|
159
170
|
if (!Boolean(interactiveElement)) {
|
|
160
171
|
return;
|
|
161
172
|
}
|
|
@@ -37,9 +37,11 @@ const SwirlSelect$1 = /*@__PURE__*/ proxyCustomElement(class SwirlSelect extends
|
|
|
37
37
|
this.onOpen = (event) => {
|
|
38
38
|
this.placement = event.detail.position?.placement;
|
|
39
39
|
this.open = true;
|
|
40
|
+
this.optionList.querySelector('[tabIndex="0"]')?.focus();
|
|
40
41
|
};
|
|
41
42
|
this.onClose = () => {
|
|
42
43
|
this.open = false;
|
|
44
|
+
this.input.focus();
|
|
43
45
|
};
|
|
44
46
|
this.onKeyDown = (event) => {
|
|
45
47
|
if (event.code === "Space" || event.code === "Enter") {
|
|
@@ -92,11 +94,11 @@ const SwirlSelect$1 = /*@__PURE__*/ proxyCustomElement(class SwirlSelect extends
|
|
|
92
94
|
"select--inline": this.inline,
|
|
93
95
|
"select--multi": this.multiSelect,
|
|
94
96
|
});
|
|
95
|
-
return (h(Host, { onKeyDown: this.onKeyDown }, h("div", { class: className }, h("swirl-popover-trigger", { popover: this.popover, setAriaAttributes: false }, h("input", { "aria-describedby": this.swirlAriaDescribedby, "aria-disabled": this.disabled ? "true" : undefined, "aria-invalid": ariaInvalid, class: "select__input", disabled: this.disabled, readOnly: true, type: "text", value: label })), h("span", { class: "select__multi-select-values" }, this.value
|
|
97
|
+
return (h(Host, { onKeyDown: this.onKeyDown }, h("div", { class: className }, h("swirl-popover-trigger", { popover: this.popover, setAriaAttributes: false }, h("input", { "aria-describedby": this.swirlAriaDescribedby, "aria-disabled": this.disabled ? "true" : undefined, "aria-invalid": ariaInvalid, class: "select__input", disabled: this.disabled, readOnly: true, ref: (el) => (this.input = el), type: "text", value: label })), h("span", { class: "select__multi-select-values" }, this.value
|
|
96
98
|
?.map((value) => this.options.find((option) => option.value === value))
|
|
97
99
|
?.map((option) => (h("swirl-tag", { "aria-hidden": "true", label: option?.label,
|
|
98
100
|
// eslint-disable-next-line react/jsx-no-bind
|
|
99
|
-
onRemove: () => this.unselectOption(option?.value), removable: !this.disabled && this.allowDeselect })))), h("span", { class: "select__indicator" }, this.open ? (h("swirl-icon-expand-less", null)) : (h("swirl-icon-expand-more", null))), h("swirl-popover", { animation: "scale-in-y", class: "select__popover", id: `select-options-${this.selectId}`, label: this.label, offset: [0, offset], onPopoverClose: this.onClose, onPopoverOpen: this.onOpen, ref: (el) => (this.popover = el), useContainerWidth: "swirl-form-control" }, h("swirl-option-list", { allowDeselect: this.allowDeselect, onValueChange: this.select, multiSelect: this.multiSelect, value: this.value }, h("slot", { onSlotchange: this.onSlotChange }))))));
|
|
101
|
+
onRemove: () => this.unselectOption(option?.value), removable: !this.disabled && this.allowDeselect })))), h("span", { class: "select__indicator" }, this.open ? (h("swirl-icon-expand-less", null)) : (h("swirl-icon-expand-more", null))), h("swirl-popover", { animation: "scale-in-y", class: "select__popover", id: `select-options-${this.selectId}`, label: this.label, offset: [0, offset], onPopoverClose: this.onClose, onPopoverOpen: this.onOpen, ref: (el) => (this.popover = el), useContainerWidth: "swirl-form-control" }, h("swirl-option-list", { allowDeselect: this.allowDeselect, onValueChange: this.select, multiSelect: this.multiSelect, ref: (el) => (this.optionList = el), value: this.value }, h("slot", { onSlotchange: this.onSlotChange }))))));
|
|
100
102
|
}
|
|
101
103
|
get el() { return this; }
|
|
102
104
|
static get style() { return swirlSelectCss; }
|