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 , Point } 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 , Point } 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
}
@@ -2928,55 +2934,69 @@ describe('CdkDrag', () => {
2928
2934
} ) ;
2929
2935
} ) ) ;
2930
2936
2931
- it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2932
- const fixture = createComponent ( ConnectedDropZones ) ;
2933
- fixture . detectChanges ( ) ;
2937
+ it ( 'should set a class when a container can receive an item' , fakeAsync ( ( ) => {
2938
+ const fixture = createComponent ( ConnectedDropZones ) ;
2939
+ fixture . detectChanges ( ) ;
2934
2940
2935
- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2936
- const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
2941
+ const dropZones =
2942
+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2943
+ const item = fixture . componentInstance . groupedDragItems [ 0 ] [ 1 ] ;
2937
2944
2938
- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2939
- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2945
+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2946
+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2940
2947
2941
- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2942
- fixture . detectChanges ( ) ;
2948
+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2949
+ fixture . detectChanges ( ) ;
2943
2950
2944
- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2945
- 'Expected source container not to have the receiving class.' ) ;
2951
+ expect ( dropZones [ 0 ] . classList )
2952
+ . not . toContain (
2953
+ 'cdk-drop-list-receiving' ,
2954
+ 'Expected source container not to have the receiving class.' ) ;
2946
2955
2947
- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2948
- 'Expected target container to have the receiving class.' ) ;
2949
- } ) ) ;
2956
+ expect ( dropZones [ 1 ] . classList )
2957
+ . toContain (
2958
+ 'cdk-drop-list-receiving' ,
2959
+ 'Expected target container to have the receiving class.' ) ;
2960
+ } ) ) ;
2950
2961
2951
- it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2952
- const fixture = createComponent ( ConnectedDropZones ) ;
2953
- fixture . detectChanges ( ) ;
2962
+ it ( 'should toggle the `receiving` class when the item enters a new list' , fakeAsync ( ( ) => {
2963
+ const fixture = createComponent ( ConnectedDropZones ) ;
2964
+ fixture . detectChanges ( ) ;
2954
2965
2955
- const groups = fixture . componentInstance . groupedDragItems ;
2956
- const dropZones = fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2957
- const item = groups [ 0 ] [ 1 ] ;
2958
- const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
2966
+ const groups = fixture . componentInstance . groupedDragItems ;
2967
+ const dropZones =
2968
+ fixture . componentInstance . dropInstances . map ( d => d . element . nativeElement ) ;
2969
+ const item = groups [ 0 ] [ 1 ] ;
2970
+ const targetRect = groups [ 1 ] [ 2 ] . element . nativeElement . getBoundingClientRect ( ) ;
2959
2971
2960
- expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2961
- . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2972
+ expect ( dropZones . every ( c => ! c . classList . contains ( 'cdk-drop-list-receiving' ) ) )
2973
+ . toBe ( true , 'Expected neither of the containers to have the class.' ) ;
2962
2974
2963
- startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2975
+ startDraggingViaMouse ( fixture , item . element . nativeElement ) ;
2964
2976
2965
- expect ( dropZones [ 0 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2966
- 'Expected source container not to have the receiving class.' ) ;
2977
+ expect ( dropZones [ 0 ] . classList )
2978
+ . not . toContain (
2979
+ 'cdk-drop-list-receiving' ,
2980
+ 'Expected source container not to have the receiving class.' ) ;
2967
2981
2968
- expect ( dropZones [ 1 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2969
- 'Expected target container to have the receiving class.' ) ;
2982
+ expect ( dropZones [ 1 ] . classList )
2983
+ . toContain (
2984
+ 'cdk-drop-list-receiving' ,
2985
+ 'Expected target container to have the receiving class.' ) ;
2970
2986
2971
- dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2972
- fixture . detectChanges ( ) ;
2987
+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
2988
+ fixture . detectChanges ( ) ;
2973
2989
2974
- expect ( dropZones [ 0 ] . classList ) . toContain ( 'cdk-drop-list-receiving' ,
2975
- 'Expected old container not to have the receiving class after exiting.' ) ;
2990
+ expect ( dropZones [ 0 ] . classList )
2991
+ . toContain (
2992
+ 'cdk-drop-list-receiving' ,
2993
+ 'Expected old container not to have the receiving class after exiting.' ) ;
2976
2994
2977
- expect ( dropZones [ 1 ] . classList ) . not . toContain ( 'cdk-drop-list-receiving' ,
2978
- 'Expected new container not to have the receiving class after entering.' ) ;
2979
- } ) ) ;
2995
+ expect ( dropZones [ 1 ] . classList )
2996
+ . not . toContain (
2997
+ 'cdk-drop-list-receiving' ,
2998
+ 'Expected new container not to have the receiving class after entering.' ) ;
2999
+ } ) ) ;
2980
3000
2981
3001
it ( 'should be able to move the item over an intermediate container before ' +
2982
3002
'dropping it into the final one' , fakeAsync ( ( ) => {
@@ -3083,8 +3103,50 @@ describe('CdkDrag', () => {
3083
3103
expect ( fixture . componentInstance . droppedSpy ) . not . toHaveBeenCalled ( ) ;
3084
3104
} ) ) ;
3085
3105
3106
+ it ( 'should toggle a class when dragging an item inside a wrapper component component ' +
3107
+ 'with OnPush change detection' ,
3108
+ fakeAsync ( ( ) => {
3109
+ const fixture =
3110
+ createComponent ( ConnectedWrappedDropZones , [ ] , 0 , [ WrappedDropContainerComponent ] ) ;
3111
+ fixture . detectChanges ( ) ;
3112
+
3113
+ const [ startZone , targetZone ] = fixture . nativeElement . querySelectorAll ( '.cdk-drop-list' ) ;
3114
+ const item = startZone . querySelector ( '.cdk-drag' ) ;
3115
+ const targetRect = targetZone . getBoundingClientRect ( ) ;
3116
+
3117
+ expect ( startZone . classList )
3118
+ . not . toContain (
3119
+ 'cdk-drop-list-dragging' ,
3120
+ 'Expected start not to have dragging class on init.' ) ;
3121
+ expect ( targetZone . classList )
3122
+ . not . toContain (
3123
+ 'cdk-drop-list-dragging' ,
3124
+ 'Expected target not to have dragging class on init.' ) ;
3125
+
3126
+ startDraggingViaMouse ( fixture , item ) ;
3127
+
3128
+ expect ( startZone . classList )
3129
+ . toContain (
3130
+ 'cdk-drop-list-dragging' ,
3131
+ 'Expected start to have dragging class after dragging has started.' ) ;
3132
+ expect ( targetZone . classList )
3133
+ . not . toContain (
3134
+ 'cdk-drop-list-dragging' ,
3135
+ 'Expected target not to have dragging class after dragging has started.' ) ;
3136
+
3137
+ dispatchMouseEvent ( document , 'mousemove' , targetRect . left + 1 , targetRect . top + 1 ) ;
3138
+ fixture . detectChanges ( ) ;
3139
+
3140
+ expect ( startZone . classList )
3141
+ . not . toContain (
3142
+ 'cdk-drop-list-dragging' ,
3143
+ 'Expected start not to have dragging class once item has been moved over.' ) ;
3144
+ expect ( targetZone . classList )
3145
+ . toContain (
3146
+ 'cdk-drop-list-dragging' ,
3147
+ 'Expected target to have dragging class once item has been moved over.' ) ;
3148
+ } ) ) ;
3086
3149
} ) ;
3087
-
3088
3150
} ) ;
3089
3151
3090
3152
@Component ( {
@@ -3568,6 +3630,34 @@ class DraggableInDropZoneWithoutEvents {
3568
3630
] ;
3569
3631
}
3570
3632
3633
+ @Component ( {
3634
+ encapsulation : ViewEncapsulation . None ,
3635
+ styles : [ `
3636
+ .cdk-drop-list {
3637
+ display: block;
3638
+ width: 100px;
3639
+ min-height: ${ ITEM_HEIGHT } px;
3640
+ background: hotpink;
3641
+ }
3642
+
3643
+ .cdk-drag {
3644
+ display: block;
3645
+ height: ${ ITEM_HEIGHT } px;
3646
+ background: red;
3647
+ }
3648
+ ` ] ,
3649
+ template : `
3650
+ <div cdkDropListGroup>
3651
+ <wrapped-drop-container [items]="todo"></wrapped-drop-container>
3652
+ <wrapped-drop-container [items]="done"></wrapped-drop-container>
3653
+ </div>
3654
+ `
3655
+ } )
3656
+ class ConnectedWrappedDropZones {
3657
+ todo = [ 'Zero' , 'One' , 'Two' , 'Three' ] ;
3658
+ done = [ 'Four' , 'Five' , 'Six' ] ;
3659
+ }
3660
+
3571
3661
/**
3572
3662
* Component that passes through whatever content is projected into it.
3573
3663
* Used to test having drag elements being projected into a component.
@@ -3578,6 +3668,21 @@ class DraggableInDropZoneWithoutEvents {
3578
3668
} )
3579
3669
class PassthroughComponent { }
3580
3670
3671
+
3672
+ /** Component that wraps a drop container and uses OnPush change detection. */
3673
+ @Component ( {
3674
+ selector : 'wrapped-drop-container' ,
3675
+ template : `
3676
+ <div cdkDropList [cdkDropListData]="items">
3677
+ <div *ngFor="let item of items" cdkDrag>{{item}}</div>
3678
+ </div>
3679
+ ` ,
3680
+ changeDetection : ChangeDetectionStrategy . OnPush
3681
+ } )
3682
+ class WrappedDropContainerComponent {
3683
+ @Input ( ) items : string [ ] ;
3684
+ }
3685
+
3581
3686
/**
3582
3687
* Drags an element to a position on the page using the mouse.
3583
3688
* @param fixture Fixture on which to run change detection.
0 commit comments