@angular/cdk 10.0.2 → 10.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/a11y/aria-describer/aria-describer.d.ts +10 -1
  2. package/a11y/index.metadata.json +1 -1
  3. package/a11y/interactivity-checker/interactivity-checker.d.ts +11 -1
  4. package/a11y/key-manager/list-key-manager.d.ts +6 -0
  5. package/accordion/accordion.d.ts +7 -1
  6. package/accordion/index.d.ts +1 -0
  7. package/accordion/index.metadata.json +1 -1
  8. package/bundles/cdk-a11y.umd.js +63 -11
  9. package/bundles/cdk-a11y.umd.js.map +1 -1
  10. package/bundles/cdk-a11y.umd.min.js +11 -11
  11. package/bundles/cdk-a11y.umd.min.js.map +1 -1
  12. package/bundles/cdk-accordion.umd.js +12 -4
  13. package/bundles/cdk-accordion.umd.js.map +1 -1
  14. package/bundles/cdk-accordion.umd.min.js +2 -2
  15. package/bundles/cdk-accordion.umd.min.js.map +1 -1
  16. package/bundles/cdk-drag-drop.umd.js +640 -599
  17. package/bundles/cdk-drag-drop.umd.js.map +1 -1
  18. package/bundles/cdk-drag-drop.umd.min.js +8 -16
  19. package/bundles/cdk-drag-drop.umd.min.js.map +1 -1
  20. package/bundles/cdk-overlay.umd.js +199 -42
  21. package/bundles/cdk-overlay.umd.js.map +1 -1
  22. package/bundles/cdk-overlay.umd.min.js +11 -18
  23. package/bundles/cdk-overlay.umd.min.js.map +1 -1
  24. package/bundles/cdk-platform.umd.min.js +1 -1
  25. package/bundles/cdk-platform.umd.min.js.map +1 -1
  26. package/bundles/cdk-scrolling.umd.js +9 -1
  27. package/bundles/cdk-scrolling.umd.js.map +1 -1
  28. package/bundles/cdk-scrolling.umd.min.js +7 -0
  29. package/bundles/cdk-scrolling.umd.min.js.map +1 -1
  30. package/bundles/cdk-testing-protractor.umd.min.js +1 -1
  31. package/bundles/cdk-testing-protractor.umd.min.js.map +1 -1
  32. package/bundles/cdk-testing-testbed.umd.min.js +8 -8
  33. package/bundles/cdk-testing-testbed.umd.min.js.map +1 -1
  34. package/bundles/cdk-testing.umd.js +32 -0
  35. package/bundles/cdk-testing.umd.js.map +1 -1
  36. package/bundles/cdk-testing.umd.min.js +5 -5
  37. package/bundles/cdk-testing.umd.min.js.map +1 -1
  38. package/bundles/cdk-tree.umd.js +6 -2
  39. package/bundles/cdk-tree.umd.js.map +1 -1
  40. package/bundles/cdk-tree.umd.min.js +3 -3
  41. package/bundles/cdk-tree.umd.min.js.map +1 -1
  42. package/bundles/cdk.umd.js +1 -1
  43. package/bundles/cdk.umd.js.map +1 -1
  44. package/bundles/cdk.umd.min.js +1 -1
  45. package/bundles/cdk.umd.min.js.map +1 -1
  46. package/drag-drop/directives/drag-handle.d.ts +7 -1
  47. package/drag-drop/directives/drag-placeholder.d.ts +7 -1
  48. package/drag-drop/directives/drag-preview.d.ts +7 -1
  49. package/drag-drop/directives/drag.d.ts +3 -7
  50. package/drag-drop/directives/drop-list-group.d.ts +7 -1
  51. package/drag-drop/directives/drop-list.d.ts +7 -1
  52. package/drag-drop/index.d.ts +2 -2
  53. package/drag-drop/index.metadata.json +1 -1
  54. package/esm2015/a11y/aria-describer/aria-describer.js +20 -6
  55. package/esm2015/a11y/interactivity-checker/interactivity-checker.js +16 -3
  56. package/esm2015/a11y/key-manager/list-key-manager.js +27 -2
  57. package/esm2015/accordion/accordion-item.js +7 -7
  58. package/esm2015/accordion/accordion.js +9 -2
  59. package/esm2015/accordion/index.js +2 -1
  60. package/esm2015/drag-drop/directives/drag-handle.js +11 -4
  61. package/esm2015/drag-drop/directives/drag-placeholder.js +10 -3
  62. package/esm2015/drag-drop/directives/drag-preview.js +10 -3
  63. package/esm2015/drag-drop/directives/drag.js +19 -15
  64. package/esm2015/drag-drop/directives/drop-list-group.js +9 -2
  65. package/esm2015/drag-drop/directives/drop-list.js +11 -6
  66. package/esm2015/drag-drop/index.js +3 -2
  67. package/esm2015/layout/breakpoints-observer.js +1 -1
  68. package/esm2015/overlay/dispatchers/base-overlay-dispatcher.js +51 -0
  69. package/esm2015/overlay/dispatchers/index.js +10 -0
  70. package/esm2015/overlay/dispatchers/overlay-keyboard-dispatcher.js +79 -0
  71. package/esm2015/overlay/dispatchers/overlay-outside-click-dispatcher.js +94 -0
  72. package/esm2015/overlay/index.js +5 -4
  73. package/esm2015/overlay/overlay-config.js +5 -1
  74. package/esm2015/overlay/overlay-directives.js +17 -7
  75. package/esm2015/overlay/overlay-module.js +2 -2
  76. package/esm2015/overlay/overlay-ref.js +24 -2
  77. package/esm2015/overlay/overlay-reference.js +1 -1
  78. package/esm2015/overlay/overlay.js +10 -5
  79. package/esm2015/overlay/position/overlay-position-builder.js +1 -1
  80. package/esm2015/overlay/public-api.js +2 -2
  81. package/esm2015/scrolling/public-api.js +2 -1
  82. package/esm2015/scrolling/virtual-for-of.js +1 -1
  83. package/esm2015/scrolling/virtual-scroll-repeater.js +8 -0
  84. package/esm2015/scrolling/virtual-scroll-viewport.js +2 -2
  85. package/esm2015/testing/component-harness.js +19 -1
  86. package/esm2015/testing/harness-environment.js +7 -1
  87. package/esm2015/tree/control/nested-tree-control.js +7 -3
  88. package/esm2015/version.js +1 -1
  89. package/fesm2015/a11y.js +60 -10
  90. package/fesm2015/a11y.js.map +1 -1
  91. package/fesm2015/accordion.js +13 -6
  92. package/fesm2015/accordion.js.map +1 -1
  93. package/fesm2015/cdk.js +1 -1
  94. package/fesm2015/cdk.js.map +1 -1
  95. package/fesm2015/drag-drop.js +607 -570
  96. package/fesm2015/drag-drop.js.map +1 -1
  97. package/fesm2015/overlay.js +196 -32
  98. package/fesm2015/overlay.js.map +1 -1
  99. package/fesm2015/scrolling.js +9 -1
  100. package/fesm2015/scrolling.js.map +1 -1
  101. package/fesm2015/testing.js +25 -1
  102. package/fesm2015/testing.js.map +1 -1
  103. package/fesm2015/tree.js +6 -2
  104. package/fesm2015/tree.js.map +1 -1
  105. package/overlay/dispatchers/base-overlay-dispatcher.d.ts +28 -0
  106. package/overlay/dispatchers/index.d.ts +9 -0
  107. package/overlay/{keyboard → dispatchers}/overlay-keyboard-dispatcher.d.ts +4 -10
  108. package/overlay/dispatchers/overlay-outside-click-dispatcher.d.ts +27 -0
  109. package/overlay/index.d.ts +4 -3
  110. package/overlay/index.metadata.json +1 -1
  111. package/overlay/overlay-config.d.ts +4 -0
  112. package/overlay/overlay-directives.d.ts +4 -0
  113. package/overlay/overlay-ref.d.ts +8 -2
  114. package/overlay/overlay-reference.d.ts +1 -0
  115. package/overlay/overlay.d.ts +4 -2
  116. package/overlay/public-api.d.ts +1 -1
  117. package/package.json +1 -1
  118. package/schematics/ng-add/index.js +1 -1
  119. package/scrolling/index.metadata.json +1 -1
  120. package/scrolling/public-api.d.ts +1 -0
  121. package/scrolling/virtual-for-of.d.ts +2 -1
  122. package/scrolling/virtual-scroll-repeater.d.ts +16 -0
  123. package/scrolling/virtual-scroll-viewport.d.ts +4 -4
  124. package/testing/component-harness.d.ts +12 -0
  125. package/testing/harness-environment.d.ts +1 -0
  126. package/tree/control/nested-tree-control.d.ts +7 -2
  127. package/tree/index.metadata.json +1 -1
  128. package/esm2015/overlay/keyboard/overlay-keyboard-dispatcher.js +0 -96
@@ -1,10 +1,10 @@
1
- import { ɵɵdefineInjectable, ɵɵinject, NgZone, Injectable, Inject, InjectionToken, Directive, ElementRef, Optional, Input, TemplateRef, EventEmitter, isDevMode, SkipSelf, ViewContainerRef, ChangeDetectorRef, ContentChildren, ContentChild, Output, NgModule } from '@angular/core';
1
+ import { ɵɵdefineInjectable, ɵɵinject, NgZone, Injectable, Inject, InjectionToken, Directive, Input, EventEmitter, ElementRef, ChangeDetectorRef, Optional, SkipSelf, Output, TemplateRef, isDevMode, ViewContainerRef, Self, ContentChildren, ContentChild, NgModule } from '@angular/core';
2
2
  import { DOCUMENT } from '@angular/common';
3
3
  import { ViewportRuler, ScrollDispatcher, CdkScrollableModule } from '@angular/cdk/scrolling';
4
4
  import { normalizePassiveListenerOptions, _getShadowRoot } from '@angular/cdk/platform';
5
- import { coerceBooleanProperty, coerceElement, coerceNumberProperty, coerceArray } from '@angular/cdk/coercion';
5
+ import { coerceBooleanProperty, coerceElement, coerceArray, coerceNumberProperty } from '@angular/cdk/coercion';
6
6
  import { Subject, Subscription, interval, animationFrameScheduler, Observable, merge } from 'rxjs';
