1
+ import { Directionality } from '@angular/cdk/bidi' ;
2
+ import {
3
+ createMouseEvent ,
4
+ createTouchEvent ,
5
+ dispatchEvent ,
6
+ dispatchMouseEvent ,
7
+ dispatchTouchEvent ,
8
+ } from '@angular/cdk/testing' ;
1
9
import {
2
10
AfterViewInit ,
11
+ ChangeDetectionStrategy ,
3
12
Component ,
4
13
ElementRef ,
14
+ Input ,
5
15
NgZone ,
6
16
Provider ,
7
17
QueryList ,
8
18
Type ,
9
19
ViewChild ,
10
20
ViewChildren ,
11
21
ViewEncapsulation ,
12
- ChangeDetectionStrategy ,
13
22
} from '@angular/core' ;
14
23
import { TestBed , ComponentFixture , fakeAsync , flush , tick } from '@angular/core/testing' ;
15
24
import { DOCUMENT } from '@angular/common' ;
16
- import { DragDropModule } from '../drag-drop-module' ;
17
- import {
18
- createMouseEvent ,
19
- dispatchEvent ,
20
- dispatchMouseEvent ,
21
- dispatchTouchEvent ,
22
- createTouchEvent ,
23
- } from '@angular/cdk/testing' ;
24
- import { Directionality } from '@angular/cdk/bidi' ;
25
25
import { of as observableOf } from 'rxjs' ;
26
- import { CdkDrag , CDK_DRAG_CONFIG } from './drag' ;
26
+
27
+ import { DragDropModule } from '../drag-drop-module' ;
27
28
import { CdkDragDrop } from '../drag-events' ;
29
+ import { DragRefConfig } from '../drag-ref' ;
30
+ import { extendStyles } from '../drag-styling' ;
28
31
import { moveItemInArray } from '../drag-utils' ;
29
- import { CdkDropList } from './drop-list' ;
32
+
33
+ import { CDK_DRAG_CONFIG , CdkDrag } from './drag' ;
30
34
import { CdkDragHandle } from './drag-handle' ;
35
+ import { CdkDropList } from './drop-list' ;
31
36
import { CdkDropListGroup } from './drop-list-group' ;
32
- import { extendStyles } from '../drag-styling' ;
33
- import { DragRefConfig } from '../drag-ref' ;
34
37
35
38
const ITEM_HEIGHT = 25 ;
36
39
const ITEM_WIDTH = 75 ;
37
40
38
41
describe ( 'CdkDrag' , ( ) => {
39
- function createComponent < T > ( componentType : Type < T > , providers : Provider [ ] = [ ] , dragDistance = 0 ) :
40
- ComponentFixture < T > {
41
- TestBed . configureTestingModule ( {
42
- imports : [ DragDropModule ] ,
43
- declarations : [ componentType , PassthroughComponent ] ,
44
- providers : [
45
- {
46
- provide : CDK_DRAG_CONFIG ,
47
- useValue : {
48
- // We default the `dragDistance` to zero, because the majority of the tests
49
- // don't care about it and drags are a lot easier to simulate when we don't
50
- // have to deal with thresholds.
51
- dragStartThreshold : dragDistance ,
52
- pointerDirectionChangeThreshold : 5
53
- } as DragRefConfig
54
- } ,
55
- ...providers
56
- ] ,
57
- } ) . compileComponents ( ) ;
42
+ function createComponent < T > (
43
+ componentType : Type < T > , providers : Provider [ ] = [ ] , dragDistance = 0 ,
44
+ extraDeclarations : Type < any > [ ] = [ ] ) : ComponentFixture < T > {
45
+ TestBed
46
+ . configureTestingModule ( {
47
+ imports : [ DragDropModule ] ,
48
+ declarations : [ componentType , PassthroughComponent , ...extraDeclarations ] ,
49
+ providers : [
50
+ {
51
+ provide : CDK_DRAG_CONFIG ,
52
+ useValue : {
53
+ // We default the `dragDistance` to zero, because the majority of the tests
54
+ // don't care about it and drags are a lot easier to simulate when we don't
55
+ // have to deal with thresholds.
56
+ dragStartThreshold : dragDistance ,
57
+ pointerDirectionChangeThreshold : 5
58
+ } as DragRefConfig
59
+ } ,
60
+ ...providers
61
+ ] ,
62
+ } )
63
+ . compileComponents ( ) ;
58
64
59
65
return TestBed . createComponent < T > ( componentType ) ;
60
66
}
@@ -2883,55 +2889,69 @@ describe('CdkDrag', () => {
2883
2889
} ) ;
2884
2890
} ) ) ;
2885
2891
2886
- it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2887
- const fixture = createComponent ( ConnectedDropZones ) ;
2888
- fixture . detectChanges ( ) ;
2892
+ it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2893
+ const fixture = createComponent ( ConnectedDropZones ) ;
2894
+ fixture . detectChanges ( ) ;
2889
2895
2890
- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2891
- const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
2896
+ const dropZones =
2897
+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2898
+ const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
2892
2899
2893
- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2894
- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2900
+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2901
+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2895
2902
2896
- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2897
- fixture . detectChanges ( ) ;
2903
+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2904
+ fixture . detectChanges ( ) ;
2898
2905
2899
- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2900
- 'Expected source container not to have the receiving class.' ) ;
2906
+ expect ( dropZones [ 0 ] . classList )
2907
+ . not . toContain (
2908
+ 'cdk-drop-list-receiving' ,
2909
+ 'Expected source container not to have the receiving class.' ) ;
2901
2910
2902
- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2903
- 'Expected target container to have the receiving class.' ) ;
2904
- } ) ) ;
2911
+ expect ( dropZones [ 1 ] . classList )
2912
+ . toContain (
2913
+ 'cdk-drop-list-receiving' ,
2914
+ 'Expected target container to have the receiving class.' ) ;
2915
+ } ) ) ;
2905
2916
2906
- it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2907
- const fixture = createComponent ( ConnectedDropZones ) ;
2908
- fixture . detectChanges ( ) ;
2917
+ it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2918
+ const fixture = createComponent ( ConnectedDropZones ) ;
2919
+ fixture . detectChanges ( ) ;
2909
2920
2910
- const groups = fixture . componentInstance . groupedDragItems ;
2911
- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2912
- const item = groups [ 0 ] [ 1 ] ;
2913
- const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
2921
+ const groups = fixture . componentInstance . groupedDragItems ;
2922
+ const dropZones =
2923
+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2924
+ const item = groups [ 0 ] [ 1 ] ;
2925
+ const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
2914
2926
2915
- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2916
- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2927
+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2928
+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2917
2929
2918
- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2930
+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2919
2931
2920
- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2921
- 'Expected source container not to have the receiving class.' ) ;
2932
+ expect ( dropZones [ 0 ] . classList )
2933
+ . not . toContain (
2934
+ 'cdk-drop-list-receiving' ,
2935
+ 'Expected source container not to have the receiving class.' ) ;
2922
2936
2923
- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2924
- 'Expected target container to have the receiving class.' ) ;
2937
+ expect ( dropZones [ 1 ] . classList )
2938
+ . toContain (
2939
+ 'cdk-drop-list-receiving' ,
2940
+ 'Expected target container to have the receiving class.' ) ;
2925
2941
2926
- dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2927
- fixture . detectChanges ( ) ;
2942
+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2943
+ fixture . detectChanges ( ) ;
2928
2944
2929
- expect ( dropZones [ 0 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2930
- 'Expected old container not to have the receiving class after exiting.' ) ;
2945
+ expect ( dropZones [ 0 ] . classList )
2946
+ . toContain (
2947
+ 'cdk-drop-list-receiving' ,
2948
+ 'Expected old container not to have the receiving class after exiting.' ) ;
2931
2949
2932
- expect ( dropZones [ 1 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2933
- 'Expected new container not to have the receiving class after entering.' ) ;
2934
- } ) ) ;
2950
+ expect ( dropZones [ 1 ] . classList )
2951
+ . not . toContain (
2952
+ 'cdk-drop-list-receiving' ,
2953
+ 'Expected new container not to have the receiving class after entering.' ) ;
2954
+ } ) ) ;
2935
2955
2936
2956
it ( 'should be able to move the item over an intermediate container before ' +
2937
2957
'dropping it into the final one' , fakeAsync ( ( ) => {
@@ -3038,8 +3058,50 @@ describe('CdkDrag', () => {
3038
3058
expect ( fixture . componentInstance . droppedSpy ) . not . toHaveBeenCalled ( ) ;
3039
3059
} ) ) ;
3040
3060
3061
+ it ( 'should toggle a class when dragging an item inside a wrapper component component ' +
3062
+ 'with OnPush change detection' ,
3063
+ fakeAsync ( ( ) => {
3064
+ const fixture =
3065
+ createComponent ( ConnectedWrappedDropZones , [ ] , 0 , [ WrappedDropContainerComponent ] ) ;
3066
+ fixture . detectChanges ( ) ;
3067
+
3068
+ const [ startZone , targetZone ] = fixture . nativeElement . querySelectorAll ( '.cdk-drop-list' ) ;
3069
+ const item = startZone . querySelector ( '.cdk-drag' ) ;
3070
+ const targetRect = targetZone . getBoundingClientRect ( ) ;
3071
+
3072
+ expect ( startZone . classList )
3073
+ . not . toContain (
3074
+ 'cdk-drop-list-dragging' ,
3075
+ 'Expected start not to have dragging class on init.' ) ;
3076
+ expect ( targetZone . classList )
3077
+ . not . toContain (
3078
+ 'cdk-drop-list-dragging' ,
3079
+ 'Expected target not to have dragging class on init.' ) ;
3080
+
3081
+ startDraggingViaMouse ( fixture , item ) ;
3082
+
3083
+ expect ( startZone . classList )
3084
+ . toContain (
3085
+ 'cdk-drop-list-dragging' ,
3086
+ 'Expected start to have dragging class after dragging has started.' ) ;
3087
+ expect ( targetZone . classList )
3088
+ . not . toContain (
3089
+ 'cdk-drop-list-dragging' ,
3090
+ 'Expected target not to have dragging class after dragging has started.' ) ;
3091
+
3092
+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
3093
+ fixture . detectChanges ( ) ;
3094
+
3095
+ expect ( startZone . classList )
3096
+ . not . toContain (
3097
+ 'cdk-drop-list-dragging' ,
3098
+ 'Expected start not to have dragging class once item has been moved over.' ) ;
3099
+ expect ( targetZone . classList )
3100
+ . toContain (
3101
+ 'cdk-drop-list-dragging' ,
3102
+ 'Expected target to have dragging class once item has been moved over.' ) ;
3103
+ } ) ) ;
3041
3104
} ) ;
3042
-
3043
3105
} ) ;
3044
3106
3045
3107
@Component ( {
@@ -3519,6 +3581,34 @@ class DraggableInDropZoneWithoutEvents {
3519
3581
] ;
3520
3582
}
3521
3583
3584
+ @Component ( {
3585
+ encapsulation : ViewEncapsulation . None ,
3586
+ styles : [ `
3587
+ .cdk-drop-list {
3588
+ display: block;
3589
+ width: 100px;
3590
+ min-height: ${ ITEM_HEIGHT } px;
3591
+ background: hotpink;
3592
+ }
3593
+
3594
+ .cdk-drag {
3595
+ display: block;
3596
+ height: ${ ITEM_HEIGHT } px;
3597
+ background: red;
3598
+ }
3599
+ ` ] ,
3600
+ template : `
3601
+ <div cdkDropListGroup>
3602
+ <wrapped-drop-container [items]="todo"></wrapped-drop-container>
3603
+ <wrapped-drop-container [items]="done"></wrapped-drop-container>
3604
+ </div>
3605
+ `
3606
+ } )
3607
+ class ConnectedWrappedDropZones {
3608
+ todo = [ 'Zero' , 'One' , 'Two' , 'Three' ] ;
3609
+ done = [ 'Four' , 'Five' , 'Six' ] ;
3610
+ }
3611
+
3522
3612
/**
3523
3613
* Component that passes through whatever content is projected into it.
3524
3614
* Used to test having drag elements being projected into a component.
@@ -3529,6 +3619,21 @@ class DraggableInDropZoneWithoutEvents {
3529
3619
} )
3530
3620
class PassthroughComponent { }
3531
3621
3622
+
3623
+ /** Component that wraps a drop container and uses OnPush change detection. */
3624
+ @Component ( {
3625
+ selector : 'wrapped-drop-container' ,
3626
+ template : `
3627
+ <div cdkDropList [cdkDropListData]="items">
3628
+ <div *ngFor="let item of items" cdkDrag>{{item}}</div>
3629
+ </div>
3630
+ ` ,
3631
+ changeDetection : ChangeDetectionStrategy . OnPush
3632
+ } )
3633
+ class WrappedDropContainerComponent {
3634
+ @Input ( ) items : string [ ] ;
3635
+ }
3636
+
3532
3637
/**
3533
3638
* Drags an element to a position on the page using the mouse.
3534
3639
* @param fixture Fixture on which to run change detection.
0 commit comments