@@ -30,7 +30,7 @@ import {CdkDropList} from './drop-list';
30
30
import { CdkDragHandle } from './drag-handle' ;
31
31
import { CdkDropListGroup } from './drop-list-group' ;
32
32
import { extendStyles } from '../drag-styling' ;
33
- import { DragRefConfig } from '../drag-ref' ;
33
+ import { DragRefConfig , Point } from '../drag-ref' ;
34
34
35
35
const ITEM_HEIGHT = 25 ;
36
36
const ITEM_WIDTH = 75 ;
@@ -697,6 +697,24 @@ describe('CdkDrag', () => {
697
697
expect ( dragElement . style . transform ) . toBe ( 'translate3d(100px, 100px, 0px)' ) ;
698
698
} ) ) ;
699
699
700
+ it ( 'should allow for the position constrain logic to be customized' , fakeAsync ( ( ) => {
701
+ const fixture = createComponent ( StandaloneDraggable ) ;
702
+ const spy = jasmine . createSpy ( 'constrain position spy' ) . and . returnValue ( {
703
+ x : 50 ,
704
+ y : 50
705
+ } as Point ) ;
706
+
707
+ fixture . componentInstance . constrainPosition = spy ;
708
+ fixture . detectChanges ( ) ;
709
+ const dragElement = fixture . componentInstance . dragElement . nativeElement ;
710
+
711
+ expect ( dragElement . style . transform ) . toBeFalsy ( ) ;
712
+ dragElementViaMouse ( fixture , dragElement , 300 , 300 ) ;
713
+
714
+ expect ( spy ) . toHaveBeenCalledWith ( jasmine . objectContaining ( { x : 300 , y : 300 } ) ) ;
715
+ expect ( dragElement . style . transform ) . toBe ( 'translate3d(50px, 50px, 0px)' ) ;
716
+ } ) ) ;
717
+
700
718
it ( 'should throw if attached to an ng-container' , fakeAsync ( ( ) => {
701
719
expect ( ( ) => {
702
720
createComponent ( DraggableOnNgContainer ) . detectChanges ( ) ;
@@ -2105,6 +2123,33 @@ describe('CdkDrag', () => {
2105
2123
expect ( Math . floor ( previewRect . right ) ) . toBe ( Math . floor ( listRect . right ) ) ;
2106
2124
} ) ) ;
2107
2125
2126
+ it ( 'should be able to constrain the preview position with a custom function' , fakeAsync ( ( ) => {
2127
+ const fixture = createComponent ( DraggableInDropZoneWithCustomPreview ) ;
2128
+ const spy = jasmine . createSpy ( 'constrain position spy' ) . and . returnValue ( {
2129
+ x : 50 ,
2130
+ y : 50
2131
+ } as Point ) ;
2132
+
2133
+ fixture . componentInstance . constrainPosition = spy ;
2134
+ fixture . detectChanges ( ) ;
2135
+ const item = fixture . componentInstance . dragItems . toArray ( ) [ 1 ] . element . nativeElement ;
2136
+
2137
+ startDraggingViaMouse ( fixture , item ) ;
2138
+
2139
+ const preview = document . querySelector ( '.cdk-drag-preview' ) ! as HTMLElement ;
2140
+
2141
+ startDraggingViaMouse ( fixture , item , 200 , 200 ) ;
2142
+ flush ( ) ;
2143
+ dispatchMouseEvent ( document , 'mousemove' , 200 , 200 ) ;
2144
+ fixture . detectChanges ( ) ;
2145
+
2146
+ const previewRect = preview . getBoundingClientRect ( ) ;
2147
+
2148
+ expect ( spy ) . toHaveBeenCalledWith ( jasmine . objectContaining ( { x : 200 , y : 200 } ) ) ;
2149
+ expect ( Math . floor ( previewRect . top ) ) . toBe ( 50 ) ;
2150
+ expect ( Math . floor ( previewRect . left ) ) . toBe ( 50 ) ;
2151
+ } ) ) ;
2152
+
2108
2153
it ( 'should revert the element back to its parent after dragging with a custom ' +
2109
2154
'preview has stopped' , fakeAsync ( ( ) => {
2110
2155
const fixture = createComponent ( DraggableInDropZoneWithCustomPreview ) ;
@@ -3049,6 +3094,7 @@ describe('CdkDrag', () => {
3049
3094
cdkDrag
3050
3095
[cdkDragBoundary]="boundarySelector"
3051
3096
[cdkDragStartDelay]="dragStartDelay"
3097
+ [cdkDragConstrainPosition]="constrainPosition"
3052
3098
(cdkDragStarted)="startedSpy($event)"
3053
3099
(cdkDragReleased)="releasedSpy($event)"
3054
3100
(cdkDragEnded)="endedSpy($event)"
@@ -3065,6 +3111,7 @@ class StandaloneDraggable {
3065
3111
releasedSpy = jasmine . createSpy ( 'released spy' ) ;
3066
3112
boundarySelector : string ;
3067
3113
dragStartDelay : number ;
3114
+ constrainPosition : ( point : Point ) => Point ;
3068
3115
}
3069
3116
3070
3117
@Component ( {
@@ -3263,6 +3310,7 @@ class DraggableInHorizontalDropZone {
3263
3310
<div
3264
3311
*ngFor="let item of items"
3265
3312
cdkDrag
3313
+ [cdkDragConstrainPosition]="constrainPosition"
3266
3314
[cdkDragBoundary]="boundarySelector"
3267
3315
style="width: 100%; height: ${ ITEM_HEIGHT } px; background: red;">
3268
3316
{{item}}
@@ -3283,6 +3331,7 @@ class DraggableInDropZoneWithCustomPreview {
3283
3331
items = [ 'Zero' , 'One' , 'Two' , 'Three' ] ;
3284
3332
boundarySelector : string ;
3285
3333
renderCustomPreview = true ;
3334
+ constrainPosition : ( point : Point ) => Point ;
3286
3335
}
3287
3336
3288
3337
0 commit comments