7
- import { takeUntil, map, take, startWith, tap, switchMap } from 'rxjs/operators';
7
+ import { takeUntil, startWith, map, take, tap, switchMap } from 'rxjs/operators';
8
8
  import { Directionality } from '@angular/cdk/bidi';
9
9
 
10
10
  /**
@@ -2361,115 +2361,41 @@ DragDrop.ctorParameters = () => [
2361
2361
  * found in the LICENSE file at https://angular.io/license
2362
2362
  */
2363
2363
  /**
2364
- * Injection token that can be used for a `CdkDrag` to provide itself as a parent to the
2365
- * drag-specific child directive (`CdkDragHandle`, `CdkDragPreview` etc.). Used primarily
2366
- * to avoid circular imports.
2367
- * @docs-private
2364
+ * Injection token that can be used to reference instances of `CdkDropListGroup`. It serves as
2365
+ * alternative token to the actual `CdkDropListGroup` class which could cause unnecessary
2366
+ * retention of the class and its directive metadata.
2368
2367
  */
2369
- const CDK_DRAG_PARENT = new InjectionToken('CDK_DRAG_PARENT');
2370
-
2368
+ const CDK_DROP_LIST_GROUP = new InjectionToken('CdkDropListGroup');
2371
2369
  /**
2372
- * @license
2373
- * Copyright Google LLC All Rights Reserved.
2374
- *
2375
- * Use of this source code is governed by an MIT-style license that can be
2376
- * found in the LICENSE file at https://angular.io/license
2370
+ * Declaratively connects sibling `cdkDropList` instances together. All of the `cdkDropList`
2371
+ * elements that are placed inside a `cdkDropListGroup` will be connected to each other
2372
+ * automatically. Can be used as an alternative to the `cdkDropListConnectedTo` input
2373
+ * from `cdkDropList`.
2377
2374
  */
