@jobber/components-native 0.37.0 → 0.38.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/src/ContentOverlay/ContentOverlay.js +144 -0
- package/dist/src/ContentOverlay/ContentOverlay.style.js +56 -0
- package/dist/src/ContentOverlay/hooks/useKeyboardVisibility.js +21 -0
- package/dist/src/ContentOverlay/hooks/useViewLayoutHeight.js +10 -0
- package/dist/src/ContentOverlay/index.js +1 -0
- package/dist/src/ContentOverlay/messages.js +8 -0
- package/dist/src/ContentOverlay/types.js +1 -0
- package/dist/src/index.js +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/src/ContentOverlay/ContentOverlay.d.ts +6 -0
- package/dist/types/src/ContentOverlay/ContentOverlay.style.d.ts +60 -0
- package/dist/types/src/ContentOverlay/hooks/useKeyboardVisibility.d.ts +6 -0
- package/dist/types/src/ContentOverlay/hooks/useViewLayoutHeight.d.ts +6 -0
- package/dist/types/src/ContentOverlay/index.d.ts +2 -0
- package/dist/types/src/ContentOverlay/messages.d.ts +7 -0
- package/dist/types/src/ContentOverlay/types.d.ts +87 -0
- package/dist/types/src/index.d.ts +1 -0
- package/package.json +2 -2
- package/src/ContentOverlay/ContentOverlay.style.ts +70 -0
- package/src/ContentOverlay/ContentOverlay.test.tsx +371 -0
- package/src/ContentOverlay/ContentOverlay.tsx +295 -0
- package/src/ContentOverlay/hooks/useKeyboardVisibility.test.ts +42 -0
- package/src/ContentOverlay/hooks/useKeyboardVisibility.ts +36 -0
- package/src/ContentOverlay/hooks/useViewLayoutHeight.test.ts +56 -0
- package/src/ContentOverlay/hooks/useViewLayoutHeight.ts +18 -0
- package/src/ContentOverlay/index.ts +2 -0
- package/src/ContentOverlay/messages.ts +9 -0
- package/src/ContentOverlay/types.ts +96 -0
- package/src/index.ts +1 -0
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { ContentOverlayProps } from "./types";
|
|
3
|
+
export declare const ContentOverlay: React.ForwardRefExoticComponent<ContentOverlayProps & React.RefAttributes<{
|
|
4
|
+
open?: ((dest?: import("react-native-modalize/lib/options").TOpen | undefined) => void) | undefined;
|
|
5
|
+
close?: ((dest?: import("react-native-modalize/lib/options").TClose | undefined) => void) | undefined;
|
|
6
|
+
} | undefined>>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
export declare const styles: {
|
|
2
|
+
handle: {
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
backgroundColor: string;
|
|
6
|
+
top: number;
|
|
7
|
+
borderRadius: number;
|
|
8
|
+
};
|
|
9
|
+
overlay: {
|
|
10
|
+
backgroundColor: string;
|
|
11
|
+
};
|
|
12
|
+
modal: {
|
|
13
|
+
borderTopLeftRadius: number;
|
|
14
|
+
borderTopRightRadius: number;
|
|
15
|
+
};
|
|
16
|
+
modalForLargeScreens: {
|
|
17
|
+
width: number;
|
|
18
|
+
alignSelf: "center";
|
|
19
|
+
};
|
|
20
|
+
header: {
|
|
21
|
+
flexDirection: "row";
|
|
22
|
+
backgroundColor: string;
|
|
23
|
+
paddingTop: number;
|
|
24
|
+
zIndex: number;
|
|
25
|
+
borderTopLeftRadius: number;
|
|
26
|
+
borderTopRightRadius: number;
|
|
27
|
+
height: number;
|
|
28
|
+
};
|
|
29
|
+
headerShadow: {
|
|
30
|
+
shadowColor: string;
|
|
31
|
+
shadowOffset: {
|
|
32
|
+
width: number;
|
|
33
|
+
height: number;
|
|
34
|
+
};
|
|
35
|
+
shadowOpacity: number;
|
|
36
|
+
shadowRadius: number;
|
|
37
|
+
elevation: number;
|
|
38
|
+
};
|
|
39
|
+
childrenStyle: {
|
|
40
|
+
zIndex: number;
|
|
41
|
+
};
|
|
42
|
+
dismissButton: {
|
|
43
|
+
alignItems: "center";
|
|
44
|
+
};
|
|
45
|
+
hiddenContent: {
|
|
46
|
+
opacity: number;
|
|
47
|
+
};
|
|
48
|
+
titleWithoutDimiss: {
|
|
49
|
+
flex: number;
|
|
50
|
+
flexDirection: "row";
|
|
51
|
+
justifyContent: "center";
|
|
52
|
+
paddingTop: number;
|
|
53
|
+
};
|
|
54
|
+
titleWithDismiss: {
|
|
55
|
+
flex: number;
|
|
56
|
+
justifyContent: "center";
|
|
57
|
+
paddingLeft: number;
|
|
58
|
+
paddingRight: number;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
import { Modalize } from "react-native-modalize";
|
|
3
|
+
export interface ContentOverlayProps {
|
|
4
|
+
/**
|
|
5
|
+
* Content to be passed into the overlay
|
|
6
|
+
*/
|
|
7
|
+
readonly children: ReactNode;
|
|
8
|
+
/**
|
|
9
|
+
* Title of overlay, appears in the header next to the close button.
|
|
10
|
+
*/
|
|
11
|
+
readonly title: string;
|
|
12
|
+
/**
|
|
13
|
+
* Optional accessibilityLabel describing the overlay.
|
|
14
|
+
* This will read out when the overlay is opened.
|
|
15
|
+
* @default "Close {title} modal"
|
|
16
|
+
*/
|
|
17
|
+
readonly accessibilityLabel?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Force overlay height to fill the screen.
|
|
20
|
+
* Width not impacted.
|
|
21
|
+
* @default false
|
|
22
|
+
*/
|
|
23
|
+
readonly fullScreen?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Display the dismiss button in the header of the overlay.
|
|
26
|
+
* @default false
|
|
27
|
+
*/
|
|
28
|
+
readonly showDismiss?: boolean;
|
|
29
|
+
/**
|
|
30
|
+
* If false, hides the handle and turns off dragging.
|
|
31
|
+
* @default true
|
|
32
|
+
*/
|
|
33
|
+
readonly isDraggable?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* If true, automatically adjusts the overlay height to the content height.
|
|
36
|
+
* This will disable the ability to drag the overlay to fullscreen when
|
|
37
|
+
* `isDraggable` is true.
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
readonly adjustToContentHeight?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Allows taps to be registered behind keyboard if enabled
|
|
43
|
+
* @default false
|
|
44
|
+
*/
|
|
45
|
+
readonly keyboardShouldPersistTaps?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Enables scrolling in the content body of overlay
|
|
48
|
+
*/
|
|
49
|
+
readonly scrollEnabled?: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Set the background color of the modal window
|
|
52
|
+
* @default "surface"
|
|
53
|
+
*/
|
|
54
|
+
readonly modalBackgroundColor?: ModalBackgroundColor;
|
|
55
|
+
/**
|
|
56
|
+
* Callback that is called when the overlay is closed.
|
|
57
|
+
*/
|
|
58
|
+
readonly onClose?: () => void;
|
|
59
|
+
/**
|
|
60
|
+
* Callback that is called when the overlay is opened.
|
|
61
|
+
*/
|
|
62
|
+
readonly onOpen?: () => void;
|
|
63
|
+
/**
|
|
64
|
+
* Callback that is called between overlay is closed and when the "x" button is pressed
|
|
65
|
+
*/
|
|
66
|
+
readonly onBeforeExit?: () => void;
|
|
67
|
+
/**
|
|
68
|
+
* Define the behavior of the keyboard when having inputs inside the modal.
|
|
69
|
+
* @default padding
|
|
70
|
+
*/
|
|
71
|
+
readonly keyboardAvoidingBehavior?: "height" | "padding" | "position";
|
|
72
|
+
/**
|
|
73
|
+
* Boolean to show a disabled state
|
|
74
|
+
* @default false
|
|
75
|
+
*/
|
|
76
|
+
readonly loading?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* Define keyboard's Android behavior like iOS's one.
|
|
79
|
+
* @default Platform.select({ ios: true, android: false })
|
|
80
|
+
*/
|
|
81
|
+
readonly avoidKeyboardLikeIOS?: boolean;
|
|
82
|
+
}
|
|
83
|
+
export type ModalBackgroundColor = "surface" | "background";
|
|
84
|
+
export type ContentOverlayRef = {
|
|
85
|
+
open?: Modalize["open"];
|
|
86
|
+
close?: Modalize["close"];
|
|
87
|
+
} | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jobber/components-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.38.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "React Native implementation of Atlantis",
|
|
6
6
|
"repository": {
|
|
@@ -75,5 +75,5 @@
|
|
|
75
75
|
"react-native": ">=0.69.2",
|
|
76
76
|
"react-native-modal-datetime-picker": " >=13.0.0"
|
|
77
77
|
},
|
|
78
|
-
"gitHead": "
|
|
78
|
+
"gitHead": "5c76dda512a1f72636c5695a9b73fc8470291066"
|
|
79
79
|
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { StyleSheet } from "react-native";
|
|
2
|
+
import { tokens } from "../utils/design";
|
|
3
|
+
|
|
4
|
+
const modalBorderRadius = tokens["radius-larger"];
|
|
5
|
+
const titleOffsetFromHandle = tokens["space-small"] + tokens["space-smallest"];
|
|
6
|
+
|
|
7
|
+
export const styles = StyleSheet.create({
|
|
8
|
+
handle: {
|
|
9
|
+
width: tokens["space-largest"],
|
|
10
|
+
height: tokens["space-smaller"] + tokens["space-smallest"],
|
|
11
|
+
backgroundColor: tokens["color-border"],
|
|
12
|
+
top: tokens["space-small"],
|
|
13
|
+
borderRadius: tokens["radius-circle"],
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
overlay: {
|
|
17
|
+
backgroundColor: tokens["color-overlay"],
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
modal: {
|
|
21
|
+
borderTopLeftRadius: modalBorderRadius,
|
|
22
|
+
borderTopRightRadius: modalBorderRadius,
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
modalForLargeScreens: {
|
|
26
|
+
width: 640,
|
|
27
|
+
alignSelf: "center",
|
|
28
|
+
},
|
|
29
|
+
|
|
30
|
+
header: {
|
|
31
|
+
flexDirection: "row",
|
|
32
|
+
backgroundColor: tokens["color-surface"],
|
|
33
|
+
paddingTop: titleOffsetFromHandle,
|
|
34
|
+
zIndex: tokens["elevation-base"],
|
|
35
|
+
borderTopLeftRadius: modalBorderRadius,
|
|
36
|
+
borderTopRightRadius: modalBorderRadius,
|
|
37
|
+
height: tokens["space-extravagant"],
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
headerShadow: {
|
|
41
|
+
...tokens["shadow-base"],
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
childrenStyle: {
|
|
45
|
+
// We need to explicity lower the zIndex because otherwise, the modal content slides over the header shadow.
|
|
46
|
+
zIndex: -1,
|
|
47
|
+
},
|
|
48
|
+
|
|
49
|
+
dismissButton: {
|
|
50
|
+
alignItems: "center",
|
|
51
|
+
},
|
|
52
|
+
|
|
53
|
+
hiddenContent: {
|
|
54
|
+
opacity: 0,
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
titleWithoutDimiss: {
|
|
58
|
+
flex: 1,
|
|
59
|
+
flexDirection: "row",
|
|
60
|
+
justifyContent: "center",
|
|
61
|
+
paddingTop: tokens["space-base"],
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
titleWithDismiss: {
|
|
65
|
+
flex: 1,
|
|
66
|
+
justifyContent: "center",
|
|
67
|
+
paddingLeft: tokens["space-base"],
|
|
68
|
+
paddingRight: tokens["space-smaller"],
|
|
69
|
+
},
|
|
70
|
+
});
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import React, { createRef } from "react";
|
|
2
|
+
import { fireEvent, render, waitFor } from "@testing-library/react-native";
|
|
3
|
+
import { AccessibilityInfo, View } from "react-native";
|
|
4
|
+
import { Host } from "react-native-portalize";
|
|
5
|
+
import { ReactTestInstance, act } from "react-test-renderer";
|
|
6
|
+
import { useIntl } from "react-intl";
|
|
7
|
+
import {
|
|
8
|
+
ContentOverlay,
|
|
9
|
+
ContentOverlayRef,
|
|
10
|
+
ModalBackgroundColor,
|
|
11
|
+
} from "./ContentOverlay";
|
|
12
|
+
import { messages } from "./messages";
|
|
13
|
+
import { tokens } from "../utils/design";
|
|
14
|
+
import { Button } from "../Button";
|
|
15
|
+
import { Content } from "../Content";
|
|
16
|
+
import { Text } from "../Text";
|
|
17
|
+
|
|
18
|
+
jest.unmock("../hooks/useIsScreenReaderEnabled");
|
|
19
|
+
function fireLayoutEvent(childrenContent: ReactTestInstance) {
|
|
20
|
+
fireEvent(childrenContent, "onLayout", {
|
|
21
|
+
nativeEvent: {
|
|
22
|
+
layout: {
|
|
23
|
+
height: 100,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
interface testRendererOptions {
|
|
30
|
+
text: string;
|
|
31
|
+
title: string;
|
|
32
|
+
buttonLabel: string;
|
|
33
|
+
a11yLabel?: string;
|
|
34
|
+
fullScreen?: boolean;
|
|
35
|
+
showDismiss?: boolean;
|
|
36
|
+
modalBackgroundColor?: ModalBackgroundColor;
|
|
37
|
+
onCloseCallback?: () => void;
|
|
38
|
+
onOpenCallback?: () => void;
|
|
39
|
+
onBeforeExitCallback?: () => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function getDefaultOptions(): testRendererOptions {
|
|
43
|
+
return {
|
|
44
|
+
text: "I am the contentOverlay text",
|
|
45
|
+
title: "Title",
|
|
46
|
+
buttonLabel: "Open Content Overlay",
|
|
47
|
+
fullScreen: false,
|
|
48
|
+
showDismiss: false,
|
|
49
|
+
modalBackgroundColor: "surface",
|
|
50
|
+
onCloseCallback: () => {
|
|
51
|
+
return;
|
|
52
|
+
},
|
|
53
|
+
onOpenCallback: () => {
|
|
54
|
+
return;
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function renderContentOverlay(
|
|
60
|
+
{
|
|
61
|
+
text,
|
|
62
|
+
title,
|
|
63
|
+
buttonLabel,
|
|
64
|
+
a11yLabel,
|
|
65
|
+
fullScreen,
|
|
66
|
+
showDismiss,
|
|
67
|
+
modalBackgroundColor,
|
|
68
|
+
onCloseCallback,
|
|
69
|
+
onOpenCallback,
|
|
70
|
+
onBeforeExitCallback,
|
|
71
|
+
} = getDefaultOptions(),
|
|
72
|
+
) {
|
|
73
|
+
const contentOverlayRef = createRef<ContentOverlayRef>();
|
|
74
|
+
|
|
75
|
+
const renderResult = render(
|
|
76
|
+
<Host>
|
|
77
|
+
<View>
|
|
78
|
+
<Text>I am a bunch of text</Text>
|
|
79
|
+
<Button
|
|
80
|
+
label={buttonLabel}
|
|
81
|
+
onPress={() => {
|
|
82
|
+
contentOverlayRef?.current?.open?.();
|
|
83
|
+
}}
|
|
84
|
+
/>
|
|
85
|
+
<ContentOverlay
|
|
86
|
+
ref={contentOverlayRef}
|
|
87
|
+
title={title}
|
|
88
|
+
onClose={onCloseCallback}
|
|
89
|
+
onOpen={onOpenCallback}
|
|
90
|
+
accessibilityLabel={a11yLabel}
|
|
91
|
+
fullScreen={fullScreen}
|
|
92
|
+
showDismiss={showDismiss}
|
|
93
|
+
modalBackgroundColor={modalBackgroundColor}
|
|
94
|
+
onBeforeExit={onBeforeExitCallback}
|
|
95
|
+
>
|
|
96
|
+
<Content>
|
|
97
|
+
<Text>{text}</Text>
|
|
98
|
+
</Content>
|
|
99
|
+
</ContentOverlay>
|
|
100
|
+
</View>
|
|
101
|
+
</Host>,
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const childrenView = renderResult.getByTestId("ATL-Overlay-Children");
|
|
105
|
+
fireLayoutEvent(childrenView);
|
|
106
|
+
const headerComponent = renderResult.getByTestId("ATL-Overlay-Header");
|
|
107
|
+
fireLayoutEvent(headerComponent);
|
|
108
|
+
|
|
109
|
+
return renderResult;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function renderAndOpenContentOverlay(defaultOptions = getDefaultOptions()) {
|
|
113
|
+
const rendered = renderContentOverlay(defaultOptions);
|
|
114
|
+
|
|
115
|
+
act(() => {
|
|
116
|
+
fireEvent.press(rendered.getByLabelText(defaultOptions.buttonLabel));
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
return rendered;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
describe("when open is called on the content overlay ref", () => {
|
|
123
|
+
it("should open the content overlay, exposing the content to the user", () => {
|
|
124
|
+
const options: testRendererOptions = {
|
|
125
|
+
...getDefaultOptions(),
|
|
126
|
+
text: "I am text within the content overlay",
|
|
127
|
+
};
|
|
128
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
129
|
+
|
|
130
|
+
expect(contentOverlayScreen.getByText(options.text)).toBeDefined();
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("when the close button is clicked on an open content overlay", () => {
|
|
135
|
+
it("should close the content overlay", async () => {
|
|
136
|
+
const options: testRendererOptions = {
|
|
137
|
+
...getDefaultOptions(),
|
|
138
|
+
text: "I am text within the content overlay",
|
|
139
|
+
showDismiss: true,
|
|
140
|
+
};
|
|
141
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
142
|
+
|
|
143
|
+
act(() => {
|
|
144
|
+
fireEvent.press(
|
|
145
|
+
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
146
|
+
);
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
await waitFor(() => {
|
|
150
|
+
expect(contentOverlayScreen.queryByText(options.text)).toBeNull();
|
|
151
|
+
});
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe("when the close button is clicked on an open content overlay with a defined onClose prop", () => {
|
|
156
|
+
it("should call the passed in onClose prop", async () => {
|
|
157
|
+
const options: testRendererOptions = {
|
|
158
|
+
...getDefaultOptions(),
|
|
159
|
+
onCloseCallback: jest.fn(),
|
|
160
|
+
showDismiss: true,
|
|
161
|
+
};
|
|
162
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
163
|
+
|
|
164
|
+
act(() => {
|
|
165
|
+
fireEvent.press(
|
|
166
|
+
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
167
|
+
);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
await waitFor(() => {
|
|
171
|
+
expect(options.onCloseCallback).toHaveBeenCalled();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
describe("when the content overlay is created with a defined onOpen prop", () => {
|
|
177
|
+
describe("when the content overlay is not opened", () => {
|
|
178
|
+
it("should not call the passed in onOpen prop", async () => {
|
|
179
|
+
const options: testRendererOptions = {
|
|
180
|
+
...getDefaultOptions(),
|
|
181
|
+
onOpenCallback: jest.fn(),
|
|
182
|
+
};
|
|
183
|
+
renderContentOverlay(options);
|
|
184
|
+
|
|
185
|
+
await waitFor(() => {
|
|
186
|
+
expect(options.onOpenCallback).not.toHaveBeenCalled();
|
|
187
|
+
});
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe("when the content overlay is opened", () => {
|
|
192
|
+
it("should call the passed in onOpen prop", async () => {
|
|
193
|
+
const options: testRendererOptions = {
|
|
194
|
+
...getDefaultOptions(),
|
|
195
|
+
onOpenCallback: jest.fn(),
|
|
196
|
+
};
|
|
197
|
+
renderAndOpenContentOverlay(options);
|
|
198
|
+
|
|
199
|
+
await waitFor(() => {
|
|
200
|
+
expect(options.onOpenCallback).toHaveBeenCalled();
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
describe("when title prop passed to content overlay", () => {
|
|
207
|
+
it("should set the header title", () => {
|
|
208
|
+
const options: testRendererOptions = {
|
|
209
|
+
...getDefaultOptions(),
|
|
210
|
+
title: "Awesome Title",
|
|
211
|
+
};
|
|
212
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
213
|
+
|
|
214
|
+
expect(contentOverlayScreen.getByText(options.title)).toBeDefined();
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
describe("when accessibilityLabel prop passed to content overlay", () => {
|
|
219
|
+
it("should set the header accessibilityLabel", () => {
|
|
220
|
+
const options: testRendererOptions = {
|
|
221
|
+
...getDefaultOptions(),
|
|
222
|
+
a11yLabel: "Awesome a11y Label",
|
|
223
|
+
showDismiss: true,
|
|
224
|
+
};
|
|
225
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
226
|
+
|
|
227
|
+
expect(
|
|
228
|
+
contentOverlayScreen.getByLabelText(options.a11yLabel || "ohno"),
|
|
229
|
+
).toBeDefined();
|
|
230
|
+
});
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
describe("when accessibilityLabel prop NOT passed to content overlay", () => {
|
|
234
|
+
it("should use default accessibilityLabel", () => {
|
|
235
|
+
const { formatMessage } = useIntl();
|
|
236
|
+
|
|
237
|
+
const options: testRendererOptions = {
|
|
238
|
+
...getDefaultOptions(),
|
|
239
|
+
title: "Awesome Title",
|
|
240
|
+
showDismiss: true,
|
|
241
|
+
};
|
|
242
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
243
|
+
|
|
244
|
+
const defaultCloseOverlayA11YLabel = formatMessage(
|
|
245
|
+
messages.closeOverlayA11YLabel,
|
|
246
|
+
{
|
|
247
|
+
title: options.title,
|
|
248
|
+
},
|
|
249
|
+
);
|
|
250
|
+
expect(
|
|
251
|
+
contentOverlayScreen.getAllByLabelText(defaultCloseOverlayA11YLabel),
|
|
252
|
+
).toHaveLength(2);
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
describe("when there is a screen reader enabled", () => {
|
|
257
|
+
jest
|
|
258
|
+
.spyOn(AccessibilityInfo, "isScreenReaderEnabled")
|
|
259
|
+
.mockImplementation(() => Promise.resolve(true));
|
|
260
|
+
|
|
261
|
+
it("should show the dismiss button", async () => {
|
|
262
|
+
const options: testRendererOptions = {
|
|
263
|
+
...getDefaultOptions(),
|
|
264
|
+
};
|
|
265
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
266
|
+
|
|
267
|
+
expect(
|
|
268
|
+
await contentOverlayScreen.findByTestId("ATL-Overlay-CloseButton"),
|
|
269
|
+
).toBeDefined();
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
describe("when fullScreen is set to true", () => {
|
|
274
|
+
it("should show the dismiss button", () => {
|
|
275
|
+
const options: testRendererOptions = {
|
|
276
|
+
...getDefaultOptions(),
|
|
277
|
+
fullScreen: true,
|
|
278
|
+
};
|
|
279
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
280
|
+
expect(
|
|
281
|
+
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
282
|
+
).toBeDefined();
|
|
283
|
+
});
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
describe("when showDismiss is set to true", () => {
|
|
287
|
+
it("should show the dismiss button", () => {
|
|
288
|
+
const options: testRendererOptions = {
|
|
289
|
+
...getDefaultOptions(),
|
|
290
|
+
showDismiss: true,
|
|
291
|
+
};
|
|
292
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
293
|
+
expect(
|
|
294
|
+
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
295
|
+
).toBeDefined();
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
describe("when the close button is clicked on an open content overlay with a defined onBeforeExit", () => {
|
|
300
|
+
it("should call the callback method on exit", async () => {
|
|
301
|
+
const options: testRendererOptions = {
|
|
302
|
+
...getDefaultOptions(),
|
|
303
|
+
onBeforeExitCallback: jest.fn(),
|
|
304
|
+
showDismiss: true,
|
|
305
|
+
};
|
|
306
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
307
|
+
|
|
308
|
+
act(() => {
|
|
309
|
+
fireEvent.press(
|
|
310
|
+
contentOverlayScreen.getByTestId("ATL-Overlay-CloseButton"),
|
|
311
|
+
);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
await waitFor(() => {
|
|
315
|
+
expect(options.onBeforeExitCallback).toHaveBeenCalled();
|
|
316
|
+
});
|
|
317
|
+
});
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
describe("modalBackgroundColor prop", () => {
|
|
321
|
+
describe("when using the default surface value", () => {
|
|
322
|
+
it("renders the component with the color-surface color", () => {
|
|
323
|
+
const options: testRendererOptions = {
|
|
324
|
+
...getDefaultOptions(),
|
|
325
|
+
};
|
|
326
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
327
|
+
const OverlayHeader = contentOverlayScreen.getByTestId(
|
|
328
|
+
"ATL-Overlay-Header",
|
|
329
|
+
).children[0] as ReactTestInstance;
|
|
330
|
+
const OverlayHeaderStyles = OverlayHeader.props.style;
|
|
331
|
+
|
|
332
|
+
expect(OverlayHeaderStyles).toEqual(
|
|
333
|
+
expect.arrayContaining([
|
|
334
|
+
expect.objectContaining({
|
|
335
|
+
backgroundColor: tokens["color-surface"],
|
|
336
|
+
}),
|
|
337
|
+
]),
|
|
338
|
+
);
|
|
339
|
+
|
|
340
|
+
expect(OverlayHeaderStyles).not.toEqual(
|
|
341
|
+
expect.arrayContaining([
|
|
342
|
+
expect.objectContaining({
|
|
343
|
+
backgroundColor: tokens["color-surface--background"],
|
|
344
|
+
}),
|
|
345
|
+
]),
|
|
346
|
+
);
|
|
347
|
+
});
|
|
348
|
+
});
|
|
349
|
+
|
|
350
|
+
describe("when set to background", () => {
|
|
351
|
+
it("changes the backround color of the modal to color-surface--background", () => {
|
|
352
|
+
const options: testRendererOptions = {
|
|
353
|
+
...getDefaultOptions(),
|
|
354
|
+
modalBackgroundColor: "background",
|
|
355
|
+
};
|
|
356
|
+
const contentOverlayScreen = renderAndOpenContentOverlay(options);
|
|
357
|
+
const OverlayHeader = contentOverlayScreen.getByTestId(
|
|
358
|
+
"ATL-Overlay-Header",
|
|
359
|
+
).children[0] as ReactTestInstance;
|
|
360
|
+
const OverlayHeaderStyles = OverlayHeader.props.style;
|
|
361
|
+
|
|
362
|
+
expect(OverlayHeaderStyles).toEqual(
|
|
363
|
+
expect.arrayContaining([
|
|
364
|
+
expect.objectContaining({
|
|
365
|
+
backgroundColor: tokens["color-surface--background"],
|
|
366
|
+
}),
|
|
367
|
+
]),
|
|
368
|
+
);
|
|
369
|
+
});
|
|
370
|
+
});
|
|
371
|
+
});
|