@@ -33,6 +33,7 @@ import {
3333 startDraggingViaMouse ,
3434 startDraggingViaTouch ,
3535} from './test-utils.spec' ;
36+ import { isInsideClientRect , isOverflowingParent } from '../dom/dom-rect' ;
3637
3738describe ( 'Standalone CdkDrag' , ( ) => {
3839 describe ( 'mouse dragging' , ( ) => {
@@ -46,6 +47,95 @@ describe('Standalone CdkDrag', () => {
4647 expect ( dragElement . style . transform ) . toBe ( 'translate3d(50px, 100px, 0px)' ) ;
4748 } ) ) ;
4849
50+ it ( 'should reset drag item to boundary' , fakeAsync ( ( ) => {
51+ const fixture = createComponent ( DragWithResizeableBoundary ) ;
52+ fixture . detectChanges ( ) ;
53+ let boundaryElement = fixture . componentInstance . boundaryElement . nativeElement ;
54+ let dragElement = fixture . componentInstance . dragElement . nativeElement ;
55+
56+ dragElementViaMouse ( fixture , dragElement , 50 , 100 ) ;
57+
58+ // check if the drag element is within the boundary or not
59+ expect (
60+ isInsideClientRect (
61+ boundaryElement . getBoundingClientRect ( ) ,
62+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . x ,
63+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . y ,
64+ ) ,
65+ ) . toBeTrue ( ) ;
66+
67+ // drag it till the end of the boundary
68+ dragElementViaMouse ( fixture , dragElement , 400 , 400 ) ;
69+
70+ // it should still be present within the boundary
71+ expect (
72+ isInsideClientRect (
73+ boundaryElement . getBoundingClientRect ( ) ,
74+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . x ,
75+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . y ,
76+ ) ,
77+ ) . toBeTrue ( ) ;
78+
79+ // shrink boundary to check if we are within boundary or not
80+ fixture . componentInstance . setBoundary ( '200px' , '200px' ) ;
81+ fixture . detectChanges ( ) ;
82+
83+ // it should not be within the boundary anymore as we shrinked it
84+ expect (
85+ isInsideClientRect (
86+ boundaryElement . getBoundingClientRect ( ) ,
87+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . x ,
88+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . y ,
89+ ) ,
90+ ) . toBeFalse ( ) ;
91+
92+ fixture . componentInstance . dragInstance . resetToBoundary ( ) ;
93+ fixture . detectChanges ( ) ;
94+
95+ // should be be within bounding box of its boundary now that we have reseted it
96+ expect (
97+ isInsideClientRect (
98+ boundaryElement . getBoundingClientRect ( ) ,
99+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . x ,
100+ fixture . componentInstance . dragInstance . getFreeDragPosition ( ) . y ,
101+ ) ,
102+ ) . toBeTrue ( ) ;
103+
104+ // expand the boundary enough that so can we can make the draggable item to be overflown
105+ // of its parent from top side
106+ fixture . componentInstance . setBoundary ( '500px' , '500px' ) ;
107+ fixture . detectChanges ( ) ;
108+
109+ // drag it till the end of the boundary
110+ dragElementViaMouse ( fixture , dragElement , 500 , 500 ) ;
111+
112+ // shrink boundary to make draggable item to be overflown
113+ fixture . componentInstance . setBoundary ( '400px' , '400px' ) ;
114+ fixture . detectChanges ( ) ;
115+
116+ // should be within bounding rect but it's overflowing as it was placed in a way that
117+ // it is overflowing
118+ expect (
119+ isOverflowingParent (
120+ boundaryElement . getBoundingClientRect ( ) ,
121+ dragElement . getBoundingClientRect ( ) ,
122+ ) ,
123+ ) . toBeTrue ( ) ;
124+
125+ // reset it so that overflowing offset is fixed
126+ fixture . componentInstance . dragInstance . resetToBoundary ( ) ;
127+ fixture . detectChanges ( ) ;
128+
129+ // should be within bounding rect but it's overflowing as it was placed in a way that
130+ // it is overflowing
131+ expect (
132+ isOverflowingParent (
133+ boundaryElement . getBoundingClientRect ( ) ,
134+ dragElement . getBoundingClientRect ( ) ,
135+ ) ,
136+ ) . toBeFalse ( ) ;
137+ } ) ) ;
138+
49139 it ( 'should drag an element freely to a particular position when the page is scrolled' , fakeAsync ( ( ) => {
50140 const fixture = createComponent ( StandaloneDraggable ) ;
51141 fixture . detectChanges ( ) ;
@@ -2047,3 +2137,25 @@ class PlainStandaloneDraggable {
20472137class StandaloneDraggableWithExternalTemplateHandle {
20482138 @ViewChild ( 'dragElement' ) dragElement : ElementRef < HTMLElement > ;
20492139}
2140+
2141+ @Component ( {
2142+ template : `
2143+ <div #boundaryElement class="example-boundary" style="width: 400px; height: 400px">
2144+ <div #dragElement class="example-box" cdkDragBoundary=".example-boundary" cdkDrag style="width: 100px; height: 100px">
2145+ I can only be dragged within the container
2146+ </div>
2147+ </div>
2148+ ` ,
2149+ imports : [ CdkDrag ] ,
2150+ } )
2151+ class DragWithResizeableBoundary {
2152+ @ViewChild ( 'boundaryElement' ) boundaryElement : ElementRef < HTMLElement > ;
2153+
2154+ @ViewChild ( 'dragElement' ) dragElement : ElementRef < HTMLElement > ;
2155+ @ViewChild ( CdkDrag ) dragInstance : CdkDrag ;
2156+
2157+ setBoundary ( height : string , width : string ) {
2158+ this . boundaryElement . nativeElement . style . height = height ;
2159+ this . boundaryElement . nativeElement . style . width = width ;
2160+ }
2161+ }
0 commit comments