@momo-kits/foundation 0.152.4-beta.3 → 0.152.4-beta.5
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/Application/BottomSheet.tsx +0 -12
- package/Application/ModalScreen.tsx +3 -15
- package/Application/Navigator.ts +34 -4
- package/Application/types.ts +22 -0
- package/Layout/Screen.tsx +109 -70
- package/Layout/SnackBar.tsx +163 -0
- package/package.json +1 -1
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import React, { useCallback, useContext, useEffect, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
|
-
BackHandler,
|
|
4
3
|
Dimensions,
|
|
5
4
|
KeyboardAvoidingView,
|
|
6
5
|
Modal,
|
|
@@ -151,17 +150,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
151
150
|
[onDismiss],
|
|
152
151
|
);
|
|
153
152
|
|
|
154
|
-
useEffect(() => {
|
|
155
|
-
const backHandler = BackHandler.addEventListener(
|
|
156
|
-
'hardwareBackPress',
|
|
157
|
-
() => {
|
|
158
|
-
onDismiss();
|
|
159
|
-
return true;
|
|
160
|
-
},
|
|
161
|
-
);
|
|
162
|
-
return () => backHandler.remove();
|
|
163
|
-
}, [barrierDismissible, onDismiss]);
|
|
164
|
-
|
|
165
153
|
/**
|
|
166
154
|
* render header
|
|
167
155
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { useContext, useEffect, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
3
|
Animated,
|
|
4
4
|
Easing,
|
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
StyleSheet,
|
|
9
9
|
View,
|
|
10
10
|
Modal as ModalRN,
|
|
11
|
-
BackHandler,
|
|
12
11
|
} from 'react-native';
|
|
13
12
|
|
|
14
13
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
@@ -80,7 +79,7 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
80
79
|
};
|
|
81
80
|
}, [opacity, props.route.params, scale]);
|
|
82
81
|
|
|
83
|
-
const onDismiss =
|
|
82
|
+
const onDismiss = (callback = () => {}, preventClose = false) => {
|
|
84
83
|
if (preventClose) {
|
|
85
84
|
return;
|
|
86
85
|
}
|
|
@@ -100,18 +99,7 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
100
99
|
navigator?.pop();
|
|
101
100
|
runOnJS(callback)();
|
|
102
101
|
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
useEffect(() => {
|
|
106
|
-
const backHandler = BackHandler.addEventListener(
|
|
107
|
-
'hardwareBackPress',
|
|
108
|
-
() => {
|
|
109
|
-
onDismiss(undefined, barrierDismissible);
|
|
110
|
-
return true;
|
|
111
|
-
},
|
|
112
|
-
);
|
|
113
|
-
return () => backHandler.remove();
|
|
114
|
-
}, [barrierDismissible, onDismiss]);
|
|
102
|
+
};
|
|
115
103
|
|
|
116
104
|
return (
|
|
117
105
|
<Container
|
package/Application/Navigator.ts
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import {CommonActions, StackActions} from '@react-navigation/native';
|
|
2
|
-
import {
|
|
1
|
+
import { CommonActions, StackActions } from '@react-navigation/native';
|
|
2
|
+
import {
|
|
3
|
+
BottomSheetParams,
|
|
4
|
+
ModalParams,
|
|
5
|
+
ScreenParams,
|
|
6
|
+
SnackBar,
|
|
7
|
+
SnackBarHandler,
|
|
8
|
+
} from './types';
|
|
3
9
|
|
|
4
10
|
class Navigator {
|
|
5
11
|
ref?: any;
|
|
@@ -7,6 +13,7 @@ class Navigator {
|
|
|
7
13
|
isWidget?: any;
|
|
8
14
|
maxApi?: any;
|
|
9
15
|
dismissData?: any;
|
|
16
|
+
snackBarHost?: SnackBarHandler;
|
|
10
17
|
|
|
11
18
|
constructor(navigation: any, isReady: any, isWidget = false) {
|
|
12
19
|
this.ref = navigation;
|
|
@@ -160,12 +167,35 @@ class Navigator {
|
|
|
160
167
|
*/
|
|
161
168
|
setCurrentContext = (context: {
|
|
162
169
|
code?: string;
|
|
163
|
-
name?: {vi: string; en: string};
|
|
164
|
-
description?: {vi: string; en: string};
|
|
170
|
+
name?: { vi: string; en: string };
|
|
171
|
+
description?: { vi: string; en: string };
|
|
165
172
|
icon?: string;
|
|
166
173
|
}) => {
|
|
167
174
|
console.log(context);
|
|
168
175
|
};
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* register host to render snackbar inside current screen
|
|
179
|
+
* @param handler
|
|
180
|
+
*/
|
|
181
|
+
setSnackBarHost = (handler?: SnackBarHandler) => {
|
|
182
|
+
this.snackBarHost = handler;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* show snackbar via current host
|
|
187
|
+
* @param params
|
|
188
|
+
*/
|
|
189
|
+
showSnackBar = (params: SnackBar) => {
|
|
190
|
+
this.snackBarHost?.show?.(params);
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* hide snackbar via current host
|
|
195
|
+
*/
|
|
196
|
+
hideSnackBar = () => {
|
|
197
|
+
this.snackBarHost?.hide?.();
|
|
198
|
+
};
|
|
169
199
|
}
|
|
170
200
|
|
|
171
201
|
export default Navigator;
|
package/Application/types.ts
CHANGED
|
@@ -15,6 +15,25 @@ export type NavigationProps = {
|
|
|
15
15
|
setOptions: (params: NavigationOptions) => void;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
export type SnackBarCustom = {
|
|
19
|
+
type: 'custom';
|
|
20
|
+
content: () => React.ReactNode;
|
|
21
|
+
heightContent?: number;
|
|
22
|
+
duration?: number;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export type SnackBarToast = {
|
|
26
|
+
type: 'toast';
|
|
27
|
+
duration?: number;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export type SnackBar = SnackBarCustom | SnackBarToast;
|
|
31
|
+
|
|
32
|
+
export type SnackBarHandler = {
|
|
33
|
+
show: (params: SnackBar) => void;
|
|
34
|
+
hide: () => void;
|
|
35
|
+
};
|
|
36
|
+
|
|
18
37
|
export type NavigatorProps = {
|
|
19
38
|
ref?: any;
|
|
20
39
|
isReady?: any;
|
|
@@ -40,6 +59,9 @@ export type NavigatorProps = {
|
|
|
40
59
|
description?: { vi: string; en: string };
|
|
41
60
|
icon?: string;
|
|
42
61
|
}) => void;
|
|
62
|
+
showSnackBar: (params: SnackBar) => void;
|
|
63
|
+
hideSnackBar: () => void;
|
|
64
|
+
setSnackBarHost?: (handler?: SnackBarHandler) => void;
|
|
43
65
|
};
|
|
44
66
|
|
|
45
67
|
export type LocalizeProps = {
|
package/Layout/Screen.tsx
CHANGED
|
@@ -49,6 +49,10 @@ import {
|
|
|
49
49
|
HeaderTitle,
|
|
50
50
|
SearchHeader,
|
|
51
51
|
} from '../Application';
|
|
52
|
+
import {
|
|
53
|
+
SnackBarContext,
|
|
54
|
+
useScreenSnackBar,
|
|
55
|
+
} from './SnackBar';
|
|
52
56
|
|
|
53
57
|
export interface ScreenProps extends ViewProps {
|
|
54
58
|
/**
|
|
@@ -191,7 +195,7 @@ const Screen = forwardRef(
|
|
|
191
195
|
) => {
|
|
192
196
|
const screenRef = useRef<View | ScrollView>(null);
|
|
193
197
|
const { width: widthDevice } = useWindowDimensions();
|
|
194
|
-
const { theme } = useContext(ApplicationContext);
|
|
198
|
+
const { theme, navigator } = useContext(ApplicationContext);
|
|
195
199
|
const screen: any = useContext(ScreenContext);
|
|
196
200
|
const insets = useSafeAreaInsets();
|
|
197
201
|
const heightHeader = useHeaderHeight();
|
|
@@ -200,6 +204,18 @@ const Screen = forwardRef(
|
|
|
200
204
|
);
|
|
201
205
|
const currentTint = useRef<string | undefined>(undefined);
|
|
202
206
|
const isTab = navigation?.instance?.getState?.()?.type === 'tab';
|
|
207
|
+
const {
|
|
208
|
+
snackBarContextValue,
|
|
209
|
+
snackBarConfig,
|
|
210
|
+
snackBarBottomOffset,
|
|
211
|
+
snackBarTranslateY,
|
|
212
|
+
handleFooterLayout,
|
|
213
|
+
handleSnackBarLayout,
|
|
214
|
+
} = useScreenSnackBar({
|
|
215
|
+
Footer,
|
|
216
|
+
bottomInset: insets.bottom,
|
|
217
|
+
navigator,
|
|
218
|
+
});
|
|
203
219
|
|
|
204
220
|
let handleScroll;
|
|
205
221
|
let Component: any = View;
|
|
@@ -564,79 +580,102 @@ const Screen = forwardRef(
|
|
|
564
580
|
};
|
|
565
581
|
|
|
566
582
|
return (
|
|
567
|
-
<
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
<HeaderExtendHeader
|
|
576
|
-
headerType={headerType}
|
|
577
|
-
heightHeader={heightHeader}
|
|
578
|
-
headerRightWidth={headerRightWidth}
|
|
579
|
-
animatedValue={animatedValue.current}
|
|
580
|
-
inputSearchProps={inputSearchProps}
|
|
581
|
-
navigation={navigation}
|
|
582
|
-
inputSearchRef={inputSearchRef}
|
|
583
|
-
useShadowHeader={useShadowHeader}
|
|
584
|
-
gradientColor={gradientColor}
|
|
585
|
-
headerBackground={headerBackground}
|
|
586
|
-
/>
|
|
587
|
-
|
|
588
|
-
<KeyboardAvoidingView
|
|
589
|
-
style={Styles.flex}
|
|
590
|
-
enabled={enableKeyboardAvoidingView}
|
|
591
|
-
keyboardVerticalOffset={keyboardVerticalOffset ?? keyboardOffset}
|
|
592
|
-
behavior={Platform.select({
|
|
593
|
-
ios: 'padding',
|
|
594
|
-
android: undefined,
|
|
595
|
-
})}
|
|
583
|
+
<SnackBarContext.Provider value={snackBarContextValue}>
|
|
584
|
+
<View
|
|
585
|
+
style={[
|
|
586
|
+
Styles.flex,
|
|
587
|
+
{
|
|
588
|
+
backgroundColor: backgroundColor ?? theme.colors.background.default,
|
|
589
|
+
},
|
|
590
|
+
]}
|
|
596
591
|
>
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
{
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
592
|
+
<HeaderExtendHeader
|
|
593
|
+
headerType={headerType}
|
|
594
|
+
heightHeader={heightHeader}
|
|
595
|
+
headerRightWidth={headerRightWidth}
|
|
596
|
+
animatedValue={animatedValue.current}
|
|
597
|
+
inputSearchProps={inputSearchProps}
|
|
598
|
+
navigation={navigation}
|
|
599
|
+
inputSearchRef={inputSearchRef}
|
|
600
|
+
useShadowHeader={useShadowHeader}
|
|
601
|
+
gradientColor={gradientColor}
|
|
602
|
+
headerBackground={headerBackground}
|
|
603
|
+
/>
|
|
604
|
+
|
|
605
|
+
<KeyboardAvoidingView
|
|
606
606
|
style={Styles.flex}
|
|
607
|
+
enabled={enableKeyboardAvoidingView}
|
|
608
|
+
keyboardVerticalOffset={keyboardVerticalOffset ?? keyboardOffset}
|
|
609
|
+
behavior={Platform.select({
|
|
610
|
+
ios: 'padding',
|
|
611
|
+
android: undefined,
|
|
612
|
+
})}
|
|
607
613
|
>
|
|
608
|
-
{
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
bottom={
|
|
619
|
-
Footer || isTab ? 12 : Math.min(insets.bottom, 21) + Spacing.S
|
|
620
|
-
}
|
|
621
|
-
/>
|
|
622
|
-
</View>
|
|
623
|
-
)}
|
|
624
|
-
|
|
625
|
-
{Footer && (
|
|
626
|
-
<View
|
|
627
|
-
style={[
|
|
628
|
-
styles.shadow,
|
|
629
|
-
{
|
|
630
|
-
paddingBottom: Math.min(insets.bottom, 21) + Spacing.S,
|
|
631
|
-
backgroundColor: theme.colors.background.surface,
|
|
632
|
-
},
|
|
633
|
-
]}
|
|
614
|
+
{Header}
|
|
615
|
+
|
|
616
|
+
<Component
|
|
617
|
+
{...scrollViewProps}
|
|
618
|
+
ref={screenRef}
|
|
619
|
+
showsVerticalScrollIndicator={false}
|
|
620
|
+
onScroll={handleScroll}
|
|
621
|
+
onScrollEndDrag={handleScrollEnd}
|
|
622
|
+
scrollEventThrottle={16}
|
|
623
|
+
style={Styles.flex}
|
|
634
624
|
>
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
625
|
+
{renderAnimatedHeader()}
|
|
626
|
+
|
|
627
|
+
{useGridLayout ? renderContent(children) : children}
|
|
628
|
+
</Component>
|
|
629
|
+
|
|
630
|
+
{floatingButtonProps && (
|
|
631
|
+
<View>
|
|
632
|
+
<FloatingButton
|
|
633
|
+
{...floatingButtonProps}
|
|
634
|
+
animatedValue={animatedValue.current}
|
|
635
|
+
bottom={
|
|
636
|
+
Footer || isTab ? 12 : Math.min(insets.bottom, 21) + Spacing.S
|
|
637
|
+
}
|
|
638
|
+
/>
|
|
639
|
+
</View>
|
|
640
|
+
)}
|
|
641
|
+
|
|
642
|
+
{snackBarConfig?.type === 'custom' && (
|
|
643
|
+
<Animated.View
|
|
644
|
+
accessibilityLiveRegion="polite"
|
|
645
|
+
style={{
|
|
646
|
+
position: 'absolute',
|
|
647
|
+
width: '100%',
|
|
648
|
+
bottom: snackBarBottomOffset,
|
|
649
|
+
transform: [{ translateY: snackBarTranslateY }],
|
|
650
|
+
}}
|
|
651
|
+
>
|
|
652
|
+
<View
|
|
653
|
+
accessible
|
|
654
|
+
accessibilityRole="summary"
|
|
655
|
+
onLayout={handleSnackBarLayout}
|
|
656
|
+
>
|
|
657
|
+
{snackBarConfig.content?.()}
|
|
658
|
+
</View>
|
|
659
|
+
</Animated.View>
|
|
660
|
+
)}
|
|
661
|
+
|
|
662
|
+
{Footer && (
|
|
663
|
+
<View
|
|
664
|
+
onLayout={handleFooterLayout}
|
|
665
|
+
style={[
|
|
666
|
+
styles.shadow,
|
|
667
|
+
{
|
|
668
|
+
paddingBottom: Math.min(insets.bottom, 21) + Spacing.S,
|
|
669
|
+
backgroundColor: theme.colors.background.surface,
|
|
670
|
+
},
|
|
671
|
+
]}
|
|
672
|
+
>
|
|
673
|
+
<Section>{Footer}</Section>
|
|
674
|
+
</View>
|
|
675
|
+
)}
|
|
676
|
+
</KeyboardAvoidingView>
|
|
677
|
+
</View>
|
|
678
|
+
</SnackBarContext.Provider>
|
|
640
679
|
);
|
|
641
680
|
},
|
|
642
681
|
);
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createContext,
|
|
3
|
+
ReactNode,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useMemo,
|
|
7
|
+
useRef,
|
|
8
|
+
useState,
|
|
9
|
+
} from 'react';
|
|
10
|
+
import { Animated, LayoutChangeEvent } from 'react-native';
|
|
11
|
+
import { Spacing } from '../Consts';
|
|
12
|
+
import { NavigatorProps, SnackBar } from '../Application/types';
|
|
13
|
+
|
|
14
|
+
type SnackBarContextValue = {
|
|
15
|
+
showSnackBar: (params: SnackBar) => void;
|
|
16
|
+
hideSnackBar: () => void;
|
|
17
|
+
isVisible: boolean;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const SnackBarContext = createContext<SnackBarContextValue>({
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
22
|
+
showSnackBar: () => { },
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
24
|
+
hideSnackBar: () => { },
|
|
25
|
+
isVisible: false,
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
type UseScreenSnackBarParams = {
|
|
29
|
+
/**
|
|
30
|
+
* Footer component passed to Screen.
|
|
31
|
+
* Used only to compute bottom offset when it exists.
|
|
32
|
+
*/
|
|
33
|
+
Footer?: ReactNode;
|
|
34
|
+
/**
|
|
35
|
+
* Bottom safe-area inset of the device.
|
|
36
|
+
*/
|
|
37
|
+
bottomInset: number;
|
|
38
|
+
/**
|
|
39
|
+
* Global navigator instance to register snack bar host on.
|
|
40
|
+
*/
|
|
41
|
+
navigator?: NavigatorProps;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export const useScreenSnackBar = ({
|
|
45
|
+
Footer,
|
|
46
|
+
bottomInset,
|
|
47
|
+
navigator,
|
|
48
|
+
}: UseScreenSnackBarParams) => {
|
|
49
|
+
const snackBarAnimation = useRef(new Animated.Value(0));
|
|
50
|
+
const [snackBarConfig, setSnackBarConfig] = useState<SnackBar | null>(null);
|
|
51
|
+
const [snackBarHeight, setSnackBarHeight] = useState(0);
|
|
52
|
+
const [footerHeight, setFooterHeight] = useState(0);
|
|
53
|
+
const footerHeightRef = useRef(0);
|
|
54
|
+
|
|
55
|
+
const animateSnackBar = useCallback(
|
|
56
|
+
(toValue: number, duration: number, onEnd?: () => void) => {
|
|
57
|
+
snackBarAnimation.current.stopAnimation();
|
|
58
|
+
Animated.timing(snackBarAnimation.current, {
|
|
59
|
+
toValue,
|
|
60
|
+
duration,
|
|
61
|
+
useNativeDriver: true,
|
|
62
|
+
}).start(({ finished }) => {
|
|
63
|
+
if (finished) {
|
|
64
|
+
onEnd?.();
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
},
|
|
68
|
+
[],
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
const hideSnackBar = useCallback(() => {
|
|
72
|
+
animateSnackBar(0, 200, () => {
|
|
73
|
+
setSnackBarConfig(null);
|
|
74
|
+
});
|
|
75
|
+
}, [animateSnackBar]);
|
|
76
|
+
|
|
77
|
+
const showSnackBar = useCallback(
|
|
78
|
+
(config: SnackBar) => {
|
|
79
|
+
setSnackBarConfig(config);
|
|
80
|
+
animateSnackBar(1, 350);
|
|
81
|
+
},
|
|
82
|
+
[animateSnackBar],
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
const navigatorRef = useRef(navigator);
|
|
86
|
+
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
navigatorRef.current = navigator;
|
|
89
|
+
}, [navigator]);
|
|
90
|
+
|
|
91
|
+
useEffect(() => {
|
|
92
|
+
if (!snackBarConfig?.duration) return;
|
|
93
|
+
|
|
94
|
+
const timer = setTimeout(() => {
|
|
95
|
+
navigatorRef.current?.hideSnackBar();
|
|
96
|
+
}, snackBarConfig.duration);
|
|
97
|
+
|
|
98
|
+
return () => clearTimeout(timer);
|
|
99
|
+
}, [snackBarConfig?.duration]);
|
|
100
|
+
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
navigator?.setSnackBarHost?.({
|
|
103
|
+
show: showSnackBar,
|
|
104
|
+
hide: hideSnackBar,
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
return () => {
|
|
108
|
+
navigator?.setSnackBarHost?.(undefined);
|
|
109
|
+
};
|
|
110
|
+
}, [navigator, showSnackBar, hideSnackBar]);
|
|
111
|
+
|
|
112
|
+
const snackBarContextValue = useMemo(
|
|
113
|
+
() => ({
|
|
114
|
+
showSnackBar,
|
|
115
|
+
hideSnackBar,
|
|
116
|
+
isVisible: !!snackBarConfig,
|
|
117
|
+
}),
|
|
118
|
+
[showSnackBar, hideSnackBar, snackBarConfig],
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const handleFooterLayout = useCallback((event: LayoutChangeEvent) => {
|
|
122
|
+
const { height } = event.nativeEvent.layout;
|
|
123
|
+
if (height !== footerHeightRef.current) {
|
|
124
|
+
footerHeightRef.current = height;
|
|
125
|
+
setFooterHeight(height);
|
|
126
|
+
}
|
|
127
|
+
}, []);
|
|
128
|
+
|
|
129
|
+
const handleSnackBarLayout = useCallback(
|
|
130
|
+
(event: LayoutChangeEvent) => {
|
|
131
|
+
const { height } = event.nativeEvent.layout;
|
|
132
|
+
if (height !== snackBarHeight) {
|
|
133
|
+
setSnackBarHeight(height);
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
[snackBarHeight],
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const snackBarBottomOffset =
|
|
140
|
+
Math.min(bottomInset, 21) + Spacing.S + (Footer ? footerHeight : 0);
|
|
141
|
+
|
|
142
|
+
const snackBarCustomHeight =
|
|
143
|
+
snackBarConfig?.type === 'custom' ? snackBarConfig.heightContent : 0;
|
|
144
|
+
const snackBarHiddenOffset =
|
|
145
|
+
(snackBarHeight || snackBarCustomHeight || 0) + Spacing.XL;
|
|
146
|
+
|
|
147
|
+
const snackBarTranslateY = snackBarAnimation.current.interpolate({
|
|
148
|
+
inputRange: [0, 1],
|
|
149
|
+
outputRange: [snackBarHiddenOffset, 0],
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return {
|
|
153
|
+
snackBarContextValue,
|
|
154
|
+
snackBarConfig,
|
|
155
|
+
snackBarBottomOffset,
|
|
156
|
+
snackBarTranslateY,
|
|
157
|
+
handleFooterLayout,
|
|
158
|
+
handleSnackBarLayout,
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
|