@progress/kendo-angular-listbox 21.0.0-develop.9 → 21.0.1-develop.1
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 +7 -5
- package/esm2022/data-binding.directive.mjs +128 -33
- package/esm2022/item-selectable.directive.mjs +6 -1
- package/esm2022/keyboard-navigation.service.mjs +73 -24
- package/esm2022/listbox.component.mjs +139 -51
- 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 +473 -116
- package/index.d.ts +0 -1
- package/keyboard-navigation.service.d.ts +17 -3
- package/listbox.component.d.ts +24 -8
- 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
|
@@ -0,0 +1,52 @@
|
|
|
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
|
+
"use strict";
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
23
|
+
if (mod && mod.__esModule) return mod;
|
|
24
|
+
var result = {};
|
|
25
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
26
|
+
__setModuleDefault(result, mod);
|
|
27
|
+
return result;
|
|
28
|
+
};
|
|
29
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
+
exports.default = default_1;
|
|
31
|
+
const utils_1 = require("../utils");
|
|
32
|
+
const fs = __importStar(require("fs"));
|
|
33
|
+
const index_1 = require("../template-transformer/index");
|
|
34
|
+
function default_1(fileInfo, api) {
|
|
35
|
+
const filePath = fileInfo.path;
|
|
36
|
+
if (filePath.endsWith('.html')) {
|
|
37
|
+
if ((0, utils_1.hasKendoInTemplate)(fileInfo.source)) {
|
|
38
|
+
let updatedContent = fileInfo.source;
|
|
39
|
+
updatedContent = (0, utils_1.htmlEventTransformer)({ ...fileInfo, source: updatedContent }, 'kendo-listbox', 'actionClick', 'action');
|
|
40
|
+
// Only write to file once after all transformations
|
|
41
|
+
fs.writeFileSync(filePath, updatedContent, 'utf-8');
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const j = api.jscodeshift;
|
|
46
|
+
const rootSource = j(fileInfo.source);
|
|
47
|
+
(0, index_1.templateTransformer)(rootSource, j, (root) => {
|
|
48
|
+
(0, utils_1.templateEventTransformer)(root, 'kendo-listbox', 'actionClick', 'action');
|
|
49
|
+
});
|
|
50
|
+
(0, utils_1.tsPropertyTransformer)(fileInfo.source, rootSource, j, 'ListBoxComponent', 'actionClick', 'action');
|
|
51
|
+
return rootSource.toSource();
|
|
52
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
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
|
+
"use strict";
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.default = default_1;
|
|
8
|
+
function default_1(fileInfo, api) {
|
|
9
|
+
const filePath = fileInfo.path;
|
|
10
|
+
if (filePath.endsWith('.html')) {
|
|
11
|
+
// HTML transformations not needed for this migration
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
const j = api.jscodeshift;
|
|
15
|
+
const rootSource = j(fileInfo.source);
|
|
16
|
+
tsSelectedIndexTransformer(fileInfo.source, rootSource, j, 'ListBoxComponent');
|
|
17
|
+
return rootSource.toSource();
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Custom transformer to convert selectedIndex property access to selectedIndices[0]
|
|
21
|
+
* for ListBoxComponent instances
|
|
22
|
+
*/
|
|
23
|
+
const tsSelectedIndexTransformer = (source, root, j, componentType) => {
|
|
24
|
+
if (source.includes(componentType)) {
|
|
25
|
+
// Find all class properties that are of type ListBoxComponent
|
|
26
|
+
const properties = new Set();
|
|
27
|
+
// Find properties with type annotations
|
|
28
|
+
root.find(j.ClassProperty, {
|
|
29
|
+
typeAnnotation: {
|
|
30
|
+
typeAnnotation: {
|
|
31
|
+
typeName: {
|
|
32
|
+
name: componentType,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
}).forEach((path) => {
|
|
37
|
+
if (path.node.key.type === 'Identifier') {
|
|
38
|
+
properties.add(path.node.key.name);
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
// Find function parameters of type componentType
|
|
42
|
+
const parameters = new Set();
|
|
43
|
+
root.find(j.FunctionDeclaration).forEach((path) => {
|
|
44
|
+
if (path.node.params) {
|
|
45
|
+
path.node.params.forEach((param) => {
|
|
46
|
+
if (param.type === 'Identifier' &&
|
|
47
|
+
param.typeAnnotation &&
|
|
48
|
+
param.typeAnnotation.typeAnnotation?.type === 'TSTypeReference' &&
|
|
49
|
+
param.typeAnnotation.typeAnnotation.typeName.type === 'Identifier' &&
|
|
50
|
+
param.typeAnnotation.typeAnnotation.typeName.name === componentType) {
|
|
51
|
+
parameters.add(param.name);
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
// Also check method declarations in classes
|
|
57
|
+
root.find(j.ClassMethod).forEach((path) => {
|
|
58
|
+
if (path.node.params) {
|
|
59
|
+
path.node.params.forEach((param) => {
|
|
60
|
+
if (param.type === 'Identifier' &&
|
|
61
|
+
param.typeAnnotation &&
|
|
62
|
+
param.typeAnnotation.typeAnnotation?.type === 'TSTypeReference' &&
|
|
63
|
+
param.typeAnnotation.typeAnnotation.typeName.type === 'Identifier' &&
|
|
64
|
+
param.typeAnnotation.typeAnnotation.typeName.name === componentType) {
|
|
65
|
+
parameters.add(param.name);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
// Also check arrow functions
|
|
71
|
+
root.find(j.ArrowFunctionExpression).forEach((path) => {
|
|
72
|
+
if (path.node.params) {
|
|
73
|
+
path.node.params.forEach((param) => {
|
|
74
|
+
if (param.type === 'Identifier' &&
|
|
75
|
+
param.typeAnnotation &&
|
|
76
|
+
param.typeAnnotation.typeAnnotation?.type === 'TSTypeReference' &&
|
|
77
|
+
param.typeAnnotation.typeAnnotation.typeName.type === 'Identifier' &&
|
|
78
|
+
param.typeAnnotation.typeAnnotation.typeName.name === componentType) {
|
|
79
|
+
parameters.add(param.name);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
// Find local variable declarations of type componentType
|
|
85
|
+
const localVariables = new Set();
|
|
86
|
+
root.find(j.VariableDeclarator).forEach((path) => {
|
|
87
|
+
if (path.node.id.type === 'Identifier' &&
|
|
88
|
+
path.node.id.typeAnnotation &&
|
|
89
|
+
path.node.id.typeAnnotation.typeAnnotation?.type === 'TSTypeReference' &&
|
|
90
|
+
path.node.id.typeAnnotation.typeAnnotation.typeName.type === 'Identifier' &&
|
|
91
|
+
path.node.id.typeAnnotation.typeAnnotation.typeName.name === componentType) {
|
|
92
|
+
localVariables.add(path.node.id.name);
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Find all member expressions where selectedIndex property is accessed on any ListBoxComponent instance
|
|
96
|
+
root.find(j.MemberExpression, {
|
|
97
|
+
property: {
|
|
98
|
+
type: 'Identifier',
|
|
99
|
+
name: 'selectedIndex',
|
|
100
|
+
},
|
|
101
|
+
})
|
|
102
|
+
.filter((path) => {
|
|
103
|
+
// Filter to only include accesses on properties that are ListBoxComponent instances
|
|
104
|
+
if (path.node.object.type === 'MemberExpression' && path.node.object.property.type === 'Identifier') {
|
|
105
|
+
// handle properties of this
|
|
106
|
+
if (path.node.object.object.type === 'ThisExpression' &&
|
|
107
|
+
properties.has(path.node.object.property.name)) {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Handle function parameters and local variables
|
|
112
|
+
if (path.node.object.type === 'Identifier') {
|
|
113
|
+
return parameters.has(path.node.object.name) || localVariables.has(path.node.object.name);
|
|
114
|
+
}
|
|
115
|
+
return false;
|
|
116
|
+
})
|
|
117
|
+
.forEach((path) => {
|
|
118
|
+
// Replace selectedIndex with selectedIndices[0]
|
|
119
|
+
const memberExpression = j.memberExpression(j.memberExpression(path.node.object, j.identifier('selectedIndices')), j.numericLiteral(0), true // computed property access (uses brackets)
|
|
120
|
+
);
|
|
121
|
+
// Replace the entire member expression
|
|
122
|
+
j(path).replaceWith(memberExpression);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
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
|
+
"use strict";
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.default = default_1;
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
function default_1(fileInfo, api) {
|
|
10
|
+
const j = api.jscodeshift;
|
|
11
|
+
const rootSource = j(fileInfo.source);
|
|
12
|
+
(0, utils_1.tsInterfaceTransformer)(fileInfo, rootSource, j, '@progress/kendo-angular-listbox', 'Toolbar', 'ListBoxToolbarConfig');
|
|
13
|
+
return rootSource.toSource();
|
|
14
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright © 2025 Progress Software Corporation. All rights reserved.
|
|
3
3
|
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
|
|
5
|
+
import { NgZone, OnChanges, OnDestroy, SimpleChanges } from '@angular/core';
|
|
6
6
|
import { ListBoxComponent } from './listbox.component';
|
|
7
7
|
import * as i0 from "@angular/core";
|
|
8
8
|
/**
|
|
@@ -29,16 +29,17 @@ import * as i0 from "@angular/core";
|
|
|
29
29
|
*/
|
|
30
30
|
export declare class DataBindingDirective implements OnChanges, OnDestroy {
|
|
31
31
|
private listbox;
|
|
32
|
+
private zone;
|
|
32
33
|
/**
|
|
33
34
|
* Specifies the `ListBoxComponent` instance with which the current ListBox connects.
|
|
34
35
|
* When you link two listboxes through this input, you can transfer items between them.
|
|
35
36
|
*/
|
|
36
37
|
connectedWith: ListBoxComponent;
|
|
37
|
-
private
|
|
38
|
+
private actionSub;
|
|
38
39
|
private selectedBoxSub;
|
|
39
40
|
private connectedWithSub;
|
|
40
41
|
private selectedBox;
|
|
41
|
-
constructor(listbox: ListBoxComponent);
|
|
42
|
+
constructor(listbox: ListBoxComponent, zone: NgZone);
|
|
42
43
|
/**
|
|
43
44
|
* @hidden
|
|
44
45
|
*/
|
|
@@ -48,9 +49,10 @@ export declare class DataBindingDirective implements OnChanges, OnDestroy {
|
|
|
48
49
|
*/
|
|
49
50
|
ngOnDestroy(): void;
|
|
50
51
|
private moveVertically;
|
|
51
|
-
private
|
|
52
|
-
private
|
|
52
|
+
private removeSelectedItems;
|
|
53
|
+
private transferSelectedItems;
|
|
53
54
|
private transferAll;
|
|
55
|
+
private updateListBoxIndices;
|
|
54
56
|
static ɵfac: i0.ɵɵFactoryDeclaration<DataBindingDirective, never>;
|
|
55
57
|
static ɵdir: i0.ɵɵDirectiveDeclaration<DataBindingDirective, "[kendoListBoxDataBinding]", never, { "connectedWith": { "alias": "connectedWith"; "required": false; }; }, {}, never, never, true, never>;
|
|
56
58
|
}
|
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
* Copyright © 2025 Progress Software Corporation. All rights reserved.
|
|
3
3
|
* Licensed under commercial license. See LICENSE.md in the project root for more information
|
|
4
4
|
*-------------------------------------------------------------------------------------------*/
|
|
5
|
-
import { Directive, Input } from '@angular/core';
|
|
5
|
+
import { Directive, Input, NgZone } from '@angular/core';
|
|
6
6
|
import { isChanged } from '@progress/kendo-angular-common';
|
|
7
7
|
import { Subscription } from 'rxjs';
|
|
8
|
+
import { take } from 'rxjs/operators';
|
|
8
9
|
import { ListBoxComponent } from './listbox.component';
|
|
9
10
|
import { isPresent } from './util';
|
|
10
11
|
import * as i0 from "@angular/core";
|
|
@@ -33,22 +34,24 @@ import * as i1 from "./listbox.component";
|
|
|
33
34
|
*/
|
|
34
35
|
export class DataBindingDirective {
|
|
35
36
|
listbox;
|
|
37
|
+
zone;
|
|
36
38
|
/**
|
|
37
39
|
* Specifies the `ListBoxComponent` instance with which the current ListBox connects.
|
|
38
40
|
* When you link two listboxes through this input, you can transfer items between them.
|
|
39
41
|
*/
|
|
40
42
|
connectedWith;
|
|
41
|
-
|
|
43
|
+
actionSub = new Subscription();
|
|
42
44
|
selectedBoxSub = new Subscription();
|
|
43
45
|
connectedWithSub = new Subscription();
|
|
44
46
|
selectedBox;
|
|
45
|
-
constructor(listbox) {
|
|
47
|
+
constructor(listbox, zone) {
|
|
46
48
|
this.listbox = listbox;
|
|
49
|
+
this.zone = zone;
|
|
47
50
|
this.selectedBox = this.listbox;
|
|
48
51
|
this.connectedWithSub.add(this.listbox.getChildListbox.subscribe(() => {
|
|
49
52
|
this.listbox.childListbox = this.connectedWith;
|
|
50
53
|
}));
|
|
51
|
-
this.
|
|
54
|
+
this.actionSub.add(this.listbox.action.subscribe((actionName) => {
|
|
52
55
|
switch (actionName) {
|
|
53
56
|
case 'moveUp': {
|
|
54
57
|
this.moveVertically('up');
|
|
@@ -59,11 +62,11 @@ export class DataBindingDirective {
|
|
|
59
62
|
break;
|
|
60
63
|
}
|
|
61
64
|
case 'transferFrom': {
|
|
62
|
-
this.
|
|
65
|
+
this.transferSelectedItems(this.connectedWith, this.listbox);
|
|
63
66
|
break;
|
|
64
67
|
}
|
|
65
68
|
case 'transferTo': {
|
|
66
|
-
this.
|
|
69
|
+
this.transferSelectedItems(this.listbox, this.connectedWith);
|
|
67
70
|
break;
|
|
68
71
|
}
|
|
69
72
|
case 'transferAllTo': {
|
|
@@ -75,7 +78,7 @@ export class DataBindingDirective {
|
|
|
75
78
|
break;
|
|
76
79
|
}
|
|
77
80
|
case 'remove': {
|
|
78
|
-
this.
|
|
81
|
+
this.removeSelectedItems();
|
|
79
82
|
break;
|
|
80
83
|
}
|
|
81
84
|
default: {
|
|
@@ -95,11 +98,37 @@ export class DataBindingDirective {
|
|
|
95
98
|
}
|
|
96
99
|
this.selectedBoxSub.add(this.listbox.selectionChange.subscribe(() => {
|
|
97
100
|
this.selectedBox = this.listbox;
|
|
101
|
+
const connectedNavService = this.connectedWith.keyboardNavigationService;
|
|
102
|
+
const connectedSelService = this.connectedWith.selectionService;
|
|
103
|
+
let lastSelectedIndex = 0;
|
|
104
|
+
if (connectedSelService.selectedIndices.length > 0) {
|
|
105
|
+
lastSelectedIndex = connectedSelService.rangeSelectionTargetIndex ?? connectedSelService.lastSelectedOrUnselectedIndex ?? 0;
|
|
106
|
+
}
|
|
98
107
|
this.connectedWith.clearSelection();
|
|
108
|
+
if (this.connectedWith.data?.length > 0) {
|
|
109
|
+
const validIndex = Math.min(lastSelectedIndex, this.connectedWith.data.length - 1);
|
|
110
|
+
this.updateListBoxIndices(connectedNavService, connectedSelService, validIndex, false);
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
this.updateListBoxIndices(connectedNavService, connectedSelService, 0, false);
|
|
114
|
+
}
|
|
99
115
|
}));
|
|
100
116
|
this.selectedBoxSub.add(this.connectedWith.selectionChange.subscribe(() => {
|
|
101
117
|
this.selectedBox = this.connectedWith;
|
|
118
|
+
const listboxNavService = this.listbox.keyboardNavigationService;
|
|
119
|
+
const listboxSelService = this.listbox.selectionService;
|
|
120
|
+
let lastSelectedIndex = 0;
|
|
121
|
+
if (listboxSelService.selectedIndices.length > 0) {
|
|
122
|
+
lastSelectedIndex = listboxSelService.rangeSelectionTargetIndex ?? listboxSelService.lastSelectedOrUnselectedIndex ?? 0;
|
|
123
|
+
}
|
|
102
124
|
this.listbox.clearSelection();
|
|
125
|
+
if (this.listbox.data?.length > 0) {
|
|
126
|
+
const validIndex = Math.min(lastSelectedIndex, this.listbox.data.length - 1);
|
|
127
|
+
this.updateListBoxIndices(listboxNavService, listboxSelService, validIndex, false);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.updateListBoxIndices(listboxNavService, listboxSelService, 0, false);
|
|
131
|
+
}
|
|
103
132
|
}));
|
|
104
133
|
}
|
|
105
134
|
}
|
|
@@ -107,9 +136,9 @@ export class DataBindingDirective {
|
|
|
107
136
|
* @hidden
|
|
108
137
|
*/
|
|
109
138
|
ngOnDestroy() {
|
|
110
|
-
if (this.
|
|
111
|
-
this.
|
|
112
|
-
this.
|
|
139
|
+
if (this.actionSub) {
|
|
140
|
+
this.actionSub.unsubscribe();
|
|
141
|
+
this.actionSub = null;
|
|
113
142
|
}
|
|
114
143
|
if (this.selectedBoxSub) {
|
|
115
144
|
this.selectedBoxSub.unsubscribe();
|
|
@@ -117,49 +146,115 @@ export class DataBindingDirective {
|
|
|
117
146
|
}
|
|
118
147
|
}
|
|
119
148
|
moveVertically(dir) {
|
|
120
|
-
const
|
|
121
|
-
if (!isPresent(
|
|
149
|
+
const selectedIndices = this.selectedBox.selectedIndices;
|
|
150
|
+
if (!isPresent(selectedIndices) || selectedIndices.length === 0) {
|
|
122
151
|
return;
|
|
123
152
|
}
|
|
124
|
-
const
|
|
125
|
-
const
|
|
153
|
+
const sortedIndices = [...selectedIndices].sort((a, b) => a - b);
|
|
154
|
+
const topIndex = sortedIndices[0];
|
|
155
|
+
const bottomIndex = sortedIndices[sortedIndices.length - 1];
|
|
156
|
+
const topReached = dir === 'up' && topIndex <= 0;
|
|
157
|
+
const bottomReached = dir === 'down' && bottomIndex >= this.selectedBox.data.length - 1;
|
|
126
158
|
if (topReached || bottomReached) {
|
|
127
159
|
return;
|
|
128
160
|
}
|
|
129
|
-
const
|
|
161
|
+
const data = this.selectedBox.data;
|
|
162
|
+
const newSelectedIndices = [];
|
|
163
|
+
if (dir === 'up') {
|
|
164
|
+
for (const index of sortedIndices) {
|
|
165
|
+
const newIndex = index - 1;
|
|
166
|
+
[data[newIndex], data[index]] = [data[index], data[newIndex]];
|
|
167
|
+
newSelectedIndices.push(newIndex);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
for (let i = sortedIndices.length - 1; i >= 0; i--) {
|
|
172
|
+
const index = sortedIndices[i];
|
|
173
|
+
const newIndex = index + 1;
|
|
174
|
+
[data[newIndex], data[index]] = [data[index], data[newIndex]];
|
|
175
|
+
newSelectedIndices.push(newIndex);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
newSelectedIndices.sort((a, b) => a - b);
|
|
179
|
+
this.selectedBox.selectionService.setSelectedIndices(newSelectedIndices);
|
|
130
180
|
const navigation = this.selectedBox.keyboardNavigationService;
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
181
|
+
const currentFocusedIndex = navigation.focusedListboxItemIndex;
|
|
182
|
+
const focusedItemIndexInSelection = sortedIndices.indexOf(currentFocusedIndex);
|
|
183
|
+
let newFocusIndex;
|
|
184
|
+
if (focusedItemIndexInSelection !== -1) {
|
|
185
|
+
newFocusIndex = newSelectedIndices[focusedItemIndexInSelection];
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
newFocusIndex = dir === 'up' ? topIndex - 1 : bottomIndex + 1;
|
|
189
|
+
}
|
|
190
|
+
this.zone.onStable.pipe(take(1)).subscribe(() => {
|
|
191
|
+
const listboxItems = this.selectedBox.listboxItems.toArray();
|
|
192
|
+
const previousItem = listboxItems[currentFocusedIndex]?.nativeElement;
|
|
193
|
+
const currentItem = listboxItems[newFocusIndex]?.nativeElement;
|
|
194
|
+
navigation.changeTabindex(previousItem, currentItem);
|
|
195
|
+
navigation.focusedListboxItemIndex = newFocusIndex;
|
|
196
|
+
navigation.selectedListboxItemIndex = newFocusIndex;
|
|
197
|
+
});
|
|
134
198
|
}
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
if (!isPresent(
|
|
199
|
+
removeSelectedItems() {
|
|
200
|
+
const itemIndices = this.selectedBox.selectedIndices;
|
|
201
|
+
if (!isPresent(itemIndices) || itemIndices.length === 0) {
|
|
138
202
|
return;
|
|
139
203
|
}
|
|
140
|
-
this.selectedBox.data.
|
|
204
|
+
this.selectedBox.data = this.selectedBox.data.filter((_, index) => !itemIndices.includes(index));
|
|
141
205
|
this.selectedBox.selectionService.clearSelection();
|
|
142
206
|
}
|
|
143
|
-
|
|
144
|
-
const
|
|
145
|
-
if (!
|
|
207
|
+
transferSelectedItems(source, target) {
|
|
208
|
+
const selectedIndices = source?.data && source?.selectedIndices;
|
|
209
|
+
if (!target || !source || !isPresent(selectedIndices) || selectedIndices.length === 0) {
|
|
146
210
|
return;
|
|
147
211
|
}
|
|
148
|
-
|
|
149
|
-
|
|
212
|
+
const sourceLastIndex = source.selectionService.rangeSelectionTargetIndex ??
|
|
213
|
+
source.selectionService.lastSelectedOrUnselectedIndex ??
|
|
214
|
+
0;
|
|
215
|
+
target.data.push(...selectedIndices.map(index => source.data[index]));
|
|
216
|
+
source.data = source.data.filter((_, index) => !selectedIndices.includes(index));
|
|
150
217
|
source.clearSelection();
|
|
151
|
-
|
|
218
|
+
const removedBeforeAnchor = selectedIndices.filter(i => i < sourceLastIndex).length;
|
|
219
|
+
const adjustedAnchorIndex = Math.max(0, Math.min(sourceLastIndex - removedBeforeAnchor, source.data.length - 1));
|
|
220
|
+
const sourceNavService = source.keyboardNavigationService;
|
|
221
|
+
const sourceSelService = source.selectionService;
|
|
222
|
+
if (source.data.length > 0) {
|
|
223
|
+
this.updateListBoxIndices(sourceNavService, sourceSelService, adjustedAnchorIndex);
|
|
224
|
+
}
|
|
225
|
+
const targetIndex = target.data.length - 1;
|
|
226
|
+
target.select([targetIndex]);
|
|
227
|
+
const targetNavService = target.keyboardNavigationService;
|
|
228
|
+
const targetSelService = target.selectionService;
|
|
229
|
+
this.updateListBoxIndices(targetNavService, targetSelService, targetIndex);
|
|
152
230
|
this.selectedBox = target;
|
|
153
231
|
}
|
|
154
232
|
transferAll(source, target) {
|
|
155
|
-
if (!target || !source) {
|
|
233
|
+
if (!target || !source || source.data?.length === 0) {
|
|
156
234
|
return;
|
|
157
235
|
}
|
|
158
|
-
|
|
159
|
-
target.
|
|
236
|
+
const itemsToTransfer = source.data.splice(0, source.data.length);
|
|
237
|
+
target.data.push(...itemsToTransfer);
|
|
238
|
+
source.clearSelection();
|
|
239
|
+
const sourceNavService = source.keyboardNavigationService;
|
|
240
|
+
const sourceSelService = source.selectionService;
|
|
241
|
+
this.updateListBoxIndices(sourceNavService, sourceSelService, 0);
|
|
242
|
+
const targetIndex = target.data.length - 1;
|
|
243
|
+
target.select([targetIndex]);
|
|
244
|
+
const targetNavService = target.keyboardNavigationService;
|
|
245
|
+
const targetSelService = target.selectionService;
|
|
246
|
+
this.updateListBoxIndices(targetNavService, targetSelService, targetIndex);
|
|
160
247
|
this.selectedBox = target;
|
|
161
248
|
}
|
|
162
|
-
|
|
249
|
+
updateListBoxIndices = (keyboardNavService, selectionService, index, setFocusedIndex = true) => {
|
|
250
|
+
if (setFocusedIndex) {
|
|
251
|
+
keyboardNavService.focusedListboxItemIndex = index;
|
|
252
|
+
}
|
|
253
|
+
keyboardNavService.selectedListboxItemIndex = index;
|
|
254
|
+
selectionService.rangeSelectionAnchorIndex = index;
|
|
255
|
+
selectionService.lastSelectedOrUnselectedIndex = index;
|
|
256
|
+
};
|
|
257
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DataBindingDirective, deps: [{ token: i1.ListBoxComponent }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive });
|
|
163
258
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: DataBindingDirective, isStandalone: true, selector: "[kendoListBoxDataBinding]", inputs: { connectedWith: "connectedWith" }, usesOnChanges: true, ngImport: i0 });
|
|
164
259
|
}
|
|
165
260
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DataBindingDirective, decorators: [{
|
|
@@ -168,6 +263,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
168
263
|
selector: '[kendoListBoxDataBinding]',
|
|
169
264
|
standalone: true
|
|
170
265
|
}]
|
|
171
|
-
}], ctorParameters: () => [{ type: i1.ListBoxComponent }], propDecorators: { connectedWith: [{
|
|
266
|
+
}], ctorParameters: () => [{ type: i1.ListBoxComponent }, { type: i0.NgZone }], propDecorators: { connectedWith: [{
|
|
172
267
|
type: Input
|
|
173
268
|
}] } });
|
|
@@ -20,7 +20,12 @@ export class ItemSelectableDirective {
|
|
|
20
20
|
}
|
|
21
21
|
onClick(event) {
|
|
22
22
|
event.stopPropagation();
|
|
23
|
-
|
|
23
|
+
const ctrlKey = event.ctrlKey || event.metaKey;
|
|
24
|
+
const shiftKey = event.shiftKey;
|
|
25
|
+
if (shiftKey) {
|
|
26
|
+
event.preventDefault();
|
|
27
|
+
}
|
|
28
|
+
this.selectionService.select(this.index, ctrlKey, shiftKey);
|
|
24
29
|
}
|
|
25
30
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ItemSelectableDirective, deps: [{ token: i1.ListBoxSelectionService }], target: i0.ɵɵFactoryTarget.Directive });
|
|
26
31
|
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.14", type: ItemSelectableDirective, isStandalone: true, selector: "[kendoListBoxItemSelectable]", inputs: { index: "index" }, host: { listeners: { "mousedown": "onClick($event)" }, properties: { "class.k-selected": "this.selectedClassName" } }, ngImport: i0 });
|