@react-navigation/stack 8.0.0-alpha.3 → 8.0.0-alpha.31
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/lib/module/index.js.map +1 -1
- package/lib/module/navigators/createStackNavigator.js +3 -7
- package/lib/module/navigators/createStackNavigator.js.map +1 -1
- package/lib/module/utils/useCardAnimation.js +1 -1
- package/lib/module/utils/useCardAnimation.js.map +1 -1
- package/lib/module/utils/useGestureHandlerRef.js +1 -1
- package/lib/module/utils/useGestureHandlerRef.js.map +1 -1
- package/lib/module/utils/useKeyboardManager.js +50 -26
- package/lib/module/utils/useKeyboardManager.js.map +1 -1
- package/lib/module/views/Header/Header.js +2 -2
- package/lib/module/views/Header/Header.js.map +1 -1
- package/lib/module/views/Header/HeaderContainer.js +51 -17
- package/lib/module/views/Header/HeaderContainer.js.map +1 -1
- package/lib/module/views/Header/HeaderSegment.js +2 -2
- package/lib/module/views/Header/HeaderSegment.js.map +1 -1
- package/lib/module/views/Stack/Card.js +25 -20
- package/lib/module/views/Stack/Card.js.map +1 -1
- package/lib/module/views/Stack/CardContainer.js +69 -98
- package/lib/module/views/Stack/CardContainer.js.map +1 -1
- package/lib/module/views/Stack/CardStack.js +134 -116
- package/lib/module/views/Stack/CardStack.js.map +1 -1
- package/lib/module/views/Stack/StackView.js +82 -49
- package/lib/module/views/Stack/StackView.js.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/navigators/createStackNavigator.d.ts +8 -14
- package/lib/typescript/src/navigators/createStackNavigator.d.ts.map +1 -1
- package/lib/typescript/src/types.d.ts +46 -53
- package/lib/typescript/src/types.d.ts.map +1 -1
- package/lib/typescript/src/utils/gestureActivationCriteria.d.ts +1 -1
- package/lib/typescript/src/utils/gestureActivationCriteria.d.ts.map +1 -1
- package/lib/typescript/src/utils/useKeyboardManager.d.ts +9 -2
- package/lib/typescript/src/utils/useKeyboardManager.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/Header.d.ts +1 -1
- package/lib/typescript/src/views/Header/Header.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/HeaderContainer.d.ts +7 -2
- package/lib/typescript/src/views/Header/HeaderContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts +2 -2
- package/lib/typescript/src/views/Header/HeaderSegment.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/Card.d.ts +3 -3
- package/lib/typescript/src/views/Stack/Card.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardContainer.d.ts +4 -6
- package/lib/typescript/src/views/Stack/CardContainer.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/CardStack.d.ts +4 -3
- package/lib/typescript/src/views/Stack/CardStack.d.ts.map +1 -1
- package/lib/typescript/src/views/Stack/StackView.d.ts +6 -9
- package/lib/typescript/src/views/Stack/StackView.d.ts.map +1 -1
- package/package.json +20 -22
- package/src/index.tsx +1 -0
- package/src/navigators/createStackNavigator.tsx +9 -40
- package/src/types.tsx +73 -73
- package/src/utils/gestureActivationCriteria.tsx +1 -1
- package/src/utils/useCardAnimation.tsx +1 -1
- package/src/utils/useGestureHandlerRef.tsx +1 -1
- package/src/utils/useKeyboardManager.tsx +67 -33
- package/src/views/Header/Header.tsx +2 -2
- package/src/views/Header/HeaderContainer.tsx +66 -20
- package/src/views/Header/HeaderSegment.tsx +4 -4
- package/src/views/Stack/Card.tsx +32 -23
- package/src/views/Stack/CardContainer.tsx +81 -127
- package/src/views/Stack/CardStack.tsx +334 -318
- package/src/views/Stack/StackView.tsx +138 -66
- package/lib/module/views/Stack/CardA11yWrapper.js +0 -43
- package/lib/module/views/Stack/CardA11yWrapper.js.map +0 -1
- package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts +0 -15
- package/lib/typescript/src/views/Stack/CardA11yWrapper.d.ts.map +0 -1
- package/src/views/Stack/CardA11yWrapper.tsx +0 -67
package/src/views/Stack/Card.tsx
CHANGED
|
@@ -58,7 +58,7 @@ type Props = {
|
|
|
58
58
|
overlayEnabled: boolean;
|
|
59
59
|
shadowEnabled: boolean | undefined;
|
|
60
60
|
gestureEnabled: boolean;
|
|
61
|
-
gestureResponseDistance?: number;
|
|
61
|
+
gestureResponseDistance?: number | undefined;
|
|
62
62
|
gestureVelocityImpact: number | undefined;
|
|
63
63
|
transitionSpec: {
|
|
64
64
|
open: TransitionSpec;
|
|
@@ -66,8 +66,8 @@ type Props = {
|
|
|
66
66
|
};
|
|
67
67
|
preloaded: boolean;
|
|
68
68
|
styleInterpolator: StackCardStyleInterpolator;
|
|
69
|
-
containerStyle?: StyleProp<ViewStyle
|
|
70
|
-
contentStyle?: StyleProp<ViewStyle
|
|
69
|
+
containerStyle?: StyleProp<ViewStyle> | undefined;
|
|
70
|
+
contentStyle?: StyleProp<ViewStyle> | undefined;
|
|
71
71
|
};
|
|
72
72
|
|
|
73
73
|
const GESTURE_VELOCITY_IMPACT = 0.3;
|
|
@@ -151,14 +151,14 @@ function Card({
|
|
|
151
151
|
containerStyle: customContainerStyle,
|
|
152
152
|
contentStyle,
|
|
153
153
|
}: Props) {
|
|
154
|
-
const [, forceUpdate] = React.useReducer((x) => x + 1, 0);
|
|
155
|
-
|
|
156
154
|
const didInitiallyAnimate = React.useRef(false);
|
|
157
155
|
const lastToValueRef = React.useRef<number | undefined>(undefined);
|
|
158
156
|
|
|
159
157
|
const animationHandleRef = React.useRef<number | undefined>(undefined);
|
|
160
158
|
const pendingGestureCallbackRef =
|
|
161
159
|
React.useRef<ReturnType<typeof setTimeout>>(undefined);
|
|
160
|
+
const pendingOnCloseCallbackRef =
|
|
161
|
+
React.useRef<ReturnType<typeof setTimeout>>(undefined);
|
|
162
162
|
|
|
163
163
|
const [isClosing] = React.useState(() => new Animated.Value(FALSE));
|
|
164
164
|
|
|
@@ -218,10 +218,8 @@ function Card({
|
|
|
218
218
|
}
|
|
219
219
|
|
|
220
220
|
animationHandleRef.current = requestAnimationFrame(() => {
|
|
221
|
-
if
|
|
222
|
-
|
|
223
|
-
forceUpdate();
|
|
224
|
-
}
|
|
221
|
+
// Make sure to re-open screen if it wasn't removed
|
|
222
|
+
maybeAnimate();
|
|
225
223
|
});
|
|
226
224
|
};
|
|
227
225
|
|
|
@@ -249,6 +247,8 @@ function Card({
|
|
|
249
247
|
({ nativeEvent }: PanGestureHandlerGestureEvent) => {
|
|
250
248
|
switch (nativeEvent.state) {
|
|
251
249
|
case GestureState.ACTIVE:
|
|
250
|
+
clearTimeout(pendingGestureCallbackRef.current);
|
|
251
|
+
clearTimeout(pendingOnCloseCallbackRef.current);
|
|
252
252
|
isSwiping.setValue(TRUE);
|
|
253
253
|
onGestureBegin?.();
|
|
254
254
|
break;
|
|
@@ -305,10 +305,13 @@ function Card({
|
|
|
305
305
|
pendingGestureCallbackRef.current = setTimeout(() => {
|
|
306
306
|
onClose();
|
|
307
307
|
|
|
308
|
-
//
|
|
309
|
-
//
|
|
310
|
-
|
|
311
|
-
|
|
308
|
+
// Check if the screen is still closing with a delay
|
|
309
|
+
// So state update from onClose has a chance to go through
|
|
310
|
+
// If route wasn't removed after onClose, re-open it
|
|
311
|
+
pendingOnCloseCallbackRef.current = setTimeout(() => {
|
|
312
|
+
maybeAnimate();
|
|
313
|
+
}, 32);
|
|
314
|
+
}, 16);
|
|
312
315
|
}
|
|
313
316
|
|
|
314
317
|
onGestureEnd?.();
|
|
@@ -350,17 +353,15 @@ function Card({
|
|
|
350
353
|
}
|
|
351
354
|
|
|
352
355
|
clearTimeout(pendingGestureCallbackRef.current);
|
|
356
|
+
clearTimeout(pendingOnCloseCallbackRef.current);
|
|
353
357
|
};
|
|
354
|
-
|
|
355
|
-
// We only want to clean up the animation on unmount
|
|
356
358
|
}, []);
|
|
357
359
|
|
|
358
|
-
const timeoutRef = React.useRef<ReturnType<typeof setTimeout
|
|
360
|
+
const timeoutRef = React.useRef<ReturnType<typeof setTimeout>>(undefined);
|
|
359
361
|
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
362
|
+
const maybeAnimate = useLatestCallback(() => {
|
|
363
|
+
clearTimeout(pendingGestureCallbackRef.current);
|
|
364
|
+
clearTimeout(pendingOnCloseCallbackRef.current);
|
|
364
365
|
|
|
365
366
|
if (!didInitiallyAnimate.current) {
|
|
366
367
|
// Animate the card in on initial mount
|
|
@@ -368,9 +369,8 @@ function Card({
|
|
|
368
369
|
// rending of the screen is done. This is especially important
|
|
369
370
|
// in the new architecture
|
|
370
371
|
// cf., https://github.com/react-navigation/react-navigation/issues/12401
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
}
|
|
372
|
+
clearTimeout(timeoutRef.current);
|
|
373
|
+
|
|
374
374
|
timeoutRef.current = setTimeout(() => {
|
|
375
375
|
didInitiallyAnimate.current = true;
|
|
376
376
|
animate({ closing });
|
|
@@ -410,6 +410,14 @@ function Card({
|
|
|
410
410
|
animate({ closing });
|
|
411
411
|
}
|
|
412
412
|
}
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
React.useEffect(() => {
|
|
416
|
+
if (preloaded) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
maybeAnimate();
|
|
413
421
|
|
|
414
422
|
previousPropsRef.current = {
|
|
415
423
|
opening,
|
|
@@ -428,6 +436,7 @@ function Card({
|
|
|
428
436
|
layout,
|
|
429
437
|
opening,
|
|
430
438
|
preloaded,
|
|
439
|
+
maybeAnimate,
|
|
431
440
|
]);
|
|
432
441
|
|
|
433
442
|
const interpolationProps = React.useMemo(
|
|
@@ -16,9 +16,11 @@ import { Animated, StyleSheet, View } from 'react-native';
|
|
|
16
16
|
import type { Layout, Scene } from '../../types';
|
|
17
17
|
import { ModalPresentationContext } from '../../utils/ModalPresentationContext';
|
|
18
18
|
import { useKeyboardManager } from '../../utils/useKeyboardManager';
|
|
19
|
-
import type {
|
|
19
|
+
import type {
|
|
20
|
+
HeaderHeight,
|
|
21
|
+
Props as HeaderContainerProps,
|
|
22
|
+
} from '../Header/HeaderContainer';
|
|
20
23
|
import { Card } from './Card';
|
|
21
|
-
import { CardA11yWrapper, type CardA11yWrapperRef } from './CardA11yWrapper';
|
|
22
24
|
|
|
23
25
|
type Props = {
|
|
24
26
|
interpolationIndex: number;
|
|
@@ -49,19 +51,15 @@ type Props = {
|
|
|
49
51
|
onGestureStart: (props: { route: Route<string> }) => void;
|
|
50
52
|
onGestureEnd: (props: { route: Route<string> }) => void;
|
|
51
53
|
onGestureCancel: (props: { route: Route<string> }) => void;
|
|
52
|
-
|
|
53
|
-
headerHeight: number;
|
|
54
|
+
headerHeight: HeaderHeight | undefined;
|
|
54
55
|
onHeaderHeightChange: (props: {
|
|
55
56
|
route: Route<string>;
|
|
56
57
|
height: number;
|
|
57
58
|
}) => void;
|
|
58
59
|
isParentHeaderShown: boolean;
|
|
59
|
-
|
|
60
|
-
detachCurrentScreen: boolean;
|
|
60
|
+
children: React.ReactNode;
|
|
61
61
|
};
|
|
62
62
|
|
|
63
|
-
const EPSILON = 0.1;
|
|
64
|
-
|
|
65
63
|
function CardContainerInner({
|
|
66
64
|
interpolationIndex,
|
|
67
65
|
index,
|
|
@@ -73,12 +71,9 @@ function CardContainerInner({
|
|
|
73
71
|
modal,
|
|
74
72
|
getPreviousScene,
|
|
75
73
|
getFocusedRoute,
|
|
76
|
-
hasAbsoluteFloatHeader,
|
|
77
74
|
headerHeight,
|
|
78
75
|
onHeaderHeightChange,
|
|
79
76
|
isParentHeaderShown,
|
|
80
|
-
isNextScreenTransparent,
|
|
81
|
-
detachCurrentScreen,
|
|
82
77
|
layout,
|
|
83
78
|
onCloseRoute,
|
|
84
79
|
onOpenRoute,
|
|
@@ -94,23 +89,17 @@ function CardContainerInner({
|
|
|
94
89
|
safeAreaInsetRight,
|
|
95
90
|
safeAreaInsetTop,
|
|
96
91
|
scene,
|
|
92
|
+
children,
|
|
97
93
|
}: Props) {
|
|
98
|
-
const wrapperRef = React.useRef<CardA11yWrapperRef>(null);
|
|
99
|
-
|
|
100
94
|
const { direction } = useLocale();
|
|
101
95
|
|
|
102
|
-
const parentHeaderHeight = React.
|
|
96
|
+
const parentHeaderHeight = React.use(HeaderHeightContext);
|
|
103
97
|
|
|
104
|
-
const {
|
|
105
|
-
|
|
106
|
-
React.useCallback(() => {
|
|
107
|
-
const { options, navigation } = scene.descriptor;
|
|
98
|
+
const { options } = scene.descriptor;
|
|
99
|
+
const enabled = focused && options.keyboardHandlingEnabled !== false;
|
|
108
100
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
);
|
|
112
|
-
}, [scene.descriptor])
|
|
113
|
-
);
|
|
101
|
+
const { onPageChangeStart, onPageChangeCancel, onPageChangeConfirm } =
|
|
102
|
+
useKeyboardManager({ enabled, focused });
|
|
114
103
|
|
|
115
104
|
const handleOpen = () => {
|
|
116
105
|
const { route } = scene.descriptor;
|
|
@@ -153,17 +142,9 @@ function CardContainerInner({
|
|
|
153
142
|
closing: boolean;
|
|
154
143
|
gesture: boolean;
|
|
155
144
|
}) => {
|
|
156
|
-
wrapperRef.current?.setInert(closing);
|
|
157
|
-
|
|
158
145
|
const { route } = scene.descriptor;
|
|
159
146
|
|
|
160
|
-
|
|
161
|
-
onPageChangeConfirm?.(true);
|
|
162
|
-
} else if (active && closing) {
|
|
163
|
-
onPageChangeConfirm?.(false);
|
|
164
|
-
} else {
|
|
165
|
-
onPageChangeCancel?.();
|
|
166
|
-
}
|
|
147
|
+
onPageChangeConfirm?.({ gesture, active, closing });
|
|
167
148
|
|
|
168
149
|
onTransitionStart?.({ route }, closing);
|
|
169
150
|
};
|
|
@@ -177,20 +158,6 @@ function CardContainerInner({
|
|
|
177
158
|
|
|
178
159
|
const { colors } = useTheme();
|
|
179
160
|
|
|
180
|
-
React.useEffect(() => {
|
|
181
|
-
const listener = scene.progress.next?.addListener?.(
|
|
182
|
-
({ value }: { value: number }) => {
|
|
183
|
-
wrapperRef.current?.setInert(value > EPSILON);
|
|
184
|
-
}
|
|
185
|
-
);
|
|
186
|
-
|
|
187
|
-
return () => {
|
|
188
|
-
if (listener) {
|
|
189
|
-
scene.progress.next?.removeListener?.(listener);
|
|
190
|
-
}
|
|
191
|
-
};
|
|
192
|
-
}, [scene.progress.next]);
|
|
193
|
-
|
|
194
161
|
const {
|
|
195
162
|
presentation,
|
|
196
163
|
animation,
|
|
@@ -236,90 +203,77 @@ function CardContainerInner({
|
|
|
236
203
|
const animated = animation !== 'none';
|
|
237
204
|
|
|
238
205
|
return (
|
|
239
|
-
<
|
|
240
|
-
ref={wrapperRef}
|
|
241
|
-
focused={focused}
|
|
242
|
-
active={active}
|
|
206
|
+
<Card
|
|
243
207
|
animated={animated}
|
|
244
|
-
|
|
245
|
-
|
|
208
|
+
interpolationIndex={interpolationIndex}
|
|
209
|
+
gestureDirection={gestureDirection}
|
|
210
|
+
layout={layout}
|
|
211
|
+
insets={insets}
|
|
212
|
+
direction={direction}
|
|
213
|
+
gesture={gesture}
|
|
214
|
+
current={scene.progress.current}
|
|
215
|
+
next={scene.progress.next}
|
|
216
|
+
opening={opening}
|
|
217
|
+
closing={closing}
|
|
218
|
+
onOpen={handleOpen}
|
|
219
|
+
onClose={handleClose}
|
|
220
|
+
overlay={cardOverlay}
|
|
221
|
+
overlayEnabled={cardOverlayEnabled}
|
|
222
|
+
shadowEnabled={cardShadowEnabled}
|
|
223
|
+
onTransition={handleTransition}
|
|
224
|
+
onGestureBegin={handleGestureBegin}
|
|
225
|
+
onGestureCanceled={handleGestureCanceled}
|
|
226
|
+
onGestureEnd={handleGestureEnd}
|
|
227
|
+
gestureEnabled={index === 0 ? false : gestureEnabled}
|
|
228
|
+
gestureResponseDistance={gestureResponseDistance}
|
|
229
|
+
gestureVelocityImpact={gestureVelocityImpact}
|
|
230
|
+
transitionSpec={transitionSpec}
|
|
231
|
+
styleInterpolator={cardStyleInterpolator}
|
|
232
|
+
pageOverflowEnabled={headerMode !== 'float' && presentation !== 'modal'}
|
|
233
|
+
preloaded={preloaded}
|
|
234
|
+
contentStyle={[
|
|
235
|
+
{
|
|
236
|
+
backgroundColor:
|
|
237
|
+
presentation === 'transparentModal'
|
|
238
|
+
? 'transparent'
|
|
239
|
+
: colors.background,
|
|
240
|
+
},
|
|
241
|
+
cardStyle,
|
|
242
|
+
]}
|
|
246
243
|
>
|
|
247
|
-
<
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
transitionSpec={transitionSpec}
|
|
272
|
-
styleInterpolator={cardStyleInterpolator}
|
|
273
|
-
pageOverflowEnabled={headerMode !== 'float' && presentation !== 'modal'}
|
|
274
|
-
preloaded={preloaded}
|
|
275
|
-
containerStyle={
|
|
276
|
-
hasAbsoluteFloatHeader && headerMode !== 'screen'
|
|
277
|
-
? { marginTop: headerHeight }
|
|
278
|
-
: null
|
|
279
|
-
}
|
|
280
|
-
contentStyle={[
|
|
281
|
-
{
|
|
282
|
-
backgroundColor:
|
|
283
|
-
presentation === 'transparentModal'
|
|
284
|
-
? 'transparent'
|
|
285
|
-
: colors.background,
|
|
286
|
-
},
|
|
287
|
-
cardStyle,
|
|
288
|
-
]}
|
|
289
|
-
>
|
|
290
|
-
<View style={styles.container}>
|
|
291
|
-
<ModalPresentationContext.Provider value={modal}>
|
|
292
|
-
{headerMode !== 'float'
|
|
293
|
-
? renderHeader({
|
|
294
|
-
mode: 'screen',
|
|
295
|
-
scenes: [previousScene, scene],
|
|
296
|
-
getPreviousScene,
|
|
297
|
-
getFocusedRoute,
|
|
298
|
-
onContentHeightChange: onHeaderHeightChange,
|
|
299
|
-
style: styles.header,
|
|
300
|
-
})
|
|
301
|
-
: null}
|
|
302
|
-
<View style={styles.scene}>
|
|
303
|
-
<HeaderBackContext.Provider value={headerBack}>
|
|
304
|
-
<HeaderShownContext.Provider
|
|
305
|
-
value={isParentHeaderShown || headerShown !== false}
|
|
244
|
+
<View style={styles.container}>
|
|
245
|
+
<ModalPresentationContext.Provider value={modal}>
|
|
246
|
+
{headerMode !== 'float'
|
|
247
|
+
? renderHeader({
|
|
248
|
+
mode: 'screen',
|
|
249
|
+
scenes: [previousScene, scene],
|
|
250
|
+
getPreviousScene,
|
|
251
|
+
getFocusedRoute,
|
|
252
|
+
contentHeight: headerHeight,
|
|
253
|
+
onContentHeightChange: onHeaderHeightChange,
|
|
254
|
+
style: styles.header,
|
|
255
|
+
})
|
|
256
|
+
: null}
|
|
257
|
+
<View style={styles.scene}>
|
|
258
|
+
<HeaderBackContext.Provider value={headerBack}>
|
|
259
|
+
<HeaderShownContext.Provider
|
|
260
|
+
value={isParentHeaderShown || headerShown !== false}
|
|
261
|
+
>
|
|
262
|
+
<HeaderHeightContext.Provider
|
|
263
|
+
value={
|
|
264
|
+
headerShown !== false
|
|
265
|
+
? (headerHeight?.value ?? 0)
|
|
266
|
+
: (parentHeaderHeight ?? 0)
|
|
267
|
+
}
|
|
306
268
|
>
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
</HeaderHeightContext.Provider>
|
|
316
|
-
</HeaderShownContext.Provider>
|
|
317
|
-
</HeaderBackContext.Provider>
|
|
318
|
-
</View>
|
|
319
|
-
</ModalPresentationContext.Provider>
|
|
320
|
-
</View>
|
|
321
|
-
</Card>
|
|
322
|
-
</CardA11yWrapper>
|
|
269
|
+
{children}
|
|
270
|
+
</HeaderHeightContext.Provider>
|
|
271
|
+
</HeaderShownContext.Provider>
|
|
272
|
+
</HeaderBackContext.Provider>
|
|
273
|
+
</View>
|
|
274
|
+
</ModalPresentationContext.Provider>
|
|
275
|
+
</View>
|
|
276
|
+
</Card>
|
|
323
277
|
);
|
|
324
278
|
}
|
|
325
279
|
|