@progress/kendo-angular-sortable 21.4.1 → 22.0.0

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.
@@ -1,44 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { NgModule } from '@angular/core';
6
- import { SortableService } from "./sortable.service";
7
- import { KENDO_SORTABLE } from './directives';
8
- import * as i0 from "@angular/core";
9
- import * as i1 from "./sortable.component";
10
- import * as i2 from "./draggable.directive";
11
- import * as i3 from "./item-template.directive";
12
- import * as i4 from "./binding.directive";
13
- //IMPORTANT: NgModule export kept for backwards compatibility
14
- /**
15
- * Represents the [`NgModule`](link:site.data.urls.angular['ngmoduleapi']) definition for the Sortable component.
16
- *
17
- * @example
18
- * ```typescript
19
- * import { NgModule } from '@angular/core';
20
- * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
21
- * import { SortableModule } from '@progress/kendo-angular-sortable';
22
- * import { AppComponent } from './app.component';
23
- *
24
- * @NgModule({
25
- * declarations: [AppComponent],
26
- * imports: [BrowserModule, SortableModule],
27
- * bootstrap: [AppComponent]
28
- * })
29
- * export class AppModule {}
30
- * ```
31
- */
32
- export class SortableModule {
33
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
34
- static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, imports: [i1.SortableComponent, i2.DraggableDirective, i3.PlaceholderTemplateDirective, i3.ItemTemplateDirective, i4.SortableBindingDirective], exports: [i1.SortableComponent, i2.DraggableDirective, i3.PlaceholderTemplateDirective, i3.ItemTemplateDirective, i4.SortableBindingDirective] });
35
- static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, providers: [SortableService] });
36
- }
37
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableModule, decorators: [{
38
- type: NgModule,
39
- args: [{
40
- imports: [...KENDO_SORTABLE],
41
- exports: [...KENDO_SORTABLE],
42
- providers: [SortableService]
43
- }]
44
- }] });
@@ -1,238 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { Injectable, NgZone } from '@angular/core';
6
- import { isDocumentAvailable } from '@progress/kendo-angular-common';
7
- import { draggableFromEvent, isFocusable, MINIMAL_DRAG_DISTANCE, widgetTarget } from './util';
8
- import { Subject } from 'rxjs';
9
- import { switchMap, filter, take, tap } from 'rxjs/operators';
10
- import * as i0 from "@angular/core";
11
- const allowDrag = (e) => {
12
- const target = e.originalEvent.target;
13
- return target.hasAttribute('data-sortable-item') || !(isFocusable(target) || widgetTarget(target));
14
- };
15
- /**
16
- * The `SortableService` is a service that manages the drag-and-drop functionality
17
- * for transferring items between Sortable components.
18
- */
19
- export class SortableService {
20
- ngZone;
21
- /**
22
- * Specifies the Draggable item that is currently being moved.
23
- */
24
- activeDraggable = null;
25
- /**
26
- * Specifies the Draggable item from which the dragging started.
27
- */
28
- originDraggable = null;
29
- /**
30
- * @hidden
31
- */
32
- originIndex;
33
- /**
34
- * @hidden
35
- */
36
- targetSortable = null;
37
- /**
38
- * Specifies the Draggable item that last emitted an event.
39
- */
40
- lastDraggable = null;
41
- /**
42
- * @hidden
43
- */
44
- onPressSubject = new Subject();
45
- /**
46
- * @hidden
47
- */
48
- onDragSubject = new Subject();
49
- /**
50
- * @hidden
51
- */
52
- onReleaseSubject = new Subject();
53
- subscriptions;
54
- source = null;
55
- _target = null;
56
- sortableCounter = 0;
57
- sortableRegister = {};
58
- pressArgs;
59
- /**
60
- * Specifies the `SortableComponent` instance under the currently dragged item.
61
- */
62
- set target(target) {
63
- this._target = target;
64
- }
65
- get target() {
66
- return this._target;
67
- }
68
- /**
69
- * @hidden
70
- */
71
- constructor(ngZone) {
72
- this.ngZone = ngZone;
73
- if (!isDocumentAvailable()) {
74
- return;
75
- }
76
- this.subscriptions = this.onPressSubject.pipe(filter(allowDrag), tap(press => {
77
- this.targetSortable = this.getSortableComponentFromTouch(press);
78
- }), filter(_ => Boolean(this.targetSortable)), tap(press => {
79
- this.onReleaseSubject.pipe(take(1)).subscribe(event => this.release(event));
80
- this.pressArgs = press;
81
- if (press.isTouch) {
82
- press.originalEvent.preventDefault();
83
- }
84
- }), switchMap(_drag => this.onDragSubject.pipe(filter(_ => Boolean(this.targetSortable)), //stop further events if dragStart is prevented
85
- tap((e) => this.drag(e))))).subscribe();
86
- }
87
- /**
88
- * @hidden
89
- */
90
- onPress(e) {
91
- this.onPressSubject.next(e);
92
- }
93
- /**
94
- * @hidden
95
- */
96
- onDrag(e) {
97
- this.onDragSubject.next(e);
98
- }
99
- /**
100
- * @hidden
101
- */
102
- onRelease(e) {
103
- this.onReleaseSubject.next(e);
104
- }
105
- /**
106
- * @hidden
107
- */
108
- ngOnDestroy() {
109
- if (this.subscriptions) {
110
- this.subscriptions.unsubscribe();
111
- }
112
- }
113
- /**
114
- * Registers a `SortableComponent` with the `SortableService` so that it can be managed by the service.
115
- *
116
- * @param sortableComponent - The `SortableComponent`.
117
- * @return - The unique key that the current `SortableComponent` gets when registered.
118
- */
119
- registerComponent(sortableComponent) {
120
- const id = this.sortableCounter.toString();
121
- this.sortableRegister[id] = sortableComponent;
122
- this.sortableCounter++;
123
- return id;
124
- }
125
- /**
126
- * Removes a `SortableComponent` from the registered `SortableComponents` with which the service operates.
127
- *
128
- * @param key - The key of the `SortableComponent` which will be removed from the register.
129
- * Obtained when `registerComponent` is called.
130
- */
131
- unregisterComponent(key) {
132
- this.sortableRegister[key] = null;
133
- }
134
- /**
135
- * Sets the `SortableComponent` as a source component. When dragging an item from one Sortable to another,
136
- * the source component is the one from which the item originates.
137
- *
138
- * @param sortable - The `SortableComponent`.
139
- */
140
- setSource(sortable) {
141
- this.source = sortable;
142
- }
143
- /**
144
- * Returns the source `SortableComponent` from which
145
- * an item is dragged to other Sortable components.
146
- *
147
- * @return - The `SourceComponent`.
148
- */
149
- getSource() {
150
- return this.source;
151
- }
152
- /**
153
- * The method that finds the `SortableComponent` which is registered to
154
- * the `SortableService` by using the arguments of the `touch` event.
155
- *
156
- * @param touch - A Touch-Object of the `Touch` type interface.
157
- * Represents a single contact point (finger or stylus)
158
- * on a touch-sensitive device (touchscreen or trackpad).
159
- *
160
- * @return { component: SortableComponent, index: number } - An object where the component is the `SortableComponent` that owns the item and the index is the index of the touched item.
161
- */
162
- getSortableComponentFromTouch(touch) {
163
- if (!isDocumentAvailable()) {
164
- return { component: undefined, index: undefined };
165
- }
166
- let realTarget = document.elementFromPoint(touch.clientX, touch.clientY);
167
- while (realTarget) {
168
- const id = realTarget.getAttribute('data-sortable-id');
169
- const index = realTarget.getAttribute('data-sortable-index');
170
- if (id) {
171
- const targetSortable = this.sortableRegister[id];
172
- if (targetSortable) {
173
- return { component: targetSortable, index: parseInt(index, 10) };
174
- }
175
- }
176
- realTarget = realTarget.parentElement;
177
- }
178
- }
179
- start() {
180
- const pressArgs = this.pressArgs;
181
- if (pressArgs) {
182
- this.pressArgs = null;
183
- const startTarget = draggableFromEvent(pressArgs, this.targetSortable.component);
184
- if (this.targetSortable.component.startDrag({ target: startTarget, originalEvent: pressArgs })) {
185
- this.targetSortable = null;
186
- return true;
187
- }
188
- }
189
- }
190
- release(event) {
191
- if (this.source) {
192
- this.ngZone.run(() => {
193
- if (this.targetSortable) {
194
- const dropTarget = draggableFromEvent(event, this.targetSortable.component);
195
- this.source.endDrag({ target: dropTarget, originalEvent: event });
196
- }
197
- this.source.positionHintFromEvent(null);
198
- this.source.markForCheck();
199
- });
200
- }
201
- this.targetSortable = null;
202
- this.pressArgs = null;
203
- }
204
- drag(event) {
205
- const distance = this.pressArgs && Math.sqrt((event.pageX - this.pressArgs.pageX) ** 2 + (event.pageY - this.pressArgs.pageY) ** 2);
206
- if (distance && distance < MINIMAL_DRAG_DISTANCE) {
207
- return;
208
- }
209
- this.ngZone.run(() => {
210
- if (this.start()) {
211
- return;
212
- }
213
- this.source.positionHintFromEvent(event);
214
- const sortable = this.getSortableComponentFromTouch(event);
215
- if (!sortable || sortable && sortable.component !== this.target) {
216
- if (this.target) {
217
- this.target.leave({ target: undefined, originalEvent: event });
218
- }
219
- else if (this.source !== this.target) {
220
- this.source.leave({ target: undefined, originalEvent: event });
221
- }
222
- }
223
- if (sortable && sortable.component) {
224
- const draggable = draggableFromEvent(event, sortable.component);
225
- sortable.component.drag({ target: draggable, originalEvent: event });
226
- }
227
- this.source.markForCheck();
228
- });
229
- }
230
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
231
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableService, providedIn: 'root' });
232
- }
233
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SortableService, decorators: [{
234
- type: Injectable,
235
- args: [{
236
- providedIn: 'root'
237
- }]
238
- }], ctorParameters: () => [{ type: i0.NgZone }] });
package/esm2022/util.mjs DELETED
@@ -1,176 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2026 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import { focusableSelector, isDocumentAvailable } from '@progress/kendo-angular-common';
6
- const NODE_NAME_PREDICATES = {};
7
- const NODE_ATTR_PREDICATES = {};
8
- const focusableRegex = /^(?:a|input|select|option|textarea|button|object)$/i;
9
- /**
10
- * @hidden
11
- */
12
- export const MINIMAL_DRAG_DISTANCE = 5;
13
- /**
14
- * @hidden
15
- */
16
- export const matchesNodeName = (nodeName) => {
17
- if (!NODE_NAME_PREDICATES[nodeName]) {
18
- NODE_NAME_PREDICATES[nodeName] = (element) => String(element.nodeName).toLowerCase() === nodeName.toLowerCase();
19
- }
20
- return NODE_NAME_PREDICATES[nodeName];
21
- };
22
- /**
23
- * @hidden
24
- */
25
- export const matchesNodeAttr = (nodeAttr) => {
26
- if (!NODE_ATTR_PREDICATES[nodeAttr]) {
27
- NODE_ATTR_PREDICATES[nodeAttr] = (element) => element.hasAttribute ? element.hasAttribute(nodeAttr) : false;
28
- }
29
- return NODE_ATTR_PREDICATES[nodeAttr];
30
- };
31
- /**
32
- * @hidden
33
- */
34
- export const closest = (node, predicate) => {
35
- while (node && !predicate(node)) {
36
- node = node.parentNode;
37
- }
38
- return node;
39
- };
40
- /**
41
- * Returns an object specifying whether there is a `DraggableDirective` under the cursor.
42
- * @hidden
43
- */
44
- export const draggableFromPoint = (x, y) => {
45
- if (!isDocumentAvailable()) {
46
- return;
47
- }
48
- const el = document.elementFromPoint(x, y);
49
- if (!el) {
50
- return;
51
- }
52
- const isDraggable = el.hasAttribute("kendoDraggable");
53
- const isChild = closest(el, matchesNodeAttr("kendoDraggable")) !== null;
54
- const parentDraggable = closest(el, matchesNodeAttr("data-sortable-index"));
55
- const index = parentDraggable ? parseInt(parentDraggable.getAttribute("data-sortable-index"), 10) : -1;
56
- return {
57
- element: el,
58
- index: index,
59
- isDraggable: isDraggable,
60
- isDraggableChild: isChild,
61
- parentDraggable: parentDraggable,
62
- rect: el.getBoundingClientRect()
63
- };
64
- };
65
- /**
66
- * Returns the DraggableDirective under the cursor.
67
- * @hidden
68
- */
69
- export const draggableFromEvent = (event, sortable) => {
70
- let target;
71
- if (event.changedTouches) {
72
- const touch = event.changedTouches[0];
73
- target = draggableFromPoint(touch.clientX, touch.clientY);
74
- }
75
- else {
76
- target = draggableFromPoint(event.clientX, event.clientY);
77
- }
78
- // TODO: refactor sortable. Add draggable getter
79
- return sortable.draggables.toArray()[target ? target.index : -1];
80
- };
81
- /**
82
- * @hidden
83
- */
84
- export const getAllFocusableChildren = (parent) => {
85
- return Array.from(parent.querySelectorAll(focusableSelector)).filter((element) => element.offsetParent !== null);
86
- };
87
- /**
88
- * @hidden
89
- */
90
- export const getFirstAndLastFocusable = (parent) => {
91
- const all = getAllFocusableChildren(parent);
92
- const firstFocusable = all.length > 0 ? all[0] : parent;
93
- const lastFocusable = all.length > 0 ? all[all.length - 1] : parent;
94
- return [firstFocusable, lastFocusable];
95
- };
96
- /**
97
- * @hidden
98
- */
99
- export const keepFocusWithinComponent = (event, wrapper) => {
100
- const [firstFocusable, lastFocusable] = getFirstAndLastFocusable(wrapper);
101
- const tabAfterLastFocusable = !event.shiftKey && event.target === lastFocusable;
102
- const shiftTabAfterFirstFocusable = event.shiftKey && event.target === firstFocusable;
103
- if (tabAfterLastFocusable) {
104
- event.preventDefault();
105
- firstFocusable.focus();
106
- wrapper.blur();
107
- }
108
- if (shiftTabAfterFirstFocusable) {
109
- event.preventDefault();
110
- lastFocusable.focus();
111
- }
112
- };
113
- /**
114
- * @hidden
115
- */
116
- export const isFocusable = (element) => {
117
- if (element.tagName) {
118
- const tagName = element.tagName.toLowerCase();
119
- const tabIndex = element.getAttribute('tabIndex');
120
- const skipTab = tabIndex === '-1';
121
- let focusable = tabIndex !== null && !skipTab;
122
- if (focusableRegex.test(tagName)) {
123
- focusable = !element.disabled && !skipTab;
124
- }
125
- return focusable;
126
- }
127
- return false;
128
- };
129
- const toClassList = (classNames) => String(classNames).trim().split(' ');
130
- /**
131
- * @hidden
132
- */
133
- export const hasClasses = (element, classNames) => {
134
- const namesList = toClassList(classNames);
135
- return Boolean(toClassList(element.className).find((className) => namesList.indexOf(className) >= 0));
136
- };
137
- const isSortable = matchesNodeName('kendo-sortable');
138
- /**
139
- * @hidden
140
- */
141
- export const widgetTarget = (target) => {
142
- const element = closest(target, node => hasClasses(node, 'k-widget') || isSortable(node));
143
- return element && !isSortable(element);
144
- };
145
- const hasRelativeStackingContext = () => {
146
- if (!isDocumentAvailable()) {
147
- return false;
148
- }
149
- const top = 10;
150
- const parent = document.createElement("div");
151
- parent.style.transform = "matrix(10, 0, 0, 10, 0, 0)";
152
- const innerDiv = document.createElement('div');
153
- innerDiv.style.position = 'fixed';
154
- innerDiv.style.top = `${top}px;`;
155
- parent.appendChild(innerDiv);
156
- document.body.appendChild(parent);
157
- const isDifferent = parent.children[0].getBoundingClientRect().top !== top;
158
- document.body.removeChild(parent);
159
- return isDifferent;
160
- };
161
- const HAS_RELATIVE_STACKING_CONTEXT = hasRelativeStackingContext();
162
- /**
163
- * @hidden
164
- */
165
- export const relativeContextElement = (element) => {
166
- if (!element || !HAS_RELATIVE_STACKING_CONTEXT || !isDocumentAvailable()) {
167
- return null;
168
- }
169
- let node = element.parentElement;
170
- while (node) {
171
- if (window.getComputedStyle(node).transform !== 'none') {
172
- return node;
173
- }
174
- node = node.parentElement;
175
- }
176
- };