@progress/kendo-angular-listbox 21.1.1-develop.2 → 21.2.0-develop.10

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.
@@ -9,11 +9,10 @@ import { Subscription } from 'rxjs';
9
9
  import { getter } from '@progress/kendo-common';
10
10
  import { caretAltUpIcon, caretAltDownIcon, caretAltRightIcon, caretAltLeftIcon, caretDoubleAltRightIcon, caretDoubleAltLeftIcon, xIcon } from '@progress/kendo-svg-icons';
11
11
  import { ButtonComponent } from '@progress/kendo-angular-buttons';
12
- import { normalizeNumpadKeys, Keys, isPresent as isPresent$1, TemplateContextDirective, isChanged, ResizeBatchService } from '@progress/kendo-angular-common';
12
+ import { normalizeKeys, Keys, isPresent as isPresent$1, TemplateContextDirective, isChanged, ResizeBatchService } from '@progress/kendo-angular-common';
13
13
  import { take } from 'rxjs/operators';
14
14
  import * as i1 from '@progress/kendo-angular-l10n';
15
15
  import { ComponentMessages, LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
16
- import { NgIf, NgFor } from '@angular/common';
17
16
  import { IconsService } from '@progress/kendo-angular-icons';
18
17
  import { PopupService } from '@progress/kendo-angular-popup';
19
18
 
@@ -25,8 +24,8 @@ const packageMetadata = {
25
24
  productName: 'Kendo UI for Angular',
26
25
  productCode: 'KENDOUIANGULAR',
27
26
  productCodes: ['KENDOUIANGULAR'],
28
- publishDate: 1763729377,
29
- version: '21.1.1-develop.2',
27
+ publishDate: 1764593179,
28
+ version: '21.2.0-develop.10',
30
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'
31
30
  };
32
31
 
@@ -39,8 +38,12 @@ class ListBoxSelectionService {
39
38
  lastSelectedOrUnselectedIndex = null;
40
39
  rangeSelectionTargetIndex = null;
41
40
  rangeSelectionAnchorIndex = null;
41
+ isItemDisabled = () => false;
42
42
  onSelect = new EventEmitter();
43
43
  select(index, ctrlKey = false, shiftKey = false) {
44
+ if (this.isItemDisabled(index)) {
45
+ return;
46
+ }
44
47
  const previousSelection = [...this.selectedIndices];
45
48
  let selectedIndices = [];
46
49
  let deselectedIndices = null;
@@ -94,7 +97,9 @@ class ListBoxSelectionService {
94
97
  const endIndex = Math.max(anchorIndex, index);
95
98
  this.selectedIndices = [];
96
99
  for (let i = startIndex; i <= endIndex; i++) {
97
- this.selectedIndices.push(i);
100
+ if (!this.isItemDisabled(i)) {
101
+ this.selectedIndices.push(i);
102
+ }
98
103
  }
99
104
  this.rangeSelectionTargetIndex = index;
100
105
  selectedIndices = this.selectedIndices.filter(i => !previousSelection.includes(i));
@@ -137,13 +142,18 @@ class ListBoxSelectionService {
137
142
  const endIndex = Math.max(anchorIndex, targetIndex);
138
143
  this.selectedIndices = [];
139
144
  for (let i = startIndex; i <= endIndex; i++) {
140
- this.selectedIndices.push(i);
145
+ if (!this.isItemDisabled(i)) {
146
+ this.selectedIndices.push(i);
147
+ }
141
148
  }
142
149
  }
143
150
  setSelectedIndices(indices) {
144
- this.selectedIndices = [...indices];
151
+ this.selectedIndices = indices.filter(i => !this.isItemDisabled(i));
145
152
  }
146
153
  addToSelectedIndices(index) {
154
+ if (this.isItemDisabled(index)) {
155
+ return;
156
+ }
147
157
  if (this.selectionMode === 'single') {
148
158
  this.selectedIndices = [index];
149
159
  }
@@ -153,11 +163,17 @@ class ListBoxSelectionService {
153
163
  }
154
164
  selectAll(totalItems) {
155
165
  if (this.selectionMode === 'multiple') {
156
- this.selectedIndices = Array.from({ length: totalItems }, (_, i) => i);
166
+ this.selectedIndices = [];
167
+ for (let i = 0; i < totalItems; i++) {
168
+ if (!this.isItemDisabled(i)) {
169
+ this.selectedIndices.push(i);
170
+ }
171
+ }
157
172
  }
158
173
  }
159
174
  areAllSelected(totalItems) {
160
- return this.selectedIndices.length === totalItems && totalItems > 0;
175
+ const allSelectableItems = Array.from({ length: totalItems }, (_, i) => i).filter(i => !this.isItemDisabled(i));
176
+ return this.selectedIndices.length === allSelectableItems.length && allSelectableItems.length > 0;
161
177
  }
162
178
  isSelected(index) {
163
179
  return this.selectedIndices.indexOf(index) !== -1;
@@ -337,7 +353,7 @@ class KeyboardNavigationService {
337
353
  }
338
354
  onKeyDown(event, toolsRef, toolbar, childListbox, parentListbox, listboxItems, currentListbox) {
339
355
  const target = event.target;
340
- const keyCode = normalizeNumpadKeys(event);
356
+ const keyCode = normalizeKeys(event);
341
357
  const ctrlOrMetaKey = event.ctrlKey || event.metaKey;
342
358
  const parentListboxToolbar = parentListbox?.selectedTools;
343
359
  const tool = toolsRef.find(elem => elem.element === target);
@@ -421,6 +437,9 @@ class KeyboardNavigationService {
421
437
  if (this.selectedListboxItemIndex !== this.focusedListboxItemIndex) {
422
438
  const previousItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
423
439
  const currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
440
+ if (this.isItemDisabled(currentItem)) {
441
+ return;
442
+ }
424
443
  this.changeTabindex(previousItem, currentItem);
425
444
  }
426
445
  this.onSelectionChange.emit({
@@ -451,8 +470,10 @@ class KeyboardNavigationService {
451
470
  return;
452
471
  }
453
472
  dir === 'moveUp' ? this.onArrowUp(listboxItems) : this.onArrowDown(listboxItems);
454
- this.onSelectionChange.emit({ index: this.selectedListboxItemIndex, prevIndex: this.focusedListboxItemIndex });
455
- this.focusedListboxItemIndex = this.selectedListboxItemIndex;
473
+ if (this.selectedListboxItemIndex !== this.focusedListboxItemIndex) {
474
+ this.onSelectionChange.emit({ index: this.selectedListboxItemIndex, prevIndex: this.focusedListboxItemIndex });
475
+ this.focusedListboxItemIndex = this.selectedListboxItemIndex;
476
+ }
456
477
  }
457
478
  onArrowLeftOrRight(keyCode, parentListbox, childListbox, event, listboxItems, currentListbox) {
458
479
  event.preventDefault();
@@ -482,6 +503,9 @@ class KeyboardNavigationService {
482
503
  else {
483
504
  previousItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
484
505
  currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
506
+ if (this.isItemDisabled(currentItem)) {
507
+ return;
508
+ }
485
509
  prevIndex = this.selectedListboxItemIndex;
486
510
  this.selectedListboxItemIndex = this.focusedListboxItemIndex;
487
511
  }
@@ -610,7 +634,17 @@ class KeyboardNavigationService {
610
634
  }
611
635
  if (previousFocusIndex !== this.focusedListboxItemIndex) {
612
636
  const previousItem = listboxItems[previousFocusIndex]?.nativeElement;
613
- const currentItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
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
+ }
614
648
  this.changeTabindex(previousItem, currentItem);
615
649
  this.onSelectionChange.emit({
616
650
  index: this.focusedListboxItemIndex,
@@ -624,7 +658,13 @@ class KeyboardNavigationService {
624
658
  if (this.focusedListboxItemIndex < listboxItems.length - 1) {
625
659
  this.selectedListboxItemIndex = this.focusedListboxItemIndex + 1;
626
660
  const previousItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
627
- const currentItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
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
+ }
628
668
  this.changeTabindex(previousItem, currentItem);
629
669
  }
630
670
  }
@@ -632,10 +672,38 @@ class KeyboardNavigationService {
632
672
  if (this.focusedListboxItemIndex > 0) {
633
673
  this.selectedListboxItemIndex = this.focusedListboxItemIndex - 1;
634
674
  const previousItem = listboxItems[this.focusedListboxItemIndex]?.nativeElement;
635
- const currentItem = listboxItems[this.selectedListboxItemIndex]?.nativeElement;
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
+ }
636
682
  this.changeTabindex(previousItem, currentItem);
637
683
  }
638
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
+ }
639
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 });
640
708
  static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: KeyboardNavigationService });
641
709
  }
@@ -981,6 +1049,9 @@ class ListBoxComponent {
981
1049
  this.setToolbarClass(DEFAULT_TOOLBAR_POSITION);
982
1050
  this.setSizingClass(this.size);
983
1051
  this.direction = localization.rtl ? 'rtl' : 'ltr';
1052
+ this.selectionService.isItemDisabled = (index) => {
1053
+ return this.itemDisabled(this.data[index]);
1054
+ };
984
1055
  }
985
1056
  ngOnInit() {
986
1057
  // This event emitter gives us the connectedWith value from the DataBinding directive
@@ -1271,7 +1342,7 @@ class ListBoxComponent {
1271
1342
  this.renderer.addClass(this.hostElement.nativeElement, `k-listbox-${sizeClassMap[size]}`);
1272
1343
  }
1273
1344
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListBoxComponent, deps: [{ token: KeyboardNavigationService }, { token: ListBoxSelectionService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i1.LocalizationService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1274
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ListBoxComponent, isStandalone: true, selector: "kendo-listbox", inputs: { textField: "textField", selectable: "selectable", data: "data", size: "size", toolbar: "toolbar", listboxLabel: "listboxLabel", listboxToolbarLabel: "listboxToolbarLabel", itemDisabled: "itemDisabled" }, outputs: { selectionChange: "selectionChange", action: "action", getChildListbox: "getChildListbox" }, host: { properties: { "class.k-listbox": "this.listboxClassName", "attr.dir": "this.direction" } }, providers: [
1345
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ListBoxComponent, isStandalone: true, selector: "kendo-listbox", inputs: { textField: "textField", selectable: "selectable", data: "data", size: "size", toolbar: "toolbar", listboxLabel: "listboxLabel", listboxToolbarLabel: "listboxToolbarLabel", itemDisabled: "itemDisabled" }, outputs: { selectionChange: "selectionChange", action: "action", getChildListbox: "getChildListbox" }, host: { properties: { "class.k-listbox": "this.listboxClassName", "attr.dir": "this.direction" } }, providers: [
1275
1346
  ListBoxSelectionService,
1276
1347
  KeyboardNavigationService,
1277
1348
  LocalizationService,
@@ -1281,41 +1352,41 @@ class ListBoxComponent {
1281
1352
  },
1282
1353
  ], queries: [{ propertyName: "itemTemplate", first: true, predicate: ItemTemplateDirective, descendants: true }], viewQueries: [{ propertyName: "listboxElement", first: true, predicate: ["listbox"], descendants: true }, { propertyName: "toolbarElement", first: true, predicate: ["toolbar"], descendants: true }, { propertyName: "listboxItems", predicate: ["listboxItems"], descendants: true }, { propertyName: "tools", predicate: ["tools"], descendants: true }], ngImport: i0, template: `
1283
1354
  <ng-container kendoListBoxLocalizedMessages
1284
- i18n-moveUp="kendo.listbox.moveUp|The title of the Move Up button"
1285
- moveUp="Move Up"
1286
-
1287
- i18n-moveDown="kendo.listbox.moveDown|The title of the Move Down button"
1288
- moveDown="Move Down"
1289
-
1290
- i18n-transferTo="kendo.listbox.transferTo|The title of the Transfer To button"
1291
- transferTo="Transfer To"
1292
-
1293
- i18n-transferAllTo="kendo.listbox.transferAllTo|The title of the Transfer All To button"
1294
- transferAllTo="Transfer All To"
1295
-
1296
- i18n-transferFrom="kendo.listbox.transferFrom|The title of the Transfer From button"
1297
- transferFrom="Transfer From"
1298
-
1299
- i18n-transferAllFrom="kendo.listbox.transferAllFrom|The title of the Transfer All From button"
1300
- transferAllFrom="Transfer All From"
1301
-
1302
- i18n-remove="kendo.listbox.remove|The title of the Remove button"
1303
- remove="Remove"
1304
-
1305
- i18n-noDataText="kendo.listbox.noDataText|The text displayed when there are no items"
1306
- noDataText="No data found."
1307
- >
1355
+ i18n-moveUp="kendo.listbox.moveUp|The title of the Move Up button"
1356
+ moveUp="Move Up"
1357
+
1358
+ i18n-moveDown="kendo.listbox.moveDown|The title of the Move Down button"
1359
+ moveDown="Move Down"
1360
+
1361
+ i18n-transferTo="kendo.listbox.transferTo|The title of the Transfer To button"
1362
+ transferTo="Transfer To"
1363
+
1364
+ i18n-transferAllTo="kendo.listbox.transferAllTo|The title of the Transfer All To button"
1365
+ transferAllTo="Transfer All To"
1366
+
1367
+ i18n-transferFrom="kendo.listbox.transferFrom|The title of the Transfer From button"
1368
+ transferFrom="Transfer From"
1369
+
1370
+ i18n-transferAllFrom="kendo.listbox.transferAllFrom|The title of the Transfer All From button"
1371
+ transferAllFrom="Transfer All From"
1372
+
1373
+ i18n-remove="kendo.listbox.remove|The title of the Remove button"
1374
+ remove="Remove"
1375
+
1376
+ i18n-noDataText="kendo.listbox.noDataText|The text displayed when there are no items"
1377
+ noDataText="No data found."
1378
+ >
1308
1379
  </ng-container>
1309
- <div
1380
+ @if (selectedTools.length > 0) {
1381
+ <div
1310
1382
  #toolbar
1311
1383
  class="k-listbox-actions"
1312
- *ngIf="selectedTools.length > 0"
1313
1384
  role="toolbar"
1314
1385
  [attr.aria-label]="listboxToolbarLabel"
1315
- >
1316
- <button
1386
+ >
1387
+ @for (tool of selectedTools; track tool; let i = $index) {
1388
+ <button
1317
1389
  #tools
1318
- *ngFor="let tool of selectedTools; let i = index"
1319
1390
  kendoButton
1320
1391
  [attr.tabindex]="i === 0 ? '0' : '-1'"
1321
1392
  [size]="this.size"
@@ -1325,53 +1396,59 @@ class ListBoxComponent {
1325
1396
  (click)="performAction(tool.name)"
1326
1397
  role="button"
1327
1398
  type="button"
1328
- ></button>
1329
- </div>
1399
+ ></button>
1400
+ }
1401
+ </div>
1402
+ }
1330
1403
  <div class="k-list-scroller k-selectable">
1331
- <div class="{{ listClasses }}">
1332
- <div
1333
- *ngIf="data.length > 0"
1334
- class="k-list-content"
1404
+ <div class="{{ listClasses }}">
1405
+ @if (data.length > 0) {
1406
+ <div
1407
+ class="k-list-content"
1335
1408
  >
1336
- <ul
1337
- #listbox
1338
- class="k-list-ul"
1339
- role="listbox"
1340
- [attr.aria-label]="listboxLabel"
1341
- [attr.aria-multiselectable]="selectable === 'multiple'"
1342
- >
1343
- <li
1344
- #listboxItems
1345
- *ngFor="let item of data; let i = index"
1346
- kendoListBoxItemSelectable
1347
- class="k-list-item"
1348
- [attr.tabindex]="i === keyboardNavigationService.focusedListboxItemIndex ? '0' : '-1'"
1349
- role="option"
1350
- [attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
1351
- [index]="i"
1352
- [class.k-disabled]="itemDisabled(item)"
1353
- >
1354
- <ng-template
1355
- *ngIf="itemTemplate; else defaultItemTemplate"
1409
+ <ul
1410
+ #listbox
1411
+ class="k-list-ul"
1412
+ role="listbox"
1413
+ [attr.aria-label]="listboxLabel"
1414
+ [attr.aria-multiselectable]="selectable === 'multiple'"
1415
+ >
1416
+ @for (item of data; track item; let i = $index) {
1417
+ <li
1418
+ #listboxItems
1419
+ kendoListBoxItemSelectable
1420
+ class="k-list-item"
1421
+ [attr.tabindex]="i === keyboardNavigationService.focusedListboxItemIndex ? '0' : '-1'"
1422
+ role="option"
1423
+ [attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
1424
+ [index]="i"
1425
+ [class.k-disabled]="itemDisabled(item)"
1426
+ [attr.aria-disabled]="itemDisabled(item)"
1427
+ >
1428
+ @if (itemTemplate) {
1429
+ <ng-template
1356
1430
  [templateContext]="{
1357
1431
  templateRef: itemTemplate.templateRef,
1358
1432
  $implicit: item
1359
1433
  }"
1360
- >
1361
- </ng-template>
1362
- <ng-template #defaultItemTemplate>
1363
- <span class="k-list-item-text">{{ getText(item) }}</span>
1364
- </ng-template>
1365
- </li>
1366
- </ul>
1367
- </div>
1368
- <span
1369
- *ngIf="data.length === 0"
1370
- class="k-nodata"
1371
- >{{ messageFor('noDataText') }}</span>
1372
- </div>
1434
+ >
1435
+ </ng-template>
1436
+ } @else {
1437
+ <span class="k-list-item-text">{{ getText(item) }}</span>
1438
+ }
1439
+ </li>
1440
+ }
1441
+ </ul>
1442
+ </div>
1443
+ }
1444
+ @if (data.length === 0) {
1445
+ <span
1446
+ class="k-nodata"
1447
+ >{{ messageFor('noDataText') }}</span>
1448
+ }
1449
+ </div>
1373
1450
  </div>
1374
- `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoListBoxLocalizedMessages]" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: ItemSelectableDirective, selector: "[kendoListBoxItemSelectable]", inputs: ["index"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }] });
1451
+ `, isInline: true, dependencies: [{ kind: "directive", type: LocalizedMessagesDirective, selector: "[kendoListBoxLocalizedMessages]" }, { kind: "component", type: ButtonComponent, selector: "button[kendoButton]", inputs: ["arrowIcon", "toggleable", "togglable", "selected", "tabIndex", "imageUrl", "iconClass", "icon", "disabled", "size", "rounded", "fillMode", "themeColor", "svgIcon", "primary", "look"], outputs: ["selectedChange", "click"], exportAs: ["kendoButton"] }, { kind: "directive", type: ItemSelectableDirective, selector: "[kendoListBoxItemSelectable]", inputs: ["index"] }, { kind: "directive", type: TemplateContextDirective, selector: "[templateContext]", inputs: ["templateContext"] }] });
1375
1452
  }
1376
1453
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListBoxComponent, decorators: [{
1377
1454
  type: Component,
@@ -1388,41 +1465,41 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1388
1465
  ],
1389
1466
  template: `
1390
1467
  <ng-container kendoListBoxLocalizedMessages
1391
- i18n-moveUp="kendo.listbox.moveUp|The title of the Move Up button"
1392
- moveUp="Move Up"
1393
-
1394
- i18n-moveDown="kendo.listbox.moveDown|The title of the Move Down button"
1395
- moveDown="Move Down"
1396
-
1397
- i18n-transferTo="kendo.listbox.transferTo|The title of the Transfer To button"
1398
- transferTo="Transfer To"
1399
-
1400
- i18n-transferAllTo="kendo.listbox.transferAllTo|The title of the Transfer All To button"
1401
- transferAllTo="Transfer All To"
1402
-
1403
- i18n-transferFrom="kendo.listbox.transferFrom|The title of the Transfer From button"
1404
- transferFrom="Transfer From"
1405
-
1406
- i18n-transferAllFrom="kendo.listbox.transferAllFrom|The title of the Transfer All From button"
1407
- transferAllFrom="Transfer All From"
1408
-
1409
- i18n-remove="kendo.listbox.remove|The title of the Remove button"
1410
- remove="Remove"
1411
-
1412
- i18n-noDataText="kendo.listbox.noDataText|The text displayed when there are no items"
1413
- noDataText="No data found."
1414
- >
1468
+ i18n-moveUp="kendo.listbox.moveUp|The title of the Move Up button"
1469
+ moveUp="Move Up"
1470
+
1471
+ i18n-moveDown="kendo.listbox.moveDown|The title of the Move Down button"
1472
+ moveDown="Move Down"
1473
+
1474
+ i18n-transferTo="kendo.listbox.transferTo|The title of the Transfer To button"
1475
+ transferTo="Transfer To"
1476
+
1477
+ i18n-transferAllTo="kendo.listbox.transferAllTo|The title of the Transfer All To button"
1478
+ transferAllTo="Transfer All To"
1479
+
1480
+ i18n-transferFrom="kendo.listbox.transferFrom|The title of the Transfer From button"
1481
+ transferFrom="Transfer From"
1482
+
1483
+ i18n-transferAllFrom="kendo.listbox.transferAllFrom|The title of the Transfer All From button"
1484
+ transferAllFrom="Transfer All From"
1485
+
1486
+ i18n-remove="kendo.listbox.remove|The title of the Remove button"
1487
+ remove="Remove"
1488
+
1489
+ i18n-noDataText="kendo.listbox.noDataText|The text displayed when there are no items"
1490
+ noDataText="No data found."
1491
+ >
1415
1492
  </ng-container>
1416
- <div
1493
+ @if (selectedTools.length > 0) {
1494
+ <div
1417
1495
  #toolbar
1418
1496
  class="k-listbox-actions"
1419
- *ngIf="selectedTools.length > 0"
1420
1497
  role="toolbar"
1421
1498
  [attr.aria-label]="listboxToolbarLabel"
1422
- >
1423
- <button
1499
+ >
1500
+ @for (tool of selectedTools; track tool; let i = $index) {
1501
+ <button
1424
1502
  #tools
1425
- *ngFor="let tool of selectedTools; let i = index"
1426
1503
  kendoButton
1427
1504
  [attr.tabindex]="i === 0 ? '0' : '-1'"
1428
1505
  [size]="this.size"
@@ -1432,55 +1509,61 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1432
1509
  (click)="performAction(tool.name)"
1433
1510
  role="button"
1434
1511
  type="button"
1435
- ></button>
1436
- </div>
1512
+ ></button>
1513
+ }
1514
+ </div>
1515
+ }
1437
1516
  <div class="k-list-scroller k-selectable">
1438
- <div class="{{ listClasses }}">
1439
- <div
1440
- *ngIf="data.length > 0"
1441
- class="k-list-content"
1517
+ <div class="{{ listClasses }}">
1518
+ @if (data.length > 0) {
1519
+ <div
1520
+ class="k-list-content"
1442
1521
  >
1443
- <ul
1444
- #listbox
1445
- class="k-list-ul"
1446
- role="listbox"
1447
- [attr.aria-label]="listboxLabel"
1448
- [attr.aria-multiselectable]="selectable === 'multiple'"
1449
- >
1450
- <li
1451
- #listboxItems
1452
- *ngFor="let item of data; let i = index"
1453
- kendoListBoxItemSelectable
1454
- class="k-list-item"
1455
- [attr.tabindex]="i === keyboardNavigationService.focusedListboxItemIndex ? '0' : '-1'"
1456
- role="option"
1457
- [attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
1458
- [index]="i"
1459
- [class.k-disabled]="itemDisabled(item)"
1460
- >
1461
- <ng-template
1462
- *ngIf="itemTemplate; else defaultItemTemplate"
1522
+ <ul
1523
+ #listbox
1524
+ class="k-list-ul"
1525
+ role="listbox"
1526
+ [attr.aria-label]="listboxLabel"
1527
+ [attr.aria-multiselectable]="selectable === 'multiple'"
1528
+ >
1529
+ @for (item of data; track item; let i = $index) {
1530
+ <li
1531
+ #listboxItems
1532
+ kendoListBoxItemSelectable
1533
+ class="k-list-item"
1534
+ [attr.tabindex]="i === keyboardNavigationService.focusedListboxItemIndex ? '0' : '-1'"
1535
+ role="option"
1536
+ [attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
1537
+ [index]="i"
1538
+ [class.k-disabled]="itemDisabled(item)"
1539
+ [attr.aria-disabled]="itemDisabled(item)"
1540
+ >
1541
+ @if (itemTemplate) {
1542
+ <ng-template
1463
1543
  [templateContext]="{
1464
1544
  templateRef: itemTemplate.templateRef,
1465
1545
  $implicit: item
1466
1546
  }"
1467
- >
1468
- </ng-template>
1469
- <ng-template #defaultItemTemplate>
1470
- <span class="k-list-item-text">{{ getText(item) }}</span>
1471
- </ng-template>
1472
- </li>
1473
- </ul>
1474
- </div>
1475
- <span
1476
- *ngIf="data.length === 0"
1477
- class="k-nodata"
1478
- >{{ messageFor('noDataText') }}</span>
1479
- </div>
1547
+ >
1548
+ </ng-template>
1549
+ } @else {
1550
+ <span class="k-list-item-text">{{ getText(item) }}</span>
1551
+ }
1552
+ </li>
1553
+ }
1554
+ </ul>
1555
+ </div>
1556
+ }
1557
+ @if (data.length === 0) {
1558
+ <span
1559
+ class="k-nodata"
1560
+ >{{ messageFor('noDataText') }}</span>
1561
+ }
1562
+ </div>
1480
1563
  </div>
1481
- `,
1564
+ `,
1482
1565
  standalone: true,
1483
- imports: [LocalizedMessagesDirective, NgIf, NgFor, ButtonComponent, ItemSelectableDirective, TemplateContextDirective]
1566
+ imports: [LocalizedMessagesDirective, ButtonComponent, ItemSelectableDirective, TemplateContextDirective]
1484
1567
  }]
1485
1568
  }], ctorParameters: () => [{ type: KeyboardNavigationService }, { type: ListBoxSelectionService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.LocalizationService }, { type: i0.ChangeDetectorRef }], propDecorators: { listboxClassName: [{
1486
1569
  type: HostBinding,
@@ -1750,12 +1833,24 @@ class DataBindingDirective {
1750
1833
  if (!target || !source || source.data?.length === 0) {
1751
1834
  return;
1752
1835
  }
1753
- const itemsToTransfer = source.data.splice(0, source.data.length);
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));
1754
1841
  target.data.push(...itemsToTransfer);
1755
1842
  source.clearSelection();
1756
1843
  const sourceNavService = source.keyboardNavigationService;
1757
1844
  const sourceSelService = source.selectionService;
1758
- this.updateListBoxIndices(sourceNavService, sourceSelService, 0);
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
+ }
1759
1854
  const targetIndex = target.data.length - 1;
1760
1855
  target.select([targetIndex]);
1761
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.1.1-develop.2",
3
+ "version": "21.2.0-develop.10",
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": 1763729377,
47
+ "publishDate": 1764593179,
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,16 +54,15 @@
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.1.1-develop.2",
58
- "@progress/kendo-angular-common": "21.1.1-develop.2",
59
- "@progress/kendo-angular-popup": "21.1.1-develop.2",
57
+ "@progress/kendo-angular-buttons": "21.2.0-develop.10",
58
+ "@progress/kendo-angular-common": "21.2.0-develop.10",
59
+ "@progress/kendo-angular-popup": "21.2.0-develop.10",
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.1.1-develop.2",
65
- "@progress/kendo-common": "^1.0.1",
66
- "node-html-parser": "^7.0.1"
64
+ "@progress/kendo-angular-schematics": "21.2.0-develop.10",
65
+ "@progress/kendo-common": "^1.0.1"
67
66
  },
68
67
  "schematics": "./schematics/collection.json",
69
68
  "module": "fesm2022/progress-kendo-angular-listbox.mjs",