@progress/kendo-angular-listbox 21.2.0-develop.3 → 21.2.0-develop.5
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/esm2022/data-binding.directive.mjs +14 -2
- package/esm2022/keyboard-navigation.service.mjs +57 -5
- package/esm2022/listbox.component.mjs +5 -0
- package/esm2022/package-metadata.mjs +2 -2
- package/esm2022/selection.service.mjs +22 -5
- package/fesm2022/progress-kendo-angular-listbox.mjs +100 -14
- package/keyboard-navigation.service.d.ts +3 -0
- package/package.json +6 -6
- package/schematics/ngAdd/index.js +4 -4
- package/selection.service.d.ts +1 -0
|
@@ -233,12 +233,24 @@ export class DataBindingDirective {
|
|
|
233
233
|
if (!target || !source || source.data?.length === 0) {
|
|
234
234
|
return;
|
|
235
235
|
}
|
|
236
|
-
const itemsToTransfer = source.data.
|
|
236
|
+
const itemsToTransfer = source.data.filter((item) => !source.itemDisabled(item));
|
|
237
|
+
if (itemsToTransfer.length === 0) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
source.data = source.data.filter((item) => source.itemDisabled(item));
|
|
237
241
|
target.data.push(...itemsToTransfer);
|
|
238
242
|
source.clearSelection();
|
|
239
243
|
const sourceNavService = source.keyboardNavigationService;
|
|
240
244
|
const sourceSelService = source.selectionService;
|
|
241
|
-
|
|
245
|
+
if (source.data.length === 0) {
|
|
246
|
+
this.updateListBoxIndices(sourceNavService, sourceSelService, 0);
|
|
247
|
+
}
|
|
248
|
+
else {
|
|
249
|
+
sourceNavService.focusedListboxItemIndex = 0;
|
|
250
|
+
sourceNavService.selectedListboxItemIndex = -1;
|
|
251
|
+
sourceSelService.rangeSelectionAnchorIndex = null;
|
|
252
|
+
sourceSelService.lastSelectedOrUnselectedIndex = null;
|
|
253
|
+
}
|
|
242
254
|
const targetIndex = target.data.length - 1;
|
|
243
255
|
target.select([targetIndex]);
|
|
244
256
|
const targetNavService = target.keyboardNavigationService;
|
|
@@ -114,6 +114,9 @@ export class KeyboardNavigationService {
|
|
|
114
114
|
if (this.selectedListboxItemIndex !== this.focusedListboxItemIndex) {
|
|
115
115
|
const previousItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
116
116
|
const currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
117
|
+
if (this.isItemDisabled(currentItem)) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
117
120
|
this.changeTabindex(previousItem, currentItem);
|
|
118
121
|
}
|
|
119
122
|
this.onSelectionChange.emit({
|
|
@@ -144,8 +147,10 @@ export class KeyboardNavigationService {
|
|
|
144
147
|
return;
|
|
145
148
|
}
|
|
146
149
|
dir === 'moveUp' ? this.onArrowUp(listboxItems) : this.onArrowDown(listboxItems);
|
|
147
|
-
|
|
148
|
-
|
|
150
|
+
if (this.selectedListboxItemIndex !== this.focusedListboxItemIndex) {
|
|
151
|
+
this.onSelectionChange.emit({ index: this.selectedListboxItemIndex, prevIndex: this.focusedListboxItemIndex });
|
|
152
|
+
this.focusedListboxItemIndex = this.selectedListboxItemIndex;
|
|
153
|
+
}
|
|
149
154
|
}
|
|
150
155
|
onArrowLeftOrRight(keyCode, parentListbox, childListbox, event, listboxItems, currentListbox) {
|
|
151
156
|
event.preventDefault();
|
|
@@ -175,6 +180,9 @@ export class KeyboardNavigationService {
|
|
|
175
180
|
else {
|
|
176
181
|
previousItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
177
182
|
currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
183
|
+
if (this.isItemDisabled(currentItem)) {
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
178
186
|
prevIndex = this.selectedListboxItemIndex;
|
|
179
187
|
this.selectedListboxItemIndex = this.focusedListboxItemIndex;
|
|
180
188
|
}
|
|
@@ -303,7 +311,17 @@ export class KeyboardNavigationService {
|
|
|
303
311
|
}
|
|
304
312
|
if (previousFocusIndex !== this.focusedListboxItemIndex) {
|
|
305
313
|
const previousItem = listboxItems[previousFocusIndex]?.nativeElement;
|
|
306
|
-
|
|
314
|
+
let currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
315
|
+
if (this.isItemDisabled(currentItem)) {
|
|
316
|
+
const step = dir === 'moveDown' ? 1 : -1;
|
|
317
|
+
const nextEnabledIndex = this.findNextEnabledIndex(this.focusedListboxItemIndex, listboxItems, step);
|
|
318
|
+
if (nextEnabledIndex === -1) {
|
|
319
|
+
this.focusedListboxItemIndex = previousFocusIndex;
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
this.focusedListboxItemIndex = nextEnabledIndex;
|
|
323
|
+
currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
324
|
+
}
|
|
307
325
|
this.changeTabindex(previousItem, currentItem);
|
|
308
326
|
this.onSelectionChange.emit({
|
|
309
327
|
index: this.focusedListboxItemIndex,
|
|
@@ -317,7 +335,13 @@ export class KeyboardNavigationService {
|
|
|
317
335
|
if (this.focusedListboxItemIndex < listboxItems.length - 1) {
|
|
318
336
|
this.selectedListboxItemIndex = this.focusedListboxItemIndex + 1;
|
|
319
337
|
const previousItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
320
|
-
|
|
338
|
+
let currentItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
339
|
+
if (this.isItemDisabled(currentItem)) {
|
|
340
|
+
currentItem = this.calculateNextActiveItem(listboxItems, 1);
|
|
341
|
+
if (!currentItem) {
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
321
345
|
this.changeTabindex(previousItem, currentItem);
|
|
322
346
|
}
|
|
323
347
|
}
|
|
@@ -325,10 +349,38 @@ export class KeyboardNavigationService {
|
|
|
325
349
|
if (this.focusedListboxItemIndex > 0) {
|
|
326
350
|
this.selectedListboxItemIndex = this.focusedListboxItemIndex - 1;
|
|
327
351
|
const previousItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
328
|
-
|
|
352
|
+
let currentItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
353
|
+
if (this.isItemDisabled(currentItem)) {
|
|
354
|
+
currentItem = this.calculateNextActiveItem(listboxItems, -1);
|
|
355
|
+
if (!currentItem) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
329
359
|
this.changeTabindex(previousItem, currentItem);
|
|
330
360
|
}
|
|
331
361
|
}
|
|
362
|
+
isItemDisabled(item) {
|
|
363
|
+
return item.getAttribute('aria-disabled') === 'true';
|
|
364
|
+
}
|
|
365
|
+
findNextEnabledIndex(startIndex, listboxItems, step) {
|
|
366
|
+
let index = startIndex;
|
|
367
|
+
while (index >= 0 && index < listboxItems.length) {
|
|
368
|
+
const item = listboxItems[index]?.nativeElement;
|
|
369
|
+
if (!this.isItemDisabled(item)) {
|
|
370
|
+
return index;
|
|
371
|
+
}
|
|
372
|
+
index += step;
|
|
373
|
+
}
|
|
374
|
+
return -1;
|
|
375
|
+
}
|
|
376
|
+
calculateNextActiveItem(listboxItems, step) {
|
|
377
|
+
this.selectedListboxItemIndex = this.findNextEnabledIndex(this.selectedListboxItemIndex, listboxItems, step);
|
|
378
|
+
if (this.selectedListboxItemIndex === -1) {
|
|
379
|
+
this.selectedListboxItemIndex = this.focusedListboxItemIndex;
|
|
380
|
+
return null;
|
|
381
|
+
}
|
|
382
|
+
return listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
383
|
+
}
|
|
332
384
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KeyboardNavigationService, deps: [{ token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
333
385
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KeyboardNavigationService });
|
|
334
386
|
}
|
|
@@ -230,6 +230,9 @@ export class ListBoxComponent {
|
|
|
230
230
|
this.setToolbarClass(DEFAULT_TOOLBAR_POSITION);
|
|
231
231
|
this.setSizingClass(this.size);
|
|
232
232
|
this.direction = localization.rtl ? 'rtl' : 'ltr';
|
|
233
|
+
this.selectionService.isItemDisabled = (index) => {
|
|
234
|
+
return this.itemDisabled(this.data[index]);
|
|
235
|
+
};
|
|
233
236
|
}
|
|
234
237
|
ngOnInit() {
|
|
235
238
|
// This event emitter gives us the connectedWith value from the DataBinding directive
|
|
@@ -601,6 +604,7 @@ export class ListBoxComponent {
|
|
|
601
604
|
[attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
|
|
602
605
|
[index]="i"
|
|
603
606
|
[class.k-disabled]="itemDisabled(item)"
|
|
607
|
+
[attr.aria-disabled]="itemDisabled(item)"
|
|
604
608
|
>
|
|
605
609
|
@if (itemTemplate) {
|
|
606
610
|
<ng-template
|
|
@@ -713,6 +717,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
713
717
|
[attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
|
|
714
718
|
[index]="i"
|
|
715
719
|
[class.k-disabled]="itemDisabled(item)"
|
|
720
|
+
[attr.aria-disabled]="itemDisabled(item)"
|
|
716
721
|
>
|
|
717
722
|
@if (itemTemplate) {
|
|
718
723
|
<ng-template
|
|
@@ -10,7 +10,7 @@ export const packageMetadata = {
|
|
|
10
10
|
productName: 'Kendo UI for Angular',
|
|
11
11
|
productCode: 'KENDOUIANGULAR',
|
|
12
12
|
productCodes: ['KENDOUIANGULAR'],
|
|
13
|
-
publishDate:
|
|
14
|
-
version: '21.2.0-develop.
|
|
13
|
+
publishDate: 1764064235,
|
|
14
|
+
version: '21.2.0-develop.5',
|
|
15
15
|
licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
|
|
16
16
|
};
|
|
@@ -13,8 +13,12 @@ export class ListBoxSelectionService {
|
|
|
13
13
|
lastSelectedOrUnselectedIndex = null;
|
|
14
14
|
rangeSelectionTargetIndex = null;
|
|
15
15
|
rangeSelectionAnchorIndex = null;
|
|
16
|
+
isItemDisabled = () => false;
|
|
16
17
|
onSelect = new EventEmitter();
|
|
17
18
|
select(index, ctrlKey = false, shiftKey = false) {
|
|
19
|
+
if (this.isItemDisabled(index)) {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
18
22
|
const previousSelection = [...this.selectedIndices];
|
|
19
23
|
let selectedIndices = [];
|
|
20
24
|
let deselectedIndices = null;
|
|
@@ -68,7 +72,9 @@ export class ListBoxSelectionService {
|
|
|
68
72
|
const endIndex = Math.max(anchorIndex, index);
|
|
69
73
|
this.selectedIndices = [];
|
|
70
74
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
71
|
-
this.
|
|
75
|
+
if (!this.isItemDisabled(i)) {
|
|
76
|
+
this.selectedIndices.push(i);
|
|
77
|
+
}
|
|
72
78
|
}
|
|
73
79
|
this.rangeSelectionTargetIndex = index;
|
|
74
80
|
selectedIndices = this.selectedIndices.filter(i => !previousSelection.includes(i));
|
|
@@ -111,13 +117,18 @@ export class ListBoxSelectionService {
|
|
|
111
117
|
const endIndex = Math.max(anchorIndex, targetIndex);
|
|
112
118
|
this.selectedIndices = [];
|
|
113
119
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
114
|
-
this.
|
|
120
|
+
if (!this.isItemDisabled(i)) {
|
|
121
|
+
this.selectedIndices.push(i);
|
|
122
|
+
}
|
|
115
123
|
}
|
|
116
124
|
}
|
|
117
125
|
setSelectedIndices(indices) {
|
|
118
|
-
this.selectedIndices =
|
|
126
|
+
this.selectedIndices = indices.filter(i => !this.isItemDisabled(i));
|
|
119
127
|
}
|
|
120
128
|
addToSelectedIndices(index) {
|
|
129
|
+
if (this.isItemDisabled(index)) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
121
132
|
if (this.selectionMode === 'single') {
|
|
122
133
|
this.selectedIndices = [index];
|
|
123
134
|
}
|
|
@@ -127,11 +138,17 @@ export class ListBoxSelectionService {
|
|
|
127
138
|
}
|
|
128
139
|
selectAll(totalItems) {
|
|
129
140
|
if (this.selectionMode === 'multiple') {
|
|
130
|
-
this.selectedIndices =
|
|
141
|
+
this.selectedIndices = [];
|
|
142
|
+
for (let i = 0; i < totalItems; i++) {
|
|
143
|
+
if (!this.isItemDisabled(i)) {
|
|
144
|
+
this.selectedIndices.push(i);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
131
147
|
}
|
|
132
148
|
}
|
|
133
149
|
areAllSelected(totalItems) {
|
|
134
|
-
|
|
150
|
+
const allSelectableItems = Array.from({ length: totalItems }, (_, i) => i).filter(i => !this.isItemDisabled(i));
|
|
151
|
+
return this.selectedIndices.length === allSelectableItems.length && allSelectableItems.length > 0;
|
|
135
152
|
}
|
|
136
153
|
isSelected(index) {
|
|
137
154
|
return this.selectedIndices.indexOf(index) !== -1;
|
|
@@ -24,8 +24,8 @@ const packageMetadata = {
|
|
|
24
24
|
productName: 'Kendo UI for Angular',
|
|
25
25
|
productCode: 'KENDOUIANGULAR',
|
|
26
26
|
productCodes: ['KENDOUIANGULAR'],
|
|
27
|
-
publishDate:
|
|
28
|
-
version: '21.2.0-develop.
|
|
27
|
+
publishDate: 1764064235,
|
|
28
|
+
version: '21.2.0-develop.5',
|
|
29
29
|
licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning'
|
|
30
30
|
};
|
|
31
31
|
|
|
@@ -38,8 +38,12 @@ class ListBoxSelectionService {
|
|
|
38
38
|
lastSelectedOrUnselectedIndex = null;
|
|
39
39
|
rangeSelectionTargetIndex = null;
|
|
40
40
|
rangeSelectionAnchorIndex = null;
|
|
41
|
+
isItemDisabled = () => false;
|
|
41
42
|
onSelect = new EventEmitter();
|
|
42
43
|
select(index, ctrlKey = false, shiftKey = false) {
|
|
44
|
+
if (this.isItemDisabled(index)) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
43
47
|
const previousSelection = [...this.selectedIndices];
|
|
44
48
|
let selectedIndices = [];
|
|
45
49
|
let deselectedIndices = null;
|
|
@@ -93,7 +97,9 @@ class ListBoxSelectionService {
|
|
|
93
97
|
const endIndex = Math.max(anchorIndex, index);
|
|
94
98
|
this.selectedIndices = [];
|
|
95
99
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
96
|
-
this.
|
|
100
|
+
if (!this.isItemDisabled(i)) {
|
|
101
|
+
this.selectedIndices.push(i);
|
|
102
|
+
}
|
|
97
103
|
}
|
|
98
104
|
this.rangeSelectionTargetIndex = index;
|
|
99
105
|
selectedIndices = this.selectedIndices.filter(i => !previousSelection.includes(i));
|
|
@@ -136,13 +142,18 @@ class ListBoxSelectionService {
|
|
|
136
142
|
const endIndex = Math.max(anchorIndex, targetIndex);
|
|
137
143
|
this.selectedIndices = [];
|
|
138
144
|
for (let i = startIndex; i <= endIndex; i++) {
|
|
139
|
-
this.
|
|
145
|
+
if (!this.isItemDisabled(i)) {
|
|
146
|
+
this.selectedIndices.push(i);
|
|
147
|
+
}
|
|
140
148
|
}
|
|
141
149
|
}
|
|
142
150
|
setSelectedIndices(indices) {
|
|
143
|
-
this.selectedIndices =
|
|
151
|
+
this.selectedIndices = indices.filter(i => !this.isItemDisabled(i));
|
|
144
152
|
}
|
|
145
153
|
addToSelectedIndices(index) {
|
|
154
|
+
if (this.isItemDisabled(index)) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
146
157
|
if (this.selectionMode === 'single') {
|
|
147
158
|
this.selectedIndices = [index];
|
|
148
159
|
}
|
|
@@ -152,11 +163,17 @@ class ListBoxSelectionService {
|
|
|
152
163
|
}
|
|
153
164
|
selectAll(totalItems) {
|
|
154
165
|
if (this.selectionMode === 'multiple') {
|
|
155
|
-
this.selectedIndices =
|
|
166
|
+
this.selectedIndices = [];
|
|
167
|
+
for (let i = 0; i < totalItems; i++) {
|
|
168
|
+
if (!this.isItemDisabled(i)) {
|
|
169
|
+
this.selectedIndices.push(i);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
156
172
|
}
|
|
157
173
|
}
|
|
158
174
|
areAllSelected(totalItems) {
|
|
159
|
-
|
|
175
|
+
const allSelectableItems = Array.from({ length: totalItems }, (_, i) => i).filter(i => !this.isItemDisabled(i));
|
|
176
|
+
return this.selectedIndices.length === allSelectableItems.length && allSelectableItems.length > 0;
|
|
160
177
|
}
|
|
161
178
|
isSelected(index) {
|
|
162
179
|
return this.selectedIndices.indexOf(index) !== -1;
|
|
@@ -420,6 +437,9 @@ class KeyboardNavigationService {
|
|
|
420
437
|
if (this.selectedListboxItemIndex !== this.focusedListboxItemIndex) {
|
|
421
438
|
const previousItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
422
439
|
const currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
440
|
+
if (this.isItemDisabled(currentItem)) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
423
443
|
this.changeTabindex(previousItem, currentItem);
|
|
424
444
|
}
|
|
425
445
|
this.onSelectionChange.emit({
|
|
@@ -450,8 +470,10 @@ class KeyboardNavigationService {
|
|
|
450
470
|
return;
|
|
451
471
|
}
|
|
452
472
|
dir === 'moveUp' ? this.onArrowUp(listboxItems) : this.onArrowDown(listboxItems);
|
|
453
|
-
|
|
454
|
-
|
|
473
|
+
if (this.selectedListboxItemIndex !== this.focusedListboxItemIndex) {
|
|
474
|
+
this.onSelectionChange.emit({ index: this.selectedListboxItemIndex, prevIndex: this.focusedListboxItemIndex });
|
|
475
|
+
this.focusedListboxItemIndex = this.selectedListboxItemIndex;
|
|
476
|
+
}
|
|
455
477
|
}
|
|
456
478
|
onArrowLeftOrRight(keyCode, parentListbox, childListbox, event, listboxItems, currentListbox) {
|
|
457
479
|
event.preventDefault();
|
|
@@ -481,6 +503,9 @@ class KeyboardNavigationService {
|
|
|
481
503
|
else {
|
|
482
504
|
previousItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
483
505
|
currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
506
|
+
if (this.isItemDisabled(currentItem)) {
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
484
509
|
prevIndex = this.selectedListboxItemIndex;
|
|
485
510
|
this.selectedListboxItemIndex = this.focusedListboxItemIndex;
|
|
486
511
|
}
|
|
@@ -609,7 +634,17 @@ class KeyboardNavigationService {
|
|
|
609
634
|
}
|
|
610
635
|
if (previousFocusIndex !== this.focusedListboxItemIndex) {
|
|
611
636
|
const previousItem = listboxItems[previousFocusIndex]?.nativeElement;
|
|
612
|
-
|
|
637
|
+
let currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
638
|
+
if (this.isItemDisabled(currentItem)) {
|
|
639
|
+
const step = dir === 'moveDown' ? 1 : -1;
|
|
640
|
+
const nextEnabledIndex = this.findNextEnabledIndex(this.focusedListboxItemIndex, listboxItems, step);
|
|
641
|
+
if (nextEnabledIndex === -1) {
|
|
642
|
+
this.focusedListboxItemIndex = previousFocusIndex;
|
|
643
|
+
return;
|
|
644
|
+
}
|
|
645
|
+
this.focusedListboxItemIndex = nextEnabledIndex;
|
|
646
|
+
currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
647
|
+
}
|
|
613
648
|
this.changeTabindex(previousItem, currentItem);
|
|
614
649
|
this.onSelectionChange.emit({
|
|
615
650
|
index: this.focusedListboxItemIndex,
|
|
@@ -623,7 +658,13 @@ class KeyboardNavigationService {
|
|
|
623
658
|
if (this.focusedListboxItemIndex < listboxItems.length - 1) {
|
|
624
659
|
this.selectedListboxItemIndex = this.focusedListboxItemIndex + 1;
|
|
625
660
|
const previousItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
626
|
-
|
|
661
|
+
let currentItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
662
|
+
if (this.isItemDisabled(currentItem)) {
|
|
663
|
+
currentItem = this.calculateNextActiveItem(listboxItems, 1);
|
|
664
|
+
if (!currentItem) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
}
|
|
627
668
|
this.changeTabindex(previousItem, currentItem);
|
|
628
669
|
}
|
|
629
670
|
}
|
|
@@ -631,10 +672,38 @@ class KeyboardNavigationService {
|
|
|
631
672
|
if (this.focusedListboxItemIndex > 0) {
|
|
632
673
|
this.selectedListboxItemIndex = this.focusedListboxItemIndex - 1;
|
|
633
674
|
const previousItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
|
|
634
|
-
|
|
675
|
+
let currentItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
676
|
+
if (this.isItemDisabled(currentItem)) {
|
|
677
|
+
currentItem = this.calculateNextActiveItem(listboxItems, -1);
|
|
678
|
+
if (!currentItem) {
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
}
|
|
635
682
|
this.changeTabindex(previousItem, currentItem);
|
|
636
683
|
}
|
|
637
684
|
}
|
|
685
|
+
isItemDisabled(item) {
|
|
686
|
+
return item.getAttribute('aria-disabled') === 'true';
|
|
687
|
+
}
|
|
688
|
+
findNextEnabledIndex(startIndex, listboxItems, step) {
|
|
689
|
+
let index = startIndex;
|
|
690
|
+
while (index >= 0 && index < listboxItems.length) {
|
|
691
|
+
const item = listboxItems[index]?.nativeElement;
|
|
692
|
+
if (!this.isItemDisabled(item)) {
|
|
693
|
+
return index;
|
|
694
|
+
}
|
|
695
|
+
index += step;
|
|
696
|
+
}
|
|
697
|
+
return -1;
|
|
698
|
+
}
|
|
699
|
+
calculateNextActiveItem(listboxItems, step) {
|
|
700
|
+
this.selectedListboxItemIndex = this.findNextEnabledIndex(this.selectedListboxItemIndex, listboxItems, step);
|
|
701
|
+
if (this.selectedListboxItemIndex === -1) {
|
|
702
|
+
this.selectedListboxItemIndex = this.focusedListboxItemIndex;
|
|
703
|
+
return null;
|
|
704
|
+
}
|
|
705
|
+
return listboxItems[this.selectedListboxItemIndex]?.nativeElement;
|
|
706
|
+
}
|
|
638
707
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KeyboardNavigationService, deps: [{ token: i0.Renderer2 }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
639
708
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KeyboardNavigationService });
|
|
640
709
|
}
|
|
@@ -980,6 +1049,9 @@ class ListBoxComponent {
|
|
|
980
1049
|
this.setToolbarClass(DEFAULT_TOOLBAR_POSITION);
|
|
981
1050
|
this.setSizingClass(this.size);
|
|
982
1051
|
this.direction = localization.rtl ? 'rtl' : 'ltr';
|
|
1052
|
+
this.selectionService.isItemDisabled = (index) => {
|
|
1053
|
+
return this.itemDisabled(this.data[index]);
|
|
1054
|
+
};
|
|
983
1055
|
}
|
|
984
1056
|
ngOnInit() {
|
|
985
1057
|
// This event emitter gives us the connectedWith value from the DataBinding directive
|
|
@@ -1351,6 +1423,7 @@ class ListBoxComponent {
|
|
|
1351
1423
|
[attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
|
|
1352
1424
|
[index]="i"
|
|
1353
1425
|
[class.k-disabled]="itemDisabled(item)"
|
|
1426
|
+
[attr.aria-disabled]="itemDisabled(item)"
|
|
1354
1427
|
>
|
|
1355
1428
|
@if (itemTemplate) {
|
|
1356
1429
|
<ng-template
|
|
@@ -1463,6 +1536,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
1463
1536
|
[attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
|
|
1464
1537
|
[index]="i"
|
|
1465
1538
|
[class.k-disabled]="itemDisabled(item)"
|
|
1539
|
+
[attr.aria-disabled]="itemDisabled(item)"
|
|
1466
1540
|
>
|
|
1467
1541
|
@if (itemTemplate) {
|
|
1468
1542
|
<ng-template
|
|
@@ -1759,12 +1833,24 @@ class DataBindingDirective {
|
|
|
1759
1833
|
if (!target || !source || source.data?.length === 0) {
|
|
1760
1834
|
return;
|
|
1761
1835
|
}
|
|
1762
|
-
const itemsToTransfer = source.data.
|
|
1836
|
+
const itemsToTransfer = source.data.filter((item) => !source.itemDisabled(item));
|
|
1837
|
+
if (itemsToTransfer.length === 0) {
|
|
1838
|
+
return;
|
|
1839
|
+
}
|
|
1840
|
+
source.data = source.data.filter((item) => source.itemDisabled(item));
|
|
1763
1841
|
target.data.push(...itemsToTransfer);
|
|
1764
1842
|
source.clearSelection();
|
|
1765
1843
|
const sourceNavService = source.keyboardNavigationService;
|
|
1766
1844
|
const sourceSelService = source.selectionService;
|
|
1767
|
-
|
|
1845
|
+
if (source.data.length === 0) {
|
|
1846
|
+
this.updateListBoxIndices(sourceNavService, sourceSelService, 0);
|
|
1847
|
+
}
|
|
1848
|
+
else {
|
|
1849
|
+
sourceNavService.focusedListboxItemIndex = 0;
|
|
1850
|
+
sourceNavService.selectedListboxItemIndex = -1;
|
|
1851
|
+
sourceSelService.rangeSelectionAnchorIndex = null;
|
|
1852
|
+
sourceSelService.lastSelectedOrUnselectedIndex = null;
|
|
1853
|
+
}
|
|
1768
1854
|
const targetIndex = target.data.length - 1;
|
|
1769
1855
|
target.select([targetIndex]);
|
|
1770
1856
|
const targetNavService = target.keyboardNavigationService;
|
|
@@ -50,6 +50,9 @@ export declare class KeyboardNavigationService {
|
|
|
50
50
|
private onShiftArrow;
|
|
51
51
|
private onArrowDown;
|
|
52
52
|
private onArrowUp;
|
|
53
|
+
private isItemDisabled;
|
|
54
|
+
private findNextEnabledIndex;
|
|
55
|
+
private calculateNextActiveItem;
|
|
53
56
|
static ɵfac: i0.ɵɵFactoryDeclaration<KeyboardNavigationService, never>;
|
|
54
57
|
static ɵprov: i0.ɵɵInjectableDeclaration<KeyboardNavigationService>;
|
|
55
58
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@progress/kendo-angular-listbox",
|
|
3
|
-
"version": "21.2.0-develop.
|
|
3
|
+
"version": "21.2.0-develop.5",
|
|
4
4
|
"description": "Kendo UI for Angular ListBox",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
6
6
|
"author": "Progress",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"package": {
|
|
45
45
|
"productName": "Kendo UI for Angular",
|
|
46
46
|
"productCode": "KENDOUIANGULAR",
|
|
47
|
-
"publishDate":
|
|
47
|
+
"publishDate": 1764064235,
|
|
48
48
|
"licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/?utm_medium=product&utm_source=kendoangular&utm_campaign=kendo-ui-angular-purchase-license-keys-warning"
|
|
49
49
|
}
|
|
50
50
|
},
|
|
@@ -54,14 +54,14 @@
|
|
|
54
54
|
"@angular/core": "18 - 21",
|
|
55
55
|
"@angular/platform-browser": "18 - 21",
|
|
56
56
|
"@progress/kendo-licensing": "^1.7.0",
|
|
57
|
-
"@progress/kendo-angular-buttons": "21.2.0-develop.
|
|
58
|
-
"@progress/kendo-angular-common": "21.2.0-develop.
|
|
59
|
-
"@progress/kendo-angular-popup": "21.2.0-develop.
|
|
57
|
+
"@progress/kendo-angular-buttons": "21.2.0-develop.5",
|
|
58
|
+
"@progress/kendo-angular-common": "21.2.0-develop.5",
|
|
59
|
+
"@progress/kendo-angular-popup": "21.2.0-develop.5",
|
|
60
60
|
"rxjs": "^6.5.3 || ^7.0.0"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
63
|
"tslib": "^2.3.1",
|
|
64
|
-
"@progress/kendo-angular-schematics": "21.2.0-develop.
|
|
64
|
+
"@progress/kendo-angular-schematics": "21.2.0-develop.5",
|
|
65
65
|
"@progress/kendo-common": "^1.0.1",
|
|
66
66
|
"node-html-parser": "^7.0.1"
|
|
67
67
|
},
|
|
@@ -11,11 +11,11 @@ function default_1(options) {
|
|
|
11
11
|
// Additional dependencies to install.
|
|
12
12
|
// See https://github.com/telerik/kendo-schematics/issues/28
|
|
13
13
|
peerDependencies: {
|
|
14
|
-
'@progress/kendo-angular-buttons': '21.2.0-develop.
|
|
15
|
-
'@progress/kendo-angular-common': '21.2.0-develop.
|
|
16
|
-
'@progress/kendo-angular-l10n': '21.2.0-develop.
|
|
14
|
+
'@progress/kendo-angular-buttons': '21.2.0-develop.5',
|
|
15
|
+
'@progress/kendo-angular-common': '21.2.0-develop.5',
|
|
16
|
+
'@progress/kendo-angular-l10n': '21.2.0-develop.5',
|
|
17
17
|
// Peer of kendo-angular-buttons
|
|
18
|
-
'@progress/kendo-angular-popup': '21.2.0-develop.
|
|
18
|
+
'@progress/kendo-angular-popup': '21.2.0-develop.5'
|
|
19
19
|
} });
|
|
20
20
|
return (0, schematics_1.externalSchematic)('@progress/kendo-angular-schematics', 'ng-add', finalOptions);
|
|
21
21
|
}
|
package/selection.service.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export declare class ListBoxSelectionService {
|
|
|
30
30
|
lastSelectedOrUnselectedIndex: number | null;
|
|
31
31
|
rangeSelectionTargetIndex: number | null;
|
|
32
32
|
rangeSelectionAnchorIndex: number | null;
|
|
33
|
+
isItemDisabled: (index: number) => boolean;
|
|
33
34
|
onSelect: EventEmitter<any>;
|
|
34
35
|
select(index: number, ctrlKey?: boolean, shiftKey?: boolean): void;
|
|
35
36
|
selectRange(targetIndex: number): void;
|