@@ -29,7 +29,7 @@ import {CdkDropList} from './drop-list';
29
29
import { CdkDragHandle } from './drag-handle' ;
30
30
import { CdkDropListGroup } from './drop-list-group' ;
31
31
import { extendStyles } from '../drag-styling' ;
32
- import { DragRefConfig } from '../drag-ref' ;
32
+ import { DragRefConfig , Point } from '../drag-ref' ;
33
33
34
34
const ITEM_HEIGHT = 25 ;
35
35
const ITEM_WIDTH = 75 ;
@@ -696,6 +696,24 @@ describe('CdkDrag', () => {
696
696
expect ( dragElement . style . transform ) . toBe ( 'translate3d(100px, 100px, 0px)' ) ;
697
697
} ) ) ;
698
698
699
+ it ( 'should allow for the position constrain logic to be customized' , fakeAsync ( ( ) => {
700
+ const fixture = createComponent ( StandaloneDraggable ) ;
701
+ const spy = jasmine . createSpy ( 'constrain position spy' ) . and . returnValue ( {
702
+ x : 50 ,
703
+ y : 50
704
+ } as Point ) ;
705
+
706
+ fixture . componentInstance . constrainPosition = spy ;
707
+ fixture . detectChanges ( ) ;
708
+ const dragElement = fixture . componentInstance . dragElement . nativeElement ;
709
+
710
+ expect ( dragElement . style . transform ) . toBeFalsy ( ) ;
711
+ dragElementViaMouse ( fixture , dragElement , 300 , 300 ) ;
712
+
713
+ expect ( spy ) . toHaveBeenCalledWith ( jasmine . objectContaining ( { x : 300 , y : 300 } ) ) ;
714
+ expect ( dragElement . style . transform ) . toBe ( 'translate3d(50px, 50px, 0px)' ) ;
715
+ } ) ) ;
716
+
699
717
it ( 'should throw if attached to an ng-container' , fakeAsync ( ( ) => {
700
718
expect ( ( ) => {
701
719
createComponent ( DraggableOnNgContainer ) . detectChanges ( ) ;
@@ -1990,6 +2008,33 @@ describe('CdkDrag', () => {
1990
2008
expect ( Math . floor ( previewRect . right ) ) . toBe ( Math . floor ( listRect . right ) ) ;
1991
2009
} ) ) ;
1992
2010
2011
+ it ( 'should be able to constrain the preview position with a custom function' , fakeAsync ( ( ) => {
2012
+ const fixture = createComponent ( DraggableInDropZoneWithCustomPreview ) ;
2013
+ const spy = jasmine . createSpy ( 'constrain position spy' ) . and . returnValue ( {
2014
+ x : 50 ,
2015
+ y : 50
2016
+ } as Point ) ;
2017
+
2018
+ fixture . componentInstance . constrainPosition = spy ;
2019
+ fixture . detectChanges ( ) ;
2020
+ const item = fixture . componentInstance . dragItems . toArray ( ) [ 1 ] . element . nativeElement ;
2021
+
2022
+ startDraggingViaMouse ( fixture , item ) ;
2023
+
2024
+ const preview = document . querySelector ( '.cdk-drag-preview' ) ! as HTMLElement ;
2025
+
2026
+ startDraggingViaMouse ( fixture , item , 200 , 200 ) ;
2027
+ flush ( ) ;
2028
+ dispatchMouseEvent ( document , 'mousemove' , 200 , 200 ) ;
2029
+ fixture . detectChanges ( ) ;
2030
+
2031
+ const previewRect = preview . getBoundingClientRect ( ) ;
2032
+
2033
+ expect ( spy ) . toHaveBeenCalledWith ( jasmine . objectContaining ( { x : 200 , y : 200 } ) ) ;
2034
+ expect ( Math . floor ( previewRect . top ) ) . toBe ( 50 ) ;
2035
+ expect ( Math . floor ( previewRect . left ) ) . toBe ( 50 ) ;
2036
+ } ) ) ;
2037
+
1993
2038
it ( 'should revert the element back to its parent after dragging with a custom ' +
1994
2039
'preview has stopped' , fakeAsync ( ( ) => {
1995
2040
const fixture = createComponent ( DraggableInDropZoneWithCustomPreview ) ;
@@ -2832,6 +2877,7 @@ describe('CdkDrag', () => {
2832
2877
<div
2833
2878
cdkDrag
2834
2879
[cdkDragBoundary]="boundarySelector"
2880
+ [cdkDragConstrainPosition]="constrainPosition"
2835
2881
(cdkDragStarted)="startedSpy($event)"
2836
2882
(cdkDragReleased)="releasedSpy($event)"
2837
2883
(cdkDragEnded)="endedSpy($event)"
@@ -2847,6 +2893,7 @@ class StandaloneDraggable {
2847
2893
endedSpy = jasmine . createSpy ( 'ended spy' ) ;
2848
2894
releasedSpy = jasmine . createSpy ( 'released spy' ) ;
2849
2895
boundarySelector : string ;
2896
+ constrainPosition : ( point : Point ) => Point ;
2850
2897
}
2851
2898
2852
2899
@Component ( {
@@ -3045,6 +3092,7 @@ class DraggableInHorizontalDropZone {
3045
3092
<div
3046
3093
*ngFor="let item of items"
3047
3094
cdkDrag
3095
+ [cdkDragConstrainPosition]="constrainPosition"
3048
3096
[cdkDragBoundary]="boundarySelector"
3049
3097
style="width: 100%; height: ${ ITEM_HEIGHT } px; background: red;">
3050
3098
{{item}}
@@ -3065,6 +3113,7 @@ class DraggableInDropZoneWithCustomPreview {
3065
3113
items = [ 'Zero' , 'One' , 'Two' , 'Three' ] ;
3066
3114
boundarySelector : string ;
3067
3115
renderCustomPreview = true ;
3116
+ constrainPosition : ( point : Point ) => Point ;
3068
3117
}
3069
3118
3070
3119
0 commit comments