@progress/kendo-angular-sortable 17.0.0-develop.9 → 17.0.1-develop.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2046 +0,0 @@
1
- /**-----------------------------------------------------------------------------------------
2
- * Copyright © 2024 Progress Software Corporation. All rights reserved.
3
- * Licensed under commercial license. See LICENSE.md in the project root for more information
4
- *-------------------------------------------------------------------------------------------*/
5
- import * as i0 from '@angular/core';
6
- import { Injectable, Directive, Input, HostBinding, QueryList, EventEmitter, forwardRef, TemplateRef, Component, ContentChildren, ViewChildren, ViewChild, Output, NgModule } from '@angular/core';
7
- import { Subject, merge } from 'rxjs';
8
- import { isDocumentAvailable, focusableSelector, isChanged, Keys } from '@progress/kendo-angular-common';
9
- import { filter, tap, take, switchMap } from 'rxjs/operators';
10
- import * as i1 from '@progress/kendo-angular-l10n';
11
- import { LocalizationService, L10N_PREFIX } from '@progress/kendo-angular-l10n';
12
- import { validatePackage } from '@progress/kendo-licensing';
13
- import { Draggable } from '@progress/kendo-draggable';
14
- import { NgFor, NgClass, NgStyle, NgIf, NgTemplateOutlet } from '@angular/common';
15
-
16
- const NODE_NAME_PREDICATES = {};
17
- const NODE_ATTR_PREDICATES = {};
18
- const focusableRegex = /^(?:a|input|select|option|textarea|button|object)$/i;
19
- /**
20
- * @hidden
21
- */
22
- const matchesNodeName = (nodeName) => {
23
- if (!NODE_NAME_PREDICATES[nodeName]) {
24
- NODE_NAME_PREDICATES[nodeName] = (element) => String(element.nodeName).toLowerCase() === nodeName.toLowerCase();
25
- }
26
- return NODE_NAME_PREDICATES[nodeName];
27
- };
28
- /**
29
- * @hidden
30
- */
31
- const matchesNodeAttr = (nodeAttr) => {
32
- if (!NODE_ATTR_PREDICATES[nodeAttr]) {
33
- NODE_ATTR_PREDICATES[nodeAttr] = (element) => element.hasAttribute ? element.hasAttribute(nodeAttr) : false;
34
- }
35
- return NODE_ATTR_PREDICATES[nodeAttr];
36
- };
37
- /**
38
- * @hidden
39
- */
40
- const closest = (node, predicate) => {
41
- while (node && !predicate(node)) {
42
- node = node.parentNode;
43
- }
44
- return node;
45
- };
46
- /**
47
- * Returns an object specifiying whether there is a DraggableDirective under the cursor.
48
- * @hidden
49
- */
50
- const draggableFromPoint = (x, y) => {
51
- if (!isDocumentAvailable()) {
52
- return;
53
- }
54
- const el = document.elementFromPoint(x, y);
55
- if (!el) {
56
- return;
57
- }
58
- const isDraggable = el.hasAttribute("kendoDraggable");
59
- const isChild = closest(el, matchesNodeAttr("kendoDraggable")) !== null;
60
- const parentDraggable = closest(el, matchesNodeAttr("data-sortable-index"));
61
- const index = parentDraggable ? parseInt(parentDraggable.getAttribute("data-sortable-index"), 10) : -1;
62
- return {
63
- element: el,
64
- index: index,
65
- isDraggable: isDraggable,
66
- isDraggableChild: isChild,
67
- parentDraggable: parentDraggable,
68
- rect: el.getBoundingClientRect()
69
- };
70
- };
71
- /**
72
- * Returns the DraggableDirective under the cursor.
73
- * @hidden
74
- */
75
- const draggableFromEvent = (event, sortable) => {
76
- let target;
77
- if (event.changedTouches) {
78
- const touch = event.changedTouches[0];
79
- target = draggableFromPoint(touch.clientX, touch.clientY);
80
- }
81
- else {
82
- target = draggableFromPoint(event.clientX, event.clientY);
83
- }
84
- // TODO: refactor sortable. Add draggable getter
85
- return sortable.draggables.toArray()[target ? target.index : -1];
86
- };
87
- /**
88
- * @hidden
89
- */
90
- const getAllFocusableChildren = (parent) => {
91
- return Array.from(parent.querySelectorAll(focusableSelector)).filter((element) => element.offsetParent !== null);
92
- };
93
- /**
94
- * @hidden
95
- */
96
- const getFirstAndLastFocusable = (parent) => {
97
- const all = getAllFocusableChildren(parent);
98
- const firstFocusable = all.length > 0 ? all[0] : parent;
99
- const lastFocusable = all.length > 0 ? all[all.length - 1] : parent;
100
- return [firstFocusable, lastFocusable];
101
- };
102
- /**
103
- * @hidden
104
- */
105
- const keepFocusWithinComponent = (event, wrapper) => {
106
- const [firstFocusable, lastFocusable] = getFirstAndLastFocusable(wrapper);
107
- const tabAfterLastFocusable = !event.shiftKey && event.target === lastFocusable;
108
- const shiftTabAfterFirstFocusable = event.shiftKey && event.target === firstFocusable;
109
- if (tabAfterLastFocusable) {
110
- event.preventDefault();
111
- firstFocusable.focus();
112
- wrapper.blur();
113
- }
114
- if (shiftTabAfterFirstFocusable) {
115
- event.preventDefault();
116
- lastFocusable.focus();
117
- }
118
- };
119
- /**
120
- * @hidden
121
- */
122
- const isFocusable = (element) => {
123
- if (element.tagName) {
124
- const tagName = element.tagName.toLowerCase();
125
- const tabIndex = element.getAttribute('tabIndex');
126
- const skipTab = tabIndex === '-1';
127
- let focusable = tabIndex !== null && !skipTab;
128
- if (focusableRegex.test(tagName)) {
129
- focusable = !element.disabled && !skipTab;
130
- }
131
- return focusable;
132
- }
133
- return false;
134
- };
135
- const toClassList = (classNames) => String(classNames).trim().split(' ');
136
- /**
137
- * @hidden
138
- */
139
- const hasClasses = (element, classNames) => {
140
- const namesList = toClassList(classNames);
141
- return Boolean(toClassList(element.className).find((className) => namesList.indexOf(className) >= 0));
142
- };
143
- const isSortable = matchesNodeName('kendo-sortable');
144
- /**
145
- * @hidden
146
- */
147
- const widgetTarget = (target) => {
148
- const element = closest(target, node => hasClasses(node, 'k-widget') || isSortable(node));
149
- return element && !isSortable(element);
150
- };
151
- const hasRelativeStackingContext = () => {
152
- if (!isDocumentAvailable()) {
153
- return false;
154
- }
155
- const top = 10;
156
- const parent = document.createElement("div");
157
- parent.style.transform = "matrix(10, 0, 0, 10, 0, 0)";
158
- const innerDiv = document.createElement('div');
159
- innerDiv.style.position = 'fixed';
160
- innerDiv.style.top = `${top}px;`;
161
- parent.appendChild(innerDiv);
162
- document.body.appendChild(parent);
163
- const isDifferent = parent.children[0].getBoundingClientRect().top !== top;
164
- document.body.removeChild(parent);
165
- return isDifferent;
166
- };
167
- const HAS_RELATIVE_STACKING_CONTEXT = hasRelativeStackingContext();
168
- /**
169
- * @hidden
170
- */
171
- const relativeContextElement = (element) => {
172
- if (!element || !HAS_RELATIVE_STACKING_CONTEXT) {
173
- return null;
174
- }
175
- let node = element.parentElement;
176
- while (node) {
177
- if (window.getComputedStyle(node).transform !== 'none') {
178
- return node;
179
- }
180
- node = node.parentElement;
181
- }
182
- };
183
-
184
- /**
185
- * @hidden
186
- */
187
- const packageMetadata = {
188
- name: '@progress/kendo-angular-sortable',
189
- productName: 'Kendo UI for Angular',
190
- productCodes: ['KENDOUIANGULAR', 'KENDOUICOMPLETE'],
191
- publishDate: 1729174763,
192
- version: '17.0.0-develop.9',
193
- licensingDocsUrl: 'https://www.telerik.com/kendo-angular-ui/my-license/'
194
- };
195
-
196
- const allowDrag = (e) => {
197
- const target = e.originalEvent.target;
198
- return target.hasAttribute('data-sortable-item') || !(isFocusable(target) || widgetTarget(target));
199
- };
200
- /**
201
- * The service that provides the drag-and-drop functionality for
202
- * transferring items between Sortable components within the same page.
203
- *
204
- */
205
- class SortableService {
206
- constructor(ngZone) {
207
- this.ngZone = ngZone;
208
- /**
209
- * Specifies the Draggable item that is currently being moved.
210
- */
211
- this.activeDraggable = null;
212
- /**
213
- * Specifies the Draggable item from which the dragging started.
214
- */
215
- this.originDraggable = null;
216
- /**
217
- * @hidden
218
- */
219
- this.targetSortable = null;
220
- /**
221
- * Specifies the Draggable item that last emitted an event.
222
- */
223
- this.lastDraggable = null;
224
- /**
225
- * @hidden
226
- */
227
- this.onPressSubject = new Subject();
228
- /**
229
- * @hidden
230
- */
231
- this.onDragSubject = new Subject();
232
- /**
233
- * @hidden
234
- */
235
- this.onReleaseSubject = new Subject();
236
- this.source = null;
237
- this._target = null;
238
- this.sortableCounter = 0;
239
- this.sortableRegister = {};
240
- if (!isDocumentAvailable()) {
241
- return;
242
- }
243
- this.subscriptions = this.onPressSubject.pipe(filter(allowDrag), tap(press => {
244
- this.targetSortable = this.getSortableComponentFromTouch(press);
245
- }), filter(_ => Boolean(this.targetSortable)), tap(press => {
246
- this.onReleaseSubject.pipe(take(1)).subscribe(event => this.release(event));
247
- this.pressArgs = press;
248
- if (press.isTouch) {
249
- press.originalEvent.preventDefault();
250
- }
251
- }), switchMap(_drag => this.onDragSubject.pipe(filter(_ => Boolean(this.targetSortable)), //stop further events if dragStart is prevented
252
- tap((e) => this.drag(e))))).subscribe();
253
- }
254
- /**
255
- * Specifies the `SortableComponent` instance under the currently dragged item.
256
- */
257
- set target(target) {
258
- this._target = target;
259
- }
260
- get target() {
261
- return this._target;
262
- }
263
- /**
264
- * @hidden
265
- */
266
- onPress(e) {
267
- this.onPressSubject.next(e);
268
- }
269
- /**
270
- * @hidden
271
- */
272
- onDrag(e) {
273
- this.onDragSubject.next(e);
274
- }
275
- /**
276
- * @hidden
277
- */
278
- onRelease(e) {
279
- this.onReleaseSubject.next(e);
280
- }
281
- /**
282
- * @hidden
283
- */
284
- ngOnDestroy() {
285
- if (this.subscriptions) {
286
- this.subscriptions.unsubscribe();
287
- }
288
- }
289
- /**
290
- * Registers a `SortableComponent` with which the service operates.
291
- *
292
- * @param sortableComponent - The `SortableComponent`.
293
- * @return - The unique key that the current `SortableComponent` gets when registered.
294
- */
295
- registerComponent(sortableComponent) {
296
- const id = this.sortableCounter.toString();
297
- this.sortableRegister[id] = sortableComponent;
298
- this.sortableCounter++;
299
- return id;
300
- }
301
- /**
302
- * Removes a `SortableComponent` from the registered `SortableComponents` with which the service operates.
303
- *
304
- * @param key - The key of the `SortableComponent` which will be removed from the register.
305
- * Obtained when `registerComponent` is called.
306
- */
307
- unregisterComponent(key) {
308
- this.sortableRegister[key] = null;
309
- }
310
- /**
311
- * Sets the `SortableComponent` as a source component. When dragging an item from one Sortable to another,
312
- * the source component is the one from which the item originates.
313
- *
314
- * @param sortable - The `SortableComponent`.
315
- */
316
- setSource(sortable) {
317
- this.source = sortable;
318
- }
319
- /**
320
- * Returns the source `SortableComponent` from which
321
- * an item is dragged to other Sortable components.
322
- *
323
- * @return - The `SourceComponent`.
324
- */
325
- getSource() {
326
- return this.source;
327
- }
328
- /**
329
- * The method that finds the `SortableComponent` which is registered to
330
- * the `SortableService` by using the arguments of the `touch` event.
331
- *
332
- * @param touch - A Touch-Object of the `Touch` type interface.
333
- * Represents a single contact point (finger or stylus)
334
- * on a touch-sensitive device (touchscreen or trackpad).
335
- *
336
- * @return { component: SortableComponent, index: number } - An object
337
- * where the component is the `SortableComponent` that owns the item
338
- * and the index is the index of the touched item.
339
- */
340
- getSortableComponentFromTouch(touch) {
341
- if (!isDocumentAvailable()) {
342
- return { component: undefined, index: undefined };
343
- }
344
- let realTarget = document.elementFromPoint(touch.clientX, touch.clientY);
345
- while (realTarget) {
346
- const id = realTarget.getAttribute('data-sortable-id');
347
- const index = realTarget.getAttribute('data-sortable-index');
348
- if (id) {
349
- const targetSortable = this.sortableRegister[id];
350
- if (targetSortable) {
351
- return { component: targetSortable, index: parseInt(index, 10) };
352
- }
353
- }
354
- realTarget = realTarget.parentElement;
355
- }
356
- }
357
- start() {
358
- const pressArgs = this.pressArgs;
359
- if (pressArgs) {
360
- this.pressArgs = null;
361
- const startTarget = draggableFromEvent(pressArgs, this.targetSortable.component);
362
- if (this.targetSortable.component.startDrag({ target: startTarget, originalEvent: pressArgs })) {
363
- this.targetSortable = null;
364
- return true;
365
- }
366
- }
367
- }
368
- release(event) {
369
- if (this.source) {
370
- this.ngZone.run(() => {
371
- if (this.targetSortable) {
372
- const dropTarget = draggableFromEvent(event, this.targetSortable.component);
373
- this.source.endDrag({ target: dropTarget, originalEvent: event });
374
- }
375
- this.source.positionHintFromEvent(null);
376
- this.source.markForCheck();
377
- });
378
- }
379
- this.targetSortable = null;
380
- this.pressArgs = null;
381
- }
382
- drag(event) {
383
- this.ngZone.run(() => {
384
- if (this.start()) {
385
- return;
386
- }
387
- this.source.positionHintFromEvent(event);
388
- const sortable = this.getSortableComponentFromTouch(event);
389
- if (!sortable || sortable && sortable.component !== this.target) {
390
- if (this.target) {
391
- this.target.leave({ target: undefined, originalEvent: event });
392
- }
393
- else if (this.source !== this.target) {
394
- this.source.leave({ target: undefined, originalEvent: event });
395
- }
396
- }
397
- if (sortable && sortable.component) {
398
- const draggable = draggableFromEvent(event, sortable.component);
399
- sortable.component.drag({ target: draggable, originalEvent: event });
400
- }
401
- this.source.markForCheck();
402
- });
403
- }
404
- }
405
- SortableService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
406
- SortableService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableService, providedIn: 'root' });
407
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableService, decorators: [{
408
- type: Injectable,
409
- args: [{
410
- providedIn: 'root'
411
- }]
412
- }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
413
-
414
- /**
415
- * @hidden
416
- */
417
- class SortableContainer {
418
- }
419
- SortableContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableContainer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
420
- SortableContainer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableContainer });
421
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableContainer, decorators: [{
422
- type: Injectable
423
- }] });
424
-
425
- /**
426
- * @hidden
427
- */
428
- class DraggableDirective {
429
- constructor(parent, el, renderer) {
430
- this.parent = parent;
431
- this.el = el;
432
- this.renderer = renderer;
433
- }
434
- set hidden(value) {
435
- this._hidden = value;
436
- this.updateDisplayStyle();
437
- }
438
- get hidden() {
439
- return this._hidden;
440
- }
441
- get _focused() {
442
- return this.disabled ? false : (this.index === this.parent.activeIndex);
443
- }
444
- get _disabled() {
445
- return this.disabled;
446
- }
447
- get display() {
448
- return this.hidden ? "none" : this._display;
449
- }
450
- set display(display) {
451
- this._display = display;
452
- this.updateDisplayStyle();
453
- }
454
- ngOnInit() {
455
- const nativeElement = this.el.nativeElement;
456
- this.display = nativeElement.style.display;
457
- if (nativeElement) { // Remove the inline styles after a few releases of the themes with the style.
458
- this.renderer.setStyle(nativeElement, 'user-select', 'none');
459
- this.renderer.setStyle(nativeElement, '-ms-user-select', 'none');
460
- this.renderer.setStyle(nativeElement, '-moz-user-select', 'none');
461
- this.renderer.setStyle(nativeElement, '-webkit-user-select', 'none');
462
- }
463
- }
464
- updateDisplayStyle() {
465
- this.renderer.setStyle(this.el.nativeElement, 'display', this.display);
466
- }
467
- }
468
- DraggableDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DraggableDirective, deps: [{ token: SortableContainer }, { token: i0.ElementRef }, { token: i0.Renderer2 }], target: i0.ɵɵFactoryTarget.Directive });
469
- DraggableDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: DraggableDirective, isStandalone: true, selector: "[kendoDraggable]", inputs: { index: "index", disabled: "disabled", hidden: "hidden" }, host: { properties: { "class.k-focus": "this._focused", "attr.aria-disabled": "this._disabled" } }, ngImport: i0 });
470
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DraggableDirective, decorators: [{
471
- type: Directive,
472
- args: [{
473
- selector: '[kendoDraggable]',
474
- standalone: true
475
- }]
476
- }], ctorParameters: function () { return [{ type: SortableContainer }, { type: i0.ElementRef }, { type: i0.Renderer2 }]; }, propDecorators: { index: [{
477
- type: Input
478
- }], disabled: [{
479
- type: Input
480
- }], hidden: [{
481
- type: Input
482
- }], _focused: [{
483
- type: HostBinding,
484
- args: ['class.k-focus']
485
- }], _disabled: [{
486
- type: HostBinding,
487
- args: ['attr.aria-disabled']
488
- }] } });
489
-
490
- //TODO: RENAME FILE AND UPDATE EXPORTS AND MODULES
491
- /**
492
- * @hidden
493
- */
494
- class ItemTemplateDirective {
495
- constructor(templateRef) {
496
- this.templateRef = templateRef;
497
- }
498
- }
499
- ItemTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ItemTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
500
- ItemTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: ItemTemplateDirective, isStandalone: true, selector: "[kendoSortableItemTemplate]", ngImport: i0 });
501
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: ItemTemplateDirective, decorators: [{
502
- type: Directive,
503
- args: [{
504
- selector: '[kendoSortableItemTemplate]',
505
- standalone: true
506
- }]
507
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
508
- /**
509
- * @hidden
510
- */
511
- class PlaceholderTemplateDirective {
512
- constructor(templateRef) {
513
- this.templateRef = templateRef;
514
- }
515
- }
516
- PlaceholderTemplateDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PlaceholderTemplateDirective, deps: [{ token: i0.TemplateRef }], target: i0.ɵɵFactoryTarget.Directive });
517
- PlaceholderTemplateDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: PlaceholderTemplateDirective, isStandalone: true, selector: "[kendoSortablePlaceholderTemplate]", ngImport: i0 });
518
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: PlaceholderTemplateDirective, decorators: [{
519
- type: Directive,
520
- args: [{
521
- selector: '[kendoSortablePlaceholderTemplate]',
522
- standalone: true
523
- }]
524
- }], ctorParameters: function () { return [{ type: i0.TemplateRef }]; } });
525
-
526
- /**
527
- * Defines an event whose default action can be prevented
528
- * by calling the `preventDefault` method.
529
- *
530
- * @hidden
531
- */
532
- class PreventableEvent {
533
- constructor() {
534
- this.prevented = false;
535
- }
536
- /**
537
- * Prevents the default action for a specified event.
538
- * In this way, the source component suppresses
539
- * the built-in behavior that follows the event.
540
- */
541
- preventDefault() {
542
- this.prevented = true;
543
- }
544
- /**
545
- * If the event was prevented
546
- * by any of its subscribers, returns `true`.
547
- *
548
- * @returns `true` if the default action was prevented. Otherwise, returns `false`.
549
- */
550
- isDefaultPrevented() {
551
- return this.prevented;
552
- }
553
- }
554
-
555
- /**
556
- * The `navigate` event is emitted when using the keyboard arrows.
557
- */
558
- class NavigateEvent extends PreventableEvent {
559
- /**
560
- * @hidden
561
- */
562
- constructor(options) {
563
- super();
564
- Object.assign(this, options);
565
- }
566
- }
567
-
568
- /**
569
- * The arguments for the `DraggableDirective` events.
570
- * @hidden
571
- */
572
- class DraggableEvent extends PreventableEvent {
573
- /**
574
- * @hidden
575
- */
576
- constructor(options) {
577
- super();
578
- Object.assign(this, options);
579
- }
580
- }
581
-
582
- /**
583
- * Arguments for the `dragStart` event.
584
- */
585
- class DragStartEvent extends PreventableEvent {
586
- /**
587
- * @hidden
588
- */
589
- constructor(options) {
590
- super();
591
- Object.assign(this, options);
592
- }
593
- }
594
- /**
595
- * Arguments for the `dragOver` event.
596
- */
597
- class DragOverEvent extends DragStartEvent {
598
- /**
599
- * @hidden
600
- */
601
- constructor(options) {
602
- super(options);
603
- Object.assign(this, options);
604
- }
605
- }
606
- /**
607
- * Arguments for the `dragEnd` event.
608
- */
609
- class DragEndEvent extends DragOverEvent {
610
- /**
611
- * @hidden
612
- */
613
- constructor(options) {
614
- super(options);
615
- Object.assign(this, options);
616
- }
617
- }
618
-
619
- /* eslint-disable @typescript-eslint/no-explicit-any */
620
- const KEY_SHORTCUTS = 'Control+ArrowLeft Control+ArrowRight Meta+ArrowLeft Meta+ArrowRight';
621
- /**
622
- * Represents the [Kendo UI Sortable component for Angular]({% slug overview_sortable %}).
623
- *
624
- * {% meta height:430 %}
625
- * {% embed_file sortable-api/app.component.ts %}
626
- * {% embed_file shared/app.module.ts preview %}
627
- * {% embed_file shared/main.ts hidden %}
628
- * {% endmeta %}
629
- */
630
- /**
631
- * Represents the Kendo UI Sortable component for Angular.
632
- */
633
- class SortableComponent {
634
- constructor(ngZone, renderer, changeDetector, localization, wrapper, sortableService) {
635
- this.ngZone = ngZone;
636
- this.renderer = renderer;
637
- this.changeDetector = changeDetector;
638
- this.localization = localization;
639
- /**
640
- * Specifies the tab index of the Sortable component.
641
- */
642
- this.tabIndex = null;
643
- /**
644
- * Enables or disables the [keyboard navigation]({% slug keyboard_navigation_sortable %}).
645
- * @default false
646
- */
647
- this.navigable = false;
648
- /**
649
- * Enables or disables the built-in animations.
650
- * @default false
651
- */
652
- this.animation = false;
653
- /**
654
- * Sets an array of integers, which represent the indexes of the disabled items from the data array
655
- * ([see example](slug:items_sortable#toc-disabling-items)).
656
- */
657
- this.disabledIndexes = [];
658
- /**
659
- * Sets a string that represents the name of the zone to which the Sortable belongs
660
- * ([see example](slug:items_sortable#toc-transferring-of-items)). Items can be transferred
661
- * between Sortables which belong to the same zone.
662
- */
663
- this.zone = undefined;
664
- /**
665
- * Defines the zones from which items can be transferred onto the current Sortable component
666
- * ([see example](slug:items_sortable#toc-transferring-of-items)). If the `acceptZones` property
667
- * of the target Sortable is set, allows you to transfer items between Sortables which belong
668
- * to different zones.
669
- */
670
- this.acceptZones = undefined;
671
- /**
672
- * Represents the CSS styles which are applied to each Sortable item.
673
- *
674
- * @example
675
- * ```ts
676
- * import { Component } from '@angular/core';
677
- * import { SortableModule } from '@progress/kendo-angular-sortable';
678
- *
679
- * _@Component({
680
- * selector: 'my-app',
681
- * template: `
682
- * <kendo-sortable
683
- * [data]="['1','2','3','4','5','6','7']"
684
- * [itemStyle] ="{
685
- * 'display': 'inline-block',
686
- * 'background-color': '#51A0ED',
687
- * 'height':'50px',
688
- * 'width':'50px',
689
- * 'margin':'3px',
690
- * 'cursor':'move'
691
- * }"
692
- * >
693
- * </kendo-sortable>
694
- * `
695
- * })
696
- * export class AppComponent {
697
- * }
698
- * ```
699
- */
700
- this.itemStyle = {};
701
- /**
702
- * Defines the CSS styles applied to an empty item ([see example]({% slug templates_sortable %})).
703
- */
704
- this.emptyItemStyle = undefined;
705
- /**
706
- * Defines the CSS styles which are applied to the currently dragged item ([see example]({% slug templates_sortable %})).
707
- */
708
- this.activeItemStyle = undefined;
709
- /**
710
- * Defines the CSS styles which are applied to all disabled items.
711
- */
712
- this.disabledItemStyle = undefined;
713
- /**
714
- * Defines the class which is applied to each Sortable item.
715
- */
716
- this.itemClass = "";
717
- /**
718
- * Defines the class which is applied to the active Sortable item.
719
- */
720
- this.activeItemClass = null;
721
- /**
722
- * Defines the class which is applied to the empty item when the Sortable has empty data.
723
- */
724
- this.emptyItemClass = null;
725
- /**
726
- * Defines the class which is applied to each disabled Sortable item.
727
- */
728
- this.disabledItemClass = null;
729
- /**
730
- * Sets the text message that will be displayed when the Sortable has no items.
731
- *
732
- * @example
733
- * ```ts
734
- * import { Component } from '@angular/core';
735
- * import { SortableModule } from '@progress/kendo-angular-sortable';
736
- *
737
- * _@Component({
738
- * selector: 'my-app',
739
- * template: `
740
- * <kendo-sortable [data]="[]"
741
- * [emptyText]="'No items - custom message and styles'"
742
- * [emptyItemStyle] = "{'height': '40px', 'width':'400px', 'border': '2px dashed black'}" >
743
- * </kendo-sortable>
744
- * `
745
- * })
746
- * export class AppComponent { }
747
- * ```
748
- */
749
- this.emptyText = "Empty";
750
- /**
751
- * @hidden
752
- */
753
- this.defaultTemplateRef = null;
754
- /**
755
- * Defines the template that will be used for rendering the items.
756
- * @hidden
757
- */
758
- this.itemTemplateDirectiveRef = null;
759
- /**
760
- * Defines the template that will be used for rendering the placeholder.
761
- * @hidden
762
- */
763
- this.placeholderTemplateDirectiveRef = null;
764
- this.itemWrappers = new QueryList();
765
- /**
766
- * Fires when the dragging of an item is started.
767
- */
768
- this.dragStart = new EventEmitter();
769
- /**
770
- * Fires when the dragging of an item is completed.
771
- */
772
- this.dragEnd = new EventEmitter();
773
- /**
774
- * Fires while the dragging of an item is in progress.
775
- */
776
- this.dragOver = new EventEmitter();
777
- /**
778
- * Fires when dragging an item outside of the component.
779
- */
780
- this.dragLeave = new EventEmitter();
781
- /**
782
- * Fires while the moving an item from one position to another.
783
- */
784
- this.dataMove = new EventEmitter();
785
- /**
786
- * Fires when a new item is added to the Sortable.
787
- */
788
- this.dataAdd = new EventEmitter();
789
- /**
790
- * Fires when an item is removed from the Sortable.
791
- */
792
- this.dataRemove = new EventEmitter();
793
- /**
794
- * Fires when navigating using the keyboard.
795
- */
796
- this.navigate = new EventEmitter();
797
- /**
798
- * The index of the currently focused item.
799
- * If no item is focused, set to `-1`.
800
- */
801
- this.activeIndex = -1;
802
- this.hostRole = 'list';
803
- /**
804
- * Flag indicating if the component is currently playing animations.
805
- * @hidden
806
- */
807
- this.animating = false;
808
- /**
809
- * The index of the currently dragged item.
810
- */
811
- this.dragIndex = -1;
812
- /**
813
- * The index of the item above which the dragged item is.
814
- */
815
- this.dragOverIndex = -1;
816
- this.onDragStartSubject = new Subject();
817
- this.onDragOverSubject = new Subject();
818
- this.onDragLeaveSubject = new Subject();
819
- this.onDragEndSubject = new Subject();
820
- /**
821
- * The location of the hint indicator when dragging on mobile devices.
822
- */
823
- this.hintLocation = null;
824
- this._localData = [];
825
- /**
826
- * @hidden
827
- */
828
- this.ariaKeyShortcuts = KEY_SHORTCUTS;
829
- this.focusableItems = [];
830
- this.animationDuration = 300;
831
- this.afterKeyPress = false;
832
- this.sortableService = null;
833
- this._hideActiveItem = false;
834
- this.prevActiveIndex = 0;
835
- validatePackage(packageMetadata);
836
- this.wrapper = wrapper.nativeElement;
837
- this.direction = localization.rtl ? 'rtl' : 'ltr';
838
- this.sortableService = sortableService;
839
- this.subscribeEvents();
840
- }
841
- /**
842
- * Sets an array of any data that is used as a data source for the Sortable.
843
- * {% meta height:430 %}
844
- * {% embed_file sortable-palettes/app.component.ts %}
845
- * {% embed_file shared/app.module.ts %}
846
- * {% embed_file shared/main.ts hidden %}
847
- * {% endmeta %}
848
- */
849
- set data(data) {
850
- this._data = data;
851
- //Cache each _data item instance locally to avoid repaint due to the ngTemplateOutletContext (generated by itemData)
852
- //This prevents destroying the kendoDraggable instance, which otherwise leads to losing the dragEnd event
853
- //due to non-exisitng HTML element
854
- this.cacheData();
855
- }
856
- get data() {
857
- return this._data;
858
- }
859
- /**
860
- * @hidden
861
- *
862
- * A misspelled alias for `navigable`.
863
- */
864
- set navigatable(value) {
865
- this.navigable = value;
866
- }
867
- get touchAction() {
868
- return "none";
869
- }
870
- get dir() {
871
- return this.direction;
872
- }
873
- setItemData(data, i) {
874
- this._localData[i].item = data.item;
875
- this._localData[i].index = data.index;
876
- this._localData[i].hidden = data.hidden;
877
- }
878
- /**
879
- * @hidden
880
- */
881
- itemTemplate(index) {
882
- let template = this.itemTemplateRef;
883
- if (index === this.dragOverIndex) {
884
- template = this.placeholderTemplateRef;
885
- }
886
- else if (index === this.dragIndex) {
887
- template = this.itemTemplateRef;
888
- }
889
- return template;
890
- }
891
- ngOnInit() {
892
- if (!this.data) {
893
- this.data = [];
894
- }
895
- this.id = this.sortableService.registerComponent(this);
896
- this.dragIndex = -1;
897
- const display = "display";
898
- if (this.activeItemStyle && !this.activeItemStyle[display]) {
899
- this.activeItemStyle[display] = "";
900
- }
901
- if (!this.itemStyle[display]) {
902
- this.itemStyle[display] = "";
903
- }
904
- if (this.wrapper) {
905
- this.draggable = new Draggable({
906
- press: (e) => this.sortableService.onPress(e),
907
- drag: (e) => this.sortableService.onDrag(e),
908
- release: (e) => this.sortableService.onRelease(e)
909
- });
910
- this.ngZone.runOutsideAngular(() => {
911
- this.draggable.bindTo(this.wrapper);
912
- });
913
- }
914
- }
915
- ngAfterViewInit() {
916
- if (this.navigable) {
917
- this.setInitialItemTabindex();
918
- this.setFocusableChildren();
919
- }
920
- this.childrenTabindexSubscription = this.itemWrappers.changes.subscribe(() => {
921
- if (this.navigable) {
922
- this.setInitialItemTabindex();
923
- this.setFocusableChildren();
924
- }
925
- });
926
- }
927
- ngOnChanges(changes) {
928
- if (this.data && isChanged('disabledIndexes', changes, false)) {
929
- this.cacheData();
930
- }
931
- }
932
- ngOnDestroy() {
933
- this.unsubscribeEvents();
934
- this.sortableService.unregisterComponent(this.id);
935
- if (this.draggable) {
936
- this.draggable.destroy();
937
- }
938
- }
939
- ngAfterContentInit() {
940
- this.itemTemplateRef = this.itemTemplateDirectiveRef.first || this.defaultTemplateRef.first;
941
- this.placeholderTemplateRef = this.placeholderTemplateDirectiveRef.first || this.defaultTemplateRef.first;
942
- }
943
- ngAfterViewChecked() {
944
- if (this.navigable) {
945
- if (this.afterKeyPress) {
946
- const elems = this.itemWrappers.toArray();
947
- if (elems && elems.length > 0 && this.activeIndex > -1) {
948
- const currentItem = elems[this.activeIndex].nativeElement;
949
- const prevItem = elems[this.prevActiveIndex].nativeElement;
950
- this.renderer.setAttribute(prevItem, 'tabindex', '-1');
951
- this.renderer.setAttribute(currentItem, 'tabindex', '0');
952
- currentItem.focus();
953
- }
954
- }
955
- this.afterKeyPress = false;
956
- }
957
- }
958
- /**
959
- * @hidden
960
- */
961
- setFocusableChildren() {
962
- this.itemWrappers.toArray().forEach((item) => {
963
- const itemEl = item.nativeElement;
964
- const focusableChildren = getAllFocusableChildren(itemEl);
965
- if (focusableChildren.length > 0) {
966
- this.focusableItems.push(focusableChildren);
967
- focusableChildren.forEach(focusableChild => {
968
- this.renderer.setAttribute(focusableChild, 'tabindex', '-1');
969
- });
970
- }
971
- });
972
- }
973
- /**
974
- * @hidden
975
- */
976
- updateCacheIndices() {
977
- this._localData.forEach((item, index) => {
978
- item.index = index;
979
- });
980
- }
981
- /**
982
- * @hidden
983
- */
984
- cacheData() {
985
- this._localData = [];
986
- this._data.forEach((item, index) => {
987
- this._localData.push({ item: item, active: false, disabled: !this.itemEnabled(index), index: index, hidden: false });
988
- });
989
- }
990
- /**
991
- * @hidden
992
- */
993
- startDrag(event) {
994
- const startEvent = new DraggableEvent(event);
995
- this.onDragStartSubject.next(startEvent);
996
- const prevented = startEvent.isDefaultPrevented();
997
- if (!prevented) {
998
- this.offsetParent = relativeContextElement(this.wrapper);
999
- }
1000
- return prevented;
1001
- }
1002
- /**
1003
- * @hidden
1004
- */
1005
- setInitialItemTabindex() {
1006
- this.itemWrappers.toArray().forEach((item, index) => {
1007
- if (this.itemEnabled(index)) {
1008
- const isFirstItem = index === 0 ? 0 : -1;
1009
- const tabIndexValue = `${this.navigable ? this.tabIndex || isFirstItem : this.tabIndex}`;
1010
- const hasItemTabindex = item.nativeElement.getAttribute('tabindex');
1011
- if (!hasItemTabindex) {
1012
- this.renderer.setAttribute(item.nativeElement, 'tabindex', tabIndexValue);
1013
- }
1014
- }
1015
- });
1016
- }
1017
- /**
1018
- * @hidden
1019
- */
1020
- drag(event) {
1021
- const dragEvent = new DraggableEvent(event);
1022
- this.onDragOverSubject.next(dragEvent);
1023
- return dragEvent.isDefaultPrevented();
1024
- }
1025
- /**
1026
- * @hidden
1027
- */
1028
- leave(event) {
1029
- const leaveEvent = new DraggableEvent(event);
1030
- this.onDragLeaveSubject.next(leaveEvent);
1031
- return leaveEvent.isDefaultPrevented();
1032
- }
1033
- /**
1034
- * @hidden
1035
- */
1036
- endDrag(event) {
1037
- const endEvent = new DraggableEvent(event);
1038
- this.onDragEndSubject.next(endEvent);
1039
- return endEvent.isDefaultPrevented();
1040
- }
1041
- /**
1042
- * @hidden
1043
- */
1044
- hintVisible() {
1045
- return this.dragIndex >= 0 && this.hintLocation && this === this.sortableService.getSource();
1046
- }
1047
- /**
1048
- * @hidden
1049
- */
1050
- currentItemStyle(index) {
1051
- if (index === -1) {
1052
- return this.emptyItemStyle ? this.emptyItemStyle : this.itemStyle;
1053
- }
1054
- if (!this.itemEnabled(index) && this.disabledItemStyle) {
1055
- return this.disabledItemStyle;
1056
- }
1057
- if (index === this.dragIndex || (this.dragIndex === -1 && index === this.activeIndex)) {
1058
- if (this.hideActiveItem) {
1059
- return { "display": "none" };
1060
- }
1061
- if (this.activeItemStyle) {
1062
- return this.activeItemStyle;
1063
- }
1064
- }
1065
- return this.itemStyle;
1066
- }
1067
- /**
1068
- * @hidden
1069
- */
1070
- currentItemClass(index) {
1071
- if (index === -1) {
1072
- return this.emptyItemClass ? this.emptyItemClass : this.itemClass;
1073
- }
1074
- if (!this.itemEnabled(index) && this.disabledItemClass) {
1075
- return this.disabledItemClass;
1076
- }
1077
- if ((index === this.dragIndex || this.dragIndex === -1 && index === this.activeIndex) && this.activeItemClass) {
1078
- return this.activeItemClass;
1079
- }
1080
- return this.itemClass;
1081
- }
1082
- /**
1083
- * @hidden
1084
- */
1085
- hintStyle() {
1086
- const position = {
1087
- "left": this.hintLocation.x + 10 + "px",
1088
- "position": "fixed",
1089
- "top": this.hintLocation.y + 10 + "px"
1090
- };
1091
- const style = {};
1092
- Object.assign(style, this.currentItemStyle(this.dragIndex), position);
1093
- return style;
1094
- }
1095
- /**
1096
- * @hidden
1097
- */
1098
- itemEnabled(index) {
1099
- return this.disabledIndexes.indexOf(index) === -1;
1100
- }
1101
- /**
1102
- * @hidden
1103
- */
1104
- acceptDragFrom(sortableComponent) {
1105
- if (this.acceptZones === undefined) {
1106
- return (this.zone === sortableComponent.zone);
1107
- }
1108
- else if (sortableComponent.zone !== undefined) {
1109
- return (this.acceptZones.indexOf(sortableComponent.zone) !== -1);
1110
- }
1111
- return false;
1112
- }
1113
- /**
1114
- * @hidden
1115
- */
1116
- ariaDropEffect(index) {
1117
- return this.itemEnabled(index) ? "move" : "none";
1118
- }
1119
- /**
1120
- * @hidden
1121
- */
1122
- focusHandler(index) {
1123
- if (this.navigable) {
1124
- this.activeIndex = index;
1125
- }
1126
- }
1127
- /**
1128
- * @hidden
1129
- */
1130
- blurHandler() {
1131
- if (this.navigable && !this.afterKeyPress) {
1132
- this.prevActiveIndex = this.activeIndex;
1133
- this.activeIndex = -1;
1134
- }
1135
- }
1136
- /**
1137
- * @hidden
1138
- */
1139
- onArrowHandler(event, keyCode) {
1140
- const leftKey = this.direction === 'rtl' ? Keys.ArrowRight : Keys.ArrowLeft;
1141
- const dir = keyCode === Keys.ArrowUp || keyCode === leftKey ? -1 : 1;
1142
- const limit = this.data.length - 1;
1143
- let targetIndex = this.activeIndex + dir;
1144
- while (!this.itemEnabled(targetIndex) && targetIndex <= limit) {
1145
- targetIndex += dir;
1146
- }
1147
- targetIndex = Math.min(Math.max(targetIndex, 0), limit);
1148
- this.prevActiveIndex = this.activeIndex;
1149
- if (!this.itemEnabled(targetIndex)) {
1150
- return;
1151
- }
1152
- const ctrl = event.ctrlKey || event.metaKey;
1153
- const navigateEvent = new NavigateEvent({ index: targetIndex, oldIndex: this.activeIndex, ctrlKey: ctrl });
1154
- this.navigate.emit(navigateEvent);
1155
- if (!navigateEvent.isDefaultPrevented()) {
1156
- this.activeIndex = targetIndex;
1157
- }
1158
- this.dragIndex = -1;
1159
- this.dragOverIndex = -1;
1160
- event.stopPropagation();
1161
- event.preventDefault();
1162
- this.afterKeyPress = true;
1163
- }
1164
- /**
1165
- * @hidden
1166
- */
1167
- onEnterHandler(item) {
1168
- const focusableItems = this.focusableItems[this.activeIndex];
1169
- focusableItems.forEach(focusableItem => {
1170
- this.renderer.setAttribute(focusableItem, 'tabindex', '0');
1171
- });
1172
- this.renderer.setAttribute(item, 'tabindex', '-1');
1173
- focusableItems[0].focus();
1174
- }
1175
- /**
1176
- * @hidden
1177
- */
1178
- onEscapeHandler() {
1179
- const focusableItems = this.focusableItems[this.prevActiveIndex];
1180
- const item = this.itemWrappers.toArray()[this.prevActiveIndex].nativeElement;
1181
- focusableItems.forEach(focusableItem => {
1182
- this.renderer.setAttribute(focusableItem, 'tabindex', '-1');
1183
- });
1184
- this.renderer.setAttribute(item, 'tabindex', '0');
1185
- item.focus();
1186
- }
1187
- /**
1188
- * @hidden
1189
- */
1190
- keydownHandler(event) {
1191
- const index = this.activeIndex === -1 ? this.prevActiveIndex : this.activeIndex;
1192
- const item = this.itemWrappers.toArray()[index].nativeElement;
1193
- const isItemFocused = document.activeElement === item;
1194
- const hasFocus = this.activeIndex !== -1;
1195
- const keyCode = event.keyCode;
1196
- if (this.navigable && hasFocus) {
1197
- if (keyCode >= Keys.ArrowLeft && keyCode <= Keys.ArrowDown) {
1198
- this.onArrowHandler(event, keyCode);
1199
- }
1200
- if (keyCode === Keys.Enter && isItemFocused && this.focusableItems.length > 0) {
1201
- this.onEnterHandler(item);
1202
- }
1203
- }
1204
- if (keyCode === Keys.Tab && !isItemFocused) {
1205
- keepFocusWithinComponent(event, item);
1206
- }
1207
- if (keyCode === Keys.Escape && this.focusableItems.length > 0 && this.activeIndex === -1) {
1208
- this.onEscapeHandler();
1209
- }
1210
- }
1211
- /**
1212
- * Removes the currently active item from the Data collection that the Sortable uses.
1213
- */
1214
- removeDataItem(index) {
1215
- this.dragIndex = -1;
1216
- this.dragOverIndex = -1;
1217
- this._localData.splice(index, 1);
1218
- this.data.splice(index, 1);
1219
- this.updateCacheIndices();
1220
- }
1221
- /**
1222
- * Sets a Boolean value that indicates whether the item will be hidden or not.
1223
- * @hidden
1224
- */
1225
- hideItem(index, hidden = true) {
1226
- this._localData[index].hidden = hidden;
1227
- }
1228
- /**
1229
- * Gets or sets a Boolean value that indicates whether the currently dragged item will be hidden.
1230
- *
1231
- * If the currently dragged item is hidden, returns `true`.
1232
- * If the currently dragged item is visible, returns `false`.
1233
- */
1234
- get hideActiveItem() {
1235
- return this._hideActiveItem;
1236
- }
1237
- set hideActiveItem(value) {
1238
- this.activeIndex = -1;
1239
- this._hideActiveItem = value;
1240
- }
1241
- /**
1242
- * Clears the active item.
1243
- * An active item is the item which becomes focused when the user navigates with the keyboard.
1244
- */
1245
- clearActiveItem() {
1246
- if (this.navigable) {
1247
- this.fixFocus();
1248
- }
1249
- else {
1250
- this.activeIndex = -1;
1251
- }
1252
- this.dragIndex = -1;
1253
- }
1254
- /**
1255
- * Returns the currently active item when the user navigates with the keyboard.
1256
- * @return - The data item which is currently active.
1257
- */
1258
- getActiveItem() {
1259
- if (this.data && this.dragIndex >= 0 && this.dragIndex < this.data.length) {
1260
- return this.data[this.dragIndex];
1261
- }
1262
- }
1263
- /**
1264
- * Adds a new data item to a particular index.
1265
- * @param dataItem - The data item.
1266
- * @param index - The index at which the data item is inserted.
1267
- */
1268
- addDataItem(dataItem, index) {
1269
- const originDraggable = this.sortableService.originDraggable;
1270
- if (originDraggable && originDraggable.parent === this) {
1271
- const animation = this.animation;
1272
- this.hideItem(originDraggable.index, false);
1273
- this.animation = false;
1274
- this.moveItem(originDraggable.index, index);
1275
- this.animation = animation;
1276
- }
1277
- else {
1278
- this.data.splice(index, 0, dataItem);
1279
- this._localData.splice(index, 0, { item: dataItem, active: false, disabled: !this.itemEnabled(index), index: index, hidden: false });
1280
- this.updateCacheIndices();
1281
- }
1282
- this.dragIndex = index;
1283
- this.dragOverIndex = index;
1284
- this.ngZone.onStable.pipe(take(1)).subscribe(() => {
1285
- this.sortableService.target = this;
1286
- this.sortableService.setSource(this);
1287
- this.sortableService.activeDraggable = this.draggables.toArray()[index];
1288
- this.sortableService.lastDraggable = null;
1289
- });
1290
- }
1291
- /**
1292
- * Moves data item to a particular index.
1293
- * @param fromIndex - The data item's index.
1294
- * @param toIndex - The index which the data item should be moved to. Item currently sitting at that index is pushed back one position.
1295
- */
1296
- moveItem(fromIndex, toIndex) {
1297
- if (toIndex === fromIndex) {
1298
- return;
1299
- }
1300
- let dragIndex = fromIndex;
1301
- const d = toIndex > dragIndex ? 1 : -1;
1302
- const originalIndexAnimate = dragIndex;
1303
- const toAnimate = [];
1304
- let prevIndex = dragIndex;
1305
- let tmp;
1306
- while (dragIndex !== toIndex) {
1307
- dragIndex += d;
1308
- if (this.itemEnabled(dragIndex) || dragIndex === toIndex) {
1309
- if (this.animation) {
1310
- toAnimate.push({ next: dragIndex, prev: prevIndex });
1311
- }
1312
- tmp = this._localData[prevIndex].index;
1313
- this._localData[prevIndex].index = this._localData[dragIndex].index;
1314
- this._localData[dragIndex].index = tmp;
1315
- tmp = this._localData[prevIndex];
1316
- this._localData[prevIndex] = this._localData[dragIndex];
1317
- this._localData[dragIndex] = tmp;
1318
- tmp = this.data[prevIndex];
1319
- this.data[prevIndex] = this.data[dragIndex];
1320
- this.data[dragIndex] = tmp;
1321
- prevIndex = dragIndex;
1322
- }
1323
- }
1324
- this.dragIndex = dragIndex;
1325
- this.dragOverIndex = dragIndex;
1326
- this.activeIndex = dragIndex;
1327
- if (this.focusableItems.length > 0) {
1328
- this.swapFocusableChildren(fromIndex, toIndex);
1329
- }
1330
- if (this.animation) {
1331
- setTimeout(() => {
1332
- toAnimate.push({ next: originalIndexAnimate, prev: dragIndex });
1333
- this.animating = true;
1334
- this.animate(toAnimate);
1335
- });
1336
- }
1337
- this.ngZone.onStable.pipe(take(1)).subscribe(() => {
1338
- this.sortableService.activeDraggable = this.draggables.toArray()[dragIndex];
1339
- this.sortableService.lastDraggable = null;
1340
- });
1341
- }
1342
- /**
1343
- * @hidden
1344
- */
1345
- animate(draggables) {
1346
- const itemArray = this.itemWrappers.toArray();
1347
- const prevClientRect = [];
1348
- const nextClientRect = [];
1349
- clearTimeout(this._animating);
1350
- for (let i = 0; i < draggables.length; i++) {
1351
- prevClientRect.push(itemArray[draggables[i].prev].nativeElement.getBoundingClientRect());
1352
- nextClientRect.push(itemArray[draggables[i].next].nativeElement.getBoundingClientRect());
1353
- }
1354
- for (let i = 0; i < draggables.length; i++) {
1355
- const nextIndex = draggables[i].prev;
1356
- const targetRect = nextClientRect[i];
1357
- const currentRect = prevClientRect[i];
1358
- const target = itemArray[nextIndex].nativeElement;
1359
- this.applyAnimationStyle(target, 'transition', 'none');
1360
- this.applyAnimationStyle(target, 'transform', 'translate3d('
1361
- + (targetRect.left - currentRect.left).toString() + 'px,'
1362
- + (targetRect.top - currentRect.top).toString() + 'px,0)');
1363
- this.reflow(target);
1364
- }
1365
- for (let i = 0; i < draggables.length; i++) {
1366
- const nextIndex = draggables[i].prev;
1367
- const target = itemArray[nextIndex].nativeElement;
1368
- this.applyAnimationStyle(target, 'transition', 'all ' + this.animationDuration + 'ms');
1369
- this.applyAnimationStyle(target, 'transform', 'translate3d(0,0,0)');
1370
- clearTimeout(target.animated);
1371
- target.animated = setTimeout(() => {
1372
- this.applyAnimationStyle(target, 'transition', '');
1373
- this.applyAnimationStyle(target, 'transform', '');
1374
- target.animated = false;
1375
- }, this.animationDuration);
1376
- }
1377
- this._animating = setTimeout(() => {
1378
- this.animating = false;
1379
- }, this.animationDuration);
1380
- }
1381
- /**
1382
- * @hidden
1383
- */
1384
- positionHintFromEvent(event) {
1385
- const offset = this.parentOffset();
1386
- this.hintLocation = event ? { x: event.clientX - offset.left, y: event.clientY - offset.top } : null;
1387
- }
1388
- /**
1389
- * @hidden
1390
- */
1391
- parentOffset() {
1392
- const offsetParent = this.offsetParent;
1393
- if (offsetParent) {
1394
- const rect = offsetParent.getBoundingClientRect();
1395
- return {
1396
- left: rect.left - offsetParent.scrollLeft,
1397
- top: rect.top - offsetParent.scrollTop
1398
- };
1399
- }
1400
- return { left: 0, top: 0 };
1401
- }
1402
- /**
1403
- * @hidden
1404
- */
1405
- markForCheck() {
1406
- this.changeDetector.markForCheck();
1407
- }
1408
- /**
1409
- * @hidden
1410
- */
1411
- reflow(element) {
1412
- return element.offsetWidth;
1413
- }
1414
- /**
1415
- * @hidden
1416
- */
1417
- swapFocusableChildren(firstItemIndex, secondItemIndex) {
1418
- [this.focusableItems[firstItemIndex], this.focusableItems[secondItemIndex]] = [this.focusableItems[secondItemIndex], this.focusableItems[firstItemIndex]];
1419
- }
1420
- /**
1421
- * @hidden
1422
- */
1423
- applyAnimationStyle(el, prop, val) {
1424
- const style = el && el.style;
1425
- if (style) {
1426
- if (!(prop in style)) {
1427
- prop = '-webkit-' + prop;
1428
- }
1429
- style[prop] = val;
1430
- }
1431
- }
1432
- subscribeEvents() {
1433
- this.localizationChangeSubscription = this.localization
1434
- .changes
1435
- .subscribe(({ rtl }) => this.direction = rtl ? 'rtl' : 'ltr');
1436
- this.dragStartSubscription = this.onDragStartSubject
1437
- .subscribe((event) => {
1438
- this.sortableService.originDraggable = event.target;
1439
- this.sortableService.originIndex = event.target.index;
1440
- this.sortableService.activeDraggable = event.target;
1441
- this.sortableService.lastDraggable = event.target;
1442
- this.sortableService.target = this;
1443
- this.sortableService.setSource(this);
1444
- const dragStartEvent = new DragStartEvent({ index: event.target.index });
1445
- this.dragStart.emit(dragStartEvent);
1446
- if (dragStartEvent.isDefaultPrevented()) {
1447
- event.preventDefault();
1448
- }
1449
- else {
1450
- if (!event.target.disabled) {
1451
- if (this.sortableService.target) {
1452
- this.sortableService.target.dragOverIndex = -1;
1453
- this.sortableService.target.dragIndex = -1;
1454
- }
1455
- this.dragOverIndex = event.target.index;
1456
- this.dragIndex = event.target.index;
1457
- }
1458
- }
1459
- });
1460
- this.dragOverSubscription = this.onDragOverSubject.pipe(filter(event => event.target && event.target.el.nativeElement.style.transition.length === 0), filter(() => {
1461
- // Drag started from a disabled item
1462
- return this.sortableService.originDraggable && !this.sortableService.originDraggable.disabled;
1463
- }), filter(() => {
1464
- return this.sortableService && this.acceptDragFrom(this.sortableService.getSource());
1465
- }), filter((event) => {
1466
- return event.target !== this.sortableService.lastDraggable;
1467
- }))
1468
- .subscribe((event) => {
1469
- this.sortableService.lastDraggable = event.target;
1470
- const originDraggable = this.sortableService.originDraggable;
1471
- let targetIndex = event.target.index;
1472
- if (originDraggable.hidden && originDraggable.parent === this) {
1473
- if (originDraggable.index < event.target.index) {
1474
- targetIndex = event.target.index - 1;
1475
- }
1476
- }
1477
- this.sortableService.target = this;
1478
- const oldIndex = this.sortableService.activeDraggable ? this.sortableService.activeDraggable.index : 0;
1479
- const dragOverEvent = new DragOverEvent({ index: targetIndex, oldIndex: oldIndex });
1480
- this.dragOver.emit(dragOverEvent);
1481
- if (!dragOverEvent.isDefaultPrevented() && event.target && event.target.index >= 0) {
1482
- this.dragOverIndex = event.target.index;
1483
- this.placeHolderItemData(event.target);
1484
- }
1485
- });
1486
- this.dragEndSubscription = this.onDragEndSubject
1487
- .subscribe((event) => {
1488
- const source = this.sortableService.getSource();
1489
- if (!source) {
1490
- return;
1491
- }
1492
- const target = this.sortableService.target;
1493
- const index = event.target ? event.target.index : -1;
1494
- const oldIndex = this.sortableService.originDraggable ? this.sortableService.originIndex : -1;
1495
- this.hintLocation = null;
1496
- const dragEndEvent = new DragEndEvent({ index: index, oldIndex: oldIndex });
1497
- this.dragEnd.emit(dragEndEvent);
1498
- if (!dragEndEvent.isDefaultPrevented()) {
1499
- source.dragIndex = -1;
1500
- source.dragOverIndex = -1;
1501
- source.activeIndex = -1;
1502
- if (target && target !== source) {
1503
- target.dragIndex = -1;
1504
- target.dragOverIndex = -1;
1505
- }
1506
- setTimeout(() => {
1507
- this.sortableService.activeDraggable = null;
1508
- this.sortableService.lastDraggable = null;
1509
- this.sortableService.originDraggable = null;
1510
- this.sortableService.target = null;
1511
- this.sortableService.setSource(null);
1512
- });
1513
- }
1514
- });
1515
- this.dragLeaveSubscription = this.onDragLeaveSubject.pipe(filter((e) => {
1516
- if (!isDocumentAvailable()) {
1517
- return false;
1518
- }
1519
- return this.wrapper !== document.elementFromPoint(e.originalEvent.pageX, e.originalEvent.pageY);
1520
- }), filter((_e) => {
1521
- return !this.animating;
1522
- }), filter(_ => this.sortableService.target && this.sortableService.target.dragOverIndex > -1))
1523
- .subscribe(() => {
1524
- this.dragLeave.emit({ index: this.sortableService.originDraggable.index });
1525
- this.sortableService.lastDraggable = null;
1526
- this.dragOverIndex = -1;
1527
- this.sortableService.target = null;
1528
- });
1529
- }
1530
- unsubscribeEvents() {
1531
- if (this.localizationChangeSubscription) {
1532
- this.localizationChangeSubscription.unsubscribe();
1533
- }
1534
- if (this.childrenTabindexSubscription) {
1535
- this.childrenTabindexSubscription.unsubscribe();
1536
- }
1537
- this.dragStartSubscription.unsubscribe();
1538
- this.dragOverSubscription.unsubscribe();
1539
- this.dragEndSubscription.unsubscribe();
1540
- this.dragLeaveSubscription.unsubscribe();
1541
- }
1542
- placeHolderItemData(draggable) {
1543
- if (draggable.disabled) {
1544
- return;
1545
- }
1546
- const target = this.sortableService.target;
1547
- const source = this.sortableService.getSource();
1548
- const originalData = Object.assign({}, this._localData[draggable.index]);
1549
- const newData = source._localData[source.dragIndex];
1550
- this.setItemData(newData, draggable.index);
1551
- const endSub = source.onDragEndSubject.pipe(take(1)).subscribe(() => {
1552
- this.setItemData(originalData, draggable.index);
1553
- });
1554
- const leaveSub = target.onDragLeaveSubject.pipe(take(1)).subscribe(() => {
1555
- this.setItemData(originalData, draggable.index);
1556
- });
1557
- const overSub = merge(this.onDragOverSubject.pipe(filter(() => {
1558
- return draggable.index !== this.dragOverIndex;
1559
- })), this.onDragLeaveSubject).subscribe(() => {
1560
- this.setItemData(originalData, draggable.index);
1561
- endSub.unsubscribe();
1562
- overSub.unsubscribe();
1563
- leaveSub.unsubscribe();
1564
- });
1565
- }
1566
- fixFocus() {
1567
- if (this.itemWrappers) {
1568
- const itemArray = this.itemWrappers.toArray();
1569
- if (this.dragIndex > -1 && itemArray && itemArray.length > 0) {
1570
- itemArray[this.dragIndex].nativeElement.focus();
1571
- this.activeIndex = this.dragIndex;
1572
- }
1573
- }
1574
- }
1575
- }
1576
- SortableComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", 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 });
1577
- SortableComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", 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: [
1578
- LocalizationService,
1579
- {
1580
- provide: L10N_PREFIX,
1581
- useValue: 'kendo.sortable'
1582
- },
1583
- {
1584
- provide: SortableContainer,
1585
- useExisting: forwardRef(() => SortableComponent)
1586
- }
1587
- ], 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: `
1588
- <div #itemWrapper *ngFor="let item of _localData;let i=index"
1589
- kendoDraggable
1590
- role="listitem"
1591
- [attr.aria-grabbed]="i===dragIndex"
1592
- [attr.aria-disabled]="!itemEnabled(i)"
1593
- [attr.aria-keyshortcuts]="navigable ? ariaKeyShortcuts : ''"
1594
- [attr.aria-dropeffect]="ariaDropEffect(i)"
1595
- [attr.data-sortable-item] = "true"
1596
- [attr.data-sortable-index]="i"
1597
- [attr.data-sortable-id]="id"
1598
- [index]="i"
1599
- [hidden]="item.hidden"
1600
- [disabled]="!itemEnabled(i)"
1601
- [ngClass]="currentItemClass(i)"
1602
- [ngStyle]="currentItemStyle(i)"
1603
-
1604
- (focus)="focusHandler(i)"
1605
- (blur)="blurHandler()"
1606
- (keydown)="keydownHandler($event)"
1607
- >
1608
- <ng-container *ngIf="itemTemplateRef"
1609
- [ngTemplateOutlet]="itemTemplate(i)"
1610
- [ngTemplateOutletContext]="item">
1611
- </ng-container>
1612
- <ng-container *ngIf="!itemTemplateRef">{{item.item}}</ng-container>
1613
- </div>
1614
-
1615
- <ng-container #noDataRef *ngIf="!_data.length || _localData.length === 1 && _localData[0].hidden">
1616
- <div
1617
- kendoDraggable
1618
- [index]="0"
1619
- [disabled]="true"
1620
- [attr.data-sortable-id]="id"
1621
- [attr.data-sortable-index]="0"
1622
- [ngStyle]="currentItemStyle(-1)"
1623
- [ngClass]="currentItemClass(-1)"
1624
- >{{emptyText}}</div>
1625
- </ng-container>
1626
- <div *ngIf="hintVisible()" [ngStyle]="hintStyle()" [ngClass]="currentItemClass(dragIndex)">
1627
- <ng-container *ngIf="itemTemplateRef"
1628
- [ngTemplateOutlet]="itemTemplateRef"
1629
- [ngTemplateOutletContext]="{item: _localData[dragIndex].item}">
1630
- </ng-container>
1631
- <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
1632
- </div>
1633
- `, 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"] }] });
1634
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableComponent, decorators: [{
1635
- type: Component,
1636
- args: [{
1637
- exportAs: 'kendoSortable',
1638
- providers: [
1639
- LocalizationService,
1640
- {
1641
- provide: L10N_PREFIX,
1642
- useValue: 'kendo.sortable'
1643
- },
1644
- {
1645
- provide: SortableContainer,
1646
- useExisting: forwardRef(() => SortableComponent)
1647
- }
1648
- ],
1649
- selector: 'kendo-sortable',
1650
- template: `
1651
- <div #itemWrapper *ngFor="let item of _localData;let i=index"
1652
- kendoDraggable
1653
- role="listitem"
1654
- [attr.aria-grabbed]="i===dragIndex"
1655
- [attr.aria-disabled]="!itemEnabled(i)"
1656
- [attr.aria-keyshortcuts]="navigable ? ariaKeyShortcuts : ''"
1657
- [attr.aria-dropeffect]="ariaDropEffect(i)"
1658
- [attr.data-sortable-item] = "true"
1659
- [attr.data-sortable-index]="i"
1660
- [attr.data-sortable-id]="id"
1661
- [index]="i"
1662
- [hidden]="item.hidden"
1663
- [disabled]="!itemEnabled(i)"
1664
- [ngClass]="currentItemClass(i)"
1665
- [ngStyle]="currentItemStyle(i)"
1666
-
1667
- (focus)="focusHandler(i)"
1668
- (blur)="blurHandler()"
1669
- (keydown)="keydownHandler($event)"
1670
- >
1671
- <ng-container *ngIf="itemTemplateRef"
1672
- [ngTemplateOutlet]="itemTemplate(i)"
1673
- [ngTemplateOutletContext]="item">
1674
- </ng-container>
1675
- <ng-container *ngIf="!itemTemplateRef">{{item.item}}</ng-container>
1676
- </div>
1677
-
1678
- <ng-container #noDataRef *ngIf="!_data.length || _localData.length === 1 && _localData[0].hidden">
1679
- <div
1680
- kendoDraggable
1681
- [index]="0"
1682
- [disabled]="true"
1683
- [attr.data-sortable-id]="id"
1684
- [attr.data-sortable-index]="0"
1685
- [ngStyle]="currentItemStyle(-1)"
1686
- [ngClass]="currentItemClass(-1)"
1687
- >{{emptyText}}</div>
1688
- </ng-container>
1689
- <div *ngIf="hintVisible()" [ngStyle]="hintStyle()" [ngClass]="currentItemClass(dragIndex)">
1690
- <ng-container *ngIf="itemTemplateRef"
1691
- [ngTemplateOutlet]="itemTemplateRef"
1692
- [ngTemplateOutletContext]="{item: _localData[dragIndex].item}">
1693
- </ng-container>
1694
- <ng-container *ngIf="!itemTemplateRef">{{_localData[dragIndex].item}}</ng-container>
1695
- </div>
1696
- `,
1697
- standalone: true,
1698
- imports: [NgFor, DraggableDirective, NgClass, NgStyle, NgIf, NgTemplateOutlet]
1699
- }]
1700
- }], ctorParameters: function () { return [{ type: i0.NgZone }, { type: i0.Renderer2 }, { type: i0.ChangeDetectorRef }, { type: i1.LocalizationService }, { type: i0.ElementRef }, { type: SortableService }]; }, propDecorators: { tabIndex: [{
1701
- type: Input
1702
- }], data: [{
1703
- type: Input
1704
- }], navigable: [{
1705
- type: Input
1706
- }], navigatable: [{
1707
- type: Input
1708
- }], animation: [{
1709
- type: Input
1710
- }], disabledIndexes: [{
1711
- type: Input
1712
- }], zone: [{
1713
- type: Input
1714
- }], acceptZones: [{
1715
- type: Input
1716
- }], itemStyle: [{
1717
- type: Input
1718
- }], emptyItemStyle: [{
1719
- type: Input
1720
- }], activeItemStyle: [{
1721
- type: Input
1722
- }], disabledItemStyle: [{
1723
- type: Input
1724
- }], itemClass: [{
1725
- type: Input
1726
- }], activeItemClass: [{
1727
- type: Input
1728
- }], emptyItemClass: [{
1729
- type: Input
1730
- }], disabledItemClass: [{
1731
- type: Input
1732
- }], emptyText: [{
1733
- type: Input
1734
- }], defaultTemplateRef: [{
1735
- type: ContentChildren,
1736
- args: [TemplateRef, { descendants: false }]
1737
- }], itemTemplateDirectiveRef: [{
1738
- type: ContentChildren,
1739
- args: [ItemTemplateDirective, { read: TemplateRef, descendants: false }]
1740
- }], placeholderTemplateDirectiveRef: [{
1741
- type: ContentChildren,
1742
- args: [PlaceholderTemplateDirective, { read: TemplateRef, descendants: false }]
1743
- }], itemWrappers: [{
1744
- type: ViewChildren,
1745
- args: ['itemWrapper']
1746
- }], draggables: [{
1747
- type: ViewChildren,
1748
- args: [DraggableDirective]
1749
- }], noDataContainer: [{
1750
- type: ViewChild,
1751
- args: ['noDataRef']
1752
- }], hint: [{
1753
- type: ViewChild,
1754
- args: ['hint']
1755
- }], dragStart: [{
1756
- type: Output
1757
- }], dragEnd: [{
1758
- type: Output
1759
- }], dragOver: [{
1760
- type: Output
1761
- }], dragLeave: [{
1762
- type: Output
1763
- }], dataMove: [{
1764
- type: Output
1765
- }], dataAdd: [{
1766
- type: Output
1767
- }], dataRemove: [{
1768
- type: Output
1769
- }], navigate: [{
1770
- type: Output
1771
- }], activeIndex: [{
1772
- type: Input
1773
- }], touchAction: [{
1774
- type: HostBinding,
1775
- args: ['style.touch-action']
1776
- }], dir: [{
1777
- type: HostBinding,
1778
- args: ['attr.dir']
1779
- }], hostRole: [{
1780
- type: HostBinding,
1781
- args: ['attr.role']
1782
- }] } });
1783
-
1784
- /**
1785
- * The arguments for the `SortableComponent` `dataAdd` event.
1786
- */
1787
- class DataAddEvent extends PreventableEvent {
1788
- /**
1789
- * @hidden
1790
- */
1791
- constructor(options) {
1792
- super();
1793
- Object.assign(this, options);
1794
- }
1795
- }
1796
- /**
1797
- * The arguments for the `SortableComponent` `dataRemove` event.
1798
- */
1799
- class DataRemoveEvent extends PreventableEvent {
1800
- /**
1801
- * @hidden
1802
- */
1803
- constructor(options) {
1804
- super();
1805
- Object.assign(this, options);
1806
- }
1807
- }
1808
- /**
1809
- * The arguments for the `SortableComponent` `dataMove` event.
1810
- */
1811
- class DataMoveEvent extends PreventableEvent {
1812
- /**
1813
- * @hidden
1814
- */
1815
- constructor(options) {
1816
- super();
1817
- Object.assign(this, options);
1818
- }
1819
- }
1820
-
1821
- /**
1822
- * A Directive which handles the most common scenarios such reordering and moving items between Sortables, thus minimizng boilerplate code.
1823
- * This is achieved by subscribing to the Sortable's events and handling them using the API methods it provides.
1824
- */
1825
- class SortableBindingDirective {
1826
- constructor(sortable, sortableService) {
1827
- this.sortable = sortable;
1828
- this.sortableService = sortableService;
1829
- this.sortableService = sortableService;
1830
- }
1831
- /**
1832
- * Sets a data-bound array that is used as a data source for the Sortable.
1833
- *
1834
- * {% meta height:430 %}
1835
- * {% embed_file overview/app.component.ts %}
1836
- * {% embed_file shared/app.module.ts %}
1837
- * {% embed_file shared/main.ts hidden %}
1838
- * {% endmeta %}
1839
- *
1840
- */
1841
- set data(data) {
1842
- this.sortable.data = data;
1843
- }
1844
- nextEnabledIndex(index, sortable) {
1845
- for (let i = index; i <= sortable.data.length; i++) {
1846
- if (sortable.itemEnabled(i)) {
1847
- return i;
1848
- }
1849
- }
1850
- }
1851
- addItem(event, sortable) {
1852
- let index = event.index;
1853
- const dataItem = this.sortableService.getSource().data[event.oldIndex];
1854
- const addEvent = new DataAddEvent({ index: index, dataItem: dataItem });
1855
- sortable.dataAdd.emit(addEvent);
1856
- if (!addEvent.isDefaultPrevented()) {
1857
- if (index === sortable.itemWrappers.length - 1 && !sortable.noDataContainer) {
1858
- index++;
1859
- }
1860
- sortable.addDataItem(dataItem, index);
1861
- }
1862
- return !addEvent.isDefaultPrevented();
1863
- }
1864
- removeItem(event, sortable) {
1865
- const originDraggable = this.sortableService.originDraggable;
1866
- const removeEvent = new DataRemoveEvent({ index: event.oldIndex, dataItem: sortable.data[event.oldIndex] });
1867
- sortable.dataRemove.emit(removeEvent);
1868
- if (!removeEvent.isDefaultPrevented()) {
1869
- if (originDraggable && originDraggable.parent === sortable) {
1870
- sortable.hideItem(event.oldIndex, true);
1871
- }
1872
- else {
1873
- sortable.removeDataItem(event.oldIndex);
1874
- }
1875
- }
1876
- return !removeEvent.isDefaultPrevented();
1877
- }
1878
- moveItem(event, sortable) {
1879
- if (event.index === event.oldIndex) {
1880
- return false;
1881
- }
1882
- const moveEvent = new DataMoveEvent({
1883
- dataItem: sortable.data[event.oldIndex],
1884
- index: event.index,
1885
- oldIndex: event.oldIndex
1886
- });
1887
- sortable.dataMove.emit(moveEvent);
1888
- if (!moveEvent.isDefaultPrevented()) {
1889
- sortable.moveItem(event.oldIndex, event.index);
1890
- }
1891
- return !moveEvent.isDefaultPrevented();
1892
- }
1893
- /**
1894
- * Removes the Draggable item from which the drag started.
1895
- * @hidden
1896
- */
1897
- removeOriginDraggable() {
1898
- if (this.removeHiddenSubscription) {
1899
- this.removeHiddenSubscription.unsubscribe();
1900
- }
1901
- this.removeHiddenSubscription = this.sortableService.onReleaseSubject.pipe(take(1), filter(_ => this.sortableService.originDraggable !== null && this.sortableService.originDraggable.hidden)).subscribe((e) => {
1902
- const originDraggable = this.sortableService.originDraggable;
1903
- const newSource = this.sortableService.getSource();
1904
- if (originDraggable.parent !== this.sortableService.target) {
1905
- const isTargetDraggable = e.target ? (e.target.isDraggable || e.target.isDraggableChild) : false;
1906
- if (isTargetDraggable || originDraggable.parent !== newSource) {
1907
- if (originDraggable.parent !== this.sortableService.target) {
1908
- originDraggable.parent.removeDataItem(originDraggable.index);
1909
- }
1910
- }
1911
- this.sortableService.originDraggable = null;
1912
- }
1913
- });
1914
- }
1915
- onDragOver(event) {
1916
- const source = this.sortableService.getSource();
1917
- const target = this.sortableService.target;
1918
- const targetDraggables = target.draggables.toArray();
1919
- if (event.isDefaultPrevented()) {
1920
- return;
1921
- }
1922
- event.preventDefault();
1923
- if (target === source) {
1924
- // Skip moveItem if target is the draggable after which item was just added
1925
- // Ensures item added to the end stays there until further user action
1926
- if (targetDraggables[event.index] !== this.lastTarget) {
1927
- this.moveItem(event, target);
1928
- }
1929
- this.lastTarget = undefined;
1930
- }
1931
- else {
1932
- if (!target.itemEnabled(event.index)) {
1933
- event.index = this.nextEnabledIndex(event.index, target);
1934
- }
1935
- //Add to target and remove from source
1936
- if (this.addItem(event, target) && this.removeItem(event, source)) {
1937
- this.lastTarget = target.draggables.toArray()[event.index];
1938
- this.removeOriginDraggable();
1939
- target.activeIndex = event.index;
1940
- source.activeIndex = -1;
1941
- }
1942
- }
1943
- }
1944
- onNavigate(event) {
1945
- if (event.ctrlKey) {
1946
- const moveEvent = new DataMoveEvent({
1947
- dataItem: this.sortable.data[event.oldIndex],
1948
- index: event.index,
1949
- oldIndex: event.oldIndex
1950
- });
1951
- this.sortable.dataMove.emit(moveEvent);
1952
- if (!moveEvent.isDefaultPrevented()) {
1953
- this.sortable.moveItem(event.oldIndex, event.index);
1954
- }
1955
- }
1956
- else {
1957
- this.sortable.activeIndex = event.index;
1958
- }
1959
- }
1960
- ngOnInit() {
1961
- this.dragOverSubscription = this.sortable.dragOver.subscribe(this.onDragOver.bind(this));
1962
- this.navigateSubscription = this.sortable.navigate.subscribe(this.onNavigate.bind(this));
1963
- }
1964
- ngOnDestroy() {
1965
- this.dragOverSubscription.unsubscribe();
1966
- this.navigateSubscription.unsubscribe();
1967
- if (this.removeHiddenSubscription) {
1968
- this.removeHiddenSubscription.unsubscribe();
1969
- }
1970
- }
1971
- }
1972
- SortableBindingDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableBindingDirective, deps: [{ token: SortableComponent }, { token: SortableService }], target: i0.ɵɵFactoryTarget.Directive });
1973
- SortableBindingDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.2.10", type: SortableBindingDirective, isStandalone: true, selector: "[kendoSortableBinding]", inputs: { data: ["kendoSortableBinding", "data"] }, ngImport: i0 });
1974
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableBindingDirective, decorators: [{
1975
- type: Directive,
1976
- args: [{
1977
- selector: '[kendoSortableBinding]',
1978
- standalone: true
1979
- }]
1980
- }], ctorParameters: function () { return [{ type: SortableComponent }, { type: SortableService }]; }, propDecorators: { data: [{
1981
- type: Input,
1982
- args: ["kendoSortableBinding"]
1983
- }] } });
1984
-
1985
- /**
1986
- * Utility array that contains all `@progress/kendo-angular-sortable` related components and directives
1987
- */
1988
- const KENDO_SORTABLE = [
1989
- SortableComponent,
1990
- DraggableDirective,
1991
- PlaceholderTemplateDirective,
1992
- ItemTemplateDirective,
1993
- SortableBindingDirective
1994
- ];
1995
-
1996
- //IMPORTANT: NgModule export kept for backwards compatibility
1997
- /**
1998
- *
1999
- * Represents the [`NgModule`](link:site.data.urls.angular['ngmoduleapi'])
2000
- * definition for the Sortable component.
2001
- *
2002
- * @example
2003
- *
2004
- * ```ts-no-run
2005
- * import { NgModule } from '@angular/core';
2006
- * import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
2007
- *
2008
- * // Import the Sortable module
2009
- * import { SortableModule } from '@progress/kendo-angular-sortable';
2010
- *
2011
- * // Import the app component
2012
- * import { AppComponent } from './app.component';
2013
- *
2014
- * // Define the app module
2015
- * _@NgModule({
2016
- * declarations: [AppComponent],
2017
- * imports: [BrowserModule, SortableModule],
2018
- * bootstrap: [AppComponent]
2019
- * })
2020
- * export class AppModule {}
2021
- *
2022
- * // Compile and launch the module
2023
- * platformBrowserDynamic().bootstrapModule(AppModule);
2024
- *
2025
- * ```
2026
- */
2027
- class SortableModule {
2028
- }
2029
- SortableModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
2030
- SortableModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "15.2.10", ngImport: i0, type: SortableModule, imports: [SortableComponent, DraggableDirective, PlaceholderTemplateDirective, ItemTemplateDirective, SortableBindingDirective], exports: [SortableComponent, DraggableDirective, PlaceholderTemplateDirective, ItemTemplateDirective, SortableBindingDirective] });
2031
- SortableModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableModule, providers: [SortableService], imports: [SortableComponent] });
2032
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: SortableModule, decorators: [{
2033
- type: NgModule,
2034
- args: [{
2035
- imports: [...KENDO_SORTABLE],
2036
- exports: [...KENDO_SORTABLE],
2037
- providers: [SortableService]
2038
- }]
2039
- }] });
2040
-
2041
- /**
2042
- * Generated bundle index. Do not edit.
2043
- */
2044
-
2045
- export { DataMoveEvent, DragEndEvent, DragOverEvent, DragStartEvent, DraggableDirective, DraggableEvent, ItemTemplateDirective, KENDO_SORTABLE, NavigateEvent, PlaceholderTemplateDirective, PreventableEvent, SortableBindingDirective, SortableComponent, SortableContainer, SortableModule, SortableService };
2046
-