@progress/kendo-angular-utils 17.1.2-develop.1 → 17.1.2-develop.3

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.
@@ -12,6 +12,7 @@ export declare class DragHandleDirective {
12
12
  element: ElementRef;
13
13
  constructor(element: ElementRef);
14
14
  cursorStyle: string;
15
+ touchActionStyle: string;
15
16
  static ɵfac: i0.ɵɵFactoryDeclaration<DragHandleDirective, never>;
16
17
  static ɵdir: i0.ɵɵDirectiveDeclaration<DragHandleDirective, "[kendoDragHandle]", ["kendoDragHandle"], {}, {}, never, never, true, never>;
17
18
  }
@@ -2,7 +2,7 @@
2
2
  * Copyright © 2024 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 { AfterViewInit, ChangeDetectorRef, ElementRef, EventEmitter, NgZone, Renderer2, ViewContainerRef } from '@angular/core';
5
+ import { AfterViewInit, ChangeDetectorRef, ElementRef, EventEmitter, NgZone, OnDestroy, Renderer2, ViewContainerRef } from '@angular/core';
6
6
  import { DragStateService } from './drag-state.service';
7
7
  import { DragMode, DragTargetDataFn, HintSettings } from './models';
8
8
  import { DragTargetIdFn } from './models/functions';
@@ -19,7 +19,7 @@ import * as i0 from "@angular/core";
19
19
  * </ul>
