@progress/kendo-angular-sortable 19.0.0-develop.1 → 19.0.0-develop.11

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.
@@ -10,7 +10,7 @@ export const packageMetadata = {
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCode: 'KENDOUIANGULAR',
12
12
  productCodes: ['KENDOUIANGULAR'],
13
- publishDate: 1745317667,
14
- version: '19.0.0-develop.1',
13
+ publishDate: 1746798703,
14
+ version: '19.0.0-develop.11',
15
15
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
16
16
  };
@@ -5,7 +5,7 @@
5
5
  /* eslint-disable @typescript-eslint/no-explicit-any */
6
6
  import { Component, Input, Output, QueryList, ContentChildren, ViewChild, ViewChildren, TemplateRef, ElementRef, EventEmitter, HostBinding, NgZone, ChangeDetectorRef, forwardRef, Renderer2 } from '@angular/core';
7
7
  import { Subject, merge } from 'rxjs';
8
- import { isDocumentAvailable, isChanged, Keys } from '@progress/kendo-angular-common';
8
+ import { isDocumentAvailable, isChanged, Keys, EventsOutsideAngularDirective } from '@progress/kendo-angular-common';
9
9
  import { getAllFocusableChildren, keepFocusWithinComponent, relativeContextElement } from './util';
10
10
  import { filter, take } from 'rxjs/operators';
11
11
  import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
@@ -37,10 +37,15 @@ export class SortableComponent {
37
37
  renderer;
38
38
  changeDetector;
39
39
  localization;
40
+ cdr;
40
41
  /**
41
42
  * Specifies the tab index of the Sortable component.
42
43
  */
43
44
  tabIndex = null;
45
+ /**
46
+ * Configures how the Sortable component will track changes in its items collection.
47
+ */
48
+ trackBy = (_, idx) => idx;
44
49
  /**
45
50
  * Sets an array of any data that is used as a data source for the Sortable.
46
51
  */
@@ -299,11 +304,12 @@ export class SortableComponent {
299
304
  }
300
305
  return template;
301
306
  }
