@momo-kits/foundation 0.75.1-beta.3

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.
Files changed (76) hide show
  1. package/Assets/header-background.png +0 -0
  2. package/Assets/icon.json +3947 -0
  3. package/Button/index.tsx +247 -0
  4. package/Button/styles.ts +41 -0
  5. package/CheckBox/index.tsx +61 -0
  6. package/CheckBox/styles.ts +15 -0
  7. package/CheckBox/types.ts +10 -0
  8. package/Consts/colors+spacing+radius.ts +214 -0
  9. package/Consts/index.ts +3 -0
  10. package/Consts/styles.ts +78 -0
  11. package/Consts/theme.ts +121 -0
  12. package/Divider/index.tsx +19 -0
  13. package/Icon/index.tsx +37 -0
  14. package/Icon/types.ts +8 -0
  15. package/IconButton/index.tsx +128 -0
  16. package/IconButton/styles.ts +19 -0
  17. package/Image/index.tsx +80 -0
  18. package/Image/styles.ts +13 -0
  19. package/Image/types.ts +3 -0
  20. package/Input/Input.tsx +142 -0
  21. package/Input/InputMoney.tsx +132 -0
  22. package/Input/InputSearch.tsx +161 -0
  23. package/Input/InputTextArea.tsx +152 -0
  24. package/Input/common.tsx +125 -0
  25. package/Input/index.tsx +41 -0
  26. package/Input/styles.ts +122 -0
  27. package/Input/utils.ts +63 -0
  28. package/Layout/Card.tsx +87 -0
  29. package/Layout/GridSystem.tsx +124 -0
  30. package/Layout/ScreenContainer.tsx +122 -0
  31. package/Layout/Section.tsx +143 -0
  32. package/Layout/index.ts +16 -0
  33. package/Layout/types.ts +21 -0
  34. package/Layout/utils.ts +50 -0
  35. package/Navigation/BottomTab.tsx +39 -0
  36. package/Navigation/Components.tsx +329 -0
  37. package/Navigation/ModalScreen.tsx +207 -0
  38. package/Navigation/Navigation.ts +38 -0
  39. package/Navigation/NavigationButton.tsx +54 -0
  40. package/Navigation/NavigationContainer.tsx +82 -0
  41. package/Navigation/Navigator.ts +66 -0
  42. package/Navigation/Observer.ts +79 -0
  43. package/Navigation/StackScreen.tsx +40 -0
  44. package/Navigation/index.ts +14 -0
  45. package/Navigation/types.ts +149 -0
  46. package/Navigation/utils.tsx +167 -0
  47. package/Pagination/Dot.tsx +16 -0
  48. package/Pagination/PaginationDot.tsx +33 -0
  49. package/Pagination/PaginationNumber.tsx +23 -0
  50. package/Pagination/PaginationScroll.tsx +88 -0
  51. package/Pagination/PaginationWhiteDot.tsx +32 -0
  52. package/Pagination/index.tsx +25 -0
  53. package/Pagination/styles.ts +47 -0
  54. package/Pagination/types.ts +19 -0
  55. package/Popup/PopupNotify.tsx +215 -0
  56. package/Popup/PopupPromotion.tsx +77 -0
  57. package/Popup/index.tsx +4 -0
  58. package/Popup/types.ts +22 -0
  59. package/Radio/index.tsx +65 -0
  60. package/Radio/styles.ts +11 -0
  61. package/Radio/types.ts +10 -0
  62. package/Skeleton/index.tsx +72 -0
  63. package/Skeleton/styles.ts +5 -0
  64. package/Skeleton/types.ts +3 -0
  65. package/Switch/index.tsx +40 -0
  66. package/Switch/styles.ts +23 -0
  67. package/Switch/types.ts +8 -0
  68. package/Tag/index.tsx +79 -0
  69. package/Tag/styles.ts +24 -0
  70. package/Tag/types.ts +10 -0
  71. package/Text/index.tsx +110 -0
  72. package/Text/styles.ts +35 -0
  73. package/Text/types.ts +40 -0
  74. package/index.ts +38 -0
  75. package/package.json +41 -0
  76. package/publish.sh +26 -0
