@@ -2,12 +2,28 @@ import * as React from "react";
2
2
import { render , fireEvent } from "@testing-library/react" ;
3
3
import userEvent from "@testing-library/user-event" ;
4
4
5
- import { Modal , ModalContent , ModalBody , ModalHeader , ModalFooter } from "../src" ;
5
+ import { Modal , ModalContent , ModalBody , ModalHeader , ModalFooter , useDraggable } from "../src" ;
6
6
7
7
// e.g. console.error Warning: Function components cannot be given refs.
8
8
// Attempts to access this ref will fail. Did you mean to use React.forwardRef()?
9
9
const spy = jest . spyOn ( console , "error" ) . mockImplementation ( ( ) => { } ) ;
10
10
11
+ const ModalDraggable = ( { canOverflow = false , isDisabled = false } ) => {
12
+ const targetRef = React . useRef ( null ) ;
13
+
14
+ const { moveProps} = useDraggable ( { targetRef, canOverflow, isDisabled} ) ;
15
+
16
+ return (
17
+ < Modal ref = { targetRef } isOpen >
18
+ < ModalContent >
19
+ < ModalHeader { ...moveProps } > Modal header</ ModalHeader >
20
+ < ModalBody > Modal body</ ModalBody >
21
+ < ModalFooter > Modal footer</ ModalFooter >
22
+ </ ModalContent >
23
+ </ Modal >
24
+ ) ;
25
+ } ;
26
+
11
27
describe ( "Modal" , ( ) => {
12
28
afterEach ( ( ) => {
13
29
jest . clearAllMocks ( ) ;
@@ -109,4 +125,93 @@ describe("Modal", () => {
109
125
fireEvent . keyDown ( modal , { key : "Escape" } ) ;
110
126
expect ( onClose ) . toHaveBeenCalledTimes ( 1 ) ;
111
127
} ) ;
128
+
129
+ it ( "should be rendered a draggable modal" , ( ) => {
130
+ // mock viewport size to 1920x1080
131
+ jest . spyOn ( document . documentElement , "clientWidth" , "get" ) . mockImplementation ( ( ) => 1920 ) ;
132
+ jest . spyOn ( document . documentElement , "clientHeight" , "get" ) . mockImplementation ( ( ) => 1080 ) ;
133
+
134
+ const wrapper = render ( < ModalDraggable /> ) ;
135
+
136
+ const modal = wrapper . getByRole ( "dialog" ) ;
137
+ const modalHeader = wrapper . getByText ( "Modal header" ) ;
138
+
139
+ fireEvent . touchStart ( modalHeader , { changedTouches : [ { pageX : 0 , pageY : 0 } ] } ) ;
140
+ fireEvent . touchMove ( modalHeader , { changedTouches : [ { pageX : 100 , pageY : 50 } ] } ) ;
141
+ fireEvent . touchEnd ( modalHeader , { changedTouches : [ { pageX : 100 , pageY : 50 } ] } ) ;
142
+
143
+ expect ( ( ) => wrapper . unmount ( ) ) . not . toThrow ( ) ;
144
+ expect ( document . documentElement . clientWidth ) . toBe ( 1920 ) ;
145
+ expect ( document . documentElement . clientHeight ) . toBe ( 1080 ) ;
146
+ expect ( modalHeader . style . cursor ) . toBe ( "move" ) ;
147
+ expect ( modal . style . transform ) . toBe ( "translate(100px, 50px)" ) ;
148
+ } ) ;
149
+
150
+ it ( "should be rendered a draggable modal on mobile" , ( ) => {
151
+ // mock viewport size to 375x667
152
+ jest . spyOn ( document . documentElement , "clientWidth" , "get" ) . mockImplementation ( ( ) => 375 ) ;
153
+ jest . spyOn ( document . documentElement , "clientHeight" , "get" ) . mockImplementation ( ( ) => 667 ) ;
154
+
155
+ const wrapper = render ( < ModalDraggable /> ) ;
156
+
157
+ const modal = wrapper . getByRole ( "dialog" ) ;
158
+ const modalHeader = wrapper . getByText ( "Modal header" ) ;
159
+
160
+ fireEvent . touchStart ( modalHeader , { changedTouches : [ { pageX : 0 , pageY : 0 } ] } ) ;
161
+ fireEvent . touchMove ( modalHeader , { changedTouches : [ { pageX : 0 , pageY : 50 } ] } ) ;
162
+ fireEvent . touchEnd ( modalHeader , { changedTouches : [ { pageX : 0 , pageY : 50 } ] } ) ;
163
+
164
+ expect ( document . documentElement . clientWidth ) . toBe ( 375 ) ;
165
+ expect ( document . documentElement . clientHeight ) . toBe ( 667 ) ;
166
+ expect ( modal . style . transform ) . toBe ( "translate(0px, 50px)" ) ;
167
+ } ) ;
168
+
169
+ it ( "should not drag overflow viewport" , ( ) => {
170
+ // mock viewport size to 1920x1080
171
+ jest . spyOn ( document . documentElement , "clientWidth" , "get" ) . mockImplementation ( ( ) => 1920 ) ;
172
+ jest . spyOn ( document . documentElement , "clientHeight" , "get" ) . mockImplementation ( ( ) => 1080 ) ;
173
+ const wrapper = render ( < ModalDraggable /> ) ;
174
+ const modal = wrapper . getByRole ( "dialog" ) ;
175
+ const modalHeader = wrapper . getByText ( "Modal header" ) ;
176
+
177
+ fireEvent . touchStart ( modalHeader , { changedTouches : [ { pageX : 100 , pageY : 50 } ] } ) ;
178
+ fireEvent . touchMove ( modalHeader , { changedTouches : [ { pageX : 10000 , pageY : 5000 } ] } ) ;
179
+ fireEvent . touchEnd ( modalHeader , { changedTouches : [ { pageX : 10000 , pageY : 5000 } ] } ) ;
180
+
181
+ expect ( modal . style . transform ) . toBe ( "translate(1920px, 1080px)" ) ;
182
+ } ) ;
183
+
184
+ it ( "should not drag when disabled" , ( ) => {
185
+ // mock viewport size to 1920x1080
186
+ jest . spyOn ( document . documentElement , "clientWidth" , "get" ) . mockImplementation ( ( ) => 1920 ) ;
187
+ jest . spyOn ( document . documentElement , "clientHeight" , "get" ) . mockImplementation ( ( ) => 1080 ) ;
188
+ const wrapper = render ( < ModalDraggable isDisabled /> ) ;
189
+ const modal = wrapper . getByRole ( "dialog" ) ;
190
+ const modalHeader = wrapper . getByText ( "Modal header" ) ;
191
+
192
+ fireEvent . touchStart ( modalHeader , { changedTouches : [ { pageX : 100 , pageY : 50 } ] } ) ;
193
+ fireEvent . touchMove ( modalHeader , { changedTouches : [ { pageX : 200 , pageY : 100 } ] } ) ;
194
+ fireEvent . touchEnd ( modalHeader , { changedTouches : [ { pageX : 200 , pageY : 100 } ] } ) ;
195
+
196
+ expect ( modal . style . transform ) . toBe ( "" ) ;
197
+ } ) ;
198
+
199
+ test ( "should be rendered a draggable modal with overflow" , ( ) => {
200
+ // mock viewport size to 1920x1080
201
+ jest . spyOn ( document . documentElement , "clientWidth" , "get" ) . mockImplementation ( ( ) => 1920 ) ;
202
+ jest . spyOn ( document . documentElement , "clientHeight" , "get" ) . mockImplementation ( ( ) => 1080 ) ;
203
+
204
+ const wrapper = render ( < ModalDraggable canOverflow /> ) ;
205
+
206
+ const modal = wrapper . getByRole ( "dialog" ) ;
207
+ const modalHeader = wrapper . getByText ( "Modal header" ) ;
208
+
209
+ fireEvent . touchStart ( modalHeader , { changedTouches : [ { pageX : 0 , pageY : 0 } ] } ) ;
210
+ fireEvent . touchMove ( modalHeader , { changedTouches : [ { pageX : 2000 , pageY : 1500 } ] } ) ;
211
+ fireEvent . touchEnd ( modalHeader , { changedTouches : [ { pageX : 2000 , pageY : 1500 } ] } ) ;
212
+
213
+ expect ( document . documentElement . clientWidth ) . toBe ( 1920 ) ;
214
+ expect ( document . documentElement . clientHeight ) . toBe ( 1080 ) ;
215
+ expect ( modal . style . transform ) . toBe ( "translate(2000px, 1500px)" ) ;
216
+ } ) ;
112
217
} ) ;
0 commit comments