UNPKG

7.91 kBJavaScriptView Raw
1import { getHeaderTitle, HeaderBackContext, HeaderHeightContext, HeaderShownContext } from '@react-navigation/elements';
2import { useTheme } from '@react-navigation/native';
3import * as React from 'react';
4import { StyleSheet, View } from 'react-native';
5import ModalPresentationContext from '../../utils/ModalPresentationContext';
6import useKeyboardManager from '../../utils/useKeyboardManager';
7import Card from './Card';
8const EPSILON = 0.1;
9
10function CardContainer(_ref) {
11 let {
12 interpolationIndex,
13 index,
14 active,
15 closing,
16 gesture,
17 focused,
18 modal,
19 getPreviousScene,
20 getFocusedRoute,
21 headerDarkContent,
22 hasAbsoluteFloatHeader,
23 headerHeight,
24 onHeaderHeightChange,
25 isParentHeaderShown,
26 isNextScreenTransparent,
27 detachCurrentScreen,
28 layout,
29 onCloseRoute,
30 onOpenRoute,
31 onGestureCancel,
32 onGestureEnd,
33 onGestureStart,
34 onTransitionEnd,
35 onTransitionStart,
36 renderHeader,
37 renderScene,
38 safeAreaInsetBottom,
39 safeAreaInsetLeft,
40 safeAreaInsetRight,
41 safeAreaInsetTop,
42 scene
43 } = _ref;
44 const parentHeaderHeight = React.useContext(HeaderHeightContext);
45 const {
46 onPageChangeStart,
47 onPageChangeCancel,
48 onPageChangeConfirm
49 } = useKeyboardManager(React.useCallback(() => {
50 const {
51 options,
52 navigation
53 } = scene.descriptor;
54 return navigation.isFocused() && options.keyboardHandlingEnabled !== false;
55 }, [scene.descriptor]));
56
57 const handleOpen = () => {
58 const {
59 route
60 } = scene.descriptor;
61 onTransitionEnd({
62 route
63 }, false);
64 onOpenRoute({
65 route
66 });
67 };
68
69 const handleClose = () => {
70 const {
71 route
72 } = scene.descriptor;
73 onTransitionEnd({
74 route
75 }, true);
76 onCloseRoute({
77 route
78 });
79 };
80
81 const handleGestureBegin = () => {
82 const {
83 route
84 } = scene.descriptor;
85 onPageChangeStart();
86 onGestureStart({
87 route
88 });
89 };
90
91 const handleGestureCanceled = () => {
92 const {
93 route
94 } = scene.descriptor;
95 onPageChangeCancel();
96 onGestureCancel({
97 route
98 });
99 };
100
101 const handleGestureEnd = () => {
102 const {
103 route
104 } = scene.descriptor;
105 onGestureEnd({
106 route
107 });
108 };
109
110 const handleTransition = _ref2 => {
111 let {
112 closing,
113 gesture
114 } = _ref2;
115 const {
116 route
117 } = scene.descriptor;
118
119 if (!gesture) {
120 onPageChangeConfirm === null || onPageChangeConfirm === void 0 ? void 0 : onPageChangeConfirm(true);
121 } else if (active && closing) {
122 onPageChangeConfirm === null || onPageChangeConfirm === void 0 ? void 0 : onPageChangeConfirm(false);
123 } else {
124 onPageChangeCancel === null || onPageChangeCancel === void 0 ? void 0 : onPageChangeCancel();
125 }
126
127 onTransitionStart === null || onTransitionStart === void 0 ? void 0 : onTransitionStart({
128 route
129 }, closing);
130 };
131
132 const insets = {
133 top: safeAreaInsetTop,
134 right: safeAreaInsetRight,
135 bottom: safeAreaInsetBottom,
136 left: safeAreaInsetLeft
137 };
138 const {
139 colors
140 } = useTheme();
141 const [pointerEvents, setPointerEvents] = React.useState('box-none');
142 React.useEffect(() => {
143 var _scene$progress$next, _scene$progress$next$;
144
145 const listener = (_scene$progress$next = scene.progress.next) === null || _scene$progress$next === void 0 ? void 0 : (_scene$progress$next$ = _scene$progress$next.addListener) === null || _scene$progress$next$ === void 0 ? void 0 : _scene$progress$next$.call(_scene$progress$next, _ref3 => {
146 let {
147 value
148 } = _ref3;
149 setPointerEvents(value <= EPSILON ? 'box-none' : 'none');
150 });
151 return () => {
152 if (listener) {
153 var _scene$progress$next2, _scene$progress$next3;
154
155 (_scene$progress$next2 = scene.progress.next) === null || _scene$progress$next2 === void 0 ? void 0 : (_scene$progress$next3 = _scene$progress$next2.removeListener) === null || _scene$progress$next3 === void 0 ? void 0 : _scene$progress$next3.call(_scene$progress$next2, listener);
156 }
157 };
158 }, [pointerEvents, scene.progress.next]);
159 const {
160 presentation,
161 animationEnabled,
162 cardOverlay,
163 cardOverlayEnabled,
164 cardShadowEnabled,
165 cardStyle,
166 cardStyleInterpolator,
167 gestureDirection,
168 gestureEnabled,
169 gestureResponseDistance,
170 gestureVelocityImpact,
171 headerMode,
172 headerShown,
173 transitionSpec
174 } = scene.descriptor.options;
175 const previousScene = getPreviousScene({
176 route: scene.descriptor.route
177 });
178 let backTitle;
179
180 if (previousScene) {
181 const {
182 options,
183 route
184 } = previousScene.descriptor;
185 backTitle = getHeaderTitle(options, route.name);
186 }
187
188 const headerBack = React.useMemo(() => backTitle !== undefined ? {
189 title: backTitle
190 } : undefined, [backTitle]);
191 return /*#__PURE__*/React.createElement(Card, {
192 interpolationIndex: interpolationIndex,
193 gestureDirection: gestureDirection,
194 layout: layout,
195 insets: insets,
196 gesture: gesture,
197 current: scene.progress.current,
198 next: scene.progress.next,
199 closing: closing,
200 onOpen: handleOpen,
201 onClose: handleClose,
202 overlay: cardOverlay,
203 overlayEnabled: cardOverlayEnabled,
204 shadowEnabled: cardShadowEnabled,
205 onTransition: handleTransition,
206 onGestureBegin: handleGestureBegin,
207 onGestureCanceled: handleGestureCanceled,
208 onGestureEnd: handleGestureEnd,
209 gestureEnabled: index === 0 ? false : gestureEnabled,
210 gestureResponseDistance: gestureResponseDistance,
211 gestureVelocityImpact: gestureVelocityImpact,
212 transitionSpec: transitionSpec,
213 styleInterpolator: cardStyleInterpolator,
214 accessibilityElementsHidden: !focused,
215 importantForAccessibility: focused ? 'auto' : 'no-hide-descendants',
216 pointerEvents: active ? 'box-none' : pointerEvents,
217 pageOverflowEnabled: headerMode !== 'float' && presentation !== 'modal',
218 headerDarkContent: headerDarkContent,
219 containerStyle: hasAbsoluteFloatHeader && headerMode !== 'screen' ? {
220 marginTop: headerHeight
221 } : null,
222 contentStyle: [{
223 backgroundColor: presentation === 'transparentModal' ? 'transparent' : colors.background
224 }, cardStyle],
225 style: [{
226 // This is necessary to avoid unfocused larger pages increasing scroll area
227 // The issue can be seen on the web when a smaller screen is pushed over a larger one
228 overflow: active ? undefined : 'hidden',
229 display: // Hide unfocused screens when animation isn't enabled
230 // This is also necessary for a11y on web
231 animationEnabled === false && isNextScreenTransparent === false && detachCurrentScreen !== false && !focused ? 'none' : 'flex'
232 }, StyleSheet.absoluteFill]
233 }, /*#__PURE__*/React.createElement(View, {
234 style: styles.container
235 }, /*#__PURE__*/React.createElement(ModalPresentationContext.Provider, {
236 value: modal
237 }, /*#__PURE__*/React.createElement(View, {
238 style: styles.scene
239 }, /*#__PURE__*/React.createElement(HeaderBackContext.Provider, {
240 value: headerBack
241 }, /*#__PURE__*/React.createElement(HeaderShownContext.Provider, {
242 value: isParentHeaderShown || headerShown !== false
243 }, /*#__PURE__*/React.createElement(HeaderHeightContext.Provider, {
244 value: headerShown ? headerHeight : parentHeaderHeight !== null && parentHeaderHeight !== void 0 ? parentHeaderHeight : 0
245 }, renderScene({
246 route: scene.descriptor.route
247 }))))), headerMode !== 'float' ? renderHeader({
248 mode: 'screen',
249 layout,
250 scenes: [previousScene, scene],
251 getPreviousScene,
252 getFocusedRoute,
253 onContentHeightChange: onHeaderHeightChange
254 }) : null)));
255}
256
257export default /*#__PURE__*/React.memo(CardContainer);
258const styles = StyleSheet.create({
259 container: {
260 flex: 1,
261 flexDirection: 'column-reverse'
262 },
263 scene: {
264 flex: 1
265 }
266});
267//# sourceMappingURL=CardContainer.js.map
\No newline at end of file