@jobber/components-native 0.99.0 → 0.100.1
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 +4 -6
- package/dist/src/Button/Button.js +2 -2
- 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/ActionLabel/ActionLabel.d.ts +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 +4 -6
- package/src/ActionLabel/ActionLabel.test.tsx +13 -1
- package/src/ActionLabel/ActionLabel.tsx +6 -1
- package/src/Button/Button.tsx +2 -2
- 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,228 +1,230 @@
|
|
|
1
|
-
import type { Ref } from "react";
|
|
2
1
|
import React, {
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
createContext,
|
|
3
|
+
useContext,
|
|
5
4
|
useImperativeHandle,
|
|
6
5
|
useMemo,
|
|
7
6
|
useRef,
|
|
8
7
|
useState,
|
|
9
8
|
} from "react";
|
|
10
|
-
import type { Modalize } from "react-native-modalize";
|
|
11
|
-
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
12
|
-
import type { NativeScrollEvent, NativeSyntheticEvent } from "react-native";
|
|
13
9
|
import {
|
|
14
10
|
AccessibilityInfo,
|
|
15
|
-
Platform,
|
|
16
11
|
View,
|
|
17
12
|
findNodeHandle,
|
|
18
13
|
useWindowDimensions,
|
|
19
14
|
} from "react-native";
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
|
|
23
|
-
|
|
15
|
+
import { useSafeAreaInsets } from "react-native-safe-area-context";
|
|
16
|
+
import {
|
|
17
|
+
BottomSheetBackdrop,
|
|
18
|
+
BottomSheetModal,
|
|
19
|
+
BottomSheetView,
|
|
20
|
+
} from "@gorhom/bottom-sheet";
|
|
24
21
|
import type {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
} from "
|
|
29
|
-
import {
|
|
22
|
+
BottomSheetBackdropProps,
|
|
23
|
+
BottomSheetModal as BottomSheetModalType,
|
|
24
|
+
BottomSheetScrollViewMethods,
|
|
25
|
+
} from "@gorhom/bottom-sheet";
|
|
26
|
+
import { BottomSheetKeyboardAwareScrollView } from "./BottomSheetKeyboardAwareScrollView";
|
|
27
|
+
import type { ContentOverlayProps, ModalBackgroundColor } from "./types";
|
|
28
|
+
import { useStyles } from "./ContentOverlay.style";
|
|
29
|
+
import { useBottomSheetModalBackHandler } from "./hooks/useBottomSheetModalBackHandler";
|
|
30
|
+
import { computeContentOverlayBehavior } from "./computeContentOverlayBehavior";
|
|
31
|
+
import { KEYBOARD_TOP_PADDING_AUTO_SCROLL } from "./constants";
|
|
30
32
|
import { useIsScreenReaderEnabled } from "../hooks";
|
|
31
33
|
import { IconButton } from "../IconButton";
|
|
32
34
|
import { Heading } from "../Heading";
|
|
33
35
|
import { useAtlantisI18n } from "../hooks/useAtlantisI18n";
|
|
34
36
|
import { useAtlantisTheme } from "../AtlantisThemeContext";
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
/**
|
|
39
|
+
* Signals whether keyboard handling inside a ContentOverlay is delegated to
|
|
40
|
+
* a keyboard-aware scroll view (e.g. BottomSheetKeyboardAwareScrollView).
|
|
41
|
+
*
|
|
42
|
+
* When `true`, InputText skips registering with the bottom-sheet's internal
|
|
43
|
+
* keyboard state so that only the scroll view manages keyboard offset —
|
|
44
|
+
* preventing double-counted spacing.
|
|
45
|
+
*/
|
|
46
|
+
const ContentOverlayKeyboardContext = createContext(false);
|
|
38
47
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
adjustToContentHeight = false,
|
|
49
|
-
keyboardShouldPersistTaps = false,
|
|
50
|
-
keyboardAvoidingBehavior,
|
|
51
|
-
scrollEnabled = false,
|
|
52
|
-
modalBackgroundColor = "surface",
|
|
53
|
-
onClose,
|
|
54
|
-
onOpen,
|
|
55
|
-
onBeforeExit,
|
|
56
|
-
loading = false,
|
|
57
|
-
avoidKeyboardLikeIOS,
|
|
58
|
-
}: ContentOverlayProps,
|
|
59
|
-
ref: Ref<ContentOverlayRef>,
|
|
48
|
+
export function useIsKeyboardHandledByScrollView() {
|
|
49
|
+
return useContext(ContentOverlayKeyboardContext);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const LARGE_SCREEN_BREAKPOINT = 640;
|
|
53
|
+
|
|
54
|
+
function getModalBackgroundColor(
|
|
55
|
+
variation: ModalBackgroundColor,
|
|
56
|
+
tokens: ReturnType<typeof useAtlantisTheme>["tokens"],
|
|
60
57
|
) {
|
|
61
|
-
|
|
62
|
-
|
|
58
|
+
switch (variation) {
|
|
59
|
+
case "surface":
|
|
60
|
+
return tokens["color-surface"];
|
|
61
|
+
case "background":
|
|
62
|
+
return tokens["color-surface--background"];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// eslint-disable-next-line max-statements
|
|
67
|
+
export function ContentOverlay({
|
|
68
|
+
children,
|
|
69
|
+
title,
|
|
70
|
+
accessibilityLabel,
|
|
71
|
+
fullScreen = false,
|
|
72
|
+
showDismiss = false,
|
|
73
|
+
isDraggable = true,
|
|
74
|
+
adjustToContentHeight = false,
|
|
75
|
+
keyboardShouldPersistTaps = false,
|
|
76
|
+
scrollEnabled = false,
|
|
77
|
+
modalBackgroundColor = "surface",
|
|
78
|
+
onClose,
|
|
79
|
+
onOpen,
|
|
80
|
+
onBeforeExit,
|
|
81
|
+
loading = false,
|
|
82
|
+
ref,
|
|
83
|
+
}: ContentOverlayProps) {
|
|
84
|
+
const insets = useSafeAreaInsets();
|
|
85
|
+
const { width: windowWidth } = useWindowDimensions();
|
|
86
|
+
const bottomSheetModalRef = useRef<BottomSheetModalType>(null);
|
|
87
|
+
const previousIndexRef = useRef(-1);
|
|
88
|
+
const [currentPosition, setCurrentPosition] = useState<number>(-1);
|
|
89
|
+
|
|
90
|
+
const styles = useStyles();
|
|
63
91
|
const { t } = useAtlantisI18n();
|
|
64
92
|
const { tokens } = useAtlantisTheme();
|
|
65
|
-
const { width: windowWidth, height: windowHeight } = useWindowDimensions();
|
|
66
|
-
const insets = useSafeAreaInsets();
|
|
67
|
-
const [position, setPosition] = useState<"top" | "initial">("initial");
|
|
68
93
|
const isScreenReaderEnabled = useIsScreenReaderEnabled();
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
94
|
+
|
|
95
|
+
const behavior = computeContentOverlayBehavior(
|
|
96
|
+
{
|
|
97
|
+
fullScreen,
|
|
98
|
+
adjustToContentHeight,
|
|
99
|
+
isDraggable,
|
|
100
|
+
hasOnBeforeExit: onBeforeExit !== undefined,
|
|
101
|
+
showDismiss,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
isScreenReaderEnabled,
|
|
105
|
+
position: currentPosition,
|
|
106
|
+
},
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const effectiveIsDraggable = behavior.isDraggable;
|
|
110
|
+
const shouldShowDismiss = behavior.showDismiss;
|
|
111
|
+
const isCloseableOnOverlayTap = onBeforeExit === undefined;
|
|
112
|
+
|
|
113
|
+
// Prevent the Overlay from being flush with the top of the screen, even if we are "100%" or "fullscreen"
|
|
114
|
+
const topInset = insets.top || tokens["space-larger"];
|
|
115
|
+
|
|
73
116
|
const [showHeaderShadow, setShowHeaderShadow] = useState<boolean>(false);
|
|
74
117
|
const overlayHeader = useRef<View>(null);
|
|
118
|
+
const scrollViewRef = useRef<
|
|
119
|
+
BottomSheetScrollViewMethods & { scrollTop?: number }
|
|
120
|
+
>(null);
|
|
75
121
|
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
122
|
+
// enableDynamicSizing will add another snap point of the content height
|
|
123
|
+
const snapPoints = useMemo(() => {
|
|
124
|
+
// There is a bug with "restore" behavior after keyboard is dismissed.
|
|
125
|
+
// https://github.com/gorhom/react-native-bottom-sheet/issues/2465
|
|
126
|
+
// providing a 100% snap point "fixes" it for now, but there is an approved PR to fix it
|
|
127
|
+
// that just needs to be merged and released: https://github.com/gorhom/react-native-bottom-sheet/pull/2511
|
|
128
|
+
return ["100%"];
|
|
83
129
|
}, []);
|
|
84
130
|
|
|
85
|
-
const
|
|
86
|
-
if (!
|
|
87
|
-
|
|
131
|
+
const onCloseController = () => {
|
|
132
|
+
if (!onBeforeExit) {
|
|
133
|
+
bottomSheetModalRef.current?.dismiss();
|
|
134
|
+
} else {
|
|
135
|
+
onBeforeExit();
|
|
88
136
|
}
|
|
137
|
+
};
|
|
89
138
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
close: modalizeMethods?.close,
|
|
93
|
-
};
|
|
94
|
-
}, [modalizeMethods]);
|
|
95
|
-
|
|
96
|
-
const { keyboardHeight } = useKeyboardVisibility();
|
|
97
|
-
useImperativeHandle(ref, () => refMethods, [refMethods]);
|
|
98
|
-
|
|
99
|
-
const {
|
|
100
|
-
handleLayout: handleChildrenLayout,
|
|
101
|
-
height: childrenHeight,
|
|
102
|
-
heightKnown: childrenHeightKnown,
|
|
103
|
-
} = useViewLayoutHeight();
|
|
104
|
-
const {
|
|
105
|
-
handleLayout: handleHeaderLayout,
|
|
106
|
-
height: headerHeight,
|
|
107
|
-
heightKnown: headerHeightKnown,
|
|
108
|
-
} = useViewLayoutHeight();
|
|
109
|
-
|
|
110
|
-
const snapPoint = useMemo(() => {
|
|
111
|
-
if (fullScreen || !isDraggable || adjustToContentHeight) {
|
|
112
|
-
return undefined;
|
|
113
|
-
}
|
|
114
|
-
const overlayHeight = headerHeight + childrenHeight;
|
|
139
|
+
const { handleSheetPositionChange } =
|
|
140
|
+
useBottomSheetModalBackHandler(onCloseController);
|
|
115
141
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
142
|
+
useImperativeHandle(
|
|
143
|
+
ref,
|
|
144
|
+
() => ({
|
|
145
|
+
open: () => {
|
|
146
|
+
bottomSheetModalRef.current?.present();
|
|
147
|
+
},
|
|
148
|
+
close: () => {
|
|
149
|
+
bottomSheetModalRef.current?.dismiss();
|
|
150
|
+
},
|
|
151
|
+
}),
|
|
152
|
+
[],
|
|
153
|
+
);
|
|
119
154
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
fullScreen,
|
|
123
|
-
isDraggable,
|
|
124
|
-
adjustToContentHeight,
|
|
125
|
-
headerHeight,
|
|
126
|
-
childrenHeight,
|
|
127
|
-
windowHeight,
|
|
128
|
-
]);
|
|
155
|
+
const handleChange = (index: number, position: number) => {
|
|
156
|
+
const previousIndex = previousIndexRef.current;
|
|
129
157
|
|
|
130
|
-
|
|
158
|
+
setCurrentPosition(position);
|
|
159
|
+
handleSheetPositionChange(index);
|
|
131
160
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
{ backgroundColor: getModalBackgroundColor(modalBackgroundColor) },
|
|
136
|
-
keyboardHeight > 0 && { marginBottom: 0 },
|
|
137
|
-
];
|
|
161
|
+
if (previousIndex === -1 && index >= 0) {
|
|
162
|
+
// Transitioned from closed to open
|
|
163
|
+
onOpen?.();
|
|
138
164
|
|
|
139
|
-
|
|
140
|
-
|
|
165
|
+
// Set accessibility focus on header when opened
|
|
166
|
+
if (overlayHeader.current) {
|
|
167
|
+
const reactTag = findNodeHandle(overlayHeader.current);
|
|
141
168
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
169
|
+
if (reactTag) {
|
|
170
|
+
AccessibilityInfo.setAccessibilityFocus(reactTag);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
145
174
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
onBeforeExit();
|
|
175
|
+
previousIndexRef.current = index;
|
|
176
|
+
};
|
|
149
177
|
|
|
150
|
-
|
|
151
|
-
|
|
178
|
+
const handleOnScroll = () => {
|
|
179
|
+
const scrollTop = scrollViewRef.current?.scrollTop || 0;
|
|
180
|
+
setShowHeaderShadow(scrollTop > 0);
|
|
152
181
|
};
|
|
153
182
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
modalTopOffset={tokens["space-larger"]}
|
|
164
|
-
snapPoint={snapPoint}
|
|
165
|
-
closeSnapPointStraightEnabled={false}
|
|
166
|
-
withHandle={isDraggable}
|
|
167
|
-
panGestureEnabled={isDraggable}
|
|
168
|
-
adjustToContentHeight={adjustToContentHeight}
|
|
169
|
-
disableScrollIfPossible={!adjustToContentHeight} // workaround for scroll not working on Android when content fills the screen with adjustToContentHeight
|
|
170
|
-
onClose={onClose}
|
|
171
|
-
onOpen={onOpen}
|
|
172
|
-
keyboardAvoidingBehavior={keyboardAvoidingBehavior}
|
|
173
|
-
avoidKeyboardLikeIOS={avoidKeyboardLikeIOS}
|
|
174
|
-
childrenStyle={styles.childrenStyle}
|
|
175
|
-
onBackButtonPress={onCloseController}
|
|
176
|
-
closeOnOverlayTap={isCloseableOnOverlayTap}
|
|
177
|
-
onOpened={() => {
|
|
178
|
-
if (overlayHeader.current) {
|
|
179
|
-
const reactTag = findNodeHandle(overlayHeader.current);
|
|
180
|
-
|
|
181
|
-
if (reactTag) {
|
|
182
|
-
AccessibilityInfo.setAccessibilityFocus(reactTag);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
}}
|
|
186
|
-
scrollViewProps={{
|
|
187
|
-
scrollEnabled,
|
|
188
|
-
showsVerticalScrollIndicator: false,
|
|
189
|
-
stickyHeaderIndices: Platform.OS === "android" ? [0] : undefined,
|
|
190
|
-
onScroll: handleOnScroll,
|
|
191
|
-
keyboardShouldPersistTaps: keyboardShouldPersistTaps
|
|
192
|
-
? "handled"
|
|
193
|
-
: "never",
|
|
194
|
-
}}
|
|
195
|
-
HeaderComponent={Platform.OS === "ios" ? renderedHeader : undefined}
|
|
196
|
-
onPositionChange={setPosition}
|
|
197
|
-
>
|
|
198
|
-
{Platform.OS === "android" ? renderedHeader : undefined}
|
|
199
|
-
{renderedChildren}
|
|
200
|
-
</UNSAFE_WrappedModalize>
|
|
201
|
-
)}
|
|
202
|
-
{!childrenHeightKnown && (
|
|
203
|
-
<View style={[styles.hiddenContent, modalStyle]}>
|
|
204
|
-
{renderedChildren}
|
|
205
|
-
</View>
|
|
206
|
-
)}
|
|
207
|
-
{!headerHeightKnown && (
|
|
208
|
-
<View style={[styles.hiddenContent, modalStyle]}>{renderedHeader}</View>
|
|
209
|
-
)}
|
|
210
|
-
</>
|
|
183
|
+
const sheetStyle = useMemo(
|
|
184
|
+
() =>
|
|
185
|
+
windowWidth > LARGE_SCREEN_BREAKPOINT
|
|
186
|
+
? {
|
|
187
|
+
width: LARGE_SCREEN_BREAKPOINT,
|
|
188
|
+
marginLeft: (windowWidth - LARGE_SCREEN_BREAKPOINT) / 2,
|
|
189
|
+
}
|
|
190
|
+
: undefined,
|
|
191
|
+
[windowWidth],
|
|
211
192
|
);
|
|
212
193
|
|
|
213
|
-
|
|
194
|
+
const backgroundStyle = [
|
|
195
|
+
styles.background,
|
|
196
|
+
{ backgroundColor: getModalBackgroundColor(modalBackgroundColor, tokens) },
|
|
197
|
+
];
|
|
198
|
+
|
|
199
|
+
const handleIndicatorStyles = [
|
|
200
|
+
styles.handle,
|
|
201
|
+
!effectiveIsDraggable && {
|
|
202
|
+
opacity: 0,
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
|
|
206
|
+
const renderHeader = () => {
|
|
214
207
|
const closeOverlayA11YLabel = t("ContentOverlay.close", {
|
|
215
208
|
title: title,
|
|
216
209
|
});
|
|
217
210
|
|
|
218
211
|
const headerStyles = [
|
|
219
212
|
styles.header,
|
|
213
|
+
{
|
|
214
|
+
// Background color is necessary for scrollable modals as the content flows behind the header.
|
|
215
|
+
backgroundColor: getModalBackgroundColor(modalBackgroundColor, tokens),
|
|
216
|
+
},
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
const headerShadowStyles = [
|
|
220
220
|
showHeaderShadow && styles.headerShadow,
|
|
221
|
-
{
|
|
221
|
+
{
|
|
222
|
+
backgroundColor: getModalBackgroundColor(modalBackgroundColor, tokens),
|
|
223
|
+
},
|
|
222
224
|
];
|
|
223
225
|
|
|
224
226
|
return (
|
|
225
|
-
<View
|
|
227
|
+
<View testID="ATL-Overlay-Header">
|
|
226
228
|
<View style={headerStyles}>
|
|
227
229
|
<View
|
|
228
230
|
style={[
|
|
@@ -260,45 +262,85 @@ function ContentOverlayInternal(
|
|
|
260
262
|
</View>
|
|
261
263
|
)}
|
|
262
264
|
</View>
|
|
265
|
+
<View>
|
|
266
|
+
<View style={headerShadowStyles} />
|
|
267
|
+
</View>
|
|
263
268
|
</View>
|
|
264
269
|
);
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
function renderChildren() {
|
|
268
|
-
return (
|
|
269
|
-
<View
|
|
270
|
-
style={{ paddingBottom: insets.bottom }}
|
|
271
|
-
onLayout={handleChildrenLayout}
|
|
272
|
-
testID="ATL-Overlay-Children"
|
|
273
|
-
>
|
|
274
|
-
{children}
|
|
275
|
-
</View>
|
|
276
|
-
);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
function handleOnScroll({
|
|
280
|
-
nativeEvent,
|
|
281
|
-
}: NativeSyntheticEvent<NativeScrollEvent>) {
|
|
282
|
-
setShowHeaderShadow(nativeEvent.contentOffset.y > 0);
|
|
283
|
-
}
|
|
270
|
+
};
|
|
284
271
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
272
|
+
return (
|
|
273
|
+
<BottomSheetModal
|
|
274
|
+
ref={bottomSheetModalRef}
|
|
275
|
+
onChange={handleChange}
|
|
276
|
+
style={sheetStyle}
|
|
277
|
+
backgroundStyle={backgroundStyle}
|
|
278
|
+
handleStyle={styles.handleWrapper}
|
|
279
|
+
handleIndicatorStyle={handleIndicatorStyles}
|
|
280
|
+
backdropComponent={props => (
|
|
281
|
+
<Backdrop
|
|
282
|
+
{...props}
|
|
283
|
+
pressBehavior={isCloseableOnOverlayTap ? "close" : "none"}
|
|
284
|
+
/>
|
|
285
|
+
)}
|
|
286
|
+
snapPoints={snapPoints}
|
|
287
|
+
enablePanDownToClose={effectiveIsDraggable}
|
|
288
|
+
enableContentPanningGesture={effectiveIsDraggable}
|
|
289
|
+
enableHandlePanningGesture={effectiveIsDraggable}
|
|
290
|
+
enableDynamicSizing={behavior.initialHeight === "contentHeight"}
|
|
291
|
+
keyboardBehavior="interactive"
|
|
292
|
+
keyboardBlurBehavior="restore"
|
|
293
|
+
topInset={topInset}
|
|
294
|
+
onDismiss={() => onClose?.()}
|
|
295
|
+
>
|
|
296
|
+
<ContentOverlayKeyboardContext.Provider value={scrollEnabled}>
|
|
297
|
+
{scrollEnabled ? (
|
|
298
|
+
<BottomSheetKeyboardAwareScrollView
|
|
299
|
+
ref={scrollViewRef}
|
|
300
|
+
contentContainerStyle={{ paddingBottom: insets.bottom }}
|
|
301
|
+
keyboardShouldPersistTaps={
|
|
302
|
+
keyboardShouldPersistTaps ? "handled" : "never"
|
|
303
|
+
}
|
|
304
|
+
showsVerticalScrollIndicator={false}
|
|
305
|
+
onScroll={handleOnScroll}
|
|
306
|
+
stickyHeaderIndices={[0]}
|
|
307
|
+
bottomOffset={KEYBOARD_TOP_PADDING_AUTO_SCROLL}
|
|
308
|
+
>
|
|
309
|
+
{renderHeader()}
|
|
310
|
+
<View testID="ATL-Overlay-Children">{children}</View>
|
|
311
|
+
</BottomSheetKeyboardAwareScrollView>
|
|
312
|
+
) : (
|
|
313
|
+
<BottomSheetView>
|
|
314
|
+
{renderHeader()}
|
|
315
|
+
<View
|
|
316
|
+
style={{ paddingBottom: insets.bottom }}
|
|
317
|
+
testID="ATL-Overlay-Children"
|
|
318
|
+
>
|
|
319
|
+
{children}
|
|
320
|
+
</View>
|
|
321
|
+
</BottomSheetView>
|
|
322
|
+
)}
|
|
323
|
+
</ContentOverlayKeyboardContext.Provider>
|
|
324
|
+
</BottomSheetModal>
|
|
325
|
+
);
|
|
293
326
|
}
|
|
294
327
|
|
|
295
|
-
function
|
|
296
|
-
|
|
297
|
-
|
|
328
|
+
function Backdrop(
|
|
329
|
+
bottomSheetBackdropProps: BottomSheetBackdropProps & {
|
|
330
|
+
pressBehavior: "none" | "close";
|
|
331
|
+
},
|
|
298
332
|
) {
|
|
333
|
+
const styles = useStyles();
|
|
334
|
+
const { pressBehavior, ...props } = bottomSheetBackdropProps;
|
|
335
|
+
|
|
299
336
|
return (
|
|
300
|
-
<
|
|
301
|
-
|
|
302
|
-
|
|
337
|
+
<BottomSheetBackdrop
|
|
338
|
+
{...props}
|
|
339
|
+
appearsOnIndex={0}
|
|
340
|
+
disappearsOnIndex={-1}
|
|
341
|
+
style={styles.backdrop}
|
|
342
|
+
opacity={1}
|
|
343
|
+
pressBehavior={pressBehavior}
|
|
344
|
+
/>
|
|
303
345
|
);
|
|
304
346
|
}
|