2378
- /** Handle that can be used to drag and CdkDrag instance. */
2379
- class CdkDragHandle {
2380
- constructor(element, parentDrag) {
2381
- this.element = element;
2382
- /** Emits when the state of the handle has changed. */
2383
- this._stateChanges = new Subject();
2375
+ class CdkDropListGroup {
2376
+ constructor() {
2377
+ /** Drop lists registered inside the group. */
2378
+ this._items = new Set();
2384
2379
  this._disabled = false;
2385
- this._parentDrag = parentDrag;
2386
- toggleNativeDragInteractions(element.nativeElement, false);
2387
2380
  }
2388
- /** Whether starting to drag through this handle is disabled. */
2381
+ /** Whether starting a dragging sequence from inside this group is disabled. */
2389
2382
  get disabled() { return this._disabled; }
2390
2383
  set disabled(value) {
2391
2384
  this._disabled = coerceBooleanProperty(value);
2392
- this._stateChanges.next(this);
2393
2385
  }
2394
2386
  ngOnDestroy() {
2395
- this._stateChanges.complete();
2396
- }
2397
- }
2398
- CdkDragHandle.decorators = [
2399
- { type: Directive, args: [{
2400
- selector: '[cdkDragHandle]',
2401
- host: {
2402
- 'class': 'cdk-drag-handle'
2403
- }
2404
- },] }
2405
- ];
2406
- CdkDragHandle.ctorParameters = () => [
2407
- { type: ElementRef },
2408
- { type: undefined, decorators: [{ type: Inject, args: [CDK_DRAG_PARENT,] }, { type: Optional }] }
2409
- ];
2410
- CdkDragHandle.propDecorators = {
2411
- disabled: [{ type: Input, args: ['cdkDragHandleDisabled',] }]
2412
- };
2413
-
2414
- /**
2415
- * @license
2416
- * Copyright Google LLC All Rights Reserved.
2417
- *
2418
- * Use of this source code is governed by an MIT-style license that can be
2419
- * found in the LICENSE file at https://angular.io/license
2420
- */
2421
- /**
2422
- * Element that will be used as a template for the placeholder of a CdkDrag when
2423
- * it is being dragged. The placeholder is displayed in place of the element being dragged.
2424
- */
2425
- class CdkDragPlaceholder {
2426
- constructor(templateRef) {
2427
- this.templateRef = templateRef;
2428
- }
2429
- }
2430
- CdkDragPlaceholder.decorators = [
2431
- { type: Directive, args: [{
2432
- selector: 'ng-template[cdkDragPlaceholder]'
2433
- },] }
2434
- ];
2435
- CdkDragPlaceholder.ctorParameters = () => [
2436
- { type: TemplateRef }
2437
- ];
2438
- CdkDragPlaceholder.propDecorators = {
2439
- data: [{ type: Input }]
2440
- };
2441
-
2442
- /**
2443
- * @license
2444
- * Copyright Google LLC All Rights Reserved.
2445
- *
2446
- * Use of this source code is governed by an MIT-style license that can be
2447
- * found in the LICENSE file at https://angular.io/license
2448
- */
2449
- /**
2450
- * Element that will be used as a template for the preview
2451
- * of a CdkDrag when it is being dragged.
2452
- */
2453
- class CdkDragPreview {
2454
- constructor(templateRef) {
2455
- this.templateRef = templateRef;
2456
- this._matchSize = false;
2387
+ this._items.clear();
2457
2388
  }
2458
- /** Whether the preview should preserve the same size as the item that is being dragged. */
2459
- get matchSize() { return this._matchSize; }
2460
- set matchSize(value) { this._matchSize = coerceBooleanProperty(value); }
2461
2389
  }
2462
- CdkDragPreview.decorators = [
2390
+ CdkDropListGroup.decorators = [
2463
2391
  { type: Directive, args: [{
2464
- selector: 'ng-template[cdkDragPreview]'
2392
+ selector: '[cdkDropListGroup]',
2393
+ exportAs: 'cdkDropListGroup',
2394
+ providers: [{ provide: CDK_DROP_LIST_GROUP, useExisting: CdkDropListGroup }],
2465
2395
  },] }
2466
2396
  ];
2467
- CdkDragPreview.ctorParameters = () => [
2468
- { type: TemplateRef }
2469
- ];
2470
- CdkDragPreview.propDecorators = {
2471
- data: [{ type: Input }],
2472
- matchSize: [{ type: Input }]
2397
+ CdkDropListGroup.propDecorators = {
2398
+ disabled: [{ type: Input, args: ['cdkDropListGroupDisabled',] }]
2473
2399
  };
2474
2400
 
2475
2401
  /**
@@ -2492,250 +2418,198 @@ const CDK_DRAG_CONFIG = new InjectionToken('CDK_DRAG_CONFIG');
2492
2418
  * Use of this source code is governed by an MIT-style license that can be
2493
2419
  * found in the LICENSE file at https://angular.io/license
2494
2420
  */
2421
+ /** Counter used to generate unique ids for drop zones. */
2422
+ let _uniqueIdCounter = 0;
2495
2423
  /**
2496
- * Injection token that is used to provide a CdkDropList instance to CdkDrag.
2497
- * Used for avoiding circular imports.
2424
+ * Injection token that can be used to reference instances of `CdkDropList`. It serves as
2425
+ * alternative token to the actual `CdkDropList` class which could cause unnecessary
2426
+ * retention of the class and its directive metadata.
2498
2427
  */
2499
- const CDK_DROP_LIST = new InjectionToken('CDK_DROP_LIST');
2500
- /** Element that can be moved inside a CdkDropList container. */
2501
- class CdkDrag {
2428
+ const CDK_DROP_LIST = new InjectionToken('CdkDropList');
2429
+ const ɵ0 = undefined;
2430
+ /** Container that wraps a set of draggable items. */
2431
+ class CdkDropList {
2502
2432
  constructor(
2503
- /** Element that the draggable is attached to. */
2504
- element,
2505
- /** Droppable container that the draggable is a part of. */
2506
- dropContainer, _document, _ngZone, _viewContainerRef, config, _dir, dragDrop, _changeDetectorRef) {
2433
+ /** Element that the drop list is attached to. */
2434
+ element, dragDrop, _changeDetectorRef, _dir, _group,
2435
+ /**
2436
+ * @deprecated _scrollDispatcher parameter to become required.
2437
+ * @breaking-change 11.0.0
2438
+ */
2439
+ _scrollDispatcher, config) {
2507
2440
  this.element = element;
2508
- this.dropContainer = dropContainer;
2509
- this._document = _document;
2510
- this._ngZone = _ngZone;
2511
- this._viewContainerRef = _viewContainerRef;
2512
- this._dir = _dir;
2513
2441
  this._changeDetectorRef = _changeDetectorRef;
2442
+ this._dir = _dir;
2443
+ this._group = _group;
2444
+ this._scrollDispatcher = _scrollDispatcher;
2445
+ /** Emits when the list has been destroyed. */
2514
2446
  this._destroyed = new Subject();
2515
- /** Emits when the user starts dragging the item. */
2516
- this.started = new EventEmitter();
2517
- /** Emits when the user has released a drag item, before any animations have started. */
2518
- this.released = new EventEmitter();
2519
- /** Emits when the user stops dragging an item in the container. */
2520
- this.ended = new EventEmitter();
2521
- /** Emits when the user has moved the item into a new container. */
2447
+ /**
2448
+ * Other draggable containers that this container is connected to and into which the
2449
+ * container's items can be transferred. Can either be references to other drop containers,
2450
+ * or their unique IDs.
2451
+ */
2452
+ this.connectedTo = [];
2453
+ /**
2454
+ * Unique ID for the drop zone. Can be used as a reference
2455
+ * in the `connectedTo` of another `CdkDropList`.
2456
+ */
2457
+ this.id = `cdk-drop-list-${_uniqueIdCounter++}`;
2458
+ /**
2459
+ * Function that is used to determine whether an item
2460
+ * is allowed to be moved into a drop container.
2461
+ */
2462
+ this.enterPredicate = () => true;
2463
+ /** Emits when the user drops an item inside the container. */
2464
+ this.dropped = new EventEmitter();
2465
+ /**
2466
+ * Emits when the user has moved a new drag item into this container.
2467
+ */
2522
2468
  this.entered = new EventEmitter();
2523
- /** Emits when the user removes the item its container by dragging it into another container. */
2469
+ /**
2470
+ * Emits when the user removes an item from the container
2471
+ * by dragging it into another container.
2472
+ */
2524
2473
  this.exited = new EventEmitter();
2525
- /** Emits when the user drops the item inside a container. */
2526
- this.dropped = new EventEmitter();
2474
+ /** Emits as the user is swapping items while actively dragging. */
2475
+ this.sorted = new EventEmitter();
2527
2476
  /**
2528
- * Emits as the user is dragging the item. Use with caution,
2529
- * because this event will fire for every pixel that the user has dragged.
2477
+ * Keeps track of the items that are registered with this container. Historically we used to
2478
+ * do this with a `ContentChildren` query, however queries don't handle transplanted views very
2479
+ * well which means that we can't handle cases like dragging the headers of a `mat-table`
2480
+ * correctly. What we do instead is to have the items register themselves with the container
2481
+ * and then we sort them based on their position in the DOM.
2530
2482
  */
2531
- this.moved = new Observable((observer) => {
2532
- const subscription = this._dragRef.moved.pipe(map(movedEvent => ({
2533
- source: this,
2534
- pointerPosition: movedEvent.pointerPosition,
2535
- event: movedEvent.event,
2536
- delta: movedEvent.delta,
2537
- distance: movedEvent.distance
2538
- }))).subscribe(observer);
2539
- return () => {
2540
- subscription.unsubscribe();
2541
- };
2542
- });
2543
- this._dragRef = dragDrop.createDrag(element, {
2544
- dragStartThreshold: config && config.dragStartThreshold != null ?
2545
- config.dragStartThreshold : 5,
2546
- pointerDirectionChangeThreshold: config && config.pointerDirectionChangeThreshold != null ?
2547
- config.pointerDirectionChangeThreshold : 5,
2548
- zIndex: config === null || config === void 0 ? void 0 : config.zIndex
2549
- });
2550
- this._dragRef.data = this;
2483
+ this._unsortedItems = new Set();
2484
+ this._dropListRef = dragDrop.createDropList(element);
2485
+ this._dropListRef.data = this;
2551
2486
  if (config) {
2552
2487
  this._assignDefaults(config);
2553
2488
  }
2554
- // Note that usually the container is assigned when the drop list is picks up the item, but in
2555
- // some cases (mainly transplanted views with OnPush, see #18341) we may end up in a situation
2556
- // where there are no items on the first change detection pass, but the items get picked up as
2557
- // soon as the user triggers another pass by dragging. This is a problem, because the item would
2558
- // have to switch from standalone mode to drag mode in the middle of the dragging sequence which
2559
- // is too late since the two modes save different kinds of information. We work around it by
2560
- // assigning the drop container both from here and the list.
2561
- if (dropContainer) {
2562
- this._dragRef._withDropContainer(dropContainer._dropListRef);
2563
- dropContainer.addItem(this);
2489
+ this._dropListRef.enterPredicate = (drag, drop) => {
2490
+ return this.enterPredicate(drag.data, drop.data);
2491
+ };
2492
+ this._setupInputSyncSubscription(this._dropListRef);
2493
+ this._handleEvents(this._dropListRef);
2494
+ CdkDropList._dropLists.push(this);
2495
+ if (_group) {
2496
+ _group._items.add(this);
2564
2497
  }
2565
- this._syncInputs(this._dragRef);
2566
- this._handleEvents(this._dragRef);
2567
2498
  }
2568
- /** Whether starting to drag this element is disabled. */
2499
+ /** Whether starting a dragging sequence from this container is disabled. */
2569
2500
  get disabled() {
2570
- return this._disabled || (this.dropContainer && this.dropContainer.disabled);
2501
+ return this._disabled || (!!this._group && this._group.disabled);
2571
2502
  }
2572
2503
  set disabled(value) {
2573
- this._disabled = coerceBooleanProperty(value);
2574
- this._dragRef.disabled = this._disabled;
2575
- }
2576
- /**
2577
- * Returns the element that is being used as a placeholder
2578
- * while the current element is being dragged.
2579
- */
2580
- getPlaceholderElement() {
2581
- return this._dragRef.getPlaceholderElement();
2504
+ // Usually we sync the directive and ref state right before dragging starts, in order to have
2505
+ // a single point of failure and to avoid having to use setters for everything. `disabled` is
2506
+ // a special case, because it can prevent the `beforeStarted` event from firing, which can lock
2507
+ // the user in a disabled state, so we also need to sync it as it's being set.
2508
+ this._dropListRef.disabled = this._disabled = coerceBooleanProperty(value);
2582
2509
  }
2583
- /** Returns the root draggable element. */
2584
- getRootElement() {
2585
- return this._dragRef.getRootElement();
2510
+ /** Registers an items with the drop list. */
2511
+ addItem(item) {
2512
+ this._unsortedItems.add(item);
2513
+ if (this._dropListRef.isDragging()) {
2514
+ this._syncItemsWithRef();
2515
+ }
2586
2516
  }
2587
- /** Resets a standalone drag item to its initial position. */
2588
- reset() {
2589
- this._dragRef.reset();
2517
+ /** Removes an item from the drop list. */
2518
+ removeItem(item) {
2519
+ this._unsortedItems.delete(item);
2520
+ if (this._dropListRef.isDragging()) {
2521
+ this._syncItemsWithRef();
2522
+ }
2590
2523
  }
2591
- /**
2592
- * Gets the pixel coordinates of the draggable outside of a drop container.
2593
- */
2594
- getFreeDragPosition() {
2595
- return this._dragRef.getFreeDragPosition();
2596
- }
2597
- ngAfterViewInit() {
2598
- // We need to wait for the zone to stabilize, in order for the reference
2599
- // element to be in the proper place in the DOM. This is mostly relevant
2600
- // for draggable elements inside portals since they get stamped out in
2601
- // their original DOM position and then they get transferred to the portal.
2602
- this._ngZone.onStable.asObservable()
2603
- .pipe(take(1), takeUntil(this._destroyed))
2604
- .subscribe(() => {
2605
- this._updateRootElement();
2606
- // Listen for any newly-added handles.
2607
- this._handles.changes.pipe(startWith(this._handles),
2608
- // Sync the new handles with the DragRef.
2609
- tap((handles) => {
2610
- const childHandleElements = handles
2611
- .filter(handle => handle._parentDrag === this)
2612
- .map(handle => handle.element);
2613
- this._dragRef.withHandles(childHandleElements);
2614
- }),
2615
- // Listen if the state of any of the handles changes.
2616
- switchMap((handles) => {
2617
- return merge(...handles.map(item => {
2618
- return item._stateChanges.pipe(startWith(item));
2619
- }));
2620
- }), takeUntil(this._destroyed)).subscribe(handleInstance => {
2621
- // Enabled/disable the handle that changed in the DragRef.
2622
- const dragRef = this._dragRef;
2623
- const handle = handleInstance.element.nativeElement;
2624
- handleInstance.disabled ? dragRef.disableHandle(handle) : dragRef.enableHandle(handle);
2625
- });
2626
- if (this.freeDragPosition) {
2627
- this._dragRef.setFreeDragPosition(this.freeDragPosition);
2628
- }
2524
+ /** Gets the registered items in the list, sorted by their position in the DOM. */
2525
+ getSortedItems() {
2526
+ return Array.from(this._unsortedItems).sort((a, b) => {
2527
+ const documentPosition = a._dragRef.getVisibleElement().compareDocumentPosition(b._dragRef.getVisibleElement());
2528
+ // `compareDocumentPosition` returns a bitmask so we have to use a bitwise operator.
2529
+ // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
2530
+ // tslint:disable-next-line:no-bitwise
2531
+ return documentPosition & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
2629
2532
  });
2630
2533
  }
2631
- ngOnChanges(changes) {
2632
- const rootSelectorChange = changes['rootElementSelector'];
2633
- const positionChange = changes['freeDragPosition'];
2634
- // We don't have to react to the first change since it's being
2635
- // handled in `ngAfterViewInit` where it needs to be deferred.
2636
- if (rootSelectorChange && !rootSelectorChange.firstChange) {
2637
- this._updateRootElement();
2638
- }
2639
- // Skip the first change since it's being handled in `ngAfterViewInit`.
2640
- if (positionChange && !positionChange.firstChange && this.freeDragPosition) {
2641
- this._dragRef.setFreeDragPosition(this.freeDragPosition);
2642
- }
2643
- }
2644
2534
  ngOnDestroy() {
2645
- if (this.dropContainer) {
2646
- this.dropContainer.removeItem(this);
2535
+ const index = CdkDropList._dropLists.indexOf(this);
2536
+ if (index > -1) {
2537
+ CdkDropList._dropLists.splice(index, 1);
2538
+ }
2539
+ if (this._group) {
2540
+ this._group._items.delete(this);
2647
2541
  }
2542
+ this._unsortedItems.clear();
2543
+ this._dropListRef.dispose();
2648
2544
  this._destroyed.next();
2649
2545
  this._destroyed.complete();
2650
- this._dragRef.dispose();
2651
- }
2652
- /** Syncs the root element with the `DragRef`. */
2653
- _updateRootElement() {
2654
- const element = this.element.nativeElement;
2655
- const rootElement = this.rootElementSelector ?
2656
- getClosestMatchingAncestor(element, this.rootElementSelector) : element;
2657
- if (rootElement && rootElement.nodeType !== this._document.ELEMENT_NODE) {
2658
- throw Error(`cdkDrag must be attached to an element node. ` +
2659
- `Currently attached to "${rootElement.nodeName}".`);
2660
- }
2661
- this._dragRef.withRootElement(rootElement || element);
2662
2546
  }
2663
- /** Gets the boundary element, based on the `boundaryElement` value. */
2664
- _getBoundaryElement() {
2665
- const boundary = this.boundaryElement;
2666
- if (!boundary) {
2667
- return null;
2668
- }
2669
- if (typeof boundary === 'string') {
2670
- return getClosestMatchingAncestor(this.element.nativeElement, boundary);
2671
- }
2672
- const element = coerceElement(boundary);
2673
- if (isDevMode() && !element.contains(this.element.nativeElement)) {
2674
- throw Error('Draggable element is not inside of the node passed into cdkDragBoundary.');
2547
+ /** Syncs the inputs of the CdkDropList with the options of the underlying DropListRef. */
2548
+ _setupInputSyncSubscription(ref) {
2549
+ if (this._dir) {
2550
+ this._dir.change
2551
+ .pipe(startWith(this._dir.value), takeUntil(this._destroyed))
2552
+ .subscribe(value => ref.withDirection(value));
2675
2553
  }
2676
- return element;
2677
- }
2678
- /** Syncs the inputs of the CdkDrag with the options of the underlying DragRef. */
2679
- _syncInputs(ref) {
2680
2554
  ref.beforeStarted.subscribe(() => {
2681
- if (!ref.isDragging()) {
2682
- const dir = this._dir;
2683
- const dragStartDelay = this.dragStartDelay;
2684
- const placeholder = this._placeholderTemplate ? {
2685
- template: this._placeholderTemplate.templateRef,
2686
- context: this._placeholderTemplate.data,
2687
- viewContainer: this._viewContainerRef
2688
- } : null;
2689
- const preview = this._previewTemplate ? {
2690
- template: this._previewTemplate.templateRef,
2691
- context: this._previewTemplate.data,
2692
- matchSize: this._previewTemplate.matchSize,
2693
- viewContainer: this._viewContainerRef
2694
- } : null;
2695
- ref.disabled = this.disabled;
2696
- ref.lockAxis = this.lockAxis;
2697
- ref.dragStartDelay = (typeof dragStartDelay === 'object' && dragStartDelay) ?
2698
- dragStartDelay : coerceNumberProperty(dragStartDelay);
2699
- ref.constrainPosition = this.constrainPosition;
2700
- ref.previewClass = this.previewClass;
2701
- ref
2702
- .withBoundaryElement(this._getBoundaryElement())
2703
- .withPlaceholderTemplate(placeholder)
2704
- .withPreviewTemplate(preview);
2705
- if (dir) {
2706
- ref.withDirection(dir.value);
2707
- }
2555
+ const siblings = coerceArray(this.connectedTo).map(drop => {
2556
+ return typeof drop === 'string' ?
2557
+ CdkDropList._dropLists.find(list => list.id === drop) : drop;
2558
+ });
2559
+ if (this._group) {
2560
+ this._group._items.forEach(drop => {
2561
+ if (siblings.indexOf(drop) === -1) {
2562
+ siblings.push(drop);
2563
+ }
2564
+ });
2565
+ }
2566
+ // Note that we resolve the scrollable parents here so that we delay the resolution
2567
+ // as long as possible, ensuring that the element is in its final place in the DOM.
2568
+ // @breaking-change 11.0.0 Remove null check for _scrollDispatcher once it's required.
2569
+ if (!this._scrollableParentsResolved && this._scrollDispatcher) {
2570
+ const scrollableParents = this._scrollDispatcher
2571
+ .getAncestorScrollContainers(this.element)
2572
+ .map(scrollable => scrollable.getElementRef().nativeElement);
2573
+ this._dropListRef.withScrollableParents(scrollableParents);
2574
+ // Only do this once since it involves traversing the DOM and the parents
2575
+ // shouldn't be able to change without the drop list being destroyed.
2576
+ this._scrollableParentsResolved = true;
2708
2577
  }
2578
+ ref.disabled = this.disabled;
2579
+ ref.lockAxis = this.lockAxis;
2580
+ ref.sortingDisabled = coerceBooleanProperty(this.sortingDisabled);
2581
+ ref.autoScrollDisabled = coerceBooleanProperty(this.autoScrollDisabled);
2582
+ ref
2583
+ .connectedTo(siblings.filter(drop => drop && drop !== this).map(list => list._dropListRef))
2584
+ .withOrientation(this.orientation);
2709
2585
  });
2710
2586
  }
2711
- /** Handles the events from the underlying `DragRef`. */
2587
+ /** Handles events from the underlying DropListRef. */
2712
2588
  _handleEvents(ref) {
2713
- ref.started.subscribe(() => {
2714
- this.started.emit({ source: this });
2715
- // Since all of these events run outside of change detection,
2716
- // we need to ensure that everything is marked correctly.
2717
- this._changeDetectorRef.markForCheck();
2718
- });
2719
- ref.released.subscribe(() => {
2720
- this.released.emit({ source: this });
2721
- });
2722
- ref.ended.subscribe(event => {
2723
- this.ended.emit({ source: this, distance: event.distance });
2724
- // Since all of these events run outside of change detection,
2725
- // we need to ensure that everything is marked correctly.
2589
+ ref.beforeStarted.subscribe(() => {
2590
+ this._syncItemsWithRef();
2726
2591
  this._changeDetectorRef.markForCheck();
2727
2592
  });
2728
2593
  ref.entered.subscribe(event => {
2729
2594
  this.entered.emit({
2730
- container: event.container.data,
2731
- item: this,
2595
+ container: this,
2596
+ item: event.item.data,
2732
2597
  currentIndex: event.currentIndex
2733
2598
  });
2734
2599
  });
2735
2600
  ref.exited.subscribe(event => {
2736
2601
  this.exited.emit({
2737
- container: event.container.data,
2738
- item: this
2602
+ container: this,
2603
+ item: event.item.data
2604
+ });
2605
+ this._changeDetectorRef.markForCheck();
2606
+ });
2607
+ ref.sorted.subscribe(event => {
2608
+ this.sorted.emit({
2609
+ previousIndex: event.previousIndex,
2610
+ currentIndex: event.currentIndex,
2611
+ container: this,
2612
+ item: event.item.data
2739
2613
  });
2740
2614
  });
2741
2615
  ref.dropped.subscribe(event => {
@@ -2744,91 +2618,75 @@ class CdkDrag {
2744
2618
  currentIndex: event.currentIndex,
2745
2619
  previousContainer: event.previousContainer.data,
2746
2620
  container: event.container.data,
2621
+ item: event.item.data,
2747
2622
  isPointerOverContainer: event.isPointerOverContainer,
2748
- item: this,
2749
2623
  distance: event.distance
2750
2624
  });
2625
+ // Mark for check since all of these events run outside of change
2626
+ // detection and we're not guaranteed for something else to have triggered it.
2627
+ this._changeDetectorRef.markForCheck();
2751
2628
  });
2752
2629
  }
2753
2630
  /** Assigns the default input values based on a provided config object. */
2754
2631
  _assignDefaults(config) {
2755
- const { lockAxis, dragStartDelay, constrainPosition, previewClass, boundaryElement, draggingDisabled, rootElementSelector } = config;
2632
+ const { lockAxis, draggingDisabled, sortingDisabled, listAutoScrollDisabled, listOrientation } = config;
2756
2633
  this.disabled = draggingDisabled == null ? false : draggingDisabled;
2757
- this.dragStartDelay = dragStartDelay || 0;
2634
+ this.sortingDisabled = sortingDisabled == null ? false : sortingDisabled;
2635
+ this.autoScrollDisabled = listAutoScrollDisabled == null ? false : listAutoScrollDisabled;
2636
+ this.orientation = listOrientation || 'vertical';
2758
2637
  if (lockAxis) {
2759
2638
  this.lockAxis = lockAxis;
2760
2639
  }
2761
- if (constrainPosition) {
2762
- this.constrainPosition = constrainPosition;
2763
- }
2764
- if (previewClass) {
2765
- this.previewClass = previewClass;
2766
- }
2767
- if (boundaryElement) {
2768
- this.boundaryElement = boundaryElement;
2769
- }
2770
- if (rootElementSelector) {
2771
- this.rootElementSelector = rootElementSelector;
2772
- }
2640
+ }
2641
+ /** Syncs up the registered drag items with underlying drop list ref. */
2642
+ _syncItemsWithRef() {
2643
+ this._dropListRef.withItems(this.getSortedItems().map(item => item._dragRef));
2773
2644
  }
2774
2645
  }
2775
- CdkDrag.decorators = [
2646
+ /** Keeps track of the drop lists that are currently on the page. */
2647
+ CdkDropList._dropLists = [];
2648
+ CdkDropList.decorators = [
2776
2649
  { type: Directive, args: [{
2777
- selector: '[cdkDrag]',
2778
- exportAs: 'cdkDrag',
2650
+ selector: '[cdkDropList], cdk-drop-list',
2651
+ exportAs: 'cdkDropList',
2652
+ providers: [
2653
+ // Prevent child drop lists from picking up the same group as their parent.
2654
+ { provide: CDK_DROP_LIST_GROUP, useValue: ɵ0 },
2655
+ { provide: CDK_DROP_LIST, useExisting: CdkDropList },
2656
+ ],
2779
2657
  host: {
2780
- 'class': 'cdk-drag',
2781
- '[class.cdk-drag-disabled]': 'disabled',
2782
- '[class.cdk-drag-dragging]': '_dragRef.isDragging()',
2783
- },
2784
- providers: [{ provide: CDK_DRAG_PARENT, useExisting: CdkDrag }]
2658
+ 'class': 'cdk-drop-list',
2659
+ '[id]': 'id',
2660
+ '[class.cdk-drop-list-disabled]': 'disabled',
2661
+ '[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()',
2662
+ '[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()',
2663
+ }
2785
2664
  },] }
2786
2665
  ];
2787
- CdkDrag.ctorParameters = () => [
2666
+ CdkDropList.ctorParameters = () => [
2788
2667
  { type: ElementRef },
2789
- { type: undefined, decorators: [{ type: Inject, args: [CDK_DROP_LIST,] }, { type: Optional }, { type: SkipSelf }] },
2790
- { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
2791
- { type: NgZone },
2792
- { type: ViewContainerRef },
2793
- { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CDK_DRAG_CONFIG,] }] },
2794
- { type: Directionality, decorators: [{ type: Optional }] },
2795
2668
  { type: DragDrop },
2796
- { type: ChangeDetectorRef }
2669
+ { type: ChangeDetectorRef },
2670
+ { type: Directionality, decorators: [{ type: Optional }] },
2671
+ { type: CdkDropListGroup, decorators: [{ type: Optional }, { type: Inject, args: [CDK_DROP_LIST_GROUP,] }, { type: SkipSelf }] },
2672
+ { type: ScrollDispatcher },
2673
+ { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CDK_DRAG_CONFIG,] }] }
2797
2674
  ];
2798
- CdkDrag.propDecorators = {
2799
- _handles: [{ type: ContentChildren, args: [CdkDragHandle, { descendants: true },] }],
2800
- _previewTemplate: [{ type: ContentChild, args: [CdkDragPreview,] }],
2801
- _placeholderTemplate: [{ type: ContentChild, args: [CdkDragPlaceholder,] }],
2802
- data: [{ type: Input, args: ['cdkDragData',] }],
2803
- lockAxis: [{ type: Input, args: ['cdkDragLockAxis',] }],
2804
- rootElementSelector: [{ type: Input, args: ['cdkDragRootElement',] }],
2805
- boundaryElement: [{ type: Input, args: ['cdkDragBoundary',] }],
2806
- dragStartDelay: [{ type: Input, args: ['cdkDragStartDelay',] }],
2807
- freeDragPosition: [{ type: Input, args: ['cdkDragFreeDragPosition',] }],
2808
- disabled: [{ type: Input, args: ['cdkDragDisabled',] }],
2809
- constrainPosition: [{ type: Input, args: ['cdkDragConstrainPosition',] }],
2810
- previewClass: [{ type: Input, args: ['cdkDragPreviewClass',] }],
2811
- started: [{ type: Output, args: ['cdkDragStarted',] }],
2812
- released: [{ type: Output, args: ['cdkDragReleased',] }],
2813
- ended: [{ type: Output, args: ['cdkDragEnded',] }],
2814
- entered: [{ type: Output, args: ['cdkDragEntered',] }],
2815
- exited: [{ type: Output, args: ['cdkDragExited',] }],
2816
- dropped: [{ type: Output, args: ['cdkDragDropped',] }],
2817
- moved: [{ type: Output, args: ['cdkDragMoved',] }]
2675
+ CdkDropList.propDecorators = {
2676
+ connectedTo: [{ type: Input, args: ['cdkDropListConnectedTo',] }],
2677
+ data: [{ type: Input, args: ['cdkDropListData',] }],
2678
+ orientation: [{ type: Input, args: ['cdkDropListOrientation',] }],
2679
+ id: [{ type: Input }],
2680
+ lockAxis: [{ type: Input, args: ['cdkDropListLockAxis',] }],
2681
+ disabled: [{ type: Input, args: ['cdkDropListDisabled',] }],
2682
+ sortingDisabled: [{ type: Input, args: ['cdkDropListSortingDisabled',] }],
2683
+ enterPredicate: [{ type: Input, args: ['cdkDropListEnterPredicate',] }],
2684
+ autoScrollDisabled: [{ type: Input, args: ['cdkDropListAutoScrollDisabled',] }],
2685
+ dropped: [{ type: Output, args: ['cdkDropListDropped',] }],
2686
+ entered: [{ type: Output, args: ['cdkDropListEntered',] }],
2687
+ exited: [{ type: Output, args: ['cdkDropListExited',] }],
2688
+ sorted: [{ type: Output, args: ['cdkDropListSorted',] }]
2818
2689
  };
2819
- /** Gets the closest ancestor of an element that matches a selector. */
2820
- function getClosestMatchingAncestor(element, selector) {
2821
- let currentElement = element.parentElement;
2822
- while (currentElement) {
2823
- // IE doesn't support `matches` so we have to fall back to `msMatchesSelector`.
2824
- if (currentElement.matches ? currentElement.matches(selector) :
2825
- currentElement.msMatchesSelector(selector)) {
2826
- return currentElement;
2827
- }
2828
- currentElement = currentElement.parentElement;
2829
- }
2830
- return null;
2831
- }
2832
2690
 
2833
2691
  /**
2834
2692
  * @license
@@ -2838,34 +2696,61 @@ function getClosestMatchingAncestor(element, selector) {
2838
2696
  * found in the LICENSE file at https://angular.io/license
2839
2697
  */
2840
2698
  /**
2841
- * Declaratively connects sibling `cdkDropList` instances together. All of the `cdkDropList`
2842
- * elements that are placed inside a `cdkDropListGroup` will be connected to each other
2843
- * automatically. Can be used as an alternative to the `cdkDropListConnectedTo` input
2844
- * from `cdkDropList`.
2699
+ * Injection token that can be used for a `CdkDrag` to provide itself as a parent to the
2700
+ * drag-specific child directive (`CdkDragHandle`, `CdkDragPreview` etc.). Used primarily
2701
+ * to avoid circular imports.
2702
+ * @docs-private
2845
2703
  */
2846
- class CdkDropListGroup {
2847
- constructor() {
2848
- /** Drop lists registered inside the group. */
2849
- this._items = new Set();
2704
+ const CDK_DRAG_PARENT = new InjectionToken('CDK_DRAG_PARENT');
2705
+
2706
+ /**
2707
+ * @license
2708
+ * Copyright Google LLC All Rights Reserved.
2709
+ *
2710
+ * Use of this source code is governed by an MIT-style license that can be
2711
+ * found in the LICENSE file at https://angular.io/license
2712
+ */
2713
+ /**
2714
+ * Injection token that can be used to reference instances of `CdkDragHandle`. It serves as
2715
+ * alternative token to the actual `CdkDragHandle` class which could cause unnecessary
2716
+ * retention of the class and its directive metadata.
2717
+ */
2718
+ const CDK_DRAG_HANDLE = new InjectionToken('CdkDragHandle');
2719
+ /** Handle that can be used to drag and CdkDrag instance. */
2720
+ class CdkDragHandle {
2721
+ constructor(element, parentDrag) {
2722
+ this.element = element;
2723
+ /** Emits when the state of the handle has changed. */
2724
+ this._stateChanges = new Subject();
2850
2725
  this._disabled = false;
2726
+ this._parentDrag = parentDrag;
2727
+ toggleNativeDragInteractions(element.nativeElement, false);
2851
2728
  }
2852
- /** Whether starting a dragging sequence from inside this group is disabled. */
2729
+ /** Whether starting to drag through this handle is disabled. */
2853
2730
  get disabled() { return this._disabled; }
2854
2731
  set disabled(value) {
2855
2732
  this._disabled = coerceBooleanProperty(value);
2733
+ this._stateChanges.next(this);
2856
2734
  }
2857
2735
  ngOnDestroy() {
2858
- this._items.clear();
2736
+ this._stateChanges.complete();
2859
2737
  }
2860
2738
  }
2861
- CdkDropListGroup.decorators = [
2739
+ CdkDragHandle.decorators = [
2862
2740
  { type: Directive, args: [{
2863
- selector: '[cdkDropListGroup]',
2864
- exportAs: 'cdkDropListGroup',
2741
+ selector: '[cdkDragHandle]',
2742
+ host: {
2743
+ 'class': 'cdk-drag-handle'
2744
+ },
2745
+ providers: [{ provide: CDK_DRAG_HANDLE, useExisting: CdkDragHandle }],
2865
2746
  },] }
2866
2747
  ];
2867
- CdkDropListGroup.propDecorators = {
2868
- disabled: [{ type: Input, args: ['cdkDropListGroupDisabled',] }]
2748
+ CdkDragHandle.ctorParameters = () => [
2749
+ { type: ElementRef },
2750
+ { type: undefined, decorators: [{ type: Inject, args: [CDK_DRAG_PARENT,] }, { type: Optional }, { type: SkipSelf }] }
2751
+ ];
2752
+ CdkDragHandle.propDecorators = {
2753
+ disabled: [{ type: Input, args: ['cdkDragHandleDisabled',] }]
2869
2754
  };
2870
2755
 
2871
2756
  /**
@@ -2875,192 +2760,327 @@ CdkDropListGroup.propDecorators = {
2875
2760
  * Use of this source code is governed by an MIT-style license that can be
2876
2761
  * found in the LICENSE file at https://angular.io/license
2877
2762
  */
2878
- /** Counter used to generate unique ids for drop zones. */
2879
- let _uniqueIdCounter = 0;
2880
- const ɵ0 = undefined;
2881
- /** Container that wraps a set of draggable items. */
2882
- class CdkDropList {
2763
+ /**
2764
+ * Injection token that can be used to reference instances of `CdkDragPlaceholder`. It serves as
2765
+ * alternative token to the actual `CdkDragPlaceholder` class which could cause unnecessary
2766
+ * retention of the class and its directive metadata.
2767
+ */
2768
+ const CDK_DRAG_PLACEHOLDER = new InjectionToken('CdkDragPlaceholder');
2769
+ /**
2770
+ * Element that will be used as a template for the placeholder of a CdkDrag when
2771
+ * it is being dragged. The placeholder is displayed in place of the element being dragged.
2772
+ */
2773
+ class CdkDragPlaceholder {
2774
+ constructor(templateRef) {
2775
+ this.templateRef = templateRef;
2776
+ }
2777
+ }
2778
+ CdkDragPlaceholder.decorators = [
2779
+ { type: Directive, args: [{
2780
+ selector: 'ng-template[cdkDragPlaceholder]',
2781
+ providers: [{ provide: CDK_DRAG_PLACEHOLDER, useExisting: CdkDragPlaceholder }],
2782
+ },] }
2783
+ ];
2784
+ CdkDragPlaceholder.ctorParameters = () => [
2785
+ { type: TemplateRef }
2786
+ ];
2787
+ CdkDragPlaceholder.propDecorators = {
2788
+ data: [{ type: Input }]
2789
+ };
2790
+
2791
+ /**
2792
+ * @license
2793
+ * Copyright Google LLC All Rights Reserved.
2794
+ *
2795
+ * Use of this source code is governed by an MIT-style license that can be
2796
+ * found in the LICENSE file at https://angular.io/license
2797
+ */
2798
+ /**
2799
+ * Injection token that can be used to reference instances of `CdkDragPreview`. It serves as
2800
+ * alternative token to the actual `CdkDragPreview` class which could cause unnecessary
2801
+ * retention of the class and its directive metadata.
2802
+ */
2803
+ const CDK_DRAG_PREVIEW = new InjectionToken('CdkDragPreview');
2804
+ /**
2805
+ * Element that will be used as a template for the preview
2806
+ * of a CdkDrag when it is being dragged.
2807
+ */
2808
+ class CdkDragPreview {
2809
+ constructor(templateRef) {
2810
+ this.templateRef = templateRef;
2811
+ this._matchSize = false;
2812
+ }
2813
+ /** Whether the preview should preserve the same size as the item that is being dragged. */
2814
+ get matchSize() { return this._matchSize; }
2815
+ set matchSize(value) { this._matchSize = coerceBooleanProperty(value); }
2816
+ }
2817
+ CdkDragPreview.decorators = [
2818
+ { type: Directive, args: [{
2819
+ selector: 'ng-template[cdkDragPreview]',
2820
+ providers: [{ provide: CDK_DRAG_PREVIEW, useExisting: CdkDragPreview }],
2821
+ },] }
2822
+ ];
2823
+ CdkDragPreview.ctorParameters = () => [
2824
+ { type: TemplateRef }
2825
+ ];
2826
+ CdkDragPreview.propDecorators = {
2827
+ data: [{ type: Input }],
2828
+ matchSize: [{ type: Input }]
2829
+ };
2830
+
2831
+ /**
2832
+ * @license
2833
+ * Copyright Google LLC All Rights Reserved.
2834
+ *
2835
+ * Use of this source code is governed by an MIT-style license that can be
2836
+ * found in the LICENSE file at https://angular.io/license
2837
+ */
2838
+ /** Element that can be moved inside a CdkDropList container. */
2839
+ class CdkDrag {
2883
2840
  constructor(
2884
- /** Element that the drop list is attached to. */
2885
- element, dragDrop, _changeDetectorRef, _dir, _group,
2886
- /**
2887
- * @deprecated _scrollDispatcher parameter to become required.
2888
- * @breaking-change 11.0.0
2889
- */
2890
- _scrollDispatcher, config) {
2841
+ /** Element that the draggable is attached to. */
2842
+ element,
2843
+ /** Droppable container that the draggable is a part of. */
2844
+ dropContainer, _document, _ngZone, _viewContainerRef, config, _dir, dragDrop, _changeDetectorRef, _selfHandle) {
2891
2845
  this.element = element;
2892
- this._changeDetectorRef = _changeDetectorRef;
2846
+ this.dropContainer = dropContainer;
2847
+ this._document = _document;
2848
+ this._ngZone = _ngZone;
2849
+ this._viewContainerRef = _viewContainerRef;
2893
2850
  this._dir = _dir;
2894
- this._group = _group;
2895
- this._scrollDispatcher = _scrollDispatcher;
2896
- /** Emits when the list has been destroyed. */
2851
+ this._changeDetectorRef = _changeDetectorRef;
2852
+ this._selfHandle = _selfHandle;
2897
2853
  this._destroyed = new Subject();
2898
- /**
2899
- * Other draggable containers that this container is connected to and into which the
2900
- * container's items can be transferred. Can either be references to other drop containers,
2901
- * or their unique IDs.
2902
- */
2903
- this.connectedTo = [];
2904
- /**
2905
- * Unique ID for the drop zone. Can be used as a reference
2906
- * in the `connectedTo` of another `CdkDropList`.
2907
- */
2908
- this.id = `cdk-drop-list-${_uniqueIdCounter++}`;
2909
- /**
2910
- * Function that is used to determine whether an item
2911
- * is allowed to be moved into a drop container.
2912
- */
2913
- this.enterPredicate = () => true;
2914
- /** Emits when the user drops an item inside the container. */
2915
- this.dropped = new EventEmitter();
2916
- /**
2917
- * Emits when the user has moved a new drag item into this container.
2918
- */
2854
+ /** Emits when the user starts dragging the item. */
2855
+ this.started = new EventEmitter();
2856
+ /** Emits when the user has released a drag item, before any animations have started. */
2857
+ this.released = new EventEmitter();
2858
+ /** Emits when the user stops dragging an item in the container. */
2859
+ this.ended = new EventEmitter();
2860
+ /** Emits when the user has moved the item into a new container. */
2919
2861
  this.entered = new EventEmitter();
2920
- /**
2921
- * Emits when the user removes an item from the container
2922
- * by dragging it into another container.
2923
- */
2862
+ /** Emits when the user removes the item its container by dragging it into another container. */
2924
2863
  this.exited = new EventEmitter();
2925
- /** Emits as the user is swapping items while actively dragging. */
2926
- this.sorted = new EventEmitter();
2864
+ /** Emits when the user drops the item inside a container. */
2865
+ this.dropped = new EventEmitter();
2927
2866
  /**
2928
- * Keeps track of the items that are registered with this container. Historically we used to
2929
- * do this with a `ContentChildren` query, however queries don't handle transplanted views very
2930
- * well which means that we can't handle cases like dragging the headers of a `mat-table`
2931
- * correctly. What we do instead is to have the items register themselves with the container
2932
- * and then we sort them based on their position in the DOM.
2867
+ * Emits as the user is dragging the item. Use with caution,
2868
+ * because this event will fire for every pixel that the user has dragged.
2933
2869
  */
2934
- this._unsortedItems = new Set();
2935
- this._dropListRef = dragDrop.createDropList(element);
2936
- this._dropListRef.data = this;
2870
+ this.moved = new Observable((observer) => {
2871
+ const subscription = this._dragRef.moved.pipe(map(movedEvent => ({
2872
+ source: this,
2873
+ pointerPosition: movedEvent.pointerPosition,
2874
+ event: movedEvent.event,
2875
+ delta: movedEvent.delta,
2876
+ distance: movedEvent.distance
2877
+ }))).subscribe(observer);
2878
+ return () => {
2879
+ subscription.unsubscribe();
2880
+ };
2881
+ });
2882
+ this._dragRef = dragDrop.createDrag(element, {
2883
+ dragStartThreshold: config && config.dragStartThreshold != null ?
2884
+ config.dragStartThreshold : 5,
2885
+ pointerDirectionChangeThreshold: config && config.pointerDirectionChangeThreshold != null ?
2886
+ config.pointerDirectionChangeThreshold : 5,
2887
+ zIndex: config === null || config === void 0 ? void 0 : config.zIndex
2888
+ });
2889
+ this._dragRef.data = this;
2937
2890
  if (config) {
2938
2891
  this._assignDefaults(config);
2939
2892
  }
2940
- this._dropListRef.enterPredicate = (drag, drop) => {
2941
- return this.enterPredicate(drag.data, drop.data);
2942
- };
2943
- this._setupInputSyncSubscription(this._dropListRef);
2944
- this._handleEvents(this._dropListRef);
2945
- CdkDropList._dropLists.push(this);
2946
- if (_group) {
2947
- _group._items.add(this);
2893
+ // Note that usually the container is assigned when the drop list is picks up the item, but in
2894
+ // some cases (mainly transplanted views with OnPush, see #18341) we may end up in a situation
2895
+ // where there are no items on the first change detection pass, but the items get picked up as
2896
+ // soon as the user triggers another pass by dragging. This is a problem, because the item would
2897
+ // have to switch from standalone mode to drag mode in the middle of the dragging sequence which
2898
+ // is too late since the two modes save different kinds of information. We work around it by
2899
+ // assigning the drop container both from here and the list.
2900
+ if (dropContainer) {
2901
+ this._dragRef._withDropContainer(dropContainer._dropListRef);
2902
+ dropContainer.addItem(this);
2948
2903
  }
2904
+ this._syncInputs(this._dragRef);
2905
+ this._handleEvents(this._dragRef);
2949
2906
  }
2950
- /** Whether starting a dragging sequence from this container is disabled. */
2907
+ /** Whether starting to drag this element is disabled. */
2951
2908
  get disabled() {
2952
- return this._disabled || (!!this._group && this._group.disabled);
2909
+ return this._disabled || (this.dropContainer && this.dropContainer.disabled);
2953
2910
  }
2954
2911
  set disabled(value) {
2955
- // Usually we sync the directive and ref state right before dragging starts, in order to have
2956
- // a single point of failure and to avoid having to use setters for everything. `disabled` is
2957
- // a special case, because it can prevent the `beforeStarted` event from firing, which can lock
2958
- // the user in a disabled state, so we also need to sync it as it's being set.
2959
- this._dropListRef.disabled = this._disabled = coerceBooleanProperty(value);
2912
+ this._disabled = coerceBooleanProperty(value);
2913
+ this._dragRef.disabled = this._disabled;
2960
2914
  }
2961
- /** Registers an items with the drop list. */
2962
- addItem(item) {
2963
- this._unsortedItems.add(item);
2964
- if (this._dropListRef.isDragging()) {
2965
- this._syncItemsWithRef();
2966
- }
2915
+ /**
2916
+ * Returns the element that is being used as a placeholder
2917
+ * while the current element is being dragged.
2918
+ */
2919
+ getPlaceholderElement() {
2920
+ return this._dragRef.getPlaceholderElement();
2967
2921
  }
2968
- /** Removes an item from the drop list. */
2969
- removeItem(item) {
2970
- this._unsortedItems.delete(item);
2971
- if (this._dropListRef.isDragging()) {
2972
- this._syncItemsWithRef();
2973
- }
2922
+ /** Returns the root draggable element. */
2923
+ getRootElement() {
2924
+ return this._dragRef.getRootElement();
2974
2925
  }
2975
- /** Gets the registered items in the list, sorted by their position in the DOM. */
2976
- getSortedItems() {
2977
- return Array.from(this._unsortedItems).sort((a, b) => {
2978
- const documentPosition = a._dragRef.getVisibleElement().compareDocumentPosition(b._dragRef.getVisibleElement());
2979
- // `compareDocumentPosition` returns a bitmask so we have to use a bitwise operator.
2980
- // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
2981
- // tslint:disable-next-line:no-bitwise
2982
- return documentPosition & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
2926
+ /** Resets a standalone drag item to its initial position. */
2927
+ reset() {
2928
+ this._dragRef.reset();
2929
+ }
2930
+ /**
2931
+ * Gets the pixel coordinates of the draggable outside of a drop container.
2932
+ */
2933
+ getFreeDragPosition() {
2934
+ return this._dragRef.getFreeDragPosition();
2935
+ }
2936
+ ngAfterViewInit() {
2937
+ // We need to wait for the zone to stabilize, in order for the reference
2938
+ // element to be in the proper place in the DOM. This is mostly relevant
2939
+ // for draggable elements inside portals since they get stamped out in
2940
+ // their original DOM position and then they get transferred to the portal.
2941
+ this._ngZone.onStable.asObservable()
2942
+ .pipe(take(1), takeUntil(this._destroyed))
2943
+ .subscribe(() => {
2944
+ this._updateRootElement();
2945
+ // Listen for any newly-added handles.
2946
+ this._handles.changes.pipe(startWith(this._handles),
2947
+ // Sync the new handles with the DragRef.
2948
+ tap((handles) => {
2949
+ const childHandleElements = handles
2950
+ .filter(handle => handle._parentDrag === this)
2951
+ .map(handle => handle.element);
2952
+ // Usually handles are only allowed to be a descendant of the drag element, but if
2953
+ // the consumer defined a different drag root, we should allow the drag element
2954
+ // itself to be a handle too.
2955
+ if (this._selfHandle && this.rootElementSelector) {
2956
+ childHandleElements.push(this.element);
2957
+ }
2958
+ this._dragRef.withHandles(childHandleElements);
2959
+ }),
2960
+ // Listen if the state of any of the handles changes.
2961
+ switchMap((handles) => {
2962
+ return merge(...handles.map(item => {
2963
+ return item._stateChanges.pipe(startWith(item));
2964
+ }));
2965
+ }), takeUntil(this._destroyed)).subscribe(handleInstance => {
2966
+ // Enabled/disable the handle that changed in the DragRef.
2967
+ const dragRef = this._dragRef;
2968
+ const handle = handleInstance.element.nativeElement;
2969
+ handleInstance.disabled ? dragRef.disableHandle(handle) : dragRef.enableHandle(handle);
2970
+ });
2971
+ if (this.freeDragPosition) {
2972
+ this._dragRef.setFreeDragPosition(this.freeDragPosition);
2973
+ }
2983
2974
  });
2984
2975
  }
2985
- ngOnDestroy() {
2986
- const index = CdkDropList._dropLists.indexOf(this);
2987
- if (index > -1) {
2988
- CdkDropList._dropLists.splice(index, 1);
2976
+ ngOnChanges(changes) {
2977
+ const rootSelectorChange = changes['rootElementSelector'];
2978
+ const positionChange = changes['freeDragPosition'];
2979
+ // We don't have to react to the first change since it's being
2980
+ // handled in `ngAfterViewInit` where it needs to be deferred.
2981
+ if (rootSelectorChange && !rootSelectorChange.firstChange) {
2982
+ this._updateRootElement();
2989
2983
  }
2990
- if (this._group) {
2991
- this._group._items.delete(this);
2984
+ // Skip the first change since it's being handled in `ngAfterViewInit`.
2985
+ if (positionChange && !positionChange.firstChange && this.freeDragPosition) {
2986
+ this._dragRef.setFreeDragPosition(this.freeDragPosition);
2987
+ }
2988
+ }
2989
+ ngOnDestroy() {
2990
+ if (this.dropContainer) {
2991
+ this.dropContainer.removeItem(this);
2992
2992
  }
2993
- this._unsortedItems.clear();
2994
- this._dropListRef.dispose();
2995
2993
  this._destroyed.next();
2996
2994
  this._destroyed.complete();
2995
+ this._dragRef.dispose();
2997
2996
  }
2998
- /** Syncs the inputs of the CdkDropList with the options of the underlying DropListRef. */
2999
- _setupInputSyncSubscription(ref) {
3000
- if (this._dir) {
3001
- this._dir.change
3002
- .pipe(startWith(this._dir.value), takeUntil(this._destroyed))
3003
- .subscribe(value => ref.withDirection(value));
2997
+ /** Syncs the root element with the `DragRef`. */
2998
+ _updateRootElement() {
2999
+ const element = this.element.nativeElement;
3000
+ const rootElement = this.rootElementSelector ?
3001
+ getClosestMatchingAncestor(element, this.rootElementSelector) : element;
3002
+ if (rootElement && rootElement.nodeType !== this._document.ELEMENT_NODE) {
3003
+ throw Error(`cdkDrag must be attached to an element node. ` +
3004
+ `Currently attached to "${rootElement.nodeName}".`);
3005
+ }
3006
+ this._dragRef.withRootElement(rootElement || element);
3007
+ }
3008
+ /** Gets the boundary element, based on the `boundaryElement` value. */
3009
+ _getBoundaryElement() {
3010
+ const boundary = this.boundaryElement;
3011
+ if (!boundary) {
3012
+ return null;
3013
+ }
3014
+ if (typeof boundary === 'string') {
3015
+ return getClosestMatchingAncestor(this.element.nativeElement, boundary);
3016
+ }
3017
+ const element = coerceElement(boundary);
3018
+ if (isDevMode() && !element.contains(this.element.nativeElement)) {
3019
+ throw Error('Draggable element is not inside of the node passed into cdkDragBoundary.');
3004
3020
  }
3021
+ return element;
3022
+ }
3023
+ /** Syncs the inputs of the CdkDrag with the options of the underlying DragRef. */
3024
+ _syncInputs(ref) {
3005
3025
  ref.beforeStarted.subscribe(() => {
3006
- const siblings = coerceArray(this.connectedTo).map(drop => {
3007
- return typeof drop === 'string' ?
3008
- CdkDropList._dropLists.find(list => list.id === drop) : drop;
3009
- });
3010
- if (this._group) {
3011
- this._group._items.forEach(drop => {
3012
- if (siblings.indexOf(drop) === -1) {
3013
- siblings.push(drop);
3014
- }
3015
- });
3016
- }
3017
- // Note that we resolve the scrollable parents here so that we delay the resolution
3018
- // as long as possible, ensuring that the element is in its final place in the DOM.
3019
- // @breaking-change 11.0.0 Remove null check for _scrollDispatcher once it's required.
3020
- if (!this._scrollableParentsResolved && this._scrollDispatcher) {
3021
- const scrollableParents = this._scrollDispatcher
3022
- .getAncestorScrollContainers(this.element)
3023
- .map(scrollable => scrollable.getElementRef().nativeElement);
3024
- this._dropListRef.withScrollableParents(scrollableParents);
3025
- // Only do this once since it involves traversing the DOM and the parents
3026
- // shouldn't be able to change without the drop list being destroyed.
3027
- this._scrollableParentsResolved = true;
3026
+ if (!ref.isDragging()) {
3027
+ const dir = this._dir;
3028
+ const dragStartDelay = this.dragStartDelay;
3029
+ const placeholder = this._placeholderTemplate ? {
3030
+ template: this._placeholderTemplate.templateRef,
3031
+ context: this._placeholderTemplate.data,
3032
+ viewContainer: this._viewContainerRef
3033
+ } : null;
3034
+ const preview = this._previewTemplate ? {
3035
+ template: this._previewTemplate.templateRef,
3036
+ context: this._previewTemplate.data,
3037
+ matchSize: this._previewTemplate.matchSize,
3038
+ viewContainer: this._viewContainerRef
3039
+ } : null;
3040
+ ref.disabled = this.disabled;
3041
+ ref.lockAxis = this.lockAxis;
3042
+ ref.dragStartDelay = (typeof dragStartDelay === 'object' && dragStartDelay) ?
3043
+ dragStartDelay : coerceNumberProperty(dragStartDelay);
3044
+ ref.constrainPosition = this.constrainPosition;
3045
+ ref.previewClass = this.previewClass;
3046
+ ref
3047
+ .withBoundaryElement(this._getBoundaryElement())
3048
+ .withPlaceholderTemplate(placeholder)
3049
+ .withPreviewTemplate(preview);
3050
+ if (dir) {
3051
+ ref.withDirection(dir.value);
3052
+ }
3028
3053
  }
3029
- ref.disabled = this.disabled;
3030
- ref.lockAxis = this.lockAxis;
3031
- ref.sortingDisabled = coerceBooleanProperty(this.sortingDisabled);
3032
- ref.autoScrollDisabled = coerceBooleanProperty(this.autoScrollDisabled);
3033
- ref
3034
- .connectedTo(siblings.filter(drop => drop && drop !== this).map(list => list._dropListRef))
3035
- .withOrientation(this.orientation);
3036
3054
  });
3037
3055
  }
3038
- /** Handles events from the underlying DropListRef. */
3056
+ /** Handles the events from the underlying `DragRef`. */
3039
3057
  _handleEvents(ref) {
3040
- ref.beforeStarted.subscribe(() => {
3041
- this._syncItemsWithRef();
3058
+ ref.started.subscribe(() => {
3059
+ this.started.emit({ source: this });
3060
+ // Since all of these events run outside of change detection,
3061
+ // we need to ensure that everything is marked correctly.
3062
+ this._changeDetectorRef.markForCheck();
3063
+ });
3064
+ ref.released.subscribe(() => {
3065
+ this.released.emit({ source: this });
3066
+ });
3067
+ ref.ended.subscribe(event => {
3068
+ this.ended.emit({ source: this, distance: event.distance });
3069
+ // Since all of these events run outside of change detection,
3070
+ // we need to ensure that everything is marked correctly.
3042
3071
  this._changeDetectorRef.markForCheck();
3043
3072
  });
3044
3073
  ref.entered.subscribe(event => {
3045
3074
  this.entered.emit({
3046
- container: this,
3047
- item: event.item.data,
3075
+ container: event.container.data,
3076
+ item: this,
3048
3077
  currentIndex: event.currentIndex
3049
3078
  });
3050
3079
  });
3051
3080
  ref.exited.subscribe(event => {
3052
3081
  this.exited.emit({
3053
- container: this,
3054
- item: event.item.data
3055
- });
3056
- this._changeDetectorRef.markForCheck();
3057
- });
3058
- ref.sorted.subscribe(event => {
3059
- this.sorted.emit({
3060
- previousIndex: event.previousIndex,
3061
- currentIndex: event.currentIndex,
3062
- container: this,
3063
- item: event.item.data
3082
+ container: event.container.data,
3083
+ item: this
3064
3084
  });
3065
3085
  });
3066
3086
  ref.dropped.subscribe(event => {
@@ -3069,75 +3089,92 @@ class CdkDropList {
3069
3089
  currentIndex: event.currentIndex,
3070
3090
  previousContainer: event.previousContainer.data,
3071
3091
  container: event.container.data,
3072
- item: event.item.data,
3073
3092
  isPointerOverContainer: event.isPointerOverContainer,
3093
+ item: this,
3074
3094
  distance: event.distance
3075
3095
  });
3076
- // Mark for check since all of these events run outside of change
3077
- // detection and we're not guaranteed for something else to have triggered it.
3078
- this._changeDetectorRef.markForCheck();
3079
3096
  });
3080
3097
  }
3081
3098
  /** Assigns the default input values based on a provided config object. */
3082
3099
  _assignDefaults(config) {
3083
- const { lockAxis, draggingDisabled, sortingDisabled, listAutoScrollDisabled, listOrientation } = config;
3100
+ const { lockAxis, dragStartDelay, constrainPosition, previewClass, boundaryElement, draggingDisabled, rootElementSelector } = config;
3084
3101
  this.disabled = draggingDisabled == null ? false : draggingDisabled;
3085
- this.sortingDisabled = sortingDisabled == null ? false : sortingDisabled;
3086
- this.autoScrollDisabled = listAutoScrollDisabled == null ? false : listAutoScrollDisabled;
3087
- this.orientation = listOrientation || 'vertical';
3102
+ this.dragStartDelay = dragStartDelay || 0;
3088
3103
  if (lockAxis) {
3089
3104
  this.lockAxis = lockAxis;
3090
3105
  }
3091
- }
3092
- /** Syncs up the registered drag items with underlying drop list ref. */
3093
- _syncItemsWithRef() {
3094
- this._dropListRef.withItems(this.getSortedItems().map(item => item._dragRef));
3106
+ if (constrainPosition) {
3107
+ this.constrainPosition = constrainPosition;
3108
+ }
3109
+ if (previewClass) {
3110
+ this.previewClass = previewClass;
3111
+ }
3112
+ if (boundaryElement) {
3113
+ this.boundaryElement = boundaryElement;
3114
+ }
3115
+ if (rootElementSelector) {
3116
+ this.rootElementSelector = rootElementSelector;
3117
+ }
3095
3118
  }
3096
3119
  }
3097
- /** Keeps track of the drop lists that are currently on the page. */
3098
- CdkDropList._dropLists = [];
3099
- CdkDropList.decorators = [
3120
+ CdkDrag.decorators = [
3100
3121
  { type: Directive, args: [{
3101
- selector: '[cdkDropList], cdk-drop-list',
3102
- exportAs: 'cdkDropList',
3103
- providers: [
3104
- // Prevent child drop lists from picking up the same group as their parent.
3105
- { provide: CdkDropListGroup, useValue: ɵ0 },
3106
- { provide: CDK_DROP_LIST, useExisting: CdkDropList },
3107
- ],
3122
+ selector: '[cdkDrag]',
3123
+ exportAs: 'cdkDrag',
3108
3124
  host: {
3109
- 'class': 'cdk-drop-list',
3110
- '[id]': 'id',
3111
- '[class.cdk-drop-list-disabled]': 'disabled',
3112
- '[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()',
3113
- '[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()',
3114
- }
3125
+ 'class': 'cdk-drag',
3126
+ '[class.cdk-drag-disabled]': 'disabled',
3127
+ '[class.cdk-drag-dragging]': '_dragRef.isDragging()',
3128
+ },
3129
+ providers: [{ provide: CDK_DRAG_PARENT, useExisting: CdkDrag }]
3115
3130
  },] }
3116
3131
  ];
3117
- CdkDropList.ctorParameters = () => [
3132
+ CdkDrag.ctorParameters = () => [
3118
3133
  { type: ElementRef },
3134
+ { type: undefined, decorators: [{ type: Inject, args: [CDK_DROP_LIST,] }, { type: Optional }, { type: SkipSelf }] },
3135
+ { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] },
3136
+ { type: NgZone },
3137
+ { type: ViewContainerRef },
3138
+ { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CDK_DRAG_CONFIG,] }] },
3139
+ { type: Directionality, decorators: [{ type: Optional }] },
3119
3140
  { type: DragDrop },
3120
3141
  { type: ChangeDetectorRef },
3121
- { type: Directionality, decorators: [{ type: Optional }] },
3122
- { type: CdkDropListGroup, decorators: [{ type: Optional }, { type: SkipSelf }] },
3123
- { type: ScrollDispatcher },
3124
- { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [CDK_DRAG_CONFIG,] }] }
3142
+ { type: CdkDragHandle, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [CDK_DRAG_HANDLE,] }] }
3125
3143
  ];
3126
- CdkDropList.propDecorators = {
3127
- connectedTo: [{ type: Input, args: ['cdkDropListConnectedTo',] }],
3128
- data: [{ type: Input, args: ['cdkDropListData',] }],
3129
- orientation: [{ type: Input, args: ['cdkDropListOrientation',] }],
3130
- id: [{ type: Input }],
3131
- lockAxis: [{ type: Input, args: ['cdkDropListLockAxis',] }],
3132
- disabled: [{ type: Input, args: ['cdkDropListDisabled',] }],
3133
- sortingDisabled: [{ type: Input, args: ['cdkDropListSortingDisabled',] }],
3134
- enterPredicate: [{ type: Input, args: ['cdkDropListEnterPredicate',] }],
3135
- autoScrollDisabled: [{ type: Input, args: ['cdkDropListAutoScrollDisabled',] }],
3136
- dropped: [{ type: Output, args: ['cdkDropListDropped',] }],
3137
- entered: [{ type: Output, args: ['cdkDropListEntered',] }],
3138
- exited: [{ type: Output, args: ['cdkDropListExited',] }],
3139
- sorted: [{ type: Output, args: ['cdkDropListSorted',] }]
3144
+ CdkDrag.propDecorators = {
3145
+ _handles: [{ type: ContentChildren, args: [CDK_DRAG_HANDLE, { descendants: true },] }],
3146
+ _previewTemplate: [{ type: ContentChild, args: [CDK_DRAG_PREVIEW,] }],
3147
+ _placeholderTemplate: [{ type: ContentChild, args: [CDK_DRAG_PLACEHOLDER,] }],
3148
+ data: [{ type: Input, args: ['cdkDragData',] }],
3149
+ lockAxis: [{ type: Input, args: ['cdkDragLockAxis',] }],
3150
+ rootElementSelector: [{ type: Input, args: ['cdkDragRootElement',] }],
3151
+ boundaryElement: [{ type: Input, args: ['cdkDragBoundary',] }],
3152
+ dragStartDelay: [{ type: Input, args: ['cdkDragStartDelay',] }],
3153
+ freeDragPosition: [{ type: Input, args: ['cdkDragFreeDragPosition',] }],
3154
+ disabled: [{ type: Input, args: ['cdkDragDisabled',] }],
3155
+ constrainPosition: [{ type: Input, args: ['cdkDragConstrainPosition',] }],
3156
+ previewClass: [{ type: Input, args: ['cdkDragPreviewClass',] }],
3157
+ started: [{ type: Output, args: ['cdkDragStarted',] }],
3158
+ released: [{ type: Output, args: ['cdkDragReleased',] }],
3159
+ ended: [{ type: Output, args: ['cdkDragEnded',] }],
3160
+ entered: [{ type: Output, args: ['cdkDragEntered',] }],
3161
+ exited: [{ type: Output, args: ['cdkDragExited',] }],
3162
+ dropped: [{ type: Output, args: ['cdkDragDropped',] }],
3163
+ moved: [{ type: Output, args: ['cdkDragMoved',] }]
3140
3164
  };
3165
+ /** Gets the closest ancestor of an element that matches a selector. */
3166
+ function getClosestMatchingAncestor(element, selector) {
3167
+ let currentElement = element.parentElement;
3168
+ while (currentElement) {
3169
+ // IE doesn't support `matches` so we have to fall back to `msMatchesSelector`.
3170
+ if (currentElement.matches ? currentElement.matches(selector) :
3171
+ currentElement.msMatchesSelector(selector)) {
3172
+ return currentElement;
3173
+ }
3174
+ currentElement = currentElement.parentElement;
3175
+ }
3176
+ return null;
3177
+ }
3141
3178
 
3142
3179
  /**
3143
3180
  * @license
@@ -3185,5 +3222,5 @@ DragDropModule.decorators = [
3185
3222
  * Generated bundle index. Do not edit.
3186
3223
  */
3187
3224
 
3188
- export { CDK_DRAG_CONFIG, CDK_DROP_LIST, CdkDrag, CdkDragHandle, CdkDragPlaceholder, CdkDragPreview, CdkDropList, CdkDropListGroup, DragDrop, DragDropModule, DragDropRegistry, DragRef, DropListRef, copyArrayItem, moveItemInArray, transferArrayItem, CDK_DRAG_PARENT as ɵangular_material_src_cdk_drag_drop_drag_drop_b };
3225
+ export { CDK_DRAG_CONFIG, CDK_DRAG_HANDLE, CDK_DRAG_PLACEHOLDER, CDK_DRAG_PREVIEW, CDK_DROP_LIST_GROUP, CdkDrag, CdkDragHandle, CdkDragPlaceholder, CdkDragPreview, CdkDropList, CdkDropListGroup, DragDrop, DragDropModule, DragDropRegistry, DragRef, DropListRef, copyArrayItem, moveItemInArray, transferArrayItem, CDK_DROP_LIST as ɵangular_material_src_cdk_drag_drop_drag_drop_b, CDK_DRAG_PARENT as ɵangular_material_src_cdk_drag_drop_drag_drop_c };
3189
3226
  //# sourceMappingURL=drag-drop.js.map