20
20
  * ```
21
21
  */
22
- export declare class DragTargetContainerDirective implements AfterViewInit {
22
+ export declare class DragTargetContainerDirective implements AfterViewInit, OnDestroy {
23
23
  wrapper: ElementRef;
24
24
  ngZone: NgZone;
25
25
  private renderer;
@@ -108,10 +108,6 @@ export declare class DragTargetContainerDirective implements AfterViewInit {
108
108
  * Used for notifying the DragTargetContainer that its content has changed.
109
109
  */
110
110
  notify(): void;
111
- private pointerDownSubscription;
112
- private pointerMoveSubscription;
113
- private pointerUpSubscription;
114
- private scrollSubscription;
115
111
  private currentDragTarget;
116
112
  private dragTimeout;
117
113
  private pressed;
@@ -128,14 +124,19 @@ export declare class DragTargetContainerDirective implements AfterViewInit {
128
124
  private _dragDisabled;
129
125
  private _dragData;
130
126
  private _dragTargetId;
127
+ private prevUserSelect;
131
128
  private get allDragTargets();
132
129
  private get dragHandles();
133
130
  private get hintTemplate();
134
131
  constructor(wrapper: ElementRef, ngZone: NgZone, renderer: Renderer2, service: DragStateService, viewContainer: ViewContainerRef, cdr: ChangeDetectorRef);
135
132
  ngAfterViewInit(): void;
133
+ ngOnDestroy(): void;
136
134
  private onPointerDown;
135
+ private onTouchStart;
137
136
  private onPointerMove;
137
+ private onTouchMove;
138
138
  private onPointerUp;
139
+ private onContextMenu;
139
140
  private handlePress;
140
141
  private handleDragStart;
141
142
  private handleDrag;
@@ -143,7 +144,8 @@ export declare class DragTargetContainerDirective implements AfterViewInit {
143
144
  private handleDragEnd;
144
145
  private get nativeElement();
145
146
  private get hintElem();
146
- private unsubscribe;
147
+ private removeListeners;
148
+ private get supportPointerEvent();
147
149
  private subscribe;
148
150
  private emitZoneAwareEvent;
149
151
  private createHint;
@@ -154,7 +156,7 @@ export declare class DragTargetContainerDirective implements AfterViewInit {
154
156
  private initializeDragTargets;
155
157
  private isDragHandle;
156
158
  private get isHandleSelectorValid();
157
- private setCursorStyle;
159
+ private setTargetStyles;
158
160
  private queryHost;
159
161
  private clearPreviousTargets;
160
162
  private performDrag;
@@ -20,6 +20,7 @@ export declare class DragTargetDirective implements OnInit, AfterContentInit, On
20
20
  private ngZone;
21
21
  private service;
22
22
  private viewContainer;
23
+ get touchActionStyle(): string;
23
24
  /**
24
25
  * Defines whether a hint will be used for dragging. By default, the hint is a copy of the drag target. ([see example]({% slug drag_hint %})).
25
26
  *
@@ -90,7 +91,6 @@ export declare class DragTargetDirective implements OnInit, AfterContentInit, On
90
91
  */
91
92
  onDragEnd: EventEmitter<DragTargetDragEndEvent>;
92
93
  private dragTarget;
93
- private domSubscriptions;
94
94
  private hintComponent;
95
95
  private dragStarted;
96
96
  private pressed;
@@ -100,12 +100,16 @@ export declare class DragTargetDirective implements OnInit, AfterContentInit, On
100
100
  private scrollableParent;
101
101
  private defaultHint;
102
102
  private _dragData;
103
+ private prevUserSelect;
103
104
  private get hintTemplate();
104
105
  private get nativeElement();
105
106
  private get hintElem();
106
107
  private onPointerDown;
108
+ private onTouchStart;
107
109
  private onPointerMove;
110
+ private onTouchMove;
108
111
  private onPointerUp;
112
+ private onContextMenu;
109
113
  dragHandles: QueryList<DragHandleDirective>;
110
114
  constructor(element: ElementRef, renderer: Renderer2, ngZone: NgZone, service: DragStateService, viewContainer: ViewContainerRef);
111
115
  ngOnInit(): void;
@@ -117,6 +121,8 @@ export declare class DragTargetDirective implements OnInit, AfterContentInit, On
117
121
  private handleRelease;
118
122
  private handleDragEnd;
119
123
  private initializeDragTarget;
124
+ private get supportPointerEvent();
125
+ private removeListeners;
120
126
  private attachDomHandlers;
121
127
  private isDragHandle;
122
128
  private getAutoScrollContainer;
@@ -31,12 +31,4 @@ export declare const setElementStyles: (renderer: Renderer2, elem: HTMLElement,
31
31
  /**
32
32
  * @hidden
33
33
  */
34
- export declare const allPointerDownEvents: string[];
35
- /**
36
- * @hidden
37
- */
38
- export declare const allPointerMoveEvents: string[];
39
- /**
40
- * @hidden
41
- */
42
- export declare const allPointerUpEvents: string[];
34
+ export declare const noop: () => void;
@@ -14,8 +14,9 @@ export class DragHandleDirective {
14
14
  this.element = element;
15
15
  }
16
16
  cursorStyle = 'move';
17
+ touchActionStyle = 'none';
17
18
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragHandleDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
18
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragHandleDirective, isStandalone: true, selector: "[kendoDragHandle]", host: { properties: { "style.cursor": "this.cursorStyle" } }, exportAs: ["kendoDragHandle"], ngImport: i0 });
19
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragHandleDirective, isStandalone: true, selector: "[kendoDragHandle]", host: { properties: { "style.cursor": "this.cursorStyle", "style.touch-action": "this.touchActionStyle" } }, exportAs: ["kendoDragHandle"], ngImport: i0 });
19
20
  }
20
21
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragHandleDirective, decorators: [{
21
22
  type: Directive,
@@ -27,4 +28,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
27
28
  }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { cursorStyle: [{
28
29
  type: HostBinding,
29
30
  args: ['style.cursor']
31
+ }], touchActionStyle: [{
32
+ type: HostBinding,
33
+ args: ['style.touch-action']
30
34
  }] } });
@@ -4,10 +4,8 @@
4
4
  *-------------------------------------------------------------------------------------------*/
5
5
  import { ChangeDetectorRef, Directive, ElementRef, EventEmitter, Input, isDevMode, NgZone, Output, Renderer2, ViewContainerRef } from '@angular/core';
6
6
  import { validatePackage } from '@progress/kendo-licensing';
7
- import { fromEvent, merge } from 'rxjs';
8
7
  import { packageMetadata } from '../package-metadata';
9
- import { filter } from 'rxjs/operators';
10
- import { closestBySelector, allPointerDownEvents, allPointerMoveEvents, allPointerUpEvents, getAction, isPresent, setElementStyles, dragTargetTransition } from './util';
8
+ import { closestBySelector, getAction, isPresent, setElementStyles, dragTargetTransition, noop } from './util';
11
9
  import { getScrollableParent } from '@progress/kendo-draggable-common';
12
10
  import { DragStateService } from './drag-state.service';
13
11
  import { contains, isDocumentAvailable, parseCSSClassNames } from '@progress/kendo-angular-common';
@@ -106,7 +104,7 @@ export class DragTargetContainerDirective {
106
104
  this._dragDisabled = value;
107
105
  if (value) {
108
106
  this.clearPreviousTargets();
109
- this.unsubscribe();
107
+ this.removeListeners();
110
108
  if (isPresent(this.hintElem)) {
111
109
  this.destroyHint();
112
110
  }
@@ -158,10 +156,6 @@ export class DragTargetContainerDirective {
158
156
  this.cdr.detectChanges();
159
157
  this.initializeDragTargets();
160
158
  }
161
- pointerDownSubscription;
162
- pointerMoveSubscription;
163
- pointerUpSubscription;
164
- scrollSubscription;
165
159
  currentDragTarget = null;
166
160
  dragTimeout = null;
167
161
  pressed = false;
@@ -178,6 +172,7 @@ export class DragTargetContainerDirective {
178
172
  _dragDisabled = false;
179
173
  _dragData = () => null;
180
174
  _dragTargetId = () => null;
175
+ prevUserSelect;
181
176
  get allDragTargets() {
182
177
  return this.queryHost(this.dragTargetFilter);
183
178
  }
@@ -203,26 +198,53 @@ export class DragTargetContainerDirective {
203
198
  }
204
199
  !this.dragDisabled && this.initializeDragTargets();
205
200
  }
201
+ ngOnDestroy() {
202
+ this.removeListeners();
203
+ }
206
204
  onPointerDown(event) {
205
+ const filterElement = closestBySelector(event.target, this.isHandleSelectorValid ? this.dragHandle : this.dragTargetFilter);
206
+ if (this.dragTargetFilter === '' || !isPresent(filterElement)) {
207
+ return;
208
+ }
209
+ if (isPresent(this.dragHandles) && !this.isDragHandle(event.target)) {
210
+ return;
211
+ }
212
+ const action = getAction(event, this.currentDragTarget);
213
+ this.service.handleDragAndDrop(action);
214
+ this.subscribe();
215
+ }
216
+ onTouchStart(event) {
217
+ const filterElement = closestBySelector(event.target, this.isHandleSelectorValid ? this.dragHandle : this.dragTargetFilter);
218
+ if (this.dragTargetFilter === '' || !isPresent(filterElement)) {
219
+ return;
220
+ }
207
221
  if (isPresent(this.dragHandles) && !this.isDragHandle(event.target)) {
208
222
  return;
209
223
  }
224
+ event.preventDefault();
210
225
  const action = getAction(event, this.currentDragTarget);
211
226
  this.service.handleDragAndDrop(action);
212
227
  this.subscribe();
213
228
  }
214
229
  onPointerMove(event) {
230
+ const action = getAction(event, this.currentDragTarget);
231
+ this.service.handleDragAndDrop(action);
232
+ }
233
+ onTouchMove(event) {
215
234
  event.preventDefault();
216
235
  const action = getAction(event, this.currentDragTarget);
217
236
  this.service.handleDragAndDrop(action);
218
237
  }
219
238
  onPointerUp(event) {
239
+ const action = getAction(event, this.currentDragTarget);
240
+ this.service.handleDragAndDrop(action);
241
+ this.subscribe();
242
+ }
243
+ onContextMenu(event) {
220
244
  event.preventDefault();
221
245
  const action = getAction(event, this.currentDragTarget);
222
246
  this.service.handleDragAndDrop(action);
223
- this.ngZone.runOutsideAngular(() => {
224
- this.subscribe();
225
- });
247
+ this.subscribe();
226
248
  }
227
249
  handlePress(event) {
228
250
  if (this.dragDelay > 0) {
@@ -234,12 +256,13 @@ export class DragTargetContainerDirective {
234
256
  else {
235
257
  this.pressed = true;
236
258
  }
237
- event.originalEvent.preventDefault();
238
259
  const eventTarget = event.originalEvent.target;
239
260
  this.currentDragTargetElement = closestBySelector(eventTarget, this.dragTargetFilter);
240
261
  this.currentDragTarget.element = this.currentDragTargetElement;
241
262
  this.service.dragIndex = this.getDragIndex();
242
263
  this.scrollableParent = this.hintTemplate ? document.body : this.currentDragTargetElement ? getScrollableParent(this.currentDragTargetElement) : null;
264
+ this.prevUserSelect = this.currentDragTargetElement.style.userSelect;
265
+ this.renderer.setStyle(this.currentDragTargetElement, 'user-select', 'none');
243
266
  this.emitZoneAwareEvent('onPress', event);
244
267
  }
245
268
  handleDragStart(event) {
@@ -302,8 +325,11 @@ export class DragTargetContainerDirective {
302
325
  if (this.dragTimeout) {
303
326
  clearTimeout(this.dragTimeout);
304
327
  this.dragTimeout = null;
305
- this.pressed = false;
306
328
  }
329
+ this.pressed = false;
330
+ this.prevUserSelect ? this.renderer.setStyle(this.currentDragTargetElement, 'user-select', this.prevUserSelect) :
331
+ this.renderer.removeStyle(this.currentDragTargetElement, 'user-select');
332
+ this.prevUserSelect = null;
307
333
  this.emitZoneAwareEvent('onRelease', event);
308
334
  }
309
335
  handleDragEnd(event) {
@@ -342,50 +368,63 @@ export class DragTargetContainerDirective {
342
368
  get hintElem() {
343
369
  return this.hintTemplate && isPresent(this.hintComponent) ? this.hintComponent.instance.element.nativeElement : this.defaultHint;
344
370
  }
345
- unsubscribe() {
346
- if (this.pointerDownSubscription) {
347
- this.pointerDownSubscription.unsubscribe();
348
- }
349
- if (this.pointerMoveSubscription) {
350
- this.pointerMoveSubscription.unsubscribe();
351
- }
352
- if (this.pointerUpSubscription) {
353
- this.pointerUpSubscription.unsubscribe();
354
- }
355
- if (this.scrollSubscription) {
356
- this.scrollSubscription.unsubscribe();
357
- }
371
+ removeListeners() {
372
+ if (isPresent(this.scrollableParent)) {
373
+ this.scrollableParent.removeEventListener('scroll', this.onPointerMove);
374
+ }
375
+ const element = this.nativeElement;
376
+ document.removeEventListener('pointermove', this.onPointerMove);
377
+ document.removeEventListener('pointerup', this.onPointerUp, true);
378
+ document.removeEventListener('pointercancel', this.onPointerUp);
379
+ document.removeEventListener('contextmenu', this.onContextMenu);
380
+ window.removeEventListener('touchmove', noop);
381
+ element.removeEventListener('touchmove', this.onTouchMove);
382
+ element.removeEventListener('touchend', this.onPointerUp);
383
+ document.removeEventListener('mousemove', this.onPointerMove);
384
+ document.removeEventListener('mouseup', this.onPointerUp);
385
+ document.removeEventListener('touchcancel', this.onPointerUp);
386
+ element.removeEventListener('pointerdown', this.onPointerDown);
387
+ element.removeEventListener('mousedown', this.onPointerDown);
388
+ element.removeEventListener('touchstart', this.onTouchStart);
389
+ }
390
+ get supportPointerEvent() {
391
+ return Boolean(typeof window !== 'undefined' && window.PointerEvent);
358
392
  }
359
393
  subscribe() {
360
394
  this.ngZone.runOutsideAngular(() => {
361
- this.unsubscribe();
395
+ this.removeListeners();
362
396
  if (!(isDocumentAvailable() && isPresent(this.wrapper))) {
363
397
  return;
364
398
  }
399
+ this.onPointerMove = this.onPointerMove.bind(this);
400
+ this.onPointerUp = this.onPointerUp.bind(this);
401
+ this.onTouchMove = this.onTouchMove.bind(this);
402
+ this.onContextMenu = this.onContextMenu.bind(this);
403
+ this.onPointerDown = this.onPointerDown.bind(this);
404
+ this.onTouchStart = this.onTouchStart.bind(this);
365
405
  const element = this.nativeElement;
366
- if (this.service.pressed) {
367
- const pointerMoveStreams = allPointerMoveEvents.map((ev) => fromEvent(document, ev));
368
- const pointerUpStreams = allPointerUpEvents.map((ev) => fromEvent(document, ev));
369
- this.pointerMoveSubscription = merge(...pointerMoveStreams)
370
- .pipe(filter(() => this.dragTargetFilter !== ''))
371
- .subscribe(e => this.onPointerMove(e));
372
- this.pointerUpSubscription = merge(...pointerUpStreams)
373
- .subscribe(e => this.onPointerUp(e));
406
+ if (this.supportPointerEvent) {
374
407
  if (isPresent(this.scrollableParent)) {
375
- this.scrollSubscription = fromEvent(this.scrollableParent, 'scroll')
376
- .subscribe(e => this.onPointerMove(e));
408
+ this.scrollableParent.addEventListener('scroll', this.onPointerMove, { passive: true });
409
+ }
410
+ element.addEventListener('pointerdown', this.onPointerDown, { passive: true });
411
+ if (this.pressed) {
412
+ document.addEventListener('pointermove', this.onPointerMove);
413
+ document.addEventListener('pointerup', this.onPointerUp, true);
414
+ document.addEventListener('contextmenu', this.onContextMenu);
415
+ document.addEventListener('pointercancel', this.onPointerUp, { passive: true });
377
416
  }
378
417
  }
379
418
  else {
380
- const pointerDownStreams = allPointerDownEvents.map((ev) => fromEvent(element, ev));
381
- this.pointerDownSubscription = merge(...pointerDownStreams)
382
- .pipe(filter(() => this.dragTargetFilter !== ''))
383
- .subscribe((e) => {
384
- const filterElement = closestBySelector(e.target, this.isHandleSelectorValid ? this.dragHandle : this.dragTargetFilter);
385
- if (filterElement) {
386
- this.onPointerDown(e);
387
- }
388
- });
419
+ window.addEventListener('touchmove', noop, { capture: false, passive: false });
420
+ element.addEventListener('mousedown', this.onPointerDown, { passive: true });
421
+ element.addEventListener('touchstart', this.onTouchStart, { passive: true });
422
+ if (this.pressed) {
423
+ document.addEventListener('mousemove', this.onPointerMove, { passive: true });
424
+ document.addEventListener('mouseup', this.onPointerUp, { passive: true });
425
+ element.addEventListener('touchmove', this.onTouchMove, { passive: true });
426
+ element.addEventListener('touchend', this.onPointerUp, { passive: true });
427
+ }
389
428
  }
390
429
  });
391
430
  }
@@ -529,7 +568,7 @@ export class DragTargetContainerDirective {
529
568
  onDrag: this.handleDrag.bind(this),
530
569
  onDragEnd: this.handleDragEnd.bind(this)
531
570
  };
532
- this.setCursorStyle();
571
+ this.setTargetStyles();
533
572
  }
534
573
  isDragHandle(el) {
535
574
  return this.dragHandles.some(dh => contains(dh, el, true));
@@ -537,7 +576,7 @@ export class DragTargetContainerDirective {
537
576
  get isHandleSelectorValid() {
538
577
  return isPresent(this.dragHandle) && this.dragHandle !== '';
539
578
  }
540
- setCursorStyle() {
579
+ setTargetStyles() {
541
580
  if (!isDocumentAvailable()) {
542
581
  return;
543
582
  }
@@ -545,12 +584,14 @@ export class DragTargetContainerDirective {
545
584
  if (isPresent(this.dragHandles) && this.dragHandles.length > 0) {
546
585
  this.dragHandles.forEach(handle => {
547
586
  this.renderer.setStyle(handle, 'cursor', 'move');
587
+ this.renderer.setStyle(handle, 'touch-action', 'none');
548
588
  });
549
589
  }
550
590
  }
551
591
  else {
552
592
  this.allDragTargets.forEach(target => {
553
593
  this.renderer.setStyle(target, 'cursor', 'move');
594
+ this.renderer.setStyle(target, 'touch-action', 'none');
554
595
  });
555
596
  }
556
597
  }
@@ -2,13 +2,13 @@
2
2
  * Copyright © 2024 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, EventEmitter, Output, ElementRef, Renderer2, NgZone, Input, ContentChildren, QueryList, ViewContainerRef, isDevMode } from "@angular/core";
5
+ import { Directive, EventEmitter, Output, ElementRef, Renderer2, NgZone, Input, ContentChildren, QueryList, ViewContainerRef, isDevMode, HostBinding } from "@angular/core";
6
6
  import { validatePackage } from '@progress/kendo-licensing';
7
7
  import { packageMetadata } from '../package-metadata';
8
8
  import { DragHandleDirective } from "./draghandle.directive";
9
9
  import { getScrollableParent } from "@progress/kendo-draggable-common";
10
10
  import { DragStateService } from "./drag-state.service";
11
- import { getAction, isPresent, setElementStyles, dragTargetTransition } from './util';
11
+ import { getAction, isPresent, setElementStyles, dragTargetTransition, noop } from './util';
12
12
  import { contains, isDocumentAvailable, parseCSSClassNames } from "@progress/kendo-angular-common";
13
13
  import { HintComponent } from "./hint.component";
14
14
  import { DragTargetDragEndEvent, DragTargetDragEvent, DragTargetDragStartEvent, DragTargetPressEvent } from "./events/drag-target";
@@ -27,6 +27,9 @@ export class DragTargetDirective {
27
27
  ngZone;
28
28
  service;
29
29
  viewContainer;
30
+ get touchActionStyle() {
31
+ return this.dragHandles.length > 0 ? null : 'none';
32
+ }
30
33
  /**
31
34
  * Defines whether a hint will be used for dragging. By default, the hint is a copy of the drag target. ([see example]({% slug drag_hint %})).
32
35
  *
@@ -104,7 +107,6 @@ export class DragTargetDirective {
104
107
  */
105
108
  onDragEnd = new EventEmitter();
106
109
  dragTarget = null;
107
- domSubscriptions = [];
108
110
  hintComponent = null;
109
111
  dragStarted = false;
110
112
  pressed = false;
@@ -114,6 +116,7 @@ export class DragTargetDirective {
114
116
  scrollableParent = null;
115
117
  defaultHint = null;
116
118
  _dragData = () => null;
119
+ prevUserSelect;
117
120
  get hintTemplate() {
118
121
  return isPresent(this.hint) && typeof this.hint === 'object' ? this.hint.hintTemplate : null;
119
122
  }
@@ -124,6 +127,17 @@ export class DragTargetDirective {
124
127
  return this.hintTemplate && isPresent(this.hintComponent) ? this.hintComponent.instance.element.nativeElement : this.defaultHint;
125
128
  }
126
129
  onPointerDown(event) {
130
+ if (this.dragHandles.length && !this.isDragHandle(event.target)) {
131
+ return;
132
+ }
133
+ const action = getAction(event, this.dragTarget);
134
+ this.service.handleDragAndDrop(action);
135
+ this.service.autoScroll = typeof this.autoScroll === 'object' ? this.autoScroll.enabled !== false : this.autoScroll;
136
+ this.service.scrollableParent = this.getAutoScrollContainer();
137
+ this.service.autoScrollDirection = typeof this.autoScroll === 'object' ? this.autoScroll.direction : { horizontal: true, vertical: true };
138
+ this.attachDomHandlers();
139
+ }
140
+ onTouchStart(event) {
127
141
  if (this.dragHandles.length && !this.isDragHandle(event.target)) {
128
142
  return;
129
143
  }
@@ -136,11 +150,20 @@ export class DragTargetDirective {
136
150
  this.attachDomHandlers();
137
151
  }
138
152
  onPointerMove(event) {
153
+ const action = getAction(event, this.dragTarget);
154
+ this.service.handleDragAndDrop(action);
155
+ }
156
+ onTouchMove(event) {
139
157
  event.preventDefault();
140
158
  const action = getAction(event, this.dragTarget);
141
159
  this.service.handleDragAndDrop(action);
142
160
  }
143
161
  onPointerUp(event) {
162
+ const action = getAction(event, this.dragTarget);
163
+ this.service.handleDragAndDrop(action);
164
+ this.attachDomHandlers();
165
+ }
166
+ onContextMenu(event) {
144
167
  event.preventDefault();
145
168
  const action = getAction(event, this.dragTarget);
146
169
  this.service.handleDragAndDrop(action);
@@ -168,7 +191,7 @@ export class DragTargetDirective {
168
191
  this.service.dragTargets.push(this.dragTarget);
169
192
  }
170
193
  ngOnDestroy() {
171
- this.domSubscriptions.forEach(subscription => subscription());
194
+ this.removeListeners();
172
195
  const currentDragTargetIndex = this.service.dragTargets.indexOf(this.dragTarget);
173
196
  this.service.dragTargets.splice(currentDragTargetIndex, 1);
174
197
  }
@@ -183,6 +206,8 @@ export class DragTargetDirective {
183
206
  this.pressed = true;
184
207
  }
185
208
  this.scrollableParent = this.dragTarget.element ? getScrollableParent(this.dragTarget.element) : null;
209
+ this.prevUserSelect = this.dragTarget.element.style.userSelect;
210
+ this.renderer.setStyle(this.dragTarget.element, 'user-select', 'none');
186
211
  this.emitZoneAwareEvent('onPress', event);
187
212
  }
188
213
  handleDragStart(event) {
@@ -240,8 +265,11 @@ export class DragTargetDirective {
240
265
  if (this.dragTimeout) {
241
266
  clearTimeout(this.dragTimeout);
242
267
  this.dragTimeout = null;
243
- this.pressed = false;
244
268
  }
269
+ this.pressed = false;
270
+ this.prevUserSelect ? this.renderer.setStyle(this.dragTarget.element, 'user-select', this.prevUserSelect) :
271
+ this.renderer.removeStyle(this.dragTarget.element, 'user-select');
272
+ this.prevUserSelect = null;
245
273
  this.emitZoneAwareEvent('onRelease', event);
246
274
  }
247
275
  handleDragEnd(event) {
@@ -281,43 +309,66 @@ export class DragTargetDirective {
281
309
  onDragEnd: this.handleDragEnd.bind(this)
282
310
  };
283
311
  }
312
+ get supportPointerEvent() {
313
+ return Boolean(typeof window !== 'undefined' && window.PointerEvent);
314
+ }
315
+ removeListeners() {
316
+ if (isPresent(this.scrollableParent)) {
317
+ this.scrollableParent.removeEventListener('scroll', this.onPointerMove);
318
+ }
319
+ const element = this.nativeElement;
320
+ document.removeEventListener('pointermove', this.onPointerMove);
321
+ document.removeEventListener('pointerup', this.onPointerUp, true);
322
+ document.removeEventListener('contextmenu', this.onContextMenu);
323
+ document.removeEventListener('pointercancel', this.onPointerUp);
324
+ window.removeEventListener('touchmove', noop);
325
+ element.removeEventListener('touchmove', this.onTouchMove);
326
+ element.removeEventListener('touchend', this.onPointerUp);
327
+ document.removeEventListener('mousemove', this.onPointerMove);
328
+ document.removeEventListener('mouseup', this.onPointerUp);
329
+ document.removeEventListener('touchcancel', this.onPointerUp);
330
+ element.removeEventListener('pointerdown', this.onPointerDown);
331
+ element.removeEventListener('mousedown', this.onPointerDown);
332
+ element.removeEventListener('touchstart', this.onTouchStart);
333
+ }
284
334
  attachDomHandlers() {
285
335
  this.ngZone.runOutsideAngular(() => {
286
- if (this.domSubscriptions.length > 0) {
287
- this.domSubscriptions.forEach(subscription => subscription());
288
- }
336
+ this.removeListeners();
289
337
  if (!(isDocumentAvailable() && isPresent(this.element))) {
290
338
  return;
291
339
  }
292
- if (this.service.pressed) {
293
- this.onPointerMove = this.onPointerMove.bind(this);
294
- this.onPointerUp = this.onPointerUp.bind(this);
295
- this.domSubscriptions = [
296
- this.renderer.listen(document, 'pointermove', this.onPointerMove),
297
- this.renderer.listen(document, 'mousemove', this.onPointerMove),
298
- this.renderer.listen(document, 'touchmove', this.onPointerMove),
299
- this.renderer.listen(document, 'pointerup', this.onPointerUp),
300
- this.renderer.listen(document, 'pointercancel', this.onPointerUp),
301
- this.renderer.listen(document, 'mouseup', this.onPointerUp),
302
- this.renderer.listen(document, 'contextmenu', this.onPointerUp),
303
- this.renderer.listen(document, 'touchend', this.onPointerUp),
304
- this.renderer.listen(document, 'touchcancel', this.onPointerUp)
305
- ];
340
+ this.onPointerMove = this.onPointerMove.bind(this);
341
+ this.onPointerUp = this.onPointerUp.bind(this);
342
+ this.onTouchMove = this.onTouchMove.bind(this);
343
+ this.onContextMenu = this.onContextMenu.bind(this);
344
+ this.onPointerDown = this.onPointerDown.bind(this);
345
+ this.onTouchStart = this.onTouchStart.bind(this);
346
+ const element = this.nativeElement;
347
+ if (this.supportPointerEvent) {
306
348
  if (isPresent(this.scrollableParent)) {
307
349
  if (this.scrollableParent === document.getElementsByTagName('html')[0]) {
308
350
  this.scrollableParent = window;
309
351
  }
310
- this.domSubscriptions.push(this.renderer.listen(this.scrollableParent, 'scroll', this.onPointerMove));
352
+ this.scrollableParent.addEventListener('scroll', this.onPointerMove, { passive: true });
353
+ }
354
+ element.addEventListener('pointerdown', this.onPointerDown, { passive: true });
355
+ if (this.pressed) {
356
+ document.addEventListener('pointermove', this.onPointerMove);
357
+ document.addEventListener('pointerup', this.onPointerUp, true);
358
+ document.addEventListener('contextmenu', this.onContextMenu);
359
+ document.addEventListener('pointercancel', this.onPointerUp, { passive: true });
311
360
  }
312
361
  }
313
362
  else {
314
- this.onPointerDown = this.onPointerDown.bind(this);
315
- const element = this.nativeElement;
316
- this.domSubscriptions = [
317
- this.renderer.listen(element, 'pointerdown', this.onPointerDown),
318
- this.renderer.listen(element, 'mousedown', this.onPointerDown),
319
- this.renderer.listen(element, 'touchstart', this.onPointerDown)
320
- ];
363
+ window.addEventListener('touchmove', noop, { capture: false, passive: false });
364
+ element.addEventListener('mousedown', this.onPointerDown, { passive: true });
365
+ element.addEventListener('touchstart', this.onTouchStart, { passive: true });
366
+ if (this.pressed) {
367
+ document.addEventListener('mousemove', this.onPointerMove, { passive: true });
368
+ document.addEventListener('mouseup', this.onPointerUp, { passive: true });
369
+ element.addEventListener('touchmove', this.onTouchMove, { passive: true });
370
+ element.addEventListener('touchend', this.onPointerUp, { passive: true });
371
+ }
321
372
  }
322
373
  });
323
374
  }
@@ -477,7 +528,7 @@ export class DragTargetDirective {
477
528
  }
478
529
  }
479
530
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragTargetDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: i1.DragStateService }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
480
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragTargetDirective, isStandalone: true, selector: "[kendoDragTarget]", inputs: { hint: "hint", threshold: "threshold", autoScroll: "autoScroll", dragTargetId: "dragTargetId", dragDelay: "dragDelay", restrictByAxis: "restrictByAxis", mode: "mode", dragData: "dragData" }, outputs: { onPress: "onPress", onDragStart: "onDragStart", onDrag: "onDrag", onDragReady: "onDragReady", onRelease: "onRelease", onDragEnd: "onDragEnd" }, queries: [{ propertyName: "dragHandles", predicate: DragHandleDirective }], exportAs: ["kendoDragTarget"], ngImport: i0 });
531
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragTargetDirective, isStandalone: true, selector: "[kendoDragTarget]", inputs: { hint: "hint", threshold: "threshold", autoScroll: "autoScroll", dragTargetId: "dragTargetId", dragDelay: "dragDelay", restrictByAxis: "restrictByAxis", mode: "mode", dragData: "dragData" }, outputs: { onPress: "onPress", onDragStart: "onDragStart", onDrag: "onDrag", onDragReady: "onDragReady", onRelease: "onRelease", onDragEnd: "onDragEnd" }, host: { properties: { "style.touch-action": "this.touchActionStyle" } }, queries: [{ propertyName: "dragHandles", predicate: DragHandleDirective }], exportAs: ["kendoDragTarget"], ngImport: i0 });
481
532
  }
482
533
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragTargetDirective, decorators: [{
483
534
  type: Directive,
@@ -486,7 +537,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
486
537
  exportAs: 'kendoDragTarget',
487
538
  standalone: true
488
539
  }]
489
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.DragStateService }, { type: i0.ViewContainerRef }]; }, propDecorators: { hint: [{
540
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: i1.DragStateService }, { type: i0.ViewContainerRef }]; }, propDecorators: { touchActionStyle: [{
541
+ type: HostBinding,
542
+ args: ['style.touch-action']
543
+ }], hint: [{
490
544
  type: Input
491
545
  }], threshold: [{
492
546
  type: Input
@@ -107,8 +107,8 @@ export class DropTargetContainerDirective {
107
107
  if (!this.service.dragTargetPresent || this.service.dropTargetPresent) {
108
108
  return;
109
109
  }
110
- const eventTarget = event.originalEvent.target;
111
- const currDropTargetElem = intersect(eventTarget, this.allDropTargets);
110
+ const currDragTargetElement = this.service.dragTarget.hint || this.service.dragTarget.element;
111
+ const currDropTargetElem = intersect(currDragTargetElement, this.allDropTargets);
112
112
  const currDropTarget = this.service.dropTargets.find(dt => dt.element === currDropTargetElem);
113
113
  if (!isPresent(currDropTargetElem) || !isPresent(currDropTarget)) {
114
114
  return;
@@ -87,12 +87,4 @@ export const setElementStyles = (renderer, elem, styles) => {
87
87
  /**
88
88
  * @hidden
89
89
  */
90
- export const allPointerDownEvents = ['pointerdown', 'mousedown', 'touchstart'];
91
- /**
92
- * @hidden
93
- */
94
- export const allPointerMoveEvents = ['pointermove', 'mousemove', 'touchmove'];
95
- /**
96
- * @hidden
97
- */
98
- export const allPointerUpEvents = ['pointerup', 'pointercancel', 'mouseup', 'contextmenu', 'touchend', 'touchcancel'];
90
+ export const noop = () => { };
@@ -9,7 +9,7 @@ export const packageMetadata = {
9
9
  name: '@progress/kendo-angular-utils',
10
10
  productName: 'Kendo UI for Angular',
11
11
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
12
- publishDate: 1733824851,
13
- version: '17.1.2-develop.1',
12
+ publishDate: 1734351362,
13
+ version: '17.1.2-develop.3',
14
14
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
15
15
  };
@@ -5,8 +5,6 @@
5
5
  import * as i0 from '@angular/core';
6
6
  import { Directive, HostBinding, Injectable, Component, Input, isDevMode, EventEmitter, Output, ContentChildren, NgModule } from '@angular/core';
7
7
  import { validatePackage } from '@progress/kendo-licensing';
8
- import { fromEvent, merge } from 'rxjs';
9
- import { filter } from 'rxjs/operators';
10
8
  import { dispatchDragAndDrop, getScrollableParent, autoScroll } from '@progress/kendo-draggable-common';
11
9
  import { PreventableEvent, contains, isDocumentAvailable, parseCSSClassNames } from '@progress/kendo-angular-common';
12
10
  import { NgTemplateOutlet } from '@angular/common';
@@ -21,8 +19,9 @@ class DragHandleDirective {
21
19
  this.element = element;
22
20
  }
23
21
  cursorStyle = 'move';
22
+ touchActionStyle = 'none';
24
23
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragHandleDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
25
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragHandleDirective, isStandalone: true, selector: "[kendoDragHandle]", host: { properties: { "style.cursor": "this.cursorStyle" } }, exportAs: ["kendoDragHandle"], ngImport: i0 });
24
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragHandleDirective, isStandalone: true, selector: "[kendoDragHandle]", host: { properties: { "style.cursor": "this.cursorStyle", "style.touch-action": "this.touchActionStyle" } }, exportAs: ["kendoDragHandle"], ngImport: i0 });
26
25
  }
27
26
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragHandleDirective, decorators: [{
28
27
  type: Directive,
@@ -34,6 +33,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
34
33
  }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { cursorStyle: [{
35
34
  type: HostBinding,
36
35
  args: ['style.cursor']
36
+ }], touchActionStyle: [{
37
+ type: HostBinding,
38
+ args: ['style.touch-action']
37
39
  }] } });
38
40
 
39
41
  /**
@@ -43,8 +45,8 @@ const packageMetadata = {
43
45
  name: '@progress/kendo-angular-utils',
44
46
  productName: 'Kendo UI for Angular',
45
47
  productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
46
- publishDate: 1733824851,
47
- version: '17.1.2-develop.1',
48
+ publishDate: 1734351362,
49
+ version: '17.1.2-develop.3',
48
50
  licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
49
51
  };
50
52
 
@@ -133,15 +135,7 @@ const setElementStyles = (renderer, elem, styles) => {
133
135
  /**
134
136
  * @hidden
135
137
  */
136
- const allPointerDownEvents = ['pointerdown', 'mousedown', 'touchstart'];
137
- /**
138
- * @hidden
139
- */
140
- const allPointerMoveEvents = ['pointermove', 'mousemove', 'touchmove'];
141
- /**
142
- * @hidden
143
- */
144
- const allPointerUpEvents = ['pointerup', 'pointercancel', 'mouseup', 'contextmenu', 'touchend', 'touchcancel'];
138
+ const noop = () => { };
145
139
 
146
140
  /**
147
141
  * @hidden
@@ -653,7 +647,7 @@ class DragTargetContainerDirective {
653
647
  this._dragDisabled = value;
654
648
  if (value) {
655
649
  this.clearPreviousTargets();
656
- this.unsubscribe();
650
+ this.removeListeners();
657
651
  if (isPresent(this.hintElem)) {
658
652
  this.destroyHint();
659
653
  }
@@ -705,10 +699,6 @@ class DragTargetContainerDirective {
705
699
  this.cdr.detectChanges();
706
700
  this.initializeDragTargets();
707
701
  }
708
- pointerDownSubscription;
709
- pointerMoveSubscription;
710
- pointerUpSubscription;
711
- scrollSubscription;
712
702
  currentDragTarget = null;
713
703
  dragTimeout = null;
714
704
  pressed = false;
@@ -725,6 +715,7 @@ class DragTargetContainerDirective {
725
715
  _dragDisabled = false;
726
716
  _dragData = () => null;
727
717
  _dragTargetId = () => null;
718
+ prevUserSelect;
728
719
  get allDragTargets() {
729
720
  return this.queryHost(this.dragTargetFilter);
730
721
  }
@@ -750,7 +741,14 @@ class DragTargetContainerDirective {
750
741
  }
751
742
  !this.dragDisabled && this.initializeDragTargets();
752
743
  }
744
+ ngOnDestroy() {
745
+ this.removeListeners();
746
+ }
753
747
  onPointerDown(event) {
748
+ const filterElement = closestBySelector(event.target, this.isHandleSelectorValid ? this.dragHandle : this.dragTargetFilter);
749
+ if (this.dragTargetFilter === '' || !isPresent(filterElement)) {
750
+ return;
751
+ }
754
752
  if (isPresent(this.dragHandles) && !this.isDragHandle(event.target)) {
755
753
  return;
756
754
  }
@@ -758,18 +756,38 @@ class DragTargetContainerDirective {
758
756
  this.service.handleDragAndDrop(action);
759
757
  this.subscribe();
760
758
  }
759
+ onTouchStart(event) {
760
+ const filterElement = closestBySelector(event.target, this.isHandleSelectorValid ? this.dragHandle : this.dragTargetFilter);
761
+ if (this.dragTargetFilter === '' || !isPresent(filterElement)) {
762
+ return;
763
+ }
764
+ if (isPresent(this.dragHandles) && !this.isDragHandle(event.target)) {
765
+ return;
766
+ }
767
+ event.preventDefault();
768
+ const action = getAction(event, this.currentDragTarget);
769
+ this.service.handleDragAndDrop(action);
770
+ this.subscribe();
771
+ }
761
772
  onPointerMove(event) {
773
+ const action = getAction(event, this.currentDragTarget);
774
+ this.service.handleDragAndDrop(action);
775
+ }
776
+ onTouchMove(event) {
762
777
  event.preventDefault();
763
778
  const action = getAction(event, this.currentDragTarget);
764
779
  this.service.handleDragAndDrop(action);
765
780
  }
766
781
  onPointerUp(event) {
782
+ const action = getAction(event, this.currentDragTarget);
783
+ this.service.handleDragAndDrop(action);
784
+ this.subscribe();
785
+ }
786
+ onContextMenu(event) {
767
787
  event.preventDefault();
768
788
  const action = getAction(event, this.currentDragTarget);
769
789
  this.service.handleDragAndDrop(action);
770
- this.ngZone.runOutsideAngular(() => {
771
- this.subscribe();
772
- });
790
+ this.subscribe();
773
791
  }
774
792
  handlePress(event) {
775
793
  if (this.dragDelay > 0) {
@@ -781,12 +799,13 @@ class DragTargetContainerDirective {
781
799
  else {
782
800
  this.pressed = true;
783
801
  }
784
- event.originalEvent.preventDefault();
785
802
  const eventTarget = event.originalEvent.target;
786
803
  this.currentDragTargetElement = closestBySelector(eventTarget, this.dragTargetFilter);
787
804
  this.currentDragTarget.element = this.currentDragTargetElement;
788
805
  this.service.dragIndex = this.getDragIndex();
789
806
  this.scrollableParent = this.hintTemplate ? document.body : this.currentDragTargetElement ? getScrollableParent(this.currentDragTargetElement) : null;
807
+ this.prevUserSelect = this.currentDragTargetElement.style.userSelect;
808
+ this.renderer.setStyle(this.currentDragTargetElement, 'user-select', 'none');
790
809
  this.emitZoneAwareEvent('onPress', event);
791
810
  }
792
811
  handleDragStart(event) {
@@ -849,8 +868,11 @@ class DragTargetContainerDirective {
849
868
  if (this.dragTimeout) {
850
869
  clearTimeout(this.dragTimeout);
851
870
  this.dragTimeout = null;
852
- this.pressed = false;
853
871
  }
872
+ this.pressed = false;
873
+ this.prevUserSelect ? this.renderer.setStyle(this.currentDragTargetElement, 'user-select', this.prevUserSelect) :
874
+ this.renderer.removeStyle(this.currentDragTargetElement, 'user-select');
875
+ this.prevUserSelect = null;
854
876
  this.emitZoneAwareEvent('onRelease', event);
855
877
  }
856
878
  handleDragEnd(event) {
@@ -889,50 +911,63 @@ class DragTargetContainerDirective {
889
911
  get hintElem() {
890
912
  return this.hintTemplate && isPresent(this.hintComponent) ? this.hintComponent.instance.element.nativeElement : this.defaultHint;
891
913
  }
892
- unsubscribe() {
893
- if (this.pointerDownSubscription) {
894
- this.pointerDownSubscription.unsubscribe();
895
- }
896
- if (this.pointerMoveSubscription) {
897
- this.pointerMoveSubscription.unsubscribe();
898
- }
899
- if (this.pointerUpSubscription) {
900
- this.pointerUpSubscription.unsubscribe();
901
- }
902
- if (this.scrollSubscription) {
903
- this.scrollSubscription.unsubscribe();
904
- }
914
+ removeListeners() {
915
+ if (isPresent(this.scrollableParent)) {
916
+ this.scrollableParent.removeEventListener('scroll', this.onPointerMove);
917
+ }
918
+ const element = this.nativeElement;
919
+ document.removeEventListener('pointermove', this.onPointerMove);
920
+ document.removeEventListener('pointerup', this.onPointerUp, true);
921
+ document.removeEventListener('pointercancel', this.onPointerUp);
922
+ document.removeEventListener('contextmenu', this.onContextMenu);
923
+ window.removeEventListener('touchmove', noop);
924
+ element.removeEventListener('touchmove', this.onTouchMove);
925
+ element.removeEventListener('touchend', this.onPointerUp);
926
+ document.removeEventListener('mousemove', this.onPointerMove);
927
+ document.removeEventListener('mouseup', this.onPointerUp);
928
+ document.removeEventListener('touchcancel', this.onPointerUp);
929
+ element.removeEventListener('pointerdown', this.onPointerDown);
930
+ element.removeEventListener('mousedown', this.onPointerDown);
931
+ element.removeEventListener('touchstart', this.onTouchStart);
932
+ }
933
+ get supportPointerEvent() {
934
+ return Boolean(typeof window !== 'undefined' && window.PointerEvent);
905
935
  }
906
936
  subscribe() {
907
937
  this.ngZone.runOutsideAngular(() => {
908
- this.unsubscribe();
938
+ this.removeListeners();
909
939
  if (!(isDocumentAvailable() && isPresent(this.wrapper))) {
910
940
  return;
911
941
  }
942
+ this.onPointerMove = this.onPointerMove.bind(this);
943
+ this.onPointerUp = this.onPointerUp.bind(this);
944
+ this.onTouchMove = this.onTouchMove.bind(this);
945
+ this.onContextMenu = this.onContextMenu.bind(this);
946
+ this.onPointerDown = this.onPointerDown.bind(this);
947
+ this.onTouchStart = this.onTouchStart.bind(this);
912
948
  const element = this.nativeElement;
913
- if (this.service.pressed) {
914
- const pointerMoveStreams = allPointerMoveEvents.map((ev) => fromEvent(document, ev));
915
- const pointerUpStreams = allPointerUpEvents.map((ev) => fromEvent(document, ev));
916
- this.pointerMoveSubscription = merge(...pointerMoveStreams)
917
- .pipe(filter(() => this.dragTargetFilter !== ''))
918
- .subscribe(e => this.onPointerMove(e));
919
- this.pointerUpSubscription = merge(...pointerUpStreams)
920
- .subscribe(e => this.onPointerUp(e));
949
+ if (this.supportPointerEvent) {
921
950
  if (isPresent(this.scrollableParent)) {
922
- this.scrollSubscription = fromEvent(this.scrollableParent, 'scroll')
923
- .subscribe(e => this.onPointerMove(e));
951
+ this.scrollableParent.addEventListener('scroll', this.onPointerMove, { passive: true });
952
+ }
953
+ element.addEventListener('pointerdown', this.onPointerDown, { passive: true });
954
+ if (this.pressed) {
955
+ document.addEventListener('pointermove', this.onPointerMove);
956
+ document.addEventListener('pointerup', this.onPointerUp, true);
957
+ document.addEventListener('contextmenu', this.onContextMenu);
958
+ document.addEventListener('pointercancel', this.onPointerUp, { passive: true });
924
959
  }
925
960
  }
926
961
  else {
927
- const pointerDownStreams = allPointerDownEvents.map((ev) => fromEvent(element, ev));
928
- this.pointerDownSubscription = merge(...pointerDownStreams)
929
- .pipe(filter(() => this.dragTargetFilter !== ''))
930
- .subscribe((e) => {
931
- const filterElement = closestBySelector(e.target, this.isHandleSelectorValid ? this.dragHandle : this.dragTargetFilter);
932
- if (filterElement) {
933
- this.onPointerDown(e);
934
- }
935
- });
962
+ window.addEventListener('touchmove', noop, { capture: false, passive: false });
963
+ element.addEventListener('mousedown', this.onPointerDown, { passive: true });
964
+ element.addEventListener('touchstart', this.onTouchStart, { passive: true });
965
+ if (this.pressed) {
966
+ document.addEventListener('mousemove', this.onPointerMove, { passive: true });
967
+ document.addEventListener('mouseup', this.onPointerUp, { passive: true });
968
+ element.addEventListener('touchmove', this.onTouchMove, { passive: true });
969
+ element.addEventListener('touchend', this.onPointerUp, { passive: true });
970
+ }
936
971
  }
937
972
  });
938
973
  }
@@ -1076,7 +1111,7 @@ class DragTargetContainerDirective {
1076
1111
  onDrag: this.handleDrag.bind(this),
1077
1112
  onDragEnd: this.handleDragEnd.bind(this)
1078
1113
  };
1079
- this.setCursorStyle();
1114
+ this.setTargetStyles();
1080
1115
  }
1081
1116
  isDragHandle(el) {
1082
1117
  return this.dragHandles.some(dh => contains(dh, el, true));
@@ -1084,7 +1119,7 @@ class DragTargetContainerDirective {
1084
1119
  get isHandleSelectorValid() {
1085
1120
  return isPresent(this.dragHandle) && this.dragHandle !== '';
1086
1121
  }
1087
- setCursorStyle() {
1122
+ setTargetStyles() {
1088
1123
  if (!isDocumentAvailable()) {
1089
1124
  return;
1090
1125
  }
@@ -1092,12 +1127,14 @@ class DragTargetContainerDirective {
1092
1127
  if (isPresent(this.dragHandles) && this.dragHandles.length > 0) {
1093
1128
  this.dragHandles.forEach(handle => {
1094
1129
  this.renderer.setStyle(handle, 'cursor', 'move');
1130
+ this.renderer.setStyle(handle, 'touch-action', 'none');
1095
1131
  });
1096
1132
  }
1097
1133
  }
1098
1134
  else {
1099
1135
  this.allDragTargets.forEach(target => {
1100
1136
  this.renderer.setStyle(target, 'cursor', 'move');
1137
+ this.renderer.setStyle(target, 'touch-action', 'none');
1101
1138
  });
1102
1139
  }
1103
1140
  }
@@ -1204,6 +1241,9 @@ class DragTargetDirective {
1204
1241
  ngZone;
1205
1242
  service;
1206
1243
  viewContainer;
1244
+ get touchActionStyle() {
1245
+ return this.dragHandles.length > 0 ? null : 'none';
1246
+ }
1207
1247
  /**
1208
1248
  * Defines whether a hint will be used for dragging. By default, the hint is a copy of the drag target. ([see example]({% slug drag_hint %})).
1209
1249
  *
@@ -1281,7 +1321,6 @@ class DragTargetDirective {
1281
1321
  */
1282
1322
  onDragEnd = new EventEmitter();
1283
1323
  dragTarget = null;
1284
- domSubscriptions = [];
1285
1324
  hintComponent = null;
1286
1325
  dragStarted = false;
1287
1326
  pressed = false;
@@ -1291,6 +1330,7 @@ class DragTargetDirective {
1291
1330
  scrollableParent = null;
1292
1331
  defaultHint = null;
1293
1332
  _dragData = () => null;
1333
+ prevUserSelect;
1294
1334
  get hintTemplate() {
1295
1335
  return isPresent(this.hint) && typeof this.hint === 'object' ? this.hint.hintTemplate : null;
1296
1336
  }
@@ -1301,6 +1341,17 @@ class DragTargetDirective {
1301
1341
  return this.hintTemplate && isPresent(this.hintComponent) ? this.hintComponent.instance.element.nativeElement : this.defaultHint;
1302
1342
  }
1303
1343
  onPointerDown(event) {
1344
+ if (this.dragHandles.length && !this.isDragHandle(event.target)) {
1345
+ return;
1346
+ }
1347
+ const action = getAction(event, this.dragTarget);
1348
+ this.service.handleDragAndDrop(action);
1349
+ this.service.autoScroll = typeof this.autoScroll === 'object' ? this.autoScroll.enabled !== false : this.autoScroll;
1350
+ this.service.scrollableParent = this.getAutoScrollContainer();
1351
+ this.service.autoScrollDirection = typeof this.autoScroll === 'object' ? this.autoScroll.direction : { horizontal: true, vertical: true };
1352
+ this.attachDomHandlers();
1353
+ }
1354
+ onTouchStart(event) {
1304
1355
  if (this.dragHandles.length && !this.isDragHandle(event.target)) {
1305
1356
  return;
1306
1357
  }
@@ -1313,11 +1364,20 @@ class DragTargetDirective {
1313
1364
  this.attachDomHandlers();
1314
1365
  }
1315
1366
  onPointerMove(event) {
1367
+ const action = getAction(event, this.dragTarget);
1368
+ this.service.handleDragAndDrop(action);
1369
+ }
1370
+ onTouchMove(event) {
1316
1371
  event.preventDefault();
1317
1372
  const action = getAction(event, this.dragTarget);
1318
1373
  this.service.handleDragAndDrop(action);
1319
1374
  }
1320
1375
  onPointerUp(event) {
1376
+ const action = getAction(event, this.dragTarget);
1377
+ this.service.handleDragAndDrop(action);
1378
+ this.attachDomHandlers();
1379
+ }
1380
+ onContextMenu(event) {
1321
1381
  event.preventDefault();
1322
1382
  const action = getAction(event, this.dragTarget);
1323
1383
  this.service.handleDragAndDrop(action);
@@ -1345,7 +1405,7 @@ class DragTargetDirective {
1345
1405
  this.service.dragTargets.push(this.dragTarget);
1346
1406
  }
1347
1407
  ngOnDestroy() {
1348
- this.domSubscriptions.forEach(subscription => subscription());
1408
+ this.removeListeners();
1349
1409
  const currentDragTargetIndex = this.service.dragTargets.indexOf(this.dragTarget);
1350
1410
  this.service.dragTargets.splice(currentDragTargetIndex, 1);
1351
1411
  }
@@ -1360,6 +1420,8 @@ class DragTargetDirective {
1360
1420
  this.pressed = true;
1361
1421
  }
1362
1422
  this.scrollableParent = this.dragTarget.element ? getScrollableParent(this.dragTarget.element) : null;
1423
+ this.prevUserSelect = this.dragTarget.element.style.userSelect;
1424
+ this.renderer.setStyle(this.dragTarget.element, 'user-select', 'none');
1363
1425
  this.emitZoneAwareEvent('onPress', event);
1364
1426
  }
1365
1427
  handleDragStart(event) {
@@ -1417,8 +1479,11 @@ class DragTargetDirective {
1417
1479
  if (this.dragTimeout) {
1418
1480
  clearTimeout(this.dragTimeout);
1419
1481
  this.dragTimeout = null;
1420
- this.pressed = false;
1421
1482
  }
1483
+ this.pressed = false;
1484
+ this.prevUserSelect ? this.renderer.setStyle(this.dragTarget.element, 'user-select', this.prevUserSelect) :
1485
+ this.renderer.removeStyle(this.dragTarget.element, 'user-select');
1486
+ this.prevUserSelect = null;
1422
1487
  this.emitZoneAwareEvent('onRelease', event);
1423
1488
  }
1424
1489
  handleDragEnd(event) {
@@ -1458,43 +1523,66 @@ class DragTargetDirective {
1458
1523
  onDragEnd: this.handleDragEnd.bind(this)
1459
1524
  };
1460
1525
  }
1526
+ get supportPointerEvent() {
1527
+ return Boolean(typeof window !== 'undefined' && window.PointerEvent);
1528
+ }
1529
+ removeListeners() {
1530
+ if (isPresent(this.scrollableParent)) {
1531
+ this.scrollableParent.removeEventListener('scroll', this.onPointerMove);
1532
+ }
1533
+ const element = this.nativeElement;
1534
+ document.removeEventListener('pointermove', this.onPointerMove);
1535
+ document.removeEventListener('pointerup', this.onPointerUp, true);
1536
+ document.removeEventListener('contextmenu', this.onContextMenu);
1537
+ document.removeEventListener('pointercancel', this.onPointerUp);
1538
+ window.removeEventListener('touchmove', noop);
1539
+ element.removeEventListener('touchmove', this.onTouchMove);
1540
+ element.removeEventListener('touchend', this.onPointerUp);
1541
+ document.removeEventListener('mousemove', this.onPointerMove);
1542
+ document.removeEventListener('mouseup', this.onPointerUp);
1543
+ document.removeEventListener('touchcancel', this.onPointerUp);
1544
+ element.removeEventListener('pointerdown', this.onPointerDown);
1545
+ element.removeEventListener('mousedown', this.onPointerDown);
1546
+ element.removeEventListener('touchstart', this.onTouchStart);
1547
+ }
1461
1548
  attachDomHandlers() {
1462
1549
  this.ngZone.runOutsideAngular(() => {
1463
- if (this.domSubscriptions.length > 0) {
1464
- this.domSubscriptions.forEach(subscription => subscription());
1465
- }
1550
+ this.removeListeners();
1466
1551
  if (!(isDocumentAvailable() && isPresent(this.element))) {
1467
1552
  return;
1468
1553
  }
1469
- if (this.service.pressed) {
1470
- this.onPointerMove = this.onPointerMove.bind(this);
1471
- this.onPointerUp = this.onPointerUp.bind(this);
1472
- this.domSubscriptions = [
1473
- this.renderer.listen(document, 'pointermove', this.onPointerMove),
1474
- this.renderer.listen(document, 'mousemove', this.onPointerMove),
1475
- this.renderer.listen(document, 'touchmove', this.onPointerMove),
1476
- this.renderer.listen(document, 'pointerup', this.onPointerUp),
1477
- this.renderer.listen(document, 'pointercancel', this.onPointerUp),
1478
- this.renderer.listen(document, 'mouseup', this.onPointerUp),
1479
- this.renderer.listen(document, 'contextmenu', this.onPointerUp),
1480
- this.renderer.listen(document, 'touchend', this.onPointerUp),
1481
- this.renderer.listen(document, 'touchcancel', this.onPointerUp)
1482
- ];
1554
+ this.onPointerMove = this.onPointerMove.bind(this);
1555
+ this.onPointerUp = this.onPointerUp.bind(this);
1556
+ this.onTouchMove = this.onTouchMove.bind(this);
1557
+ this.onContextMenu = this.onContextMenu.bind(this);
1558
+ this.onPointerDown = this.onPointerDown.bind(this);
1559
+ this.onTouchStart = this.onTouchStart.bind(this);
1560
+ const element = this.nativeElement;
1561
+ if (this.supportPointerEvent) {
1483
1562
  if (isPresent(this.scrollableParent)) {
1484
1563
  if (this.scrollableParent === document.getElementsByTagName('html')[0]) {
1485
1564
  this.scrollableParent = window;
1486
1565
  }
1487
- this.domSubscriptions.push(this.renderer.listen(this.scrollableParent, 'scroll', this.onPointerMove));
1566
+ this.scrollableParent.addEventListener('scroll', this.onPointerMove, { passive: true });
1567
+ }
1568
+ element.addEventListener('pointerdown', this.onPointerDown, { passive: true });
1569
+ if (this.pressed) {
1570
+ document.addEventListener('pointermove', this.onPointerMove);
1571
+ document.addEventListener('pointerup', this.onPointerUp, true);
1572
+ document.addEventListener('contextmenu', this.onContextMenu);
1573
+ document.addEventListener('pointercancel', this.onPointerUp, { passive: true });
1488
1574
  }
1489
1575
  }
1490
1576
  else {
1491
- this.onPointerDown = this.onPointerDown.bind(this);
1492
- const element = this.nativeElement;
1493
- this.domSubscriptions = [
1494
- this.renderer.listen(element, 'pointerdown', this.onPointerDown),
1495
- this.renderer.listen(element, 'mousedown', this.onPointerDown),
1496
- this.renderer.listen(element, 'touchstart', this.onPointerDown)
1497
- ];
1577
+ window.addEventListener('touchmove', noop, { capture: false, passive: false });
1578
+ element.addEventListener('mousedown', this.onPointerDown, { passive: true });
1579
+ element.addEventListener('touchstart', this.onTouchStart, { passive: true });
1580
+ if (this.pressed) {
1581
+ document.addEventListener('mousemove', this.onPointerMove, { passive: true });
1582
+ document.addEventListener('mouseup', this.onPointerUp, { passive: true });
1583
+ element.addEventListener('touchmove', this.onTouchMove, { passive: true });
1584
+ element.addEventListener('touchend', this.onPointerUp, { passive: true });
1585
+ }
1498
1586
  }
1499
1587
  });
1500
1588
  }
@@ -1654,7 +1742,7 @@ class DragTargetDirective {
1654
1742
  }
1655
1743
  }
1656
1744
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragTargetDirective, deps: [{ token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i0.NgZone }, { token: DragStateService }, { token: i0.ViewContainerRef }], target: i0.ɵɵFactoryTarget.Directive });
1657
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragTargetDirective, isStandalone: true, selector: "[kendoDragTarget]", inputs: { hint: "hint", threshold: "threshold", autoScroll: "autoScroll", dragTargetId: "dragTargetId", dragDelay: "dragDelay", restrictByAxis: "restrictByAxis", mode: "mode", dragData: "dragData" }, outputs: { onPress: "onPress", onDragStart: "onDragStart", onDrag: "onDrag", onDragReady: "onDragReady", onRelease: "onRelease", onDragEnd: "onDragEnd" }, queries: [{ propertyName: "dragHandles", predicate: DragHandleDirective }], exportAs: ["kendoDragTarget"], ngImport: i0 });
1745
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "16.2.12", type: DragTargetDirective, isStandalone: true, selector: "[kendoDragTarget]", inputs: { hint: "hint", threshold: "threshold", autoScroll: "autoScroll", dragTargetId: "dragTargetId", dragDelay: "dragDelay", restrictByAxis: "restrictByAxis", mode: "mode", dragData: "dragData" }, outputs: { onPress: "onPress", onDragStart: "onDragStart", onDrag: "onDrag", onDragReady: "onDragReady", onRelease: "onRelease", onDragEnd: "onDragEnd" }, host: { properties: { "style.touch-action": "this.touchActionStyle" } }, queries: [{ propertyName: "dragHandles", predicate: DragHandleDirective }], exportAs: ["kendoDragTarget"], ngImport: i0 });
1658
1746
  }
1659
1747
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DragTargetDirective, decorators: [{
1660
1748
  type: Directive,
@@ -1663,7 +1751,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
1663
1751
  exportAs: 'kendoDragTarget',
1664
1752
  standalone: true
1665
1753
  }]
1666
- }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: DragStateService }, { type: i0.ViewContainerRef }]; }, propDecorators: { hint: [{
1754
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i0.NgZone }, { type: DragStateService }, { type: i0.ViewContainerRef }]; }, propDecorators: { touchActionStyle: [{
1755
+ type: HostBinding,
1756
+ args: ['style.touch-action']
1757
+ }], hint: [{
1667
1758
  type: Input
1668
1759
  }], threshold: [{
1669
1760
  type: Input
@@ -1843,8 +1934,8 @@ class DropTargetContainerDirective {
1843
1934
  if (!this.service.dragTargetPresent || this.service.dropTargetPresent) {
1844
1935
  return;
1845
1936
  }
1846
- const eventTarget = event.originalEvent.target;
1847
- const currDropTargetElem = intersect(eventTarget, this.allDropTargets);
1937
+ const currDragTargetElement = this.service.dragTarget.hint || this.service.dragTarget.element;
1938
+ const currDropTargetElem = intersect(currDragTargetElement, this.allDropTargets);
1848
1939
  const currDropTarget = this.service.dropTargets.find(dt => dt.element === currDropTargetElem);
1849
1940
  if (!isPresent(currDropTargetElem) || !isPresent(currDropTarget)) {
1850
1941
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@progress/kendo-angular-utils",
3
- "version": "17.1.2-develop.1",
3
+ "version": "17.1.2-develop.3",
4
4
  "description": "Kendo UI Angular utils component",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Progress",
@@ -23,12 +23,12 @@
23
23
  "@angular/core": "16 - 19",
24
24
  "@angular/platform-browser": "16 - 19",
25
25
  "@progress/kendo-licensing": "^1.0.2",
26
- "@progress/kendo-angular-common": "17.1.2-develop.1",
26
+ "@progress/kendo-angular-common": "17.1.2-develop.3",
27
27
  "rxjs": "^6.5.3 || ^7.0.0"
28
28
  },
29
29
  "dependencies": {
30
30
  "tslib": "^2.3.1",
31
- "@progress/kendo-angular-schematics": "17.1.2-develop.1",
31
+ "@progress/kendo-angular-schematics": "17.1.2-develop.3",
32
32
  "@progress/kendo-draggable-common": "^0.2.3"
33
33
  },
34
34
  "schematics": "./schematics/collection.json",