@progress/kendo-angular-listbox 21.0.0-develop.2 → 21.0.0-develop.21
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/codemods/template-transformer/index.js +93 -0
- package/codemods/utils.js +711 -0
- package/codemods/v21/listbox-actionclick.js +52 -0
- package/codemods/v21/listbox-selectedindex.js +125 -0
- package/codemods/v21/listbox-toolbar.js +14 -0
- package/data-binding.directive.d.ts +6 -5
- package/esm2022/data-binding.directive.mjs +69 -31
- package/esm2022/item-selectable.directive.mjs +6 -1
- package/esm2022/keyboard-navigation.service.mjs +63 -13
- package/esm2022/listbox.component.mjs +131 -53
- package/esm2022/package-metadata.mjs +2 -2
- package/esm2022/selection-mode.mjs +5 -0
- package/esm2022/selection.service.mjs +127 -6
- package/fesm2022/progress-kendo-angular-listbox.mjs +395 -104
- package/index.d.ts +0 -1
- package/keyboard-navigation.service.d.ts +16 -2
- package/listbox.component.d.ts +24 -9
- package/package.json +33 -7
- package/schematics/ngAdd/index.js +4 -4
- package/selection-mode.d.ts +12 -0
- package/selection.service.d.ts +18 -6
- package/toolbar.d.ts +1 -10
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
5
|
/* eslint-disable @typescript-eslint/no-inferrable-types */
|
|
6
6
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
7
|
-
import {
|
|
7
|
+
import { Component, ContentChild, ElementRef, EventEmitter, HostBinding, Input, isDevMode, NgZone, Output, QueryList, Renderer2, ViewChild, ViewChildren } from '@angular/core';
|
|
8
8
|
import { validatePackage } from '@progress/kendo-licensing';
|
|
9
9
|
import { Subscription } from 'rxjs';
|
|
10
10
|
import { packageMetadata } from './package-metadata';
|
|
@@ -20,7 +20,7 @@ import { caretAltLeftIcon, caretAltRightIcon } from '@progress/kendo-svg-icons';
|
|
|
20
20
|
import { ItemSelectableDirective } from './item-selectable.directive';
|
|
21
21
|
import { NgIf, NgFor } from '@angular/common';
|
|
22
22
|
import { LocalizedMessagesDirective } from './localization/localized-messages.directive';
|
|
23
|
-
import { TemplateContextDirective } from '@progress/kendo-angular-common';
|
|
23
|
+
import { isPresent, TemplateContextDirective } from '@progress/kendo-angular-common';
|
|
24
24
|
import * as i0 from "@angular/core";
|
|
25
25
|
import * as i1 from "./keyboard-navigation.service";
|
|
26
26
|
import * as i2 from "./selection.service";
|
|
@@ -62,7 +62,6 @@ export class ListBoxComponent {
|
|
|
62
62
|
renderer;
|
|
63
63
|
zone;
|
|
64
64
|
localization;
|
|
65
|
-
changeDetector;
|
|
66
65
|
/**
|
|
67
66
|
* @hidden
|
|
68
67
|
*/
|
|
@@ -95,6 +94,18 @@ export class ListBoxComponent {
|
|
|
95
94
|
* Specifies the field of the data item that provides the text content of the nodes.
|
|
96
95
|
*/
|
|
97
96
|
textField;
|
|
97
|
+
/**
|
|
98
|
+
* Sets the selection mode of the ListBox.
|
|
99
|
+
*
|
|
100
|
+
* @default 'single'
|
|
101
|
+
*/
|
|
102
|
+
set selectable(mode) {
|
|
103
|
+
this._selectable = mode;
|
|
104
|
+
this.selectionService.selectionMode = mode;
|
|
105
|
+
}
|
|
106
|
+
get selectable() {
|
|
107
|
+
return this._selectable;
|
|
108
|
+
}
|
|
98
109
|
/**
|
|
99
110
|
* Specifies the data that the ListBox displays.
|
|
100
111
|
*
|
|
@@ -117,6 +128,8 @@ export class ListBoxComponent {
|
|
|
117
128
|
/**
|
|
118
129
|
* Configures the toolbar of the ListBox.
|
|
119
130
|
* Specifies whether to display a toolbar and which tools and position to use.
|
|
131
|
+
*
|
|
132
|
+
* @default false
|
|
120
133
|
*/
|
|
121
134
|
set toolbar(config) {
|
|
122
135
|
let position = DEFAULT_TOOLBAR_POSITION;
|
|
@@ -155,7 +168,7 @@ export class ListBoxComponent {
|
|
|
155
168
|
/**
|
|
156
169
|
* Fires when you click a ListBox item.
|
|
157
170
|
*/
|
|
158
|
-
|
|
171
|
+
action = new EventEmitter();
|
|
159
172
|
/**
|
|
160
173
|
* @hidden
|
|
161
174
|
*/
|
|
@@ -175,7 +188,7 @@ export class ListBoxComponent {
|
|
|
175
188
|
/**
|
|
176
189
|
* @hidden
|
|
177
190
|
*/
|
|
178
|
-
selectedTools =
|
|
191
|
+
selectedTools = [];
|
|
179
192
|
/**
|
|
180
193
|
* @hidden
|
|
181
194
|
*/
|
|
@@ -203,15 +216,15 @@ export class ListBoxComponent {
|
|
|
203
216
|
localizationSubscription;
|
|
204
217
|
_size = DEFAULT_SIZE;
|
|
205
218
|
subs = new Subscription();
|
|
206
|
-
shouldFireFocusIn =
|
|
207
|
-
|
|
219
|
+
shouldFireFocusIn = false;
|
|
220
|
+
_selectable = 'single';
|
|
221
|
+
constructor(keyboardNavigationService, selectionService, hostElement, renderer, zone, localization) {
|
|
208
222
|
this.keyboardNavigationService = keyboardNavigationService;
|
|
209
223
|
this.selectionService = selectionService;
|
|
210
224
|
this.hostElement = hostElement;
|
|
211
225
|
this.renderer = renderer;
|
|
212
226
|
this.zone = zone;
|
|
213
227
|
this.localization = localization;
|
|
214
|
-
this.changeDetector = changeDetector;
|
|
215
228
|
validatePackage(packageMetadata);
|
|
216
229
|
this.setToolbarClass(DEFAULT_TOOLBAR_POSITION);
|
|
217
230
|
this.setSizingClass(this.size);
|
|
@@ -224,9 +237,6 @@ export class ListBoxComponent {
|
|
|
224
237
|
// This allows us to know to which parent Listbox the child Listbox is connected to
|
|
225
238
|
this.childListbox.parentListbox = this;
|
|
226
239
|
}
|
|
227
|
-
if (this.selectedIndex) {
|
|
228
|
-
this.keyboardNavigationService.focusedToolIndex = this.selectedIndex;
|
|
229
|
-
}
|
|
230
240
|
this.localizationSubscription = this.localization.changes.subscribe(({ rtl }) => {
|
|
231
241
|
this.direction = rtl ? 'rtl' : 'ltr';
|
|
232
242
|
});
|
|
@@ -251,10 +261,10 @@ export class ListBoxComponent {
|
|
|
251
261
|
const isListboxParentAndChild = !!(this.parentListbox && this.childListbox);
|
|
252
262
|
const isListboxParent = !!(this.childListbox || (!this.childListbox && !this.parentListbox));
|
|
253
263
|
if (isListboxChild || (isListboxParentAndChild && isActionTransferFrom)) {
|
|
254
|
-
this.parentListbox.
|
|
264
|
+
this.parentListbox.action.next(actionName);
|
|
255
265
|
}
|
|
256
266
|
else if (isListboxParent || (isListboxParentAndChild && !isActionTransferFrom)) {
|
|
257
|
-
this.
|
|
267
|
+
this.action.next(actionName);
|
|
258
268
|
}
|
|
259
269
|
const toolsRef = this.tools.toArray() || this.parentListbox.tools.toArray();
|
|
260
270
|
const focusedToolIndex = toolsRef.findIndex(elem => elem.nativeElement === document.activeElement);
|
|
@@ -267,11 +277,22 @@ export class ListBoxComponent {
|
|
|
267
277
|
navService.changeTabindex(prevTool, currentTool);
|
|
268
278
|
}
|
|
269
279
|
}
|
|
280
|
+
/**
|
|
281
|
+
* Selects multiple ListBox nodes programmatically.
|
|
282
|
+
*/
|
|
283
|
+
select(indices) {
|
|
284
|
+
const validIndices = indices.filter(index => index >= 0 && index < this.data.length);
|
|
285
|
+
this.selectionService.setSelectedIndices(validIndices);
|
|
286
|
+
}
|
|
270
287
|
/**
|
|
271
288
|
* Selects a ListBox node programmatically.
|
|
289
|
+
*
|
|
290
|
+
* @hidden
|
|
272
291
|
*/
|
|
273
292
|
selectItem(index) {
|
|
274
|
-
this.
|
|
293
|
+
if (index >= 0 && index < this.data.length) {
|
|
294
|
+
this.select([index]);
|
|
295
|
+
}
|
|
275
296
|
}
|
|
276
297
|
/**
|
|
277
298
|
* Clears the ListBox selection programmatically.
|
|
@@ -280,10 +301,10 @@ export class ListBoxComponent {
|
|
|
280
301
|
this.selectionService.clearSelection();
|
|
281
302
|
}
|
|
282
303
|
/**
|
|
283
|
-
* Gets the
|
|
304
|
+
* Gets the indexes of the currently selected items in the ListBox.
|
|
284
305
|
*/
|
|
285
|
-
get
|
|
286
|
-
return this.selectionService.
|
|
306
|
+
get selectedIndices() {
|
|
307
|
+
return this.selectionService.selectedIndices;
|
|
287
308
|
}
|
|
288
309
|
/**
|
|
289
310
|
* @hidden
|
|
@@ -326,36 +347,81 @@ export class ListBoxComponent {
|
|
|
326
347
|
this.caretAltLeftIcon :
|
|
327
348
|
icon;
|
|
328
349
|
}
|
|
329
|
-
onClickEvent(prevIndex, index) {
|
|
330
|
-
this.shouldFireFocusIn = false;
|
|
331
|
-
this.selectionChange.next({ index, prevIndex: this.keyboardNavigationService.selectedListboxItemIndex });
|
|
332
|
-
this.keyboardNavigationService.selectedListboxItemIndex = index;
|
|
333
|
-
this.keyboardNavigationService.focusedListboxItemIndex = index;
|
|
334
|
-
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
335
|
-
const listboxItems = this.listboxItems.toArray();
|
|
336
|
-
const previousItem = prevIndex ? listboxItems[prevIndex].nativeElement : listboxItems[0].nativeElement;
|
|
337
|
-
const currentItem = listboxItems[index].nativeElement;
|
|
338
|
-
this.keyboardNavigationService.changeTabindex(previousItem, currentItem);
|
|
339
|
-
});
|
|
340
|
-
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
341
|
-
this.shouldFireFocusIn = true;
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
350
|
initSubscriptions(navService, hostEl, toolsRef) {
|
|
345
351
|
this.subs.add(navService.onShiftSelectedItem.subscribe((actionToPerform) => this.performAction(actionToPerform)));
|
|
346
352
|
this.subs.add(navService.onTransferAllEvent.subscribe((actionToPerform) => this.performAction(actionToPerform)));
|
|
347
|
-
this.subs.add(this.selectionService.onSelect.subscribe((
|
|
353
|
+
this.subs.add(this.selectionService.onSelect.subscribe((event) => {
|
|
354
|
+
this.shouldFireFocusIn = false;
|
|
355
|
+
this.selectionChange.next(event);
|
|
356
|
+
const newFocusIndex = isPresent(this.selectionService.rangeSelectionTargetIndex)
|
|
357
|
+
? this.selectionService.rangeSelectionTargetIndex
|
|
358
|
+
: this.selectionService.lastSelectedOrUnselectedIndex;
|
|
359
|
+
if (newFocusIndex !== null && newFocusIndex !== undefined) {
|
|
360
|
+
const listboxItems = this.listboxItems.toArray();
|
|
361
|
+
const previousItem = listboxItems[navService.focusedListboxItemIndex]?.nativeElement;
|
|
362
|
+
const currentItem = listboxItems[newFocusIndex]?.nativeElement;
|
|
363
|
+
if (previousItem !== currentItem && currentItem) {
|
|
364
|
+
navService.changeTabindex(previousItem, currentItem, false);
|
|
365
|
+
navService.focusedListboxItemIndex = newFocusIndex;
|
|
366
|
+
navService.selectedListboxItemIndex = newFocusIndex;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
this.zone.runOutsideAngular(() => setTimeout(() => {
|
|
370
|
+
this.shouldFireFocusIn = true;
|
|
371
|
+
}));
|
|
372
|
+
}));
|
|
348
373
|
this.subs.add(navService.onDeleteEvent.subscribe((index) => this.onDeleteEvent(index, navService)));
|
|
349
374
|
this.subs.add(navService.onMoveSelectedItem.subscribe((dir) => this.performAction(dir)));
|
|
375
|
+
this.subs.add(navService.onSelectAll.subscribe(() => {
|
|
376
|
+
if (this.selectable === 'multiple') {
|
|
377
|
+
const previousSelection = [...this.selectionService.selectedIndices];
|
|
378
|
+
const allSelected = this.selectionService.areAllSelected(this.data.length);
|
|
379
|
+
if (allSelected) {
|
|
380
|
+
this.selectionService.clearSelection();
|
|
381
|
+
this.selectionChange.next({
|
|
382
|
+
selectedIndices: null,
|
|
383
|
+
deselectedIndices: previousSelection.length > 0 ? previousSelection : null
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
else {
|
|
387
|
+
this.selectionService.selectAll(this.data.length);
|
|
388
|
+
const selectedIndices = this.selectionService.selectedIndices.filter(i => !previousSelection.includes(i));
|
|
389
|
+
this.selectionChange.next({
|
|
390
|
+
selectedIndices: selectedIndices.length > 0 ? selectedIndices : null,
|
|
391
|
+
deselectedIndices: null
|
|
392
|
+
});
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}));
|
|
396
|
+
this.subs.add(navService.onSelectToEnd.subscribe(({ direction }) => {
|
|
397
|
+
if (this.selectable === 'multiple') {
|
|
398
|
+
this.shouldFireFocusIn = false;
|
|
399
|
+
const previousSelection = [...this.selectionService.selectedIndices];
|
|
400
|
+
const targetIndex = direction === 'home' ? 0 : this.data.length - 1;
|
|
401
|
+
this.selectionService.selectRange(targetIndex);
|
|
402
|
+
const selectedIndices = this.selectionService.selectedIndices.filter(i => !previousSelection.includes(i));
|
|
403
|
+
const deselectedIndices = previousSelection.filter(i => !this.selectionService.selectedIndices.includes(i));
|
|
404
|
+
this.selectionChange.next({
|
|
405
|
+
selectedIndices: selectedIndices.length > 0 ? selectedIndices : null,
|
|
406
|
+
deselectedIndices: deselectedIndices.length > 0 ? deselectedIndices : null
|
|
407
|
+
});
|
|
408
|
+
const listboxItems = this.listboxItems.toArray();
|
|
409
|
+
const currentItem = listboxItems[navService.focusedListboxItemIndex]?.nativeElement;
|
|
410
|
+
const targetItem = listboxItems[targetIndex]?.nativeElement;
|
|
411
|
+
navService.changeTabindex(currentItem, targetItem);
|
|
412
|
+
navService.focusedListboxItemIndex = targetIndex;
|
|
413
|
+
this.zone.runOutsideAngular(() => setTimeout(() => {
|
|
414
|
+
this.shouldFireFocusIn = true;
|
|
415
|
+
}));
|
|
416
|
+
}
|
|
417
|
+
}));
|
|
350
418
|
if (this.listboxElement) {
|
|
351
419
|
this.subs.add(this.renderer.listen(this.listboxElement.nativeElement, 'focusin', (event) => this.onFocusIn(event)));
|
|
352
420
|
}
|
|
353
421
|
this.subs.add(this.renderer.listen(hostEl, 'keydown', (event) => navService.onKeyDown(event, toolsRef, this.selectedTools, this.childListbox, this.parentListbox, this.listboxItems.toArray())));
|
|
354
|
-
this.subs.add(navService.onSelectionChange.subscribe((
|
|
355
|
-
const {
|
|
356
|
-
this.selectionService.
|
|
357
|
-
this.selectionChange.next({ index, prevIndex });
|
|
358
|
-
this.changeDetector.markForCheck();
|
|
422
|
+
this.subs.add(navService.onSelectionChange.subscribe((event) => {
|
|
423
|
+
const { index, ctrlKey, shiftKey } = event;
|
|
424
|
+
this.selectionService.select(index, ctrlKey, shiftKey);
|
|
359
425
|
}));
|
|
360
426
|
}
|
|
361
427
|
onFocusIn(event) {
|
|
@@ -366,8 +432,15 @@ export class ListBoxComponent {
|
|
|
366
432
|
if (index === -1) {
|
|
367
433
|
return;
|
|
368
434
|
}
|
|
369
|
-
this.selectionService.
|
|
370
|
-
this.
|
|
435
|
+
const previousSelection = [...this.selectionService.selectedIndices];
|
|
436
|
+
this.selectionService.addToSelectedIndices(index);
|
|
437
|
+
navService.focusedListboxItemIndex = index;
|
|
438
|
+
navService.selectedListboxItemIndex = index;
|
|
439
|
+
const deselected = previousSelection.filter(i => i !== index);
|
|
440
|
+
this.selectionChange.next({
|
|
441
|
+
selectedIndices: [index],
|
|
442
|
+
deselectedIndices: deselected.length > 0 ? deselected : null
|
|
443
|
+
});
|
|
371
444
|
const previousItem = items[navService.selectedListboxItemIndex]?.nativeElement;
|
|
372
445
|
const currentItem = items[index]?.nativeElement;
|
|
373
446
|
this.renderer.setAttribute(previousItem, 'tabindex', '-1');
|
|
@@ -409,17 +482,20 @@ export class ListBoxComponent {
|
|
|
409
482
|
}
|
|
410
483
|
}
|
|
411
484
|
onDeleteEvent(index, navService) {
|
|
412
|
-
this.selectionService.
|
|
485
|
+
this.selectionService.addToSelectedIndices(index);
|
|
413
486
|
this.performAction('remove');
|
|
414
487
|
const listboxItems = this.listboxItems.toArray();
|
|
415
488
|
const setIndex = index + 1 === listboxItems.length ?
|
|
416
489
|
{ index: index - 1, tabindex: index - 1 } : { index, tabindex: index + 1 };
|
|
417
490
|
navService.changeTabindex(null, listboxItems[setIndex['tabindex']]?.nativeElement);
|
|
418
|
-
this.selectionChange.next({
|
|
491
|
+
this.selectionChange.next({
|
|
492
|
+
selectedIndices: [setIndex['index']],
|
|
493
|
+
deselectedIndices: null
|
|
494
|
+
});
|
|
419
495
|
navService.selectedListboxItemIndex = setIndex['index'];
|
|
420
496
|
navService.focusedListboxItemIndex = setIndex['index'];
|
|
421
497
|
navService.focusedListboxItem = setIndex['index'];
|
|
422
|
-
this.selectionService.
|
|
498
|
+
this.selectionService.selectedIndices = [setIndex['index']];
|
|
423
499
|
}
|
|
424
500
|
setToolbarClass(pos) {
|
|
425
501
|
Object.keys(actionsClasses).forEach((className) => {
|
|
@@ -434,8 +510,8 @@ export class ListBoxComponent {
|
|
|
434
510
|
setSizingClass(size) {
|
|
435
511
|
this.renderer.addClass(this.hostElement.nativeElement, `k-listbox-${sizeClassMap[size]}`);
|
|
436
512
|
}
|
|
437
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListBoxComponent, deps: [{ token: i1.KeyboardNavigationService }, { token: i2.ListBoxSelectionService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i3.LocalizationService }
|
|
438
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.14", type: ListBoxComponent, isStandalone: true, selector: "kendo-listbox", inputs: { textField: "textField", data: "data", size: "size", toolbar: "toolbar", listboxLabel: "listboxLabel", listboxToolbarLabel: "listboxToolbarLabel", itemDisabled: "itemDisabled" }, outputs: { selectionChange: "selectionChange",
|
|
513
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListBoxComponent, deps: [{ token: i1.KeyboardNavigationService }, { token: i2.ListBoxSelectionService }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i3.LocalizationService }], target: i0.ɵɵFactoryTarget.Component });
|
|
514
|
+
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: [
|
|
439
515
|
ListBoxSelectionService,
|
|
440
516
|
KeyboardNavigationService,
|
|
441
517
|
LocalizationService,
|
|
@@ -502,16 +578,16 @@ export class ListBoxComponent {
|
|
|
502
578
|
class="k-list-ul"
|
|
503
579
|
role="listbox"
|
|
504
580
|
[attr.aria-label]="listboxLabel"
|
|
505
|
-
[attr.aria-multiselectable]="
|
|
581
|
+
[attr.aria-multiselectable]="selectable === 'multiple'"
|
|
506
582
|
>
|
|
507
583
|
<li
|
|
508
584
|
#listboxItems
|
|
509
585
|
*ngFor="let item of data; let i = index"
|
|
510
586
|
kendoListBoxItemSelectable
|
|
511
587
|
class="k-list-item"
|
|
512
|
-
[attr.tabindex]="i ===
|
|
588
|
+
[attr.tabindex]="i === keyboardNavigationService.focusedListboxItemIndex ? '0' : '-1'"
|
|
513
589
|
role="option"
|
|
514
|
-
[attr.aria-selected]="
|
|
590
|
+
[attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
|
|
515
591
|
[index]="i"
|
|
516
592
|
[class.k-disabled]="itemDisabled(item)"
|
|
517
593
|
>
|
|
@@ -609,16 +685,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
609
685
|
class="k-list-ul"
|
|
610
686
|
role="listbox"
|
|
611
687
|
[attr.aria-label]="listboxLabel"
|
|
612
|
-
[attr.aria-multiselectable]="
|
|
688
|
+
[attr.aria-multiselectable]="selectable === 'multiple'"
|
|
613
689
|
>
|
|
614
690
|
<li
|
|
615
691
|
#listboxItems
|
|
616
692
|
*ngFor="let item of data; let i = index"
|
|
617
693
|
kendoListBoxItemSelectable
|
|
618
694
|
class="k-list-item"
|
|
619
|
-
[attr.tabindex]="i ===
|
|
695
|
+
[attr.tabindex]="i === keyboardNavigationService.focusedListboxItemIndex ? '0' : '-1'"
|
|
620
696
|
role="option"
|
|
621
|
-
[attr.aria-selected]="
|
|
697
|
+
[attr.aria-selected]="selectedIndices.indexOf(i) >= 0"
|
|
622
698
|
[index]="i"
|
|
623
699
|
[class.k-disabled]="itemDisabled(item)"
|
|
624
700
|
>
|
|
@@ -646,7 +722,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
646
722
|
standalone: true,
|
|
647
723
|
imports: [LocalizedMessagesDirective, NgIf, NgFor, ButtonComponent, ItemSelectableDirective, TemplateContextDirective]
|
|
648
724
|
}]
|
|
649
|
-
}], ctorParameters: () => [{ type: i1.KeyboardNavigationService }, { type: i2.ListBoxSelectionService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i3.LocalizationService }
|
|
725
|
+
}], ctorParameters: () => [{ type: i1.KeyboardNavigationService }, { type: i2.ListBoxSelectionService }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i3.LocalizationService }], propDecorators: { listboxClassName: [{
|
|
650
726
|
type: HostBinding,
|
|
651
727
|
args: ['class.k-listbox']
|
|
652
728
|
}], direction: [{
|
|
@@ -669,6 +745,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
669
745
|
args: ['tools']
|
|
670
746
|
}], textField: [{
|
|
671
747
|
type: Input
|
|
748
|
+
}], selectable: [{
|
|
749
|
+
type: Input
|
|
672
750
|
}], data: [{
|
|
673
751
|
type: Input
|
|
674
752
|
}], size: [{
|
|
@@ -683,7 +761,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
683
761
|
type: Input
|
|
684
762
|
}], selectionChange: [{
|
|
685
763
|
type: Output
|
|
686
|
-
}],
|
|
764
|
+
}], action: [{
|
|
687
765
|
type: Output
|
|
688
766
|
}], getChildListbox: [{
|
|
689
767
|
type: Output
|
|
@@ -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.0.0-develop.
|
|
13
|
+
publishDate: 1762427032,
|
|
14
|
+
version: '21.0.0-develop.21',
|
|
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
|
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**-----------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright © 2025 Progress Software Corporation. All rights reserved.
|
|
3
|
+
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
|
+
*-------------------------------------------------------------------------------------------*/
|
|
5
|
+
export {};
|
|
@@ -8,17 +8,138 @@ import * as i0 from "@angular/core";
|
|
|
8
8
|
* @hidden
|
|
9
9
|
*/
|
|
10
10
|
export class ListBoxSelectionService {
|
|
11
|
+
selectedIndices = [];
|
|
12
|
+
selectionMode = 'single';
|
|
13
|
+
lastSelectedOrUnselectedIndex = null;
|
|
14
|
+
rangeSelectionTargetIndex = null;
|
|
15
|
+
rangeSelectionAnchorIndex = null;
|
|
11
16
|
onSelect = new EventEmitter();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
17
|
+
select(index, ctrlKey = false, shiftKey = false) {
|
|
18
|
+
const previousSelection = [...this.selectedIndices];
|
|
19
|
+
let selectedIndices = [];
|
|
20
|
+
let deselectedIndices = null;
|
|
21
|
+
const previousTargetIndex = this.rangeSelectionTargetIndex;
|
|
22
|
+
if (this.selectionMode === 'single') {
|
|
23
|
+
if (ctrlKey) {
|
|
24
|
+
const isSelected = this.isSelected(index);
|
|
25
|
+
if (isSelected) {
|
|
26
|
+
this.selectedIndices = [];
|
|
27
|
+
deselectedIndices = [index];
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
this.selectedIndices = [index];
|
|
31
|
+
selectedIndices = [index];
|
|
32
|
+
if (previousSelection.length > 0) {
|
|
33
|
+
deselectedIndices = previousSelection;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
this.lastSelectedOrUnselectedIndex = index;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
this.selectedIndices = [index];
|
|
40
|
+
selectedIndices = [index];
|
|
41
|
+
this.lastSelectedOrUnselectedIndex = index;
|
|
42
|
+
this.rangeSelectionAnchorIndex = index;
|
|
43
|
+
if (previousSelection.length > 0 && previousSelection[0] !== index) {
|
|
44
|
+
deselectedIndices = previousSelection;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (this.selectionMode === 'multiple') {
|
|
49
|
+
if (shiftKey) {
|
|
50
|
+
let anchorIndex = this.rangeSelectionAnchorIndex ?? this.lastSelectedOrUnselectedIndex ?? 0;
|
|
51
|
+
if (index === anchorIndex) {
|
|
52
|
+
this.selectedIndices = [anchorIndex];
|
|
53
|
+
this.rangeSelectionTargetIndex = index;
|
|
54
|
+
selectedIndices = this.selectedIndices.filter(i => !previousSelection.includes(i));
|
|
55
|
+
const nowDeselected = previousSelection.filter(i => !this.selectedIndices.includes(i));
|
|
56
|
+
deselectedIndices = nowDeselected.length > 0 ? nowDeselected : null;
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
if (previousTargetIndex !== null && previousTargetIndex !== anchorIndex) {
|
|
60
|
+
const previousDirection = previousTargetIndex > anchorIndex ? 'down' : 'up';
|
|
61
|
+
const currentDirection = index > anchorIndex ? 'down' : 'up';
|
|
62
|
+
if (previousDirection !== currentDirection) {
|
|
63
|
+
this.rangeSelectionAnchorIndex = previousTargetIndex;
|
|
64
|
+
anchorIndex = previousTargetIndex;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const startIndex = Math.min(anchorIndex, index);
|
|
68
|
+
const endIndex = Math.max(anchorIndex, index);
|
|
69
|
+
this.selectedIndices = [];
|
|
70
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
71
|
+
this.selectedIndices.push(i);
|
|
72
|
+
}
|
|
73
|
+
this.rangeSelectionTargetIndex = index;
|
|
74
|
+
selectedIndices = this.selectedIndices.filter(i => !previousSelection.includes(i));
|
|
75
|
+
const nowDeselected = previousSelection.filter(i => !this.selectedIndices.includes(i));
|
|
76
|
+
deselectedIndices = nowDeselected.length > 0 ? nowDeselected : null;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else if (ctrlKey) {
|
|
80
|
+
const indexInSelection = this.selectedIndices.indexOf(index);
|
|
81
|
+
if (indexInSelection === -1) {
|
|
82
|
+
this.selectedIndices.push(index);
|
|
83
|
+
selectedIndices = [index];
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
this.selectedIndices.splice(indexInSelection, 1);
|
|
87
|
+
deselectedIndices = [index];
|
|
88
|
+
}
|
|
89
|
+
this.lastSelectedOrUnselectedIndex = index;
|
|
90
|
+
this.rangeSelectionAnchorIndex = index;
|
|
91
|
+
this.rangeSelectionTargetIndex = index;
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
this.selectedIndices = [index];
|
|
95
|
+
selectedIndices = [index];
|
|
96
|
+
this.lastSelectedOrUnselectedIndex = index;
|
|
97
|
+
this.rangeSelectionAnchorIndex = index;
|
|
98
|
+
this.rangeSelectionTargetIndex = index;
|
|
99
|
+
const nowDeselected = previousSelection.filter(i => i !== index);
|
|
100
|
+
deselectedIndices = nowDeselected.length > 0 ? nowDeselected : null;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
this.onSelect.next({
|
|
104
|
+
selectedIndices: selectedIndices.length > 0 ? selectedIndices : null,
|
|
105
|
+
deselectedIndices
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
selectRange(targetIndex) {
|
|
109
|
+
const anchorIndex = this.lastSelectedOrUnselectedIndex ?? 0;
|
|
110
|
+
const startIndex = Math.min(anchorIndex, targetIndex);
|
|
111
|
+
const endIndex = Math.max(anchorIndex, targetIndex);
|
|
112
|
+
this.selectedIndices = [];
|
|
113
|
+
for (let i = startIndex; i <= endIndex; i++) {
|
|
114
|
+
this.selectedIndices.push(i);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
setSelectedIndices(indices) {
|
|
118
|
+
this.selectedIndices = [...indices];
|
|
119
|
+
}
|
|
120
|
+
addToSelectedIndices(index) {
|
|
121
|
+
if (this.selectionMode === 'single') {
|
|
122
|
+
this.selectedIndices = [index];
|
|
123
|
+
}
|
|
124
|
+
else if (this.selectedIndices.indexOf(index) === -1) {
|
|
125
|
+
this.selectedIndices = [...this.selectedIndices, index];
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
selectAll(totalItems) {
|
|
129
|
+
if (this.selectionMode === 'multiple') {
|
|
130
|
+
this.selectedIndices = Array.from({ length: totalItems }, (_, i) => i);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
areAllSelected(totalItems) {
|
|
134
|
+
return this.selectedIndices.length === totalItems && totalItems > 0;
|
|
16
135
|
}
|
|
17
136
|
isSelected(index) {
|
|
18
|
-
return index
|
|
137
|
+
return this.selectedIndices.indexOf(index) !== -1;
|
|
19
138
|
}
|
|
20
139
|
clearSelection() {
|
|
21
|
-
this.
|
|
140
|
+
this.selectedIndices = [];
|
|
141
|
+
this.lastSelectedOrUnselectedIndex = null;
|
|
142
|
+
this.rangeSelectionAnchorIndex = null;
|
|
22
143
|
}
|
|
23
144
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListBoxSelectionService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
24
145
|
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ListBoxSelectionService });
|