@@ -0,0 +1,329 @@
1
+ import React, {useContext, useEffect, useState} from 'react';
2
+ import {
3
+ Animated,
4
+ DeviceEventEmitter,
5
+ StatusBar,
6
+ StyleSheet,
7
+ TouchableOpacity,
8
+ View,
9
+ } from 'react-native';
10
+ import {ApplicationContext, NavigationButton} from './index';
11
+ import {Colors, Radius, Spacing, Styles} from '../Consts';
12
+ import {Image} from '../Image';
13
+ import {
14
+ HeaderBackgroundProps,
15
+ HeaderBackProps,
16
+ TitleCustomProps,
17
+ } from './types';
18
+ import {Text} from '../Text';
19
+ import {Icon} from '../Icon';
20
+ import {requestApi} from './utils';
21
+ import Observer from './Observer';
22
+ import {PopupNotify} from '../Popup';
23
+
24
+ const styles = StyleSheet.create({
25
+ headerBackground: {
26
+ width: '100%',
27
+ height: undefined,
28
+ position: 'absolute',
29
+ aspectRatio: 375 / 154,
30
+ },
31
+ headerTitleContainer: {
32
+ alignItems: 'center',
33
+ justifyContent: 'center',
34
+ width: '100%',
35
+ },
36
+ circle: {width: 36, height: 36, borderRadius: 18},
37
+ square: {width: 36, height: 36, borderRadius: Radius.XS},
38
+ dotAvatar: {
39
+ position: 'absolute',
40
+ width: 12,
41
+ height: 12,
42
+ borderRadius: 6,
43
+ bottom: 0,
44
+ right: 0,
45
+ borderWidth: 1,
46
+ borderColor: Colors.black_01,
47
+ },
48
+ headerRightButton: {
49
+ flexDirection: 'row',
50
+ overflow: 'hidden',
51
+ justifyContent: 'center',
52
+ alignItems: 'center',
53
+ paddingRight: Spacing.M,
54
+ },
55
+ toolkitContainer: {
56
+ marginLeft: Spacing.S,
57
+ padding: Spacing.XS,
58
+ height: 28,
59
+ borderRadius: 14,
60
+ borderColor: '#00000066',
61
+ justifyContent: 'center',
62
+ alignItems: 'center',
63
+ flexDirection: 'row',
64
+ },
65
+ divider: {
66
+ width: 1,
67
+ height: 12,
68
+ marginHorizontal: 4,
69
+ },
70
+ headerLeft: {
71
+ marginLeft: 12,
72
+ },
73
+ title: {fontSize: 15, lineHeight: 22, fontWeight: 'bold'},
74
+ });
75
+
76
+ const HeaderTitle: React.FC<any> = props => {
77
+ const opacity = props.animatedValue?.interpolate({
78
+ inputRange: [0, 200],
79
+ outputRange: [0, 1],
80
+ extrapolate: 'clamp',
81
+ });
82
+ return (
83
+ <Animated.Text
84
+ {...props}
85
+ accessibilityLabel={`HeaderTitle/${props.children}`}
86
+ style={[styles.title, {opacity, color: props.tintColor}]}
87
+ />
88
+ );
89
+ };
90
+
91
+ const HeaderLeft: React.FC<HeaderBackProps> = ({tintColor, preventBack}) => {
92
+ const {navigator} = useContext(ApplicationContext);
93
+ const goBack = () => {
94
+ const canGoBack = navigator?.ref.current?.canGoBack();
95
+ if (canGoBack) {
96
+ if (preventBack) {
97
+ navigator?.showModal({
98
+ screen: () => (
99
+ <PopupNotify
100
+ {...preventBack}
101
+ primary={{
102
+ title: preventBack.primary.title,
103
+ onPress: () => {
104
+ preventBack?.primary.onPress();
105
+ navigator?.ref.current?.goBack();
106
+ },
107
+ }}
108
+ />
109
+ ),
110
+ });
111
+ } else {
112
+ navigator?.ref.current?.goBack();
113
+ }
114
+ } else {
115
+ const currentTime = new Date().getTime();
116
+ const requestId = `navigationBackPress#${currentTime}`;
117
+ DeviceEventEmitter.emit('dismiss', {requestId});
118
+ }
119
+ };
120
+
121
+ return (
122
+ <View style={styles.headerLeft}>
123
+ <NavigationButton
124
+ icon="ic_back"
125
+ tintColor={tintColor}
126
+ onPress={goBack}
127
+ accessibilityLabel={'Back'}
128
+ />
129
+ </View>
130
+ );
131
+ };
132
+
133
+ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
134
+ image,
135
+ backgroundColor,
136
+ animatedValue,
137
+ }) => {
138
+ const {theme} = useContext(ApplicationContext);
139
+ let headerImage = theme.assets?.headerBackground;
140
+ let borderBottomWidth = 0;
141
+ if (image === null) {
142
+ borderBottomWidth = 1;
143
+ headerImage = undefined;
144
+ }
145
+ const opacity = animatedValue?.interpolate({
146
+ inputRange: [0, 200],
147
+ outputRange: [0, 1],
148
+ extrapolate: 'clamp',
149
+ });
150
+
151
+ return (
152
+ <Animated.View
153
+ style={[
154
+ Styles.flex,
155
+ {
156
+ backgroundColor: backgroundColor ?? theme.colors.background.default,
157
+ overflow: 'hidden',
158
+ borderBottomWidth: borderBottomWidth,
159
+ borderColor: theme.colors.border.default,
160
+ opacity,
161
+ },
162
+ ]}>
163
+ <StatusBar
164
+ barStyle={headerImage || theme.dark ? 'light-content' : 'dark-content'}
165
+ />
166
+ {!!headerImage && (
167
+ <Image style={styles.headerBackground} source={{uri: headerImage}} />
168
+ )}
169
+ </Animated.View>
170
+ );
171
+ };
172
+
173
+ const HeaderCustom: React.FC<TitleCustomProps> = ({
174
+ title,
175
+ subTitle,
176
+ image,
177
+ imageShape = 'circle',
178
+ content,
179
+ tintColor,
180
+ dotColor,
181
+ }) => {
182
+ const avatarStyle = imageShape == 'circle' ? styles.circle : styles.square;
183
+ const header = (
184
+ <View style={Styles.row}>
185
+ <View>
186
+ <Image source={{uri: image}} style={avatarStyle} />
187
+ {!!dotColor && (
188
+ <View style={[styles.dotAvatar, {backgroundColor: dotColor}]} />
189
+ )}
190
+ </View>
191
+ <View style={[Styles.flex, Styles.paddingHorizontal8]}>
192
+ <Text typography="title_xs" color={tintColor}>
193
+ {title}
194
+ </Text>
195
+ <Text typography="description_s" color={tintColor}>
196
+ {subTitle}
197
+ </Text>
198
+ </View>
199
+ </View>
200
+ );
201
+ return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
202
+ };
203
+
204
+ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
205
+ const validType = (item: any) => {
206
+ if (item.type !== NavigationButton) {
207
+ console.warn(
208
+ 'element type of NavigationButton, Please migrate to use NavigationButton of kits.',
209
+ );
210
+ }
211
+ };
212
+ const renderAction = () => {
213
+ if (Array.isArray(children)) {
214
+ return children.map((child, index) => {
215
+ validType(child);
216
+ return (
217
+ <React.Fragment key={index}>
218
+ {React.cloneElement(child, {...restProps})}
219
+ </React.Fragment>
220
+ );
221
+ });
222
+ }
223
+
224
+ validType(children);
225
+ return React.cloneElement(children, {...restProps});
226
+ };
227
+ return <View style={styles.headerRightButton}>{renderAction()}</View>;
228
+ };
229
+
230
+ const HeaderToolkitAction: React.FC<any> = ({tintColor, utilityToolConfig}) => {
231
+ const {appCode, hidden, type, onAction} = utilityToolConfig ?? {};
232
+ const {theme} = useContext(ApplicationContext);
233
+ const [showUtility, setShowUtility] = useState(hidden === false);
234
+
235
+ let backgroundColor;
236
+ if (tintColor != Colors.black_01) {
237
+ backgroundColor = theme.colors.background.surface;
238
+ }
239
+
240
+ useEffect(() => {
241
+ let addFavorite: any;
242
+ let removeFavorite: any;
243
+ if (appCode && type === 'addFavorite') {
244
+ const addSchema = `observerToolkit_addFavorite_${appCode}`;
245
+ const removeSchema = `observerToolkit_removeFavorite_${appCode}`;
246
+ addFavorite = Observer?.getInstance(addSchema);
247
+ removeFavorite = Observer?.getInstance(removeSchema);
248
+
249
+ addFavorite?.attach((data: any) => {
250
+ if (data?.status) {
251
+ setShowUtility(false);
252
+ }
253
+ });
254
+ removeFavorite?.attach((data: any) => {
255
+ if (data?.status) {
256
+ setShowUtility(true);
257
+ }
258
+ });
259
+ }
260
+ return () => {
261
+ addFavorite?.();
262
+ removeFavorite?.();
263
+ };
264
+ }, []);
265
+
266
+ const onUtilityTool = () => {
267
+ onAction?.('onUtilityTool');
268
+ requestApi(type, [undefined], undefined);
269
+ };
270
+
271
+ const onMore = () => {
272
+ onAction?.('onMore');
273
+ requestApi('showToolkit', [utilityToolConfig], undefined);
274
+ };
275
+
276
+ const onClose = () => {
277
+ onAction?.('onClose');
278
+ requestApi('dismiss', [], undefined);
279
+ };
280
+
281
+ const renderUtilityTool = () => {
282
+ if (showUtility) {
283
+ return (
284
+ <NavigationButton
285
+ icon={type}
286
+ tintColor={tintColor}
287
+ onPress={onUtilityTool}
288
+ />
289
+ );
290
+ }
291
+ };
292
+
293
+ return (
294
+ <View style={styles.headerRightButton}>
295
+ {renderUtilityTool()}
296
+ <View
297
+ style={[
298
+ styles.toolkitContainer,
299
+ {
300
+ backgroundColor: backgroundColor ?? '#00000066',
301
+ borderWidth: backgroundColor ? 0.5 : 0,
302
+ },
303
+ ]}>
304
+ <TouchableOpacity accessibilityLabel={'Toolkit/More'} onPress={onMore}>
305
+ <Icon color={tintColor} source="navigation_more_horiz" size={20} />
306
+ </TouchableOpacity>
307
+ <View style={[styles.divider, {backgroundColor: tintColor}]} />
308
+ <TouchableOpacity
309
+ accessibilityLabel={'Toolkit/Close'}
310
+ onPress={onClose}>
311
+ <Icon
312
+ color={tintColor}
313
+ source="16_navigation_close_circle"
314
+ size={20}
315
+ />
316
+ </TouchableOpacity>
317
+ </View>
318
+ </View>
319
+ );
320
+ };
321
+
322
+ export {
323
+ HeaderTitle,
324
+ HeaderLeft,
325
+ HeaderBackground,
326
+ HeaderRightAction,
327
+ HeaderToolkitAction,
328
+ HeaderCustom,
329
+ };
@@ -0,0 +1,207 @@
1
+ import React, {useContext, useEffect, useMemo, useRef} from 'react';
2
+ import {
3
+ KeyboardAvoidingView,
4
+ Platform,
5
+ Pressable,
6
+ StyleSheet,
7
+ View,
8
+ } from 'react-native';
9
+ import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
10
+ import {BottomSheetBackdrop, BottomSheetModal} from '@gorhom/bottom-sheet';
11
+ import {BottomSheetModalMethods} from '@gorhom/bottom-sheet/lib/typescript/types';
12
+ import Navigation from './Navigation';
13
+ import {BottomSheetParams, ModalParams} from './types';
14
+ import {Radius, Spacing, Styles} from '../Consts';
15
+ import {
16
+ ApplicationContext,
17
+ HeaderRightAction,
18
+ NavigationButton,
19
+ NavigationContainer,
20
+ } from './index';
21
+
22
+ const ModalScreen: React.FC<any> = props => {
23
+ useEffect(() => {
24
+ return () => {
25
+ props.route.params?.onDismiss?.();
26
+ };
27
+ }, []);
28
+
29
+ if (props.route?.params?.isBottomSheet) {
30
+ return <BottomSheet {...props} />;
31
+ }
32
+ return <Modal {...props} />;
33
+ };
34
+
35
+ const Modal: React.FC<ModalParams> = ({navigation, route}) => {
36
+ const {theme} = useContext(ApplicationContext);
37
+ const {screen, barrierDismissible}: ModalParams = route.params;
38
+ const Component = useRef(screen).current;
39
+ const params = {
40
+ ...route.params,
41
+ navigation: new Navigation(navigation, theme),
42
+ };
43
+ delete params.screen;
44
+
45
+ const onDismiss = (pop = true) => {
46
+ if (barrierDismissible) {
47
+ return;
48
+ }
49
+ navigation.pop();
50
+ };
51
+
52
+ return (
53
+ <KeyboardAvoidingView
54
+ style={Styles.flex}
55
+ behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
56
+ <View style={styles.container}>
57
+ <Pressable
58
+ style={styles.modalSpaceHorizontal}
59
+ onPress={() => onDismiss()}
60
+ />
61
+ <View style={styles.modalCenterStage}>
62
+ <Pressable
63
+ style={styles.modalSpaceVertical}
64
+ onPress={() => onDismiss()}
65
+ />
66
+ <View style={styles.modalContent} accessibilityLabel={'Modal'}>
67
+ <Component {...params} />
68
+ </View>
69
+ <Pressable
70
+ style={styles.modalSpaceVertical}
71
+ onPress={() => onDismiss()}
72
+ />
73
+ </View>
74
+ <Pressable
75
+ style={styles.modalSpaceHorizontal}
76
+ onPress={() => onDismiss()}
77
+ />
78
+ </View>
79
+ </KeyboardAvoidingView>
80
+ );
81
+ };
82
+
83
+ const BottomSheet: React.FC<BottomSheetParams> = ({navigation, route}) => {
84
+ const {theme} = useContext(ApplicationContext);
85
+ const {screen, options}: BottomSheetParams = route.params;
86
+ const Component = useRef(screen).current;
87
+ const params = {
88
+ ...route.params,
89
+ navigation: new Navigation(navigation, theme),
90
+ };
91
+ delete params.screen;
92
+
93
+ const snapPoints = useMemo(() => ['50%', '90%'], []);
94
+ const {bottom} = useSafeAreaInsets();
95
+ const bottomSheetRef = useRef<BottomSheetModalMethods>(null);
96
+ const mountedRef = useRef(true);
97
+
98
+ useEffect(() => {
99
+ bottomSheetRef.current?.present();
100
+ return () => {
101
+ mountedRef.current = false;
102
+ };
103
+ }, []);
104
+
105
+ const backdropComponent = (backdropProps: any) => (
106
+ <BottomSheetBackdrop
107
+ disappearsOnIndex={-1}
108
+ appearsOnIndex={0}
109
+ {...backdropProps}
110
+ />
111
+ );
112
+
113
+ let backgroundColor = theme.colors.background.default;
114
+ if (options?.surface) {
115
+ backgroundColor = theme.colors.background.surface;
116
+ }
117
+ const sheetTheme = {...theme, assets: undefined};
118
+
119
+ return (
120
+ <SafeAreaView style={Styles.flex}>
121
+ <BottomSheetModal
122
+ ref={bottomSheetRef}
123
+ snapPoints={snapPoints}
124
+ onDismiss={() => {
125
+ if (mountedRef.current) {
126
+ navigation.pop();
127
+ }
128
+ }}
129
+ handleComponent={null}
130
+ backdropComponent={backdropComponent}>
131
+ <View
132
+ style={{paddingBottom: bottom}}
133
+ accessibilityLabel={'BottomSheet'}>
134
+ <View style={[styles.sheetContainer, {backgroundColor}]}>
135
+ <View style={styles.indicatorContainer}>
136
+ <View
137
+ style={[
138
+ styles.indicator,
139
+ {backgroundColor: theme.colors.text.disable},
140
+ ]}
141
+ />
142
+ </View>
143
+ <NavigationContainer
144
+ theme={sheetTheme}
145
+ screen={props => <Component {...props} {...params} />}
146
+ options={{
147
+ ...options,
148
+ ...{headerLeft: null, headerTransparent: false},
149
+ headerTitleAlign: 'center',
150
+ headerRight: props => (
151
+ <HeaderRightAction>
152
+ <NavigationButton
153
+ {...props}
154
+ icon="24_navigation_close"
155
+ backgroundColor="transparent"
156
+ useBorder={false}
157
+ onPress={bottomSheetRef.current?.dismiss}
158
+ />
159
+ </HeaderRightAction>
160
+ ),
161
+ }}
162
+ />
163
+ </View>
164
+ </View>
165
+ </BottomSheetModal>
166
+ </SafeAreaView>
167
+ );
168
+ };
169
+
170
+ const styles = StyleSheet.create({
171
+ container: {flex: 1, flexDirection: 'row'},
172
+ modalContent: {
173
+ maxWidth: '100%',
174
+ maxHeight: '80%',
175
+ },
176
+ modalCenterStage: {
177
+ maxWidth: '90%',
178
+ },
179
+ modalSpaceHorizontal: {
180
+ flex: 1,
181
+ minWidth: '5%',
182
+ },
183
+ modalSpaceVertical: {
184
+ flex: 1,
185
+ minHeight: '10%',
186
+ },
187
+ sheetContainer: {
188
+ height: '100%',
189
+ width: '100%',
190
+ borderTopLeftRadius: Radius.M,
191
+ borderTopRightRadius: Radius.M,
192
+ overflow: 'hidden',
193
+ },
194
+ indicatorContainer: {
195
+ width: '100%',
196
+ paddingTop: Spacing.S,
197
+ alignItems: 'center',
198
+ justifyContent: 'center',
199
+ },
200
+ indicator: {
201
+ width: 64,
202
+ height: 4,
203
+ borderRadius: Radius.S,
204
+ },
205
+ });
206
+
207
+ export default ModalScreen;
@@ -0,0 +1,38 @@
1
+ import {NavigationProp} from '@react-navigation/native';
2
+ import {NavigationOptions, Theme} from './types';
3
+ import {HeaderRightAction} from './index';
4
+ import {getOptions} from './utils';
5
+
6
+ class Navigation {
7
+ instance: NavigationProp<any>;
8
+ theme: Theme;
9
+
10
+ constructor(instance: any, theme: Theme) {
11
+ this.instance = instance;
12
+ this.theme = theme;
13
+ }
14
+
15
+ verifyParams = (params: NavigationOptions) => {
16
+ if (params.headerRight) {
17
+ const headerRight = params.headerRight?.();
18
+ if (headerRight.type !== HeaderRightAction) {
19
+ console.warn(
20
+ 'headerRight not return element type of HeaderRightAction, Please migrate to use HeaderRightAction of kits.',
21
+ );
22
+ }
23
+ }
24
+ return params;
25
+ };
26
+
27
+ filterParams = (params: NavigationOptions) => {
28
+ return params;
29
+ };
30
+
31
+ setOptions = (params: NavigationOptions) => {
32
+ params = this.verifyParams(params);
33
+ params = getOptions(params, this.theme);
34
+ this.instance.setOptions(params);
35
+ };
36
+ }
37
+
38
+ export default Navigation;
@@ -0,0 +1,54 @@
1
+ import {Platform, StyleSheet, TouchableOpacity as TouchRN} from 'react-native';
2
+ import {TouchableOpacity as TouchGesture} from 'react-native-gesture-handler';
3
+ import React, {useContext} from 'react';
4
+ import {NavigationButtonProps} from './types';
5
+ import {ApplicationContext} from './index';
6
+ import {Icon} from '../Icon';
7
+ import {Colors} from '../Consts';
8
+
9
+ const TouchableOpacity = Platform.OS === 'ios' ? TouchRN : TouchGesture;
10
+ const NavigationButton: React.FC<NavigationButtonProps> = ({
11
+ icon,
12
+ tintColor,
13
+ onPress,
14
+ backgroundColor,
15
+ useBorder = true,
16
+ accessibilityLabel,
17
+ }) => {
18
+ const {theme} = useContext(ApplicationContext);
19
+ if (!backgroundColor && tintColor != Colors.black_01) {
20
+ backgroundColor = theme.colors.background.surface;
21
+ }
22
+
23
+ return (
24
+ <TouchableOpacity
25
+ accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
26
+ style={[
27
+ styles.container,
28
+ {
29
+ backgroundColor: backgroundColor ?? '#00000066',
30
+ borderWidth: useBorder && backgroundColor ? 0.5 : 0,
31
+ },
32
+ ]}
33
+ onPress={onPress}>
34
+ <Icon
35
+ source={icon}
36
+ color={tintColor ?? theme.colors.text.default}
37
+ size={20}
38
+ />
39
+ </TouchableOpacity>
40
+ );
41
+ };
42
+
43
+ const styles = StyleSheet.create({
44
+ container: {
45
+ height: 28,
46
+ width: 28,
47
+ borderRadius: 14,
48
+ borderColor: '#00000066',
49
+ justifyContent: 'center',
50
+ alignItems: 'center',
51
+ },
52
+ });
53
+
54
+ export default NavigationButton;
@@ -0,0 +1,82 @@
1
+ import React, {createContext, useEffect, useRef} from 'react';
2
+ import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
3
+ import {SafeAreaProvider} from 'react-native-safe-area-context';
4
+ import {
5
+ NavigationContainer as ReactNavigationContainer,
6
+ NavigationContainerRef,
7
+ } from '@react-navigation/native';
8
+ import {createStackNavigator} from '@react-navigation/stack';
9
+ import StackScreen from './StackScreen';
10
+ import ModalScreen from './ModalScreen';
11
+ import Navigator from './Navigator';
12
+ import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
13
+ import {GridSystem} from '../Layout';
14
+ import {defaultContext} from '../Consts';
15
+ import {NavigationContainerProps} from './types';
16
+
17
+ const Stack = createStackNavigator();
18
+
19
+ const ApplicationContext = createContext(defaultContext);
20
+ const NavigationContainer: React.FC<NavigationContainerProps> = ({
21
+ screen,
22
+ theme,
23
+ options,
24
+ }) => {
25
+ const navigationRef = React.useRef<NavigationContainerRef>(null);
26
+ const navigator = useRef(new Navigator(navigationRef));
27
+
28
+ useEffect(() => {
29
+ if (options) {
30
+ navigationRef.current?.setParams({options: options});
31
+ }
32
+ }, []);
33
+
34
+ return (
35
+ <SafeAreaProvider>
36
+ <BottomSheetModalProvider>
37
+ <ApplicationContext.Provider
38
+ value={{theme, navigator: navigator.current}}>
39
+ <ReactNavigationContainer
40
+ theme={{
41
+ ...theme,
42
+ dark: false,
43
+ colors: {
44
+ ...theme.colors,
45
+ background: theme.colors.background.default,
46
+ card: theme.colors.background.surface,
47
+ text: theme.colors.text.default,
48
+ border: theme.colors.border.default,
49
+ notification: theme.colors.error.primary,
50
+ },
51
+ }}
52
+ ref={navigator.current?.ref}
53
+ independent={true}>
54
+ <Stack.Navigator initialRouteName="Stack" headerMode="screen">
55
+ <Stack.Screen
56
+ name="Stack"
57
+ component={StackScreen}
58
+ initialParams={{screen}}
59
+ options={getStackOptions(theme)}
60
+ />
61
+ <Stack.Screen
62
+ name="Dialog"
63
+ component={StackScreen}
64
+ options={getDialogOptions(theme)}
65
+ initialParams={{screen}}
66
+ />
67
+ <Stack.Screen
68
+ name="Modal"
69
+ component={ModalScreen}
70
+ options={getModalOptions()}
71
+ initialParams={{screen}}
72
+ />
73
+ </Stack.Navigator>
74
+ </ReactNavigationContainer>
75
+ </ApplicationContext.Provider>
76
+ </BottomSheetModalProvider>
77
+ {__DEV__ && <GridSystem />}
78
+ </SafeAreaProvider>
79
+ );
80
+ };
81
+
82
+ export {ApplicationContext, NavigationContainer};