302
- constructor(ngZone, renderer, changeDetector, localization, wrapper, sortableService) {
307
+ constructor(ngZone, renderer, changeDetector, localization, wrapper, sortableService, cdr) {
303
308
  this.ngZone = ngZone;
304
309
  this.renderer = renderer;
305
310
  this.changeDetector = changeDetector;
306
311
  this.localization = localization;
312
+ this.cdr = cdr;
307
313
  validatePackage(packageMetadata);
308
314
  this.wrapper = wrapper.nativeElement;
309
315
  this.direction = localization.rtl ? 'rtl' : 'ltr';
@@ -597,9 +603,9 @@ export class SortableComponent {
597
603
  /**
598
604
  * @hidden
599
605
  */
600
- onEscapeHandler() {
606
+ onEscapeHandler(event) {
601
607
  const focusableItems = this.focusableItems[this.prevActiveIndex];
602
- const item = this.itemWrappers.toArray()[this.prevActiveIndex].nativeElement;
608
+ const item = (event?.target).closest('[data-sortable-item]');
603
609
  focusableItems.forEach(focusableItem => {
604
610
  this.renderer.setAttribute(focusableItem, 'tabindex', '-1');
605
611
  });
@@ -609,27 +615,37 @@ export class SortableComponent {
609
615
  /**
610
616
  * @hidden
611
617
  */
612
- keydownHandler(event) {
618
+ keydownHandler = (event) => {
619
+ if (!this.navigable) {
620
+ return;
621
+ }
622
+ this.cdr.markForCheck();
623
+ const targetIsWrapper = this.itemWrappers.toArray().some((item) => item.nativeElement === event.target);
613
624
  const index = this.activeIndex === -1 ? this.prevActiveIndex : this.activeIndex;
614
- const item = this.itemWrappers.toArray()[index].nativeElement;
625
+ const item = this.itemWrappers.toArray()[index]?.nativeElement;
615
626
  const isItemFocused = document.activeElement === item;
616
627
  const hasFocus = this.activeIndex !== -1;
617
628
  const keyCode = event.keyCode;
629
+ if (keyCode === Keys.Tab && !isItemFocused) {
630
+ keepFocusWithinComponent(event, item);
631
+ return;
632
+ }
633
+ if (keyCode === Keys.Escape && this.focusableItems.length > 0 && this.activeIndex === -1) {
634
+ this.onEscapeHandler(event);
635
+ return;
636
+ }
637
+ if (!targetIsWrapper) {
638
+ return;
639
+ }
618
640
  if (this.navigable && hasFocus) {
619
641
  if (keyCode >= Keys.ArrowLeft && keyCode <= Keys.ArrowDown) {
620
- this.onArrowHandler(event, keyCode);
642
+ this.ngZone.run(() => this.onArrowHandler(event, keyCode));
621
643
  }
622
- if (keyCode === Keys.Enter && isItemFocused && this.focusableItems.length > 0) {
644
+ else if (keyCode === Keys.Enter && isItemFocused && this.focusableItems.length > 0) {
623
645
  this.onEnterHandler(item);
624
646
  }
625
647
  }
626
- if (keyCode === Keys.Tab && !isItemFocused) {
627
- keepFocusWithinComponent(event, item);
628
- }
629
- if (keyCode === Keys.Escape && this.focusableItems.length > 0 && this.activeIndex === -1) {
630
- this.onEscapeHandler();
631
- }
632
- }
648
+ };
633
649
  /**
634
650
  * Removes the currently active item from the Data collection that the Sortable uses.
635
651
  */
@@ -857,6 +873,9 @@ export class SortableComponent {
857
873
  .subscribe(({ rtl }) => this.direction = rtl ? 'rtl' : 'ltr');
858
874
  this.dragStartSubscription = this.onDragStartSubject
859
875
  .subscribe((event) => {
876
+ if (!event.target) {
877
+ return;
878
+ }
860
879
  this.sortableService.originDraggable = event.target;
861
880
  this.sortableService.originIndex = event.target.index;
862
881
  this.sortableService.activeDraggable = event.target;
@@ -994,8 +1013,8 @@ export class SortableComponent {
994
1013
  }
995
1014
  }
996
1015
  }
997
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SortableComponent, deps: [{ token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.LocalizationService }, { token: i0.ElementRef }, { token: i2.SortableService }], target: i0.ɵɵFactoryTarget.Component });
998
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SortableComponent, isStandalone: true, selector: "kendo-sortable", inputs: { tabIndex: "tabIndex", data: "data", navigable: "navigable", navigatable: "navigatable", animation: "animation", disabledIndexes: "disabledIndexes", zone: "zone", acceptZones: "acceptZones", itemStyle: "itemStyle", emptyItemStyle: "emptyItemStyle", activeItemStyle: "activeItemStyle", disabledItemStyle: "disabledItemStyle", itemClass: "itemClass", activeItemClass: "activeItemClass", emptyItemClass: "emptyItemClass", disabledItemClass: "disabledItemClass", emptyText: "emptyText", activeIndex: "activeIndex" }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd", dragOver: "dragOver", dragLeave: "dragLeave", dataMove: "dataMove", dataAdd: "dataAdd", dataRemove: "dataRemove", navigate: "navigate" }, host: { properties: { "style.touch-action": "this.touchAction", "attr.dir": "this.dir", "attr.role": "this.hostRole" } }, providers: [
1016
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SortableComponent, deps: [{ token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.LocalizationService }, { token: i0.ElementRef }, { token: i2.SortableService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1017
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SortableComponent, isStandalone: true, selector: "kendo-sortable", inputs: { tabIndex: "tabIndex", trackBy: "trackBy", data: "data", navigable: "navigable", navigatable: "navigatable", animation: "animation", disabledIndexes: "disabledIndexes", zone: "zone", acceptZones: "acceptZones", itemStyle: "itemStyle", emptyItemStyle: "emptyItemStyle", activeItemStyle: "activeItemStyle", disabledItemStyle: "disabledItemStyle", itemClass: "itemClass", activeItemClass: "activeItemClass", emptyItemClass: "emptyItemClass", disabledItemClass: "disabledItemClass", emptyText: "emptyText", activeIndex: "activeIndex" }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd", dragOver: "dragOver", dragLeave: "dragLeave", dataMove: "dataMove", dataAdd: "dataAdd", dataRemove: "dataRemove", navigate: "navigate" }, host: { properties: { "style.touch-action": "this.touchAction", "attr.dir": "this.dir", "attr.role": "this.hostRole" } }, providers: [
999
1018
  LocalizationService,
1000
1019
  {
1001
1020
  provide: L10N_PREFIX,
@@ -1006,7 +1025,7 @@ export class SortableComponent {
1006
1025
  useExisting: forwardRef(() => SortableComponent)
1007
1026
  }
1008
1027
  ], queries: [{ propertyName: "defaultTemplateRef", predicate: TemplateRef }, { propertyName: "itemTemplateDirectiveRef", predicate: ItemTemplateDirective, read: TemplateRef }, { propertyName: "placeholderTemplateDirectiveRef", predicate: PlaceholderTemplateDirective, read: TemplateRef }], viewQueries: [{ propertyName: "noDataContainer", first: true, predicate: ["noDataRef"], descendants: true }, { propertyName: "hint", first: true, predicate: ["hint"], descendants: true }, { propertyName: "itemWrappers", predicate: ["itemWrapper"], descendants: true }, { propertyName: "draggables", predicate: DraggableDirective, descendants: true }], exportAs: ["kendoSortable"], usesOnChanges: true, ngImport: i0, template: `
1009
- <div #itemWrapper *ngFor="let item of _localData;let i=index"
1028
+ <div #itemWrapper *ngFor="let item of _localData; let i=index; trackBy: trackBy;"
1010
1029
  kendoDraggable
1011
1030
  role="listitem"
1012
1031
  [attr.aria-grabbed]="i===dragIndex"
@@ -1024,7 +1043,9 @@ export class SortableComponent {
1024
1043
 
1025
1044
  (focus)="focusHandler(i)"
1026
1045
  (blur)="blurHandler()"
1027
- (keydown)="keydownHandler($event)"
1046
+ [kendoEventsOutsideAngular]="{
1047
+ keydown: keydownHandler
1048
+ }"
1028
1049
  >
1029
1050
  <ng-container *ngIf="itemTemplateRef"
1030
1051
  [ngTemplateOutlet]="itemTemplate(i)"
@@ -1051,7 +1072,7 @@ export class SortableComponent {
1051
1072
  </ng-container>
1052
1073
  <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
1053
1074
  </div>
1054
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["index", "disabled", "hidden"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1075
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["index", "disabled", "hidden"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }] });
1055
1076
  }
1056
1077
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SortableComponent, decorators: [{
1057
1078
  type: Component,
@@ -1070,7 +1091,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1070
1091
  ],
1071
1092
  selector: 'kendo-sortable',
1072
1093
  template: `
1073
- <div #itemWrapper *ngFor="let item of _localData;let i=index"
1094
+ <div #itemWrapper *ngFor="let item of _localData; let i=index; trackBy: trackBy;"
1074
1095
  kendoDraggable
1075
1096
  role="listitem"
1076
1097
  [attr.aria-grabbed]="i===dragIndex"
@@ -1088,7 +1109,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1088
1109
 
1089
1110
  (focus)="focusHandler(i)"
1090
1111
  (blur)="blurHandler()"
1091
- (keydown)="keydownHandler($event)"
1112
+ [kendoEventsOutsideAngular]="{
1113
+ keydown: keydownHandler
1114
+ }"
1092
1115
  >
1093
1116
  <ng-container *ngIf="itemTemplateRef"
1094
1117
  [ngTemplateOutlet]="itemTemplate(i)"
@@ -1117,9 +1140,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1117
1140
  </div>
1118
1141
  `,
1119
1142
  standalone: true,
1120
- imports: [NgFor, DraggableDirective, NgClass, NgStyle, NgIf, NgTemplateOutlet]
1143
+ imports: [NgFor, DraggableDirective, NgClass, NgStyle, NgIf, NgTemplateOutlet, EventsOutsideAngularDirective]
1121
1144
  }]
1122
- }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.LocalizationService }, { type: i0.ElementRef }, { type: i2.SortableService }]; }, propDecorators: { tabIndex: [{
1145
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.LocalizationService }, { type: i0.ElementRef }, { type: i2.SortableService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { tabIndex: [{
1146
+ type: Input
1147
+ }], trackBy: [{
1123
1148
  type: Input
1124
1149
  }], data: [{
1125
1150
  type: Input
@@ -4,7 +4,7 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { Injectable, NgZone } from '@angular/core';
6
6
  import { isDocumentAvailable } from '@progress/kendo-angular-common';
7
- import { draggableFromEvent, isFocusable, widgetTarget } from './util';
7
+ import { draggableFromEvent, isFocusable, MINIMAL_DRAG_DISTANCE, widgetTarget } from './util';
8
8
  import { Subject } from 'rxjs';
9
9
  import { switchMap, filter, take, tap } from 'rxjs/operators';
10
10
  import * as i0 from "@angular/core";
@@ -202,6 +202,10 @@ export class SortableService {
202
202
  this.pressArgs = null;
203
203
  }
204
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
+ }
205
209
  this.ngZone.run(() => {
206
210
  if (this.start()) {
207
211
  return;
package/esm2022/util.mjs CHANGED
@@ -6,6 +6,10 @@ import { focusableSelector, isDocumentAvailable } from '@progress/kendo-angular-
6
6
  const NODE_NAME_PREDICATES = {};
7
7
  const NODE_ATTR_PREDICATES = {};
8
8
  const focusableRegex = /^(?:a|input|select|option|textarea|button|object)$/i;
9
+ /**
10
+ * @hidden
11
+ */
12
+ export const MINIMAL_DRAG_DISTANCE = 5;
9
13
  /**
10
14
  * @hidden
11
15
  */
@@ -5,7 +5,7 @@
5
5
  import * as i0 from '@angular/core';
6
6
  import { Injectable, Directive, Input, HostBinding, QueryList, EventEmitter, forwardRef, TemplateRef, Component, ContentChildren, ViewChildren, ViewChild, Output, NgModule } from '@angular/core';
7
7
  import { Subject, merge } from 'rxjs';
8
- import { isDocumentAvailable, focusableSelector, isChanged, Keys } from '@progress/kendo-angular-common';
8
+ import { isDocumentAvailable, focusableSelector, isChanged, Keys, EventsOutsideAngularDirective } from '@progress/kendo-angular-common';
9
9
  import { filter, tap, take, switchMap } from 'rxjs/operators';
10
10
  import * as i1 from '@progress/kendo-angular-l10n';
11
11
  import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
@@ -16,6 +16,10 @@ import { NgFor, NgClass, NgStyle, NgIf, NgTemplateOutlet } from '@angular/common
16
16
  const NODE_NAME_PREDICATES = {};
17
17
  const NODE_ATTR_PREDICATES = {};
18
18
  const focusableRegex = /^(?:a|input|select|option|textarea|button|object)$/i;
19
+ /**
20
+ * @hidden
21
+ */
22
+ const MINIMAL_DRAG_DISTANCE = 5;
19
23
  /**
20
24
  * @hidden
21
25
  */
@@ -189,8 +193,8 @@ const packageMetadata = {
189
193
  productName: 'Kendo UI for Angular',
190
194
  productCode: 'KENDOUIANGULAR',
191
195
  productCodes: ['KENDOUIANGULAR'],
192
- publishDate: 1745317667,
193
- version: '19.0.0-develop.1',
196
+ publishDate: 1746798703,
197
+ version: '19.0.0-develop.11',
194
198
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
195
199
  };
196
200
 
@@ -388,6 +392,10 @@ class SortableService {
388
392
  this.pressArgs = null;
389
393
  }
390
394
  drag(event) {
395
+ const distance = this.pressArgs && Math.sqrt((event.pageX - this.pressArgs.pageX) ** 2 + (event.pageY - this.pressArgs.pageY) ** 2);
396
+ if (distance && distance < MINIMAL_DRAG_DISTANCE) {
397
+ return;
398
+ }
391
399
  this.ngZone.run(() => {
392
400
  if (this.start()) {
393
401
  return;
@@ -660,10 +668,15 @@ class SortableComponent {
660
668
  renderer;
661
669
  changeDetector;
662
670
  localization;
671
+ cdr;
663
672
  /**
664
673
  * Specifies the tab index of the Sortable component.
665
674
  */
666
675
  tabIndex = null;
676
+ /**
677
+ * Configures how the Sortable component will track changes in its items collection.
678
+ */
679
+ trackBy = (_, idx) => idx;
667
680
  /**
668
681
  * Sets an array of any data that is used as a data source for the Sortable.
669
682
  */
@@ -922,11 +935,12 @@ class SortableComponent {
922
935
  }
923
936
  return template;
924
937
  }
925
- constructor(ngZone, renderer, changeDetector, localization, wrapper, sortableService) {
938
+ constructor(ngZone, renderer, changeDetector, localization, wrapper, sortableService, cdr) {
926
939
  this.ngZone = ngZone;
927
940
  this.renderer = renderer;
928
941
  this.changeDetector = changeDetector;
929
942
  this.localization = localization;
943
+ this.cdr = cdr;
930
944
  validatePackage(packageMetadata);
931
945
  this.wrapper = wrapper.nativeElement;
932
946
  this.direction = localization.rtl ? 'rtl' : 'ltr';
@@ -1220,9 +1234,9 @@ class SortableComponent {
1220
1234
  /**
1221
1235
  * @hidden
1222
1236
  */
1223
- onEscapeHandler() {
1237
+ onEscapeHandler(event) {
1224
1238
  const focusableItems = this.focusableItems[this.prevActiveIndex];
1225
- const item = this.itemWrappers.toArray()[this.prevActiveIndex].nativeElement;
1239
+ const item = (event?.target).closest('[data-sortable-item]');
1226
1240
  focusableItems.forEach(focusableItem => {
1227
1241
  this.renderer.setAttribute(focusableItem, 'tabindex', '-1');
1228
1242
  });
@@ -1232,27 +1246,37 @@ class SortableComponent {
1232
1246
  /**
1233
1247
  * @hidden
1234
1248
  */
1235
- keydownHandler(event) {
1249
+ keydownHandler = (event) => {
1250
+ if (!this.navigable) {
1251
+ return;
1252
+ }
1253
+ this.cdr.markForCheck();
1254
+ const targetIsWrapper = this.itemWrappers.toArray().some((item) => item.nativeElement === event.target);
1236
1255
  const index = this.activeIndex === -1 ? this.prevActiveIndex : this.activeIndex;
1237
- const item = this.itemWrappers.toArray()[index].nativeElement;
1256
+ const item = this.itemWrappers.toArray()[index]?.nativeElement;
1238
1257
  const isItemFocused = document.activeElement === item;
1239
1258
  const hasFocus = this.activeIndex !== -1;
1240
1259
  const keyCode = event.keyCode;
1260
+ if (keyCode === Keys.Tab && !isItemFocused) {
1261
+ keepFocusWithinComponent(event, item);
1262
+ return;
1263
+ }
1264
+ if (keyCode === Keys.Escape && this.focusableItems.length > 0 && this.activeIndex === -1) {
1265
+ this.onEscapeHandler(event);
1266
+ return;
1267
+ }
1268
+ if (!targetIsWrapper) {
1269
+ return;
1270
+ }
1241
1271
  if (this.navigable && hasFocus) {
1242
1272
  if (keyCode >= Keys.ArrowLeft && keyCode <= Keys.ArrowDown) {
1243
- this.onArrowHandler(event, keyCode);
1273
+ this.ngZone.run(() => this.onArrowHandler(event, keyCode));
1244
1274
  }
1245
- if (keyCode === Keys.Enter && isItemFocused && this.focusableItems.length > 0) {
1275
+ else if (keyCode === Keys.Enter && isItemFocused && this.focusableItems.length > 0) {
1246
1276
  this.onEnterHandler(item);
1247
1277
  }
1248
1278
  }
1249
- if (keyCode === Keys.Tab && !isItemFocused) {
1250
- keepFocusWithinComponent(event, item);
1251
- }
1252
- if (keyCode === Keys.Escape && this.focusableItems.length > 0 && this.activeIndex === -1) {
1253
- this.onEscapeHandler();
1254
- }
1255
- }
1279
+ };
1256
1280
  /**
1257
1281
  * Removes the currently active item from the Data collection that the Sortable uses.
1258
1282
  */
@@ -1480,6 +1504,9 @@ class SortableComponent {
1480
1504
  .subscribe(({ rtl }) => this.direction = rtl ? 'rtl' : 'ltr');
1481
1505
  this.dragStartSubscription = this.onDragStartSubject
1482
1506
  .subscribe((event) => {
1507
+ if (!event.target) {
1508
+ return;
1509
+ }
1483
1510
  this.sortableService.originDraggable = event.target;
1484
1511
  this.sortableService.originIndex = event.target.index;
1485
1512
  this.sortableService.activeDraggable = event.target;
@@ -1617,8 +1644,8 @@ class SortableComponent {
1617
1644
  }
1618
1645
  }
1619
1646
  }
1620
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SortableComponent, deps: [{ token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.LocalizationService }, { token: i0.ElementRef }, { token: SortableService }], target: i0.ɵɵFactoryTarget.Component });
1621
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SortableComponent, isStandalone: true, selector: "kendo-sortable", inputs: { tabIndex: "tabIndex", data: "data", navigable: "navigable", navigatable: "navigatable", animation: "animation", disabledIndexes: "disabledIndexes", zone: "zone", acceptZones: "acceptZones", itemStyle: "itemStyle", emptyItemStyle: "emptyItemStyle", activeItemStyle: "activeItemStyle", disabledItemStyle: "disabledItemStyle", itemClass: "itemClass", activeItemClass: "activeItemClass", emptyItemClass: "emptyItemClass", disabledItemClass: "disabledItemClass", emptyText: "emptyText", activeIndex: "activeIndex" }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd", dragOver: "dragOver", dragLeave: "dragLeave", dataMove: "dataMove", dataAdd: "dataAdd", dataRemove: "dataRemove", navigate: "navigate" }, host: { properties: { "style.touch-action": "this.touchAction", "attr.dir": "this.dir", "attr.role": "this.hostRole" } }, providers: [
1647
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SortableComponent, deps: [{ token: i0.NgZone }, { token: i0.Renderer2 }, { token: i0.ChangeDetectorRef }, { token: i1.LocalizationService }, { token: i0.ElementRef }, { token: SortableService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1648
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: SortableComponent, isStandalone: true, selector: "kendo-sortable", inputs: { tabIndex: "tabIndex", trackBy: "trackBy", data: "data", navigable: "navigable", navigatable: "navigatable", animation: "animation", disabledIndexes: "disabledIndexes", zone: "zone", acceptZones: "acceptZones", itemStyle: "itemStyle", emptyItemStyle: "emptyItemStyle", activeItemStyle: "activeItemStyle", disabledItemStyle: "disabledItemStyle", itemClass: "itemClass", activeItemClass: "activeItemClass", emptyItemClass: "emptyItemClass", disabledItemClass: "disabledItemClass", emptyText: "emptyText", activeIndex: "activeIndex" }, outputs: { dragStart: "dragStart", dragEnd: "dragEnd", dragOver: "dragOver", dragLeave: "dragLeave", dataMove: "dataMove", dataAdd: "dataAdd", dataRemove: "dataRemove", navigate: "navigate" }, host: { properties: { "style.touch-action": "this.touchAction", "attr.dir": "this.dir", "attr.role": "this.hostRole" } }, providers: [
1622
1649
  LocalizationService,
1623
1650
  {
1624
1651
  provide: L10N_PREFIX,
@@ -1629,7 +1656,7 @@ class SortableComponent {
1629
1656
  useExisting: forwardRef(() => SortableComponent)
1630
1657
  }
1631
1658
  ], queries: [{ propertyName: "defaultTemplateRef", predicate: TemplateRef }, { propertyName: "itemTemplateDirectiveRef", predicate: ItemTemplateDirective, read: TemplateRef }, { propertyName: "placeholderTemplateDirectiveRef", predicate: PlaceholderTemplateDirective, read: TemplateRef }], viewQueries: [{ propertyName: "noDataContainer", first: true, predicate: ["noDataRef"], descendants: true }, { propertyName: "hint", first: true, predicate: ["hint"], descendants: true }, { propertyName: "itemWrappers", predicate: ["itemWrapper"], descendants: true }, { propertyName: "draggables", predicate: DraggableDirective, descendants: true }], exportAs: ["kendoSortable"], usesOnChanges: true, ngImport: i0, template: `
1632
- <div #itemWrapper *ngFor="let item of _localData;let i=index"
1659
+ <div #itemWrapper *ngFor="let item of _localData; let i=index; trackBy: trackBy;"
1633
1660
  kendoDraggable
1634
1661
  role="listitem"
1635
1662
  [attr.aria-grabbed]="i===dragIndex"
@@ -1647,7 +1674,9 @@ class SortableComponent {
1647
1674
 
1648
1675
  (focus)="focusHandler(i)"
1649
1676
  (blur)="blurHandler()"
1650
- (keydown)="keydownHandler($event)"
1677
+ [kendoEventsOutsideAngular]="{
1678
+ keydown: keydownHandler
1679
+ }"
1651
1680
  >
1652
1681
  <ng-container *ngIf="itemTemplateRef"
1653
1682
  [ngTemplateOutlet]="itemTemplate(i)"
@@ -1674,7 +1703,7 @@ class SortableComponent {
1674
1703
  </ng-container>
1675
1704
  <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
1676
1705
  </div>
1677
- `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["index", "disabled", "hidden"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1706
+ `, isInline: true, dependencies: [{ kind: "directive", type: NgFor, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: DraggableDirective, selector: "[kendoDraggable]", inputs: ["index", "disabled", "hidden"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: EventsOutsideAngularDirective, selector: "[kendoEventsOutsideAngular]", inputs: ["kendoEventsOutsideAngular", "scope"] }] });
1678
1707
  }
1679
1708
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: SortableComponent, decorators: [{
1680
1709
  type: Component,
@@ -1693,7 +1722,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1693
1722
  ],
1694
1723
  selector: 'kendo-sortable',
1695
1724
  template: `
1696
- <div #itemWrapper *ngFor="let item of _localData;let i=index"
1725
+ <div #itemWrapper *ngFor="let item of _localData; let i=index; trackBy: trackBy;"
1697
1726
  kendoDraggable
1698
1727
  role="listitem"
1699
1728
  [attr.aria-grabbed]="i===dragIndex"
@@ -1711,7 +1740,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1711
1740
 
1712
1741
  (focus)="focusHandler(i)"
1713
1742
  (blur)="blurHandler()"
1714
- (keydown)="keydownHandler($event)"
1743
+ [kendoEventsOutsideAngular]="{
1744
+ keydown: keydownHandler
1745
+ }"
1715
1746
  >
1716
1747
  <ng-container *ngIf="itemTemplateRef"
1717
1748
  [ngTemplateOutlet]="itemTemplate(i)"
@@ -1740,9 +1771,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1740
1771
  </div>
1741
1772
  `,
1742
1773
  standalone: true,
1743
- imports: [NgFor, DraggableDirective, NgClass, NgStyle, NgIf, NgTemplateOutlet]
1774
+ imports: [NgFor, DraggableDirective, NgClass, NgStyle, NgIf, NgTemplateOutlet, EventsOutsideAngularDirective]
1744
1775
  }]
1745
- }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.LocalizationService }, { type: i0.ElementRef }, { type: SortableService }]; }, propDecorators: { tabIndex: [{
1776
+ }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.LocalizationService }, { type: i0.ElementRef }, { type: SortableService }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { tabIndex: [{
1777
+ type: Input
1778
+ }], trackBy: [{
1746
1779
  type: Input
1747
1780
  }], data: [{
1748
1781
  type: Input
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-sortable",
3
- "version": "19.0.0-develop.1",
3
+ "version": "19.0.0-develop.11",
4
4
  "description": "A Sortable Component for Angular",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -19,7 +19,7 @@
19
19
  "package": {
20
20
  "productName": "Kendo UI for Angular",
21
21
  "productCode": "KENDOUIANGULAR",
22
- "publishDate": 1745317667,
22
+ "publishDate": 1746798703,
23
23
  "licensingDocsUrl": "https://www.telerik.com/kendo-angular-ui/my-license/"
24
24
  }
25
25
  },
@@ -29,13 +29,13 @@
29
29
  "@angular/core": "16 - 19",
30
30
  "@angular/platform-browser": "16 - 19",
31
31
  "@progress/kendo-licensing": "^1.5.0",
32
- "@progress/kendo-angular-common": "19.0.0-develop.1",
33
- "@progress/kendo-angular-l10n": "19.0.0-develop.1",
32
+ "@progress/kendo-angular-common": "19.0.0-develop.11",
33
+ "@progress/kendo-angular-l10n": "19.0.0-develop.11",
34
34
  "rxjs": "^6.5.3 || ^7.0.0"
35
35
  },
36
36
  "dependencies": {
37
37
  "tslib": "^2.3.1",
38
- "@progress/kendo-angular-schematics": "19.0.0-develop.1",
38
+ "@progress/kendo-angular-schematics": "19.0.0-develop.11",
39
39
  "@progress/kendo-draggable": "^3.0.2"
40
40
  },
41
41
  "schematics": "./schematics/collection.json",
@@ -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 { QueryList, TemplateRef, ElementRef, EventEmitter, OnInit, OnDestroy, AfterViewChecked, AfterContentInit, NgZone, ChangeDetectorRef, SimpleChanges, OnChanges, Renderer2, AfterViewInit } from '@angular/core';
5
+ import { QueryList, TemplateRef, ElementRef, EventEmitter, OnInit, OnDestroy, AfterViewChecked, AfterContentInit, NgZone, ChangeDetectorRef, SimpleChanges, OnChanges, Renderer2, AfterViewInit, TrackByFunction } from '@angular/core';
6
6
  import { Subject } from 'rxjs';
7
7
  import { LocalizationService } from '@progress/kendo-angular-l10n';
8
8
  import { SortableService } from './sortable.service';
@@ -20,10 +20,15 @@ export declare class SortableComponent implements OnInit, OnDestroy, OnChanges,
20
20
  private renderer;
21
21
  private changeDetector;
22
22
  private localization;
23
+ private cdr;
23
24
  /**
24
25
  * Specifies the tab index of the Sortable component.
25
26
  */
26
27
  tabIndex: number;
28
+ /**
29
+ * Configures how the Sortable component will track changes in its items collection.
30
+ */
31
+ trackBy: TrackByFunction<any>;
27
32
  /**
28
33
  * Sets an array of any data that is used as a data source for the Sortable.
29
34
  */
@@ -266,7 +271,7 @@ export declare class SortableComponent implements OnInit, OnDestroy, OnChanges,
266
271
  * @hidden
267
272
  */
268
273
  itemTemplate(index: number): TemplateRef<any>;
269
- constructor(ngZone: NgZone, renderer: Renderer2, changeDetector: ChangeDetectorRef, localization: LocalizationService, wrapper: ElementRef, sortableService: SortableService);
274
+ constructor(ngZone: NgZone, renderer: Renderer2, changeDetector: ChangeDetectorRef, localization: LocalizationService, wrapper: ElementRef, sortableService: SortableService, cdr: ChangeDetectorRef);
270
275
  ngOnInit(): void;
271
276
  ngAfterViewInit(): void;
272
277
  ngOnChanges(changes: SimpleChanges): void;
@@ -356,11 +361,11 @@ export declare class SortableComponent implements OnInit, OnDestroy, OnChanges,
356
361
  /**
357
362
  * @hidden
358
363
  */
359
- onEscapeHandler(): void;
364
+ onEscapeHandler(event: KeyboardEvent): void;
360
365
  /**
361
366
  * @hidden
362
367
  */
363
- keydownHandler(event: any): void;
368
+ keydownHandler: (event: KeyboardEvent) => void;
364
369
  /**
365
370
  * Removes the currently active item from the Data collection that the Sortable uses.
366
371
  */
@@ -433,5 +438,5 @@ export declare class SortableComponent implements OnInit, OnDestroy, OnChanges,
433
438
  private placeHolderItemData;
434
439
  private fixFocus;
435
440
  static ɵfac: i0.ɵɵFactoryDeclaration<SortableComponent, never>;
436
- static ɵcmp: i0.ɵɵComponentDeclaration<SortableComponent, "kendo-sortable", ["kendoSortable"], { "tabIndex": { "alias": "tabIndex"; "required": false; }; "data": { "alias": "data"; "required": false; }; "navigable": { "alias": "navigable"; "required": false; }; "navigatable": { "alias": "navigatable"; "required": false; }; "animation": { "alias": "animation"; "required": false; }; "disabledIndexes": { "alias": "disabledIndexes"; "required": false; }; "zone": { "alias": "zone"; "required": false; }; "acceptZones": { "alias": "acceptZones"; "required": false; }; "itemStyle": { "alias": "itemStyle"; "required": false; }; "emptyItemStyle": { "alias": "emptyItemStyle"; "required": false; }; "activeItemStyle": { "alias": "activeItemStyle"; "required": false; }; "disabledItemStyle": { "alias": "disabledItemStyle"; "required": false; }; "itemClass": { "alias": "itemClass"; "required": false; }; "activeItemClass": { "alias": "activeItemClass"; "required": false; }; "emptyItemClass": { "alias": "emptyItemClass"; "required": false; }; "disabledItemClass": { "alias": "disabledItemClass"; "required": false; }; "emptyText": { "alias": "emptyText"; "required": false; }; "activeIndex": { "alias": "activeIndex"; "required": false; }; }, { "dragStart": "dragStart"; "dragEnd": "dragEnd"; "dragOver": "dragOver"; "dragLeave": "dragLeave"; "dataMove": "dataMove"; "dataAdd": "dataAdd"; "dataRemove": "dataRemove"; "navigate": "navigate"; }, ["defaultTemplateRef", "itemTemplateDirectiveRef", "placeholderTemplateDirectiveRef"], never, true, never>;
441
+ static ɵcmp: i0.ɵɵComponentDeclaration<SortableComponent, "kendo-sortable", ["kendoSortable"], { "tabIndex": { "alias": "tabIndex"; "required": false; }; "trackBy": { "alias": "trackBy"; "required": false; }; "data": { "alias": "data"; "required": false; }; "navigable": { "alias": "navigable"; "required": false; }; "navigatable": { "alias": "navigatable"; "required": false; }; "animation": { "alias": "animation"; "required": false; }; "disabledIndexes": { "alias": "disabledIndexes"; "required": false; }; "zone": { "alias": "zone"; "required": false; }; "acceptZones": { "alias": "acceptZones"; "required": false; }; "itemStyle": { "alias": "itemStyle"; "required": false; }; "emptyItemStyle": { "alias": "emptyItemStyle"; "required": false; }; "activeItemStyle": { "alias": "activeItemStyle"; "required": false; }; "disabledItemStyle": { "alias": "disabledItemStyle"; "required": false; }; "itemClass": { "alias": "itemClass"; "required": false; }; "activeItemClass": { "alias": "activeItemClass"; "required": false; }; "emptyItemClass": { "alias": "emptyItemClass"; "required": false; }; "disabledItemClass": { "alias": "disabledItemClass"; "required": false; }; "emptyText": { "alias": "emptyText"; "required": false; }; "activeIndex": { "alias": "activeIndex"; "required": false; }; }, { "dragStart": "dragStart"; "dragEnd": "dragEnd"; "dragOver": "dragOver"; "dragLeave": "dragLeave"; "dataMove": "dataMove"; "dataAdd": "dataAdd"; "dataRemove": "dataRemove"; "navigate": "navigate"; }, ["defaultTemplateRef", "itemTemplateDirectiveRef", "placeholderTemplateDirectiveRef"], never, true, never>;
437
442
  }
package/util.d.ts CHANGED
@@ -2,6 +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
+ /**
6
+ * @hidden
7
+ */
8
+ export declare const MINIMAL_DRAG_DISTANCE = 5;
5
9
  /**
6
10
  * @hidden
7
11
  */