@progress/kendo-angular-listbox 11.4.0-develop.1 → 11.4.0-develop.11
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/data-binding.directive.d.ts +1 -0
- package/esm2020/constants.mjs +2 -2
- package/esm2020/data-binding.directive.mjs +5 -1
- package/esm2020/keyboard-navigation.service.mjs +262 -0
- package/esm2020/listbox.component.mjs +296 -90
- package/esm2020/package-metadata.mjs +2 -2
- package/esm2020/selection.service.mjs +2 -2
- package/fesm2015/progress-kendo-angular-listbox.mjs +560 -96
- package/fesm2020/progress-kendo-angular-listbox.mjs +557 -96
- package/keyboard-navigation.service.d.ts +41 -0
- package/listbox.component.d.ts +67 -7
- package/package.json +5 -5
- package/schematics/ngAdd/index.js +4 -4
- package/selection.service.d.ts +3 -2
|
@@ -17,6 +17,7 @@ export declare class DataBindingDirective implements OnChanges, OnDestroy {
|
|
|
17
17
|
connectedWith: ListBoxComponent;
|
|
18
18
|
private actionClickSub;
|
|
19
19
|
private selectedBoxSub;
|
|
20
|
+
private connectedWithSub;
|
|
20
21
|
private selectedBox;
|
|
21
22
|
constructor(listbox: ListBoxComponent);
|
|
22
23
|
/**
|
package/esm2020/constants.mjs
CHANGED
|
@@ -25,13 +25,13 @@ export const allTools = [
|
|
|
25
25
|
},
|
|
26
26
|
{
|
|
27
27
|
name: 'transferTo',
|
|
28
|
-
label: 'Transfer
|
|
28
|
+
label: 'Transfer To',
|
|
29
29
|
icon: 'caret-alt-left',
|
|
30
30
|
svgIcon: caretAltLeftIcon
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
33
|
name: 'transferFrom',
|
|
34
|
-
label: 'Transfer
|
|
34
|
+
label: 'Transfer From',
|
|
35
35
|
icon: 'caret-alt-right',
|
|
36
36
|
svgIcon: caretAltRightIcon
|
|
37
37
|
},
|
|
@@ -17,7 +17,11 @@ export class DataBindingDirective {
|
|
|
17
17
|
this.listbox = listbox;
|
|
18
18
|
this.actionClickSub = new Subscription();
|
|
19
19
|
this.selectedBoxSub = new Subscription();
|
|
20
|
+
this.connectedWithSub = new Subscription();
|
|
20
21
|
this.selectedBox = this.listbox;
|
|
22
|
+
this.connectedWithSub.add(this.listbox.getChildListbox.subscribe(() => {
|
|
23
|
+
this.listbox.childListbox = this.connectedWith;
|
|
24
|
+
}));
|
|
21
25
|
this.actionClickSub.add(this.listbox.actionClick.subscribe((actionName) => {
|
|
22
26
|
switch (actionName) {
|
|
23
27
|
case 'moveUp': {
|
|
@@ -99,7 +103,7 @@ export class DataBindingDirective {
|
|
|
99
103
|
const newIndex = dir === 'up' ? index - 1 : index + 1;
|
|
100
104
|
// ES6 Destructuring swap
|
|
101
105
|
[this.selectedBox.data[newIndex], this.selectedBox.data[index]] = [this.selectedBox.data[index], this.selectedBox.data[newIndex]];
|
|
102
|
-
this.selectedBox.selectionService.select(newIndex);
|
|
106
|
+
this.selectedBox.selectionService.select(newIndex, dir);
|
|
103
107
|
}
|
|
104
108
|
removeItem() {
|
|
105
109
|
const index = this.selectedBox.selectedIndex;
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2023 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
|
6
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
+
import { EventEmitter, Injectable, NgZone, Renderer2 } from "@angular/core";
|
|
8
|
+
import { Keys } from "@progress/kendo-angular-common";
|
|
9
|
+
import { take } from "rxjs/operators";
|
|
10
|
+
import * as i0 from "@angular/core";
|
|
11
|
+
/**
|
|
12
|
+
* @hidden
|
|
13
|
+
*/
|
|
14
|
+
export class KeyboardNavigationService {
|
|
15
|
+
constructor(renderer, zone) {
|
|
16
|
+
this.renderer = renderer;
|
|
17
|
+
this.zone = zone;
|
|
18
|
+
this.selectedListboxItemIndex = 0;
|
|
19
|
+
this.focusedListboxItemIndex = 0;
|
|
20
|
+
this.focusedToolIndex = 0;
|
|
21
|
+
this.onDeleteEvent = new EventEmitter();
|
|
22
|
+
this.onSelectionChange = new EventEmitter();
|
|
23
|
+
this.onMoveSelectedItem = new EventEmitter();
|
|
24
|
+
this.onTransferAllEvent = new EventEmitter();
|
|
25
|
+
this.onShiftSelectedItem = new EventEmitter();
|
|
26
|
+
}
|
|
27
|
+
onKeyDown(event, toolsRef, toolbar, childListbox, parentListbox) {
|
|
28
|
+
const target = event.target;
|
|
29
|
+
const keyCode = event.keyCode;
|
|
30
|
+
const ctrlOrMetaKey = event.ctrlKey || event.metaKey;
|
|
31
|
+
const parentListboxToolbar = parentListbox?.selectedTools;
|
|
32
|
+
const tool = toolsRef.find(elem => elem.element === target);
|
|
33
|
+
const activeToolbar = toolbar.length > 0 ? toolbar : parentListboxToolbar;
|
|
34
|
+
if (toolsRef.length > 0 || parentListbox?.tools.toArray().length > 0) {
|
|
35
|
+
const focusNextTool = (keyCode === Keys.ArrowDown || keyCode === Keys.ArrowRight);
|
|
36
|
+
const focusPrevTool = (keyCode === Keys.ArrowUp || keyCode === Keys.ArrowLeft);
|
|
37
|
+
if ((focusNextTool || focusPrevTool) && tool) {
|
|
38
|
+
const dir = focusPrevTool ? 'up' : 'down';
|
|
39
|
+
this.handleToolbarArrows(toolsRef, dir);
|
|
40
|
+
}
|
|
41
|
+
else if (keyCode === Keys.F10) {
|
|
42
|
+
event.preventDefault();
|
|
43
|
+
this.onF10Key(toolsRef);
|
|
44
|
+
}
|
|
45
|
+
else if (keyCode === Keys.Delete && activeToolbar.some(tool => tool.name === 'remove')) {
|
|
46
|
+
this.onDeleteEvent.emit(this.selectedListboxItemIndex);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const isTargetListboxItem = this.listboxItems.find(elem => elem === target);
|
|
50
|
+
if (isTargetListboxItem) {
|
|
51
|
+
let isTransferToolVisible;
|
|
52
|
+
if (activeToolbar) {
|
|
53
|
+
isTransferToolVisible = activeToolbar.some(tool => tool.name.startsWith('transfer'));
|
|
54
|
+
}
|
|
55
|
+
if ((keyCode === Keys.ArrowRight || keyCode === Keys.ArrowLeft) && ctrlOrMetaKey && isTransferToolVisible) {
|
|
56
|
+
this.onArrowLeftOrRight(keyCode, parentListbox, childListbox, event);
|
|
57
|
+
}
|
|
58
|
+
else if ((keyCode === Keys.ArrowUp || keyCode === Keys.ArrowDown)) {
|
|
59
|
+
this.onArrowUpOrDown(keyCode, ctrlOrMetaKey, event, activeToolbar);
|
|
60
|
+
}
|
|
61
|
+
else if ((event.metaKey && keyCode === Keys.Enter) || (event.ctrlKey && keyCode === Keys.Space)) {
|
|
62
|
+
event.stopImmediatePropagation();
|
|
63
|
+
event.preventDefault();
|
|
64
|
+
this.onSelectChange();
|
|
65
|
+
}
|
|
66
|
+
else if (keyCode === Keys.Space) {
|
|
67
|
+
if (this.selectedListboxItemIndex !== this.focusedListboxItemIndex) {
|
|
68
|
+
const items = this.listboxItems;
|
|
69
|
+
this.changeTabindex(items[this.selectedListboxItemIndex], items[this.focusedListboxItemIndex]);
|
|
70
|
+
this.selectedListboxItemIndex = this.focusedListboxItemIndex;
|
|
71
|
+
this.onSelectionChange.emit(this.selectedListboxItemIndex);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
changeTabindex(previousItem, currentItem) {
|
|
77
|
+
if (previousItem) {
|
|
78
|
+
this.renderer.setAttribute(previousItem, 'tabindex', '-1');
|
|
79
|
+
previousItem.blur();
|
|
80
|
+
}
|
|
81
|
+
;
|
|
82
|
+
if (currentItem) {
|
|
83
|
+
this.renderer.setAttribute(currentItem, 'tabindex', '0');
|
|
84
|
+
currentItem.focus();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
onFocusIn() {
|
|
88
|
+
this.onSelectionChange.emit(this.selectedListboxItemIndex);
|
|
89
|
+
}
|
|
90
|
+
handleToolbarArrows(toolsRef, dir) {
|
|
91
|
+
const topReached = dir === 'up' && this.focusedToolIndex <= 0;
|
|
92
|
+
const bottomReached = dir === 'down' && this.focusedToolIndex >= toolsRef.length - 1;
|
|
93
|
+
if (topReached || bottomReached) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const offset = dir === 'up' ? -1 : 1;
|
|
97
|
+
this.focusedToolIndex += offset;
|
|
98
|
+
const prevItem = toolsRef[this.focusedToolIndex + (offset * -1)].element;
|
|
99
|
+
const currentItem = toolsRef[this.focusedToolIndex].element;
|
|
100
|
+
this.changeTabindex(prevItem, currentItem);
|
|
101
|
+
}
|
|
102
|
+
onArrowUpOrDown(keyCode, ctrlOrMetaKey, event, activeToolbar) {
|
|
103
|
+
event.preventDefault();
|
|
104
|
+
const dir = keyCode === Keys.ArrowUp ? 'moveUp' : 'moveDown';
|
|
105
|
+
if (ctrlOrMetaKey) {
|
|
106
|
+
let isMoveToolVisible;
|
|
107
|
+
if (activeToolbar) {
|
|
108
|
+
isMoveToolVisible = activeToolbar.some(tool => tool.name.startsWith('move'));
|
|
109
|
+
}
|
|
110
|
+
if (event.shiftKey && isMoveToolVisible) {
|
|
111
|
+
this.onMoveSelectedItem.emit(dir);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
this.changeFocusedItem(dir);
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
dir === 'moveUp' ? this.onArrowUp() : this.onArrowDown();
|
|
118
|
+
this.onSelectionChange.emit(this.selectedListboxItemIndex);
|
|
119
|
+
this.focusedListboxItemIndex = this.selectedListboxItemIndex;
|
|
120
|
+
}
|
|
121
|
+
onArrowLeftOrRight(keyCode, parentListbox, childListbox, event) {
|
|
122
|
+
event.preventDefault();
|
|
123
|
+
if (event.shiftKey) {
|
|
124
|
+
this.transferAllItems(keyCode, childListbox, parentListbox);
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (this.selectedListboxItemIndex >= 0) {
|
|
128
|
+
this.transferItem(keyCode, childListbox, parentListbox);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
onSelectChange() {
|
|
132
|
+
const canDeslect = (this.selectedListboxItemIndex || this.selectedListboxItemIndex === 0) && this.selectedListboxItemIndex === this.focusedListboxItemIndex;
|
|
133
|
+
if (canDeslect) {
|
|
134
|
+
this.selectedListboxItemIndex = null;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const items = this.listboxItems;
|
|
138
|
+
this.changeTabindex(items[this.selectedListboxItemIndex], items[this.focusedListboxItemIndex]);
|
|
139
|
+
this.selectedListboxItemIndex = this.focusedListboxItemIndex;
|
|
140
|
+
}
|
|
141
|
+
this.onSelectionChange.emit(this.selectedListboxItemIndex);
|
|
142
|
+
}
|
|
143
|
+
onF10Key(tools) {
|
|
144
|
+
if (this.focusedToolIndex && this.focusedToolIndex > -1) {
|
|
145
|
+
if (this.focusedToolIndex >= tools.length) {
|
|
146
|
+
tools[tools.length - 1].element.focus();
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
tools[this.focusedToolIndex].element.focus();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
tools[0].element.focus();
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
transferAllItems(keyCode, childListbox, parentListbox) {
|
|
157
|
+
const isArrowRight = keyCode === Keys.ArrowRight;
|
|
158
|
+
const actionToPerform = isArrowRight ? 'transferAllTo' : 'transferAllFrom';
|
|
159
|
+
this.onTransferAllEvent.emit(actionToPerform);
|
|
160
|
+
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
161
|
+
const childListboxNav = childListbox?.keyboardNavigationService || parentListbox?.childListbox.keyboardNavigationService;
|
|
162
|
+
let currentItem;
|
|
163
|
+
if (isArrowRight) {
|
|
164
|
+
if (childListbox) {
|
|
165
|
+
const childListboxItemsLength = childListboxNav.listboxItems.length - 1;
|
|
166
|
+
currentItem = childListboxNav.listboxItems[childListboxItemsLength];
|
|
167
|
+
childListboxNav.focusedListboxItemIndex = childListboxItemsLength;
|
|
168
|
+
childListboxNav.selectedListboxItemIndex = childListboxItemsLength;
|
|
169
|
+
this.focusedListboxItemIndex = 0;
|
|
170
|
+
this.selectedListboxItemIndex = 0;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
if (parentListbox) {
|
|
175
|
+
const parentListboxNav = parentListbox.keyboardNavigationService;
|
|
176
|
+
const parentListboxItemsLength = parentListboxNav.listboxItems.length - 1;
|
|
177
|
+
currentItem = parentListboxNav.listboxItems[parentListboxItemsLength];
|
|
178
|
+
parentListboxNav.focusedListboxItemIndex = parentListboxItemsLength;
|
|
179
|
+
parentListboxNav.selectedListboxItemIndex = parentListboxItemsLength;
|
|
180
|
+
childListboxNav.focusedListboxItemIndex = 0;
|
|
181
|
+
childListboxNav.selectedListboxItemIndex = 0;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
this.changeTabindex(null, currentItem);
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
transferItem(keyCode, childListbox, parentListbox) {
|
|
188
|
+
const isArrowRight = keyCode === Keys.ArrowRight;
|
|
189
|
+
const actionToPerform = isArrowRight ? 'transferFrom' : 'transferTo';
|
|
190
|
+
this.onShiftSelectedItem.emit(actionToPerform);
|
|
191
|
+
const adjustTabindex = (items, firstItem, currentItem) => {
|
|
192
|
+
items.listboxItems.forEach(item => {
|
|
193
|
+
if (item.getAttribute('tabindex') === '0') {
|
|
194
|
+
this.changeTabindex(item, firstItem);
|
|
195
|
+
}
|
|
196
|
+
});
|
|
197
|
+
this.changeTabindex(null, currentItem);
|
|
198
|
+
};
|
|
199
|
+
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
200
|
+
if (isArrowRight) {
|
|
201
|
+
if (childListbox) {
|
|
202
|
+
const childListboxNav = childListbox.keyboardNavigationService;
|
|
203
|
+
const childListboxItemsLength = childListboxNav.listboxItems.length - 1;
|
|
204
|
+
const currentItem = childListboxNav.listboxItems[childListboxItemsLength];
|
|
205
|
+
const parentListboxFirstItem = this.listboxItems[0];
|
|
206
|
+
childListboxNav.focusedListboxItemIndex = childListboxItemsLength;
|
|
207
|
+
childListboxNav.selectedListboxItemIndex = childListboxItemsLength;
|
|
208
|
+
this.focusedListboxItemIndex = 0;
|
|
209
|
+
this.selectedListboxItemIndex = 0;
|
|
210
|
+
adjustTabindex(childListboxNav, parentListboxFirstItem, currentItem);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else {
|
|
214
|
+
if (parentListbox) {
|
|
215
|
+
const childListboxNav = parentListbox.childListbox.keyboardNavigationService;
|
|
216
|
+
const parentListboxNav = parentListbox.keyboardNavigationService;
|
|
217
|
+
const parentListboxItemsLength = parentListboxNav.listboxItems.length - 1;
|
|
218
|
+
const currentItem = parentListboxNav.listboxItems[parentListboxItemsLength];
|
|
219
|
+
const childListboxFirstItem = childListboxNav.listboxItems[0];
|
|
220
|
+
parentListboxNav.focusedListboxItemIndex = parentListboxItemsLength;
|
|
221
|
+
parentListboxNav.selectedListboxItemIndex = parentListboxItemsLength;
|
|
222
|
+
childListboxNav.focusedListboxItemIndex = 0;
|
|
223
|
+
childListboxNav.selectedListboxItemIndex = 0;
|
|
224
|
+
adjustTabindex(parentListboxNav, childListboxFirstItem, currentItem);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
changeFocusedItem(dir) {
|
|
230
|
+
this.listboxItems[this.focusedListboxItemIndex].blur();
|
|
231
|
+
if (this.focusedListboxItemIndex > 0 && dir === 'moveUp') {
|
|
232
|
+
this.focusedListboxItemIndex -= 1;
|
|
233
|
+
}
|
|
234
|
+
else if (this.focusedListboxItemIndex < this.listboxItems.length - 1 && dir === 'moveDown') {
|
|
235
|
+
this.focusedListboxItemIndex += 1;
|
|
236
|
+
}
|
|
237
|
+
this.listboxItems[this.focusedListboxItemIndex].focus();
|
|
238
|
+
}
|
|
239
|
+
onArrowDown() {
|
|
240
|
+
if (this.selectedListboxItemIndex < this.listboxItems.length - 1) {
|
|
241
|
+
const offset = this.selectedListboxItemIndex ? this.selectedListboxItemIndex : this.focusedListboxItemIndex;
|
|
242
|
+
this.selectedListboxItemIndex = offset + 1;
|
|
243
|
+
const previousItem = this.listboxItems[this.selectedListboxItemIndex - 1];
|
|
244
|
+
const currentItem = this.listboxItems[this.selectedListboxItemIndex];
|
|
245
|
+
this.changeTabindex(previousItem, currentItem);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
onArrowUp() {
|
|
249
|
+
if (this.selectedListboxItemIndex > 0 || this.focusedListboxItemIndex > 0) {
|
|
250
|
+
const offset = this.selectedListboxItemIndex ? this.selectedListboxItemIndex : this.focusedListboxItemIndex;
|
|
251
|
+
this.selectedListboxItemIndex = offset - 1;
|
|
252
|
+
const previousItem = this.listboxItems[this.selectedListboxItemIndex + 1];
|
|
253
|
+
const currentItem = this.listboxItems[this.selectedListboxItemIndex];
|
|
254
|
+
this.changeTabindex(previousItem, currentItem);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
KeyboardNavigationService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: KeyboardNavigationService, deps: [{ token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
259
|
+
KeyboardNavigationService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: KeyboardNavigationService });
|
|
260
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.3.12", ngImport: i0, type: KeyboardNavigationService, decorators: [{
|
|
261
|
+
type: Injectable
|
|
262
|
+
}], ctorParameters: function () { return [{ type: i0.Renderer2 }, { type: i0.NgZone }]; } });
|