@jobber/components-native 0.99.0 → 0.100.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +3 -6
- package/dist/src/ContentOverlay/BottomSheetKeyboardAwareScrollView.js +19 -0
- package/dist/src/ContentOverlay/ContentOverlay.js +143 -107
- package/dist/src/ContentOverlay/ContentOverlay.style.js +8 -12
- package/dist/src/ContentOverlay/computeContentOverlayBehavior.js +76 -0
- package/dist/src/ContentOverlay/constants.js +1 -0
- package/dist/src/ContentOverlay/hooks/useBottomSheetModalBackHandler.js +25 -0
- package/dist/src/ContentOverlay/index.js +1 -1
- package/dist/src/InputText/InputText.js +44 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/dist/types/src/ContentOverlay/BottomSheetKeyboardAwareScrollView.d.ts +11 -0
- package/dist/types/src/ContentOverlay/ContentOverlay.d.ts +2 -5
- package/dist/types/src/ContentOverlay/ContentOverlay.style.d.ts +11 -10
- package/dist/types/src/ContentOverlay/computeContentOverlayBehavior.d.ts +32 -0
- package/dist/types/src/ContentOverlay/constants.d.ts +1 -0
- package/dist/types/src/ContentOverlay/hooks/useBottomSheetModalBackHandler.d.ts +7 -0
- package/dist/types/src/ContentOverlay/index.d.ts +1 -1
- package/dist/types/src/ContentOverlay/types.d.ts +5 -12
- package/jestSetup.js +2 -0
- package/package.json +3 -6
- package/src/ContentOverlay/BottomSheetKeyboardAwareScrollView.tsx +36 -0
- package/src/ContentOverlay/ContentOverlay.stories.tsx +32 -36
- package/src/ContentOverlay/ContentOverlay.style.ts +12 -12
- package/src/ContentOverlay/ContentOverlay.test.tsx +157 -79
- package/src/ContentOverlay/ContentOverlay.tsx +247 -205
- package/src/ContentOverlay/computeContentOverlayBehavior.test.ts +276 -0
- package/src/ContentOverlay/computeContentOverlayBehavior.ts +119 -0
- package/src/ContentOverlay/constants.ts +1 -0
- package/src/ContentOverlay/hooks/useBottomSheetModalBackHandler.test.ts +81 -0
- package/src/ContentOverlay/hooks/useBottomSheetModalBackHandler.ts +36 -0
- package/src/ContentOverlay/index.ts +4 -1
- package/src/ContentOverlay/types.ts +5 -13
- package/src/InputText/InputText.test.tsx +122 -0
- package/src/InputText/InputText.tsx +62 -2
- package/dist/src/ContentOverlay/UNSAFE_WrappedModalize.js +0 -23
- package/dist/types/src/ContentOverlay/UNSAFE_WrappedModalize.d.ts +0 -3
- package/src/ContentOverlay/UNSAFE_WrappedModalize.tsx +0 -41
|
@@ -1,27 +1,41 @@
|
|
|
1
1
|
import React, { createRef } from "react";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
act,
|
|
4
|
+
render,
|
|
5
|
+
screen,
|
|
6
|
+
userEvent,
|
|
7
|
+
waitFor,
|
|
8
|
+
} from "@testing-library/react-native";
|
|
3
9
|
import { AccessibilityInfo, View } from "react-native";
|
|
4
|
-
import { Host } from "react-native-portalize";
|
|
5
10
|
import type { ReactTestInstance } from "react-test-renderer";
|
|
6
|
-
import { act } from "react-test-renderer";
|
|
7
11
|
import type { ContentOverlayRef, ModalBackgroundColor } from "./types";
|
|
8
12
|
import { ContentOverlay } from "./ContentOverlay";
|
|
13
|
+
import { AtlantisOverlayProvider } from "../AtlantisOverlayProvider";
|
|
9
14
|
import { tokens } from "../utils/design";
|
|
10
15
|
import { Button } from "../Button";
|
|
11
16
|
import { Content } from "../Content";
|
|
12
17
|
import { Text } from "../Text";
|
|
13
18
|
|
|
14
19
|
jest.unmock("../hooks/useIsScreenReaderEnabled");
|
|
20
|
+
jest.unmock("react-native-reanimated");
|
|
21
|
+
jest.unmock("@gorhom/bottom-sheet");
|
|
22
|
+
jest.mock("@gorhom/bottom-sheet/lib/commonjs/hooks/useAnimatedLayout", () => ({
|
|
23
|
+
// Fix for reanimated not actually running in the test environment.
|
|
24
|
+
useAnimatedLayout: () => {
|
|
25
|
+
const value = {
|
|
26
|
+
containerHeight: 600,
|
|
27
|
+
rawContainerHeight: 600,
|
|
28
|
+
handleHeight: 24,
|
|
29
|
+
footerHeight: 0,
|
|
30
|
+
contentHeight: 400,
|
|
31
|
+
containerOffset: { top: 0, bottom: 0, left: 0, right: 0 },
|
|
32
|
+
};
|
|
15
33
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
},
|
|
22
|
-
},
|
|
23
|
-
});
|
|
24
|
-
}
|
|
34
|
+
return { value, get: () => value };
|
|
35
|
+
},
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
const user = userEvent.setup();
|
|
25
39
|
|
|
26
40
|
interface testRendererOptions {
|
|
27
41
|
text: string;
|
|
@@ -44,12 +58,6 @@ function getDefaultOptions(): testRendererOptions {
|
|
|
44
58
|
fullScreen: false,
|
|
45
59
|
showDismiss: false,
|
|
46
60
|
modalBackgroundColor: "surface",
|
|
47
|
-
onCloseCallback: () => {
|
|
48
|
-
return;
|
|
49
|
-
},
|
|
50
|
-
onOpenCallback: () => {
|
|
51
|
-
return;
|
|
52
|
-
},
|
|
53
61
|
};
|
|
54
62
|
}
|
|
55
63
|
|
|
@@ -69,8 +77,8 @@ function renderContentOverlay(
|
|
|
69
77
|
) {
|
|
70
78
|
const contentOverlayRef = createRef<ContentOverlayRef>();
|
|
71
79
|
|
|
72
|
-
|
|
73
|
-
<
|
|
80
|
+
render(
|
|
81
|
+
<AtlantisOverlayProvider>
|
|
74
82
|
<View>
|
|
75
83
|
<Text>I am a bunch of text</Text>
|
|
76
84
|
<Button
|
|
@@ -95,32 +103,31 @@ function renderContentOverlay(
|
|
|
95
103
|
</Content>
|
|
96
104
|
</ContentOverlay>
|
|
97
105
|
</View>
|
|
98
|
-
</
|
|
106
|
+
</AtlantisOverlayProvider>,
|
|
99
107
|
);
|
|
100
|
-
|
|
101
|
-
const childrenView = renderResult.getByTestId("ATL-Overlay-Children");
|
|
102
|
-
fireLayoutEvent(childrenView);
|
|
103
|
-
const headerComponent = renderResult.getByTestId("ATL-Overlay-Header");
|
|
104
|
-
fireLayoutEvent(headerComponent);
|
|
105
|
-
|
|
106
|
-
return renderResult;
|
|
107
108
|
}
|
|
108
109
|
|
|
109
110
|
async function renderAndOpenContentOverlay(
|
|
110
111
|
defaultOptions = getDefaultOptions(),
|
|
111
112
|
) {
|
|
112
|
-
|
|
113
|
+
jest.useFakeTimers();
|
|
114
|
+
const props = {
|
|
115
|
+
onOpenCallback: jest.fn(),
|
|
116
|
+
onCloseCallback: jest.fn(),
|
|
117
|
+
...defaultOptions,
|
|
118
|
+
};
|
|
113
119
|
|
|
120
|
+
renderContentOverlay(props);
|
|
121
|
+
|
|
122
|
+
await user.press(screen.getByLabelText(defaultOptions.buttonLabel));
|
|
114
123
|
await act(async () => {
|
|
115
|
-
|
|
124
|
+
jest.runAllTimers();
|
|
116
125
|
});
|
|
117
126
|
|
|
118
|
-
// Wait for the modal to open asynchronously (due to requestAnimationFrame)
|
|
119
127
|
await waitFor(() => {
|
|
120
|
-
expect(
|
|
128
|
+
expect(screen.getByTestId("ATL-Overlay-Header")).toBeDefined();
|
|
129
|
+
expect(props.onOpenCallback).toHaveBeenCalledTimes(1);
|
|
121
130
|
});
|
|
122
|
-
|
|
123
|
-
return rendered;
|
|
124
131
|
}
|
|
125
132
|
|
|
126
133
|
describe("when open is called on the content overlay ref", () => {
|
|
@@ -129,9 +136,9 @@ describe("when open is called on the content overlay ref", () => {
|
|
|
129
136
|
...getDefaultOptions(),
|
|
130
137
|
text: "I am text within the content overlay",
|
|
131
138
|
};
|
|
132
|
-
|
|
139
|
+
await renderAndOpenContentOverlay(options);
|
|
133
140
|
|
|
134
|
-
expect(
|
|
141
|
+
expect(screen.getByText(options.text)).toBeDefined();
|
|
135
142
|
});
|
|
136
143
|
});
|
|
137
144
|
|
|
@@ -142,16 +149,16 @@ describe("when the close button is clicked on an open content overlay", () => {
|
|
|
142
149
|
text: "I am text within the content overlay",
|
|
143
150
|
showDismiss: true,
|
|
144
151
|
};
|
|
145
|
-
|
|
152
|
+
await renderAndOpenContentOverlay(options);
|
|
146
153
|
|
|
154
|
+
const closeButton = await screen.findByTestId("ATL-Overlay-CloseButton");
|
|
155
|
+
await user.press(closeButton);
|
|
147
156
|
await act(async () => {
|
|
148
|
-
|
|
149
|
-
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
150
|
-
);
|
|
157
|
+
jest.runAllTimers();
|
|
151
158
|
});
|
|
152
159
|
|
|
153
160
|
await waitFor(() => {
|
|
154
|
-
expect(
|
|
161
|
+
expect(screen.queryByText(options.text)).toBeNull();
|
|
155
162
|
});
|
|
156
163
|
});
|
|
157
164
|
});
|
|
@@ -163,12 +170,12 @@ describe("when the close button is clicked on an open content overlay with a def
|
|
|
163
170
|
onCloseCallback: jest.fn(),
|
|
164
171
|
showDismiss: true,
|
|
165
172
|
};
|
|
166
|
-
|
|
173
|
+
await renderAndOpenContentOverlay(options);
|
|
167
174
|
|
|
175
|
+
const closeButton = await screen.findByTestId("ATL-Overlay-CloseButton");
|
|
176
|
+
await user.press(closeButton);
|
|
168
177
|
await act(async () => {
|
|
169
|
-
|
|
170
|
-
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
171
|
-
);
|
|
178
|
+
jest.runAllTimers();
|
|
172
179
|
});
|
|
173
180
|
|
|
174
181
|
await waitFor(() => {
|
|
@@ -213,9 +220,9 @@ describe("when title prop passed to content overlay", () => {
|
|
|
213
220
|
...getDefaultOptions(),
|
|
214
221
|
title: "Awesome Title",
|
|
215
222
|
};
|
|
216
|
-
|
|
223
|
+
await renderAndOpenContentOverlay(options);
|
|
217
224
|
|
|
218
|
-
expect(
|
|
225
|
+
expect(screen.getByText(options.title)).toBeDefined();
|
|
219
226
|
});
|
|
220
227
|
});
|
|
221
228
|
|
|
@@ -226,11 +233,9 @@ describe("when accessibilityLabel prop passed to content overlay", () => {
|
|
|
226
233
|
a11yLabel: "Awesome a11y Label",
|
|
227
234
|
showDismiss: true,
|
|
228
235
|
};
|
|
229
|
-
|
|
236
|
+
await renderAndOpenContentOverlay(options);
|
|
230
237
|
|
|
231
|
-
expect(
|
|
232
|
-
contentOverlayScreen.getByLabelText(options.a11yLabel || "ohno"),
|
|
233
|
-
).toBeDefined();
|
|
238
|
+
expect(screen.getByLabelText(options.a11yLabel || "ohno")).toBeDefined();
|
|
234
239
|
});
|
|
235
240
|
});
|
|
236
241
|
|
|
@@ -241,10 +246,10 @@ describe("when accessibilityLabel prop NOT passed to content overlay", () => {
|
|
|
241
246
|
title: "Awesome Title",
|
|
242
247
|
showDismiss: true,
|
|
243
248
|
};
|
|
244
|
-
|
|
249
|
+
await renderAndOpenContentOverlay(options);
|
|
245
250
|
|
|
246
251
|
expect(
|
|
247
|
-
|
|
252
|
+
screen.getAllByLabelText(`Close ${options.title} modal`),
|
|
248
253
|
).toHaveLength(2);
|
|
249
254
|
});
|
|
250
255
|
});
|
|
@@ -258,11 +263,9 @@ describe("when there is a screen reader enabled", () => {
|
|
|
258
263
|
const options: testRendererOptions = {
|
|
259
264
|
...getDefaultOptions(),
|
|
260
265
|
};
|
|
261
|
-
|
|
266
|
+
await renderAndOpenContentOverlay(options);
|
|
262
267
|
|
|
263
|
-
expect(
|
|
264
|
-
await contentOverlayScreen.findByTestId("ATL-Overlay-CloseButton"),
|
|
265
|
-
).toBeDefined();
|
|
268
|
+
expect(await screen.findByTestId("ATL-Overlay-CloseButton")).toBeDefined();
|
|
266
269
|
});
|
|
267
270
|
});
|
|
268
271
|
|
|
@@ -272,10 +275,8 @@ describe("when fullScreen is set to true", () => {
|
|
|
272
275
|
...getDefaultOptions(),
|
|
273
276
|
fullScreen: true,
|
|
274
277
|
};
|
|
275
|
-
|
|
276
|
-
expect(
|
|
277
|
-
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
278
|
-
).toBeDefined();
|
|
278
|
+
await renderAndOpenContentOverlay(options);
|
|
279
|
+
expect(screen.getByTestId("ATL-Overlay-CloseButton")).toBeDefined();
|
|
279
280
|
});
|
|
280
281
|
});
|
|
281
282
|
|
|
@@ -285,10 +286,8 @@ describe("when showDismiss is set to true", () => {
|
|
|
285
286
|
...getDefaultOptions(),
|
|
286
287
|
showDismiss: true,
|
|
287
288
|
};
|
|
288
|
-
|
|
289
|
-
expect(
|
|
290
|
-
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
291
|
-
).toBeDefined();
|
|
289
|
+
await renderAndOpenContentOverlay(options);
|
|
290
|
+
expect(screen.getByTestId("ATL-Overlay-CloseButton")).toBeDefined();
|
|
292
291
|
});
|
|
293
292
|
});
|
|
294
293
|
|
|
@@ -299,13 +298,9 @@ describe("when the close button is clicked on an open content overlay with a def
|
|
|
299
298
|
onBeforeExitCallback: jest.fn(),
|
|
300
299
|
showDismiss: true,
|
|
301
300
|
};
|
|
302
|
-
|
|
301
|
+
await renderAndOpenContentOverlay(options);
|
|
303
302
|
|
|
304
|
-
await
|
|
305
|
-
fireEvent.press(
|
|
306
|
-
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
307
|
-
);
|
|
308
|
-
});
|
|
303
|
+
await user.press(screen.getByTestId("ATL-Overlay-CloseButton"));
|
|
309
304
|
|
|
310
305
|
await waitFor(() => {
|
|
311
306
|
expect(options.onBeforeExitCallback).toHaveBeenCalled();
|
|
@@ -319,10 +314,9 @@ describe("modalBackgroundColor prop", () => {
|
|
|
319
314
|
const options: testRendererOptions = {
|
|
320
315
|
...getDefaultOptions(),
|
|
321
316
|
};
|
|
322
|
-
|
|
323
|
-
const OverlayHeader =
|
|
324
|
-
|
|
325
|
-
).children[0] as ReactTestInstance;
|
|
317
|
+
await renderAndOpenContentOverlay(options);
|
|
318
|
+
const OverlayHeader = screen.getByTestId("ATL-Overlay-Header")
|
|
319
|
+
.children[0] as ReactTestInstance;
|
|
326
320
|
const OverlayHeaderStyles = OverlayHeader.props.style;
|
|
327
321
|
|
|
328
322
|
expect(OverlayHeaderStyles).toEqual(
|
|
@@ -349,10 +343,9 @@ describe("modalBackgroundColor prop", () => {
|
|
|
349
343
|
...getDefaultOptions(),
|
|
350
344
|
modalBackgroundColor: "background",
|
|
351
345
|
};
|
|
352
|
-
|
|
353
|
-
const OverlayHeader =
|
|
354
|
-
|
|
355
|
-
).children[0] as ReactTestInstance;
|
|
346
|
+
await renderAndOpenContentOverlay(options);
|
|
347
|
+
const OverlayHeader = screen.getByTestId("ATL-Overlay-Header")
|
|
348
|
+
.children[0] as ReactTestInstance;
|
|
356
349
|
const OverlayHeaderStyles = OverlayHeader.props.style;
|
|
357
350
|
|
|
358
351
|
expect(OverlayHeaderStyles).toEqual(
|
|
@@ -365,3 +358,88 @@ describe("modalBackgroundColor prop", () => {
|
|
|
365
358
|
});
|
|
366
359
|
});
|
|
367
360
|
});
|
|
361
|
+
|
|
362
|
+
describe("scrollEnabled prop", () => {
|
|
363
|
+
describe("when scrollEnabled is false (default)", () => {
|
|
364
|
+
it("should render content in BottomSheetView", async () => {
|
|
365
|
+
const options: testRendererOptions = {
|
|
366
|
+
...getDefaultOptions(),
|
|
367
|
+
};
|
|
368
|
+
await renderAndOpenContentOverlay(options);
|
|
369
|
+
|
|
370
|
+
expect(screen.getByText(options.text)).toBeDefined();
|
|
371
|
+
expect(screen.getByTestId("ATL-Overlay-Children")).toBeDefined();
|
|
372
|
+
});
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
describe("loading prop", () => {
|
|
377
|
+
describe("when loading is true", () => {
|
|
378
|
+
it("should show subdued heading text", async () => {
|
|
379
|
+
const overlayRef = createRef<ContentOverlayRef>();
|
|
380
|
+
|
|
381
|
+
render(
|
|
382
|
+
<AtlantisOverlayProvider>
|
|
383
|
+
<View>
|
|
384
|
+
<ContentOverlay
|
|
385
|
+
ref={overlayRef}
|
|
386
|
+
title="Loading Overlay"
|
|
387
|
+
loading={true}
|
|
388
|
+
showDismiss={true}
|
|
389
|
+
>
|
|
390
|
+
<Text>Loading content</Text>
|
|
391
|
+
</ContentOverlay>
|
|
392
|
+
</View>
|
|
393
|
+
</AtlantisOverlayProvider>,
|
|
394
|
+
);
|
|
395
|
+
|
|
396
|
+
await act(async () => {
|
|
397
|
+
overlayRef.current?.open?.();
|
|
398
|
+
});
|
|
399
|
+
|
|
400
|
+
await waitFor(() => {
|
|
401
|
+
expect(screen.getByText("Loading Overlay")).toBeDefined();
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
describe("onBeforeExit callback", () => {
|
|
408
|
+
describe("when close button is pressed with onBeforeExit defined", () => {
|
|
409
|
+
it("should call onBeforeExit instead of immediately closing", async () => {
|
|
410
|
+
const overlayRef = createRef<ContentOverlayRef>();
|
|
411
|
+
const onBeforeExitCallback = jest.fn();
|
|
412
|
+
|
|
413
|
+
render(
|
|
414
|
+
<AtlantisOverlayProvider>
|
|
415
|
+
<View>
|
|
416
|
+
<ContentOverlay
|
|
417
|
+
ref={overlayRef}
|
|
418
|
+
title="Confirmation Required"
|
|
419
|
+
onBeforeExit={onBeforeExitCallback}
|
|
420
|
+
showDismiss={true}
|
|
421
|
+
>
|
|
422
|
+
<Text>Must confirm to close</Text>
|
|
423
|
+
</ContentOverlay>
|
|
424
|
+
</View>
|
|
425
|
+
</AtlantisOverlayProvider>,
|
|
426
|
+
);
|
|
427
|
+
|
|
428
|
+
await act(async () => {
|
|
429
|
+
overlayRef.current?.open?.();
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
await waitFor(() => {
|
|
433
|
+
expect(screen.getByText("Must confirm to close")).toBeDefined();
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
const closeButton = screen.getByTestId("ATL-Overlay-CloseButton");
|
|
437
|
+
await user.press(closeButton);
|
|
438
|
+
|
|
439
|
+
await waitFor(() => {
|
|
440
|
+
expect(onBeforeExitCallback).toHaveBeenCalled();
|
|
441
|
+
expect(screen.getByText("Must confirm to close")).toBeDefined();
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
});
|
|
445
|
+
});
|