@momo-kits/foundation 1.0.0 → 1.0.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 (68) hide show
  1. package/Button/index.tsx +118 -171
  2. package/CheckBox/index.tsx +63 -0
  3. package/CheckBox/styles.ts +14 -0
  4. package/CheckBox/types.ts +10 -0
  5. package/Consts/colors+spacing+radius.ts +6 -4
  6. package/Consts/index.ts +4 -73
  7. package/Consts/styles.ts +1 -1
  8. package/Consts/theme.ts +121 -0
  9. package/ContentLoader/index.tsx +9 -13
  10. package/Icon/index.tsx +14 -11
  11. package/Icon/types.ts +1 -4
  12. package/IconButton/index.tsx +67 -67
  13. package/IconButton/styles.ts +19 -0
  14. package/Image/index.tsx +22 -21
  15. package/Image/types.ts +0 -1
  16. package/Input/Input.tsx +161 -0
  17. package/Input/TextArea.tsx +162 -0
  18. package/Input/common.tsx +70 -0
  19. package/Input/index.tsx +26 -0
  20. package/Input/styles.ts +92 -0
  21. package/Layout/GridSystem.tsx +109 -0
  22. package/Layout/ScreenContainer.tsx +84 -0
  23. package/Layout/ScreenSection.tsx +117 -0
  24. package/Layout/SectionItem.tsx +63 -0
  25. package/Layout/index.ts +11 -5
  26. package/Layout/types.ts +6 -33
  27. package/Layout/utils.ts +69 -23
  28. package/Navigation/Components.tsx +42 -9
  29. package/Navigation/ModalScreen.tsx +65 -40
  30. package/Navigation/Navigation.ts +5 -2
  31. package/Navigation/NavigationButton.tsx +10 -5
  32. package/Navigation/NavigationContainer.tsx +17 -13
  33. package/Navigation/StackScreen.tsx +8 -2
  34. package/Navigation/index.ts +5 -3
  35. package/Navigation/types.ts +72 -38
  36. package/Navigation/utils.tsx +37 -14
  37. package/Playground/index.tsx +132 -0
  38. package/Playground/styles.ts +16 -0
  39. package/Playground/types.ts +15 -0
  40. package/Popup/PopupNotify.tsx +210 -0
  41. package/Popup/PopupPromotion.tsx +66 -0
  42. package/Popup/index.tsx +4 -0
  43. package/Popup/types.ts +23 -0
  44. package/Radio/index.tsx +42 -0
  45. package/Radio/styles.ts +12 -0
  46. package/Radio/types.ts +7 -0
  47. package/Switch/index.tsx +35 -0
  48. package/Switch/styles.ts +23 -0
  49. package/Switch/types.ts +5 -0
  50. package/Text/index.tsx +36 -118
  51. package/Text/styles.ts +24 -23
  52. package/Text/types.ts +5 -12
  53. package/index.ts +21 -4
  54. package/package.json +3 -4
  55. package/Button/types.ts +0 -18
  56. package/CheckBox/index.js +0 -74
  57. package/CheckBox/styles.js +0 -3
  58. package/IconButton/types.ts +0 -17
  59. package/Layout/Row.tsx +0 -42
  60. package/Layout/Screen.tsx +0 -68
  61. package/Layout/Section.tsx +0 -30
  62. package/Layout/View.tsx +0 -84
  63. package/Layout/styles.ts +0 -24
  64. package/Navigation/ScreenContainer.tsx +0 -38
  65. package/SizedBox/index.js +0 -23
  66. package/SizedBox/styles.js +0 -7
  67. package/TextInput/index.js +0 -225
  68. package/TextInput/styles.js +0 -55
@@ -0,0 +1,63 @@
1
+ import React, {useContext} from 'react';
2
+ import {View} from 'react-native';
3
+ import {useGridSystem} from './index';
4
+ import {SectionItemProps} from './types';
5
+ import {ApplicationContext} from '../Navigation';
6
+
7
+ const SectionItem: React.FC<SectionItemProps> = ({
8
+ widthSpan = 12,
9
+ heightSpan,
10
+ children,
11
+ style,
12
+ }) => {
13
+ const {theme} = useContext(ApplicationContext);
14
+ const grid = useGridSystem();
15
+
16
+ /**
17
+ * render overlay view only dev mode
18
+ */
19
+ const renderOverlay = () => {
20
+ return (
21
+ <View
22
+ pointerEvents={'none'}
23
+ style={{
24
+ position: 'absolute',
25
+ top: 0,
26
+ bottom: 0,
27
+ left: 0,
28
+ right: 0,
29
+ borderColor: 'red',
30
+ borderWidth: 1,
31
+ }}
32
+ />
33
+ );
34
+ };
35
+
36
+ const styles: any = style ?? {};
37
+
38
+ return (
39
+ <View
40
+ style={{
41
+ ...styles,
42
+ width: grid.getSizeSpan(widthSpan),
43
+ height: heightSpan ? grid.getSizeSpan(heightSpan) : undefined,
44
+ overflow: 'hidden',
45
+ margin: undefined,
46
+ marginTop: undefined,
47
+ marginBottom: undefined,
48
+ marginLeft: undefined,
49
+ marginRight: undefined,
50
+ }}>
51
+ {children}
52
+ {grid.isDevMode && renderOverlay()}
53
+ </View>
54
+ );
55
+ };
56
+
57
+ SectionItem.defaultProps = {
58
+ widthSpan: 12,
59
+ };
60
+
61
+ SectionItem.displayName = 'SectionItem';
62
+
63
+ export default SectionItem;
package/Layout/index.ts CHANGED
@@ -1,6 +1,12 @@
1
- import MMRow from './Row';
2
- import MMView from './View';
3
- import MMScreen from './Screen';
4
- import MMSection from './Section';
1
+ import SectionItem from './SectionItem';
2
+ import ScreenSection from './ScreenSection';
3
+ import GridSystem from './GridSystem';
4
+ import {useGridSystem, validateChildren} from './utils';
5
5
 
6
- export {MMRow, MMView, MMScreen, MMSection};
6
+ export {
7
+ SectionItem,
8
+ ScreenSection,
9
+ GridSystem,
10
+ useGridSystem,
11
+ validateChildren,
12
+ };
package/Layout/types.ts CHANGED
@@ -1,39 +1,12 @@
1
- import {ReactElement} from 'react';
1
+ import {ViewProps} from 'react-native';
2
2
 
3
3
  type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
4
- type ViewAlignItems = 'flex-start' | 'flex-end' | 'center';
5
4
 
6
- type ViewJustifyContent =
7
- | 'flex-start'
8
- | 'flex-end'
9
- | 'center'
10
- | 'space-between'
11
- | 'space-around'
12
- | 'space-evenly';
13
-
14
- type ViewDirection = 'row' | 'column';
15
-
16
- type ViewShadow = 'none' | 'light' | 'dark';
17
- export interface MMScreenProps {
18
- children: ReactElement;
19
- scrollable: boolean;
20
- }
21
-
22
- export interface MMSectionProps {
23
- haveMargin?: boolean;
24
- children: ReactElement;
5
+ export interface ScreenSectionProps extends ViewProps {
6
+ expanded?: boolean;
25
7
  }
26
8
 
27
- export interface MMViewProps {
28
- span: SpanNumber;
29
- children: ReactElement;
30
- isEndLine?: boolean;
31
- isRowChild?: boolean;
32
- alignItems?: ViewAlignItems;
33
- justifyContent: ViewJustifyContent;
34
- padding: Array<number>;
35
- backgroundColor: string;
36
- borderRadius: number;
37
- direction: ViewDirection;
38
- shadow: ViewShadow;
9
+ export interface SectionItemProps extends ViewProps {
10
+ widthSpan: SpanNumber;
11
+ heightSpan?: SpanNumber;
39
12
  }
package/Layout/utils.ts CHANGED
@@ -1,37 +1,83 @@
1
- import {Dimensions} from 'react-native';
2
- import {FC, JSXElementConstructor, ReactElement, ReactNode} from 'react';
3
- import {MMSectionProps} from './types';
1
+ import {Alert, Dimensions} from 'react-native';
2
+ import React, {ReactElement} from 'react';
3
+ import {GutterSize, NumberOfColumns, ScreenPadding} from '../Consts';
4
4
 
5
- export const screenWidth = Dimensions.get('window').width;
5
+ /**
6
+ * hook component for use grid system
7
+ * @param useMargin
8
+ */
9
+ const useGridSystem = (useMargin: boolean = true) => {
10
+ const isDevMode = false;
11
+ const gutterSize = GutterSize;
12
+ const screenPadding = useMargin ? ScreenPadding : 0;
13
+ const numberOfColumns = NumberOfColumns;
14
+ const widthDevice = Dimensions.get('window').width;
15
+ const parentWidth = widthDevice - screenPadding * 2;
16
+ const totalGutterSize = gutterSize * (numberOfColumns - 1);
17
+ const sizePerSpan = (parentWidth - totalGutterSize) / numberOfColumns;
6
18
 
7
- export const DEFAULT_SCREEN_PADDING = 12;
19
+ /**
20
+ * get size of element with number span
21
+ * @param span
22
+ */
23
+ const getSizeSpan = (span: number = numberOfColumns): number => {
24
+ return span * sizePerSpan + (span - 1) * gutterSize;
25
+ };
8
26
 
9
- export const DEFAULT_GUTTER = 12;
10
- export const validateChildren = (
11
- children: ReactElement<any, string | JSXElementConstructor<any>> & ReactNode,
12
- childrenType:
27
+ return {
28
+ isDevMode,
29
+ gutterSize,
30
+ screenPadding,
31
+ numberOfColumns,
32
+ sizePerSpan,
33
+ getSizeSpan,
34
+ };
35
+ };
36
+
37
+ /**
38
+ * validate children type
39
+ * @param children
40
+ * @param childrenType
41
+ */
42
+ const validateChildren = (
43
+ children:
44
+ | React.ReactElement<any, string | React.JSXElementConstructor<any>>
13
45
  | string
14
- | FC<MMSectionProps>
15
- | JSXElementConstructor<any>
16
- | FC<any>,
46
+ | number
47
+ | {}
48
+ | Iterable<React.ReactNode>
49
+ | React.ReactPortal
50
+ | null
51
+ | undefined
52
+ | boolean,
53
+ childrenType: React.FC<any>,
17
54
  ) => {
55
+ if (!__DEV__) return children;
56
+ let results: React.ReactElement[] = [];
18
57
  if (Array.isArray(children)) {
19
- return children?.map((child: ReactElement) => {
58
+ results = children?.filter((child: ReactElement) => {
20
59
  if (child?.type === childrenType) {
21
60
  return child;
61
+ } else {
62
+ Alert.alert(
63
+ 'Component Kits',
64
+ `Wrong children type for this component, expected is ${childrenType.displayName}.`,
65
+ );
22
66
  }
23
- console.error(
24
- 'Wrong children type for this container, please check document.',
25
- );
26
- return null;
27
67
  });
28
68
  } else {
29
- if (children?.type === childrenType) {
30
- return children;
69
+ const singleChild: any = children;
70
+ if (singleChild?.type === childrenType) {
71
+ results = [singleChild];
72
+ } else {
73
+ Alert.alert(
74
+ 'Component Kits',
75
+ `Wrong children type for this component, expected is ${childrenType.displayName}.`,
76
+ );
31
77
  }
32
- console.error(
33
- 'Wrong children type for this container, please check document.',
34
- );
35
- return null;
36
78
  }
79
+
80
+ return results;
37
81
  };
82
+
83
+ export {useGridSystem, validateChildren};
@@ -1,6 +1,10 @@
1
1
  import React, {useContext} from 'react';
2
2
  import {StatusBar, StyleSheet, View} from 'react-native';
3
- import {Image, NavigationButton, NavigationContext, Styles} from '../index';
3
+ import {ApplicationContext, NavigationButton} from './index';
4
+ import {Styles} from '../Consts';
5
+ import {Image} from '../Image';
6
+ import {HeaderBackgroundProps, TitleCustomProps} from './types';
7
+ import {useGridSystem} from '../Layout';
4
8
 
5
9
  const styles = StyleSheet.create({
6
10
  headerBackground: {
@@ -9,19 +13,48 @@ const styles = StyleSheet.create({
9
13
  position: 'absolute',
10
14
  aspectRatio: 375 / 154,
11
15
  },
16
+ headerTitleContainer: {
17
+ alignItems: 'center',
18
+ justifyContent: 'center',
19
+ },
12
20
  });
13
21
 
14
- const HeaderBackground: React.FC<any> = () => {
15
- const {theme} = useContext(NavigationContext);
16
- const source: any = theme.assets?.headerBackground;
22
+ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
23
+ surface = false,
24
+ image,
25
+ }) => {
26
+ const {theme} = useContext(ApplicationContext);
27
+ const allowImage = !surface && theme.assets?.headerBackground;
17
28
  return (
18
29
  <View
19
30
  style={[
20
31
  Styles.flex,
21
- {backgroundColor: theme.colors.background, overflow: 'hidden'},
32
+ {backgroundColor: theme.colors.background.surface, overflow: 'hidden'},
22
33
  ]}>
23
- <StatusBar barStyle="light-content" />
24
- <Image style={styles.headerBackground} source={source} />
34
+ <StatusBar
35
+ barStyle={allowImage || theme.dark ? 'light-content' : 'dark-content'}
36
+ />
37
+ {allowImage && (
38
+ <Image
39
+ style={styles.headerBackground}
40
+ source={{uri: image ?? theme.assets?.headerBackground}}
41
+ />
42
+ )}
43
+ </View>
44
+ );
45
+ };
46
+
47
+ const HeaderCustom: React.FC<TitleCustomProps> = ({
48
+ title,
49
+ subTitle,
50
+ image,
51
+ content,
52
+ }) => {
53
+ const {getSizeSpan} = useGridSystem();
54
+
55
+ return (
56
+ <View style={[styles.headerTitleContainer, {width: getSizeSpan(10)}]}>
57
+ {content ?? <View />}
25
58
  </View>
26
59
  );
27
60
  };
@@ -29,7 +62,7 @@ const HeaderBackground: React.FC<any> = () => {
29
62
  const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
30
63
  const validType = (item: any) => {
31
64
  if (item.type !== NavigationButton) {
32
- console.error(
65
+ console.warn(
33
66
  'element type of NavigationButton, Please migrate to use NavigationButton of kits.',
34
67
  );
35
68
  }
@@ -52,4 +85,4 @@ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
52
85
  return <View style={Styles.headerRightButton}>{renderAction()}</View>;
53
86
  };
54
87
 
55
- export {HeaderBackground, HeaderRightAction};
88
+ export {HeaderBackground, HeaderRightAction, HeaderCustom};
@@ -6,21 +6,27 @@ import {
6
6
  StyleSheet,
7
7
  View,
8
8
  } from 'react-native';
9
- import {
10
- ModalParams,
11
- NavigationContext,
12
- Radius,
13
- SafeAreaView,
14
- Styles,
15
- useSafeAreaInsets,
16
- } from '../index';
9
+ import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
17
10
  import {BottomSheetBackdrop, BottomSheetModal} from '@gorhom/bottom-sheet';
18
11
  import {BottomSheetModalMethods} from '@gorhom/bottom-sheet/lib/typescript/types';
19
12
  import Navigation from './Navigation';
13
+ import {ModalParams} from './types';
14
+ import {Radius, Spacing, Styles} from '../Consts';
15
+ import {
16
+ ApplicationContext,
17
+ HeaderRightAction,
18
+ NavigationButton,
19
+ NavigationContainer,
20
+ } from './index';
20
21
 
21
- const ModalScreen: React.FC<any> = props => {
22
- const {navigation, route} = props;
23
- const {isBottomSheet, screen, onRequestClose}: ModalParams = route.params;
22
+ const ModalScreen: React.FC<ModalParams> = ({navigation, route, ...rest}) => {
23
+ const {theme} = useContext(ApplicationContext);
24
+ const {
25
+ isBottomSheet,
26
+ backgroundColor,
27
+ screen,
28
+ barrierDismissible,
29
+ }: ModalParams = route.params;
24
30
  const Component = useRef(screen).current;
25
31
  const params = {
26
32
  ...route.params,
@@ -36,11 +42,7 @@ const ModalScreen: React.FC<any> = props => {
36
42
  if (!pop) {
37
43
  action = () => {};
38
44
  }
39
- if (typeof onRequestClose === 'function' && !isBottomSheet) {
40
- onRequestClose(() => {
41
- params?.onDismiss?.();
42
- action();
43
- });
45
+ if (barrierDismissible && !isBottomSheet) {
44
46
  return;
45
47
  }
46
48
  params?.onDismiss?.();
@@ -51,9 +53,41 @@ const ModalScreen: React.FC<any> = props => {
51
53
  * build bottom sheet
52
54
  */
53
55
  if (isBottomSheet) {
56
+ const bgColor = backgroundColor ?? theme.colors.background.surface;
54
57
  return (
55
- <BottomSheet {...props} onDismiss={onDismiss}>
56
- <Component {...params} />
58
+ <BottomSheet {...rest} onDismiss={onDismiss}>
59
+ <View style={[styles.sheetContainer, {backgroundColor: bgColor}]}>
60
+ <View style={styles.indicatorContainer}>
61
+ <View
62
+ style={[
63
+ styles.indicator,
64
+ {backgroundColor: theme.colors.text.disable},
65
+ ]}
66
+ />
67
+ </View>
68
+ <NavigationContainer
69
+ theme={{...theme, assets: undefined}}
70
+ screen={props => <Component {...params} {...props} />}
71
+ onDismiss={() => {
72
+ navigation.pop();
73
+ }}
74
+ screenOptions={{
75
+ headerRight: (props: any) => (
76
+ <HeaderRightAction>
77
+ <NavigationButton
78
+ icon="24_navigation_close"
79
+ {...props}
80
+ onPress={onDismiss}
81
+ />
82
+ </HeaderRightAction>
83
+ ),
84
+ headerBackground: () => (
85
+ <View style={[Styles.flex, {backgroundColor: bgColor}]} />
86
+ ),
87
+ }}
88
+ hideBackFirst={true}
89
+ />
90
+ </View>
57
91
  </BottomSheet>
58
92
  );
59
93
  }
@@ -89,9 +123,7 @@ const ModalScreen: React.FC<any> = props => {
89
123
  );
90
124
  };
91
125
 
92
- const BottomSheet: React.FC<any> = props => {
93
- const {children, onDismiss}: ModalParams = props;
94
- const {theme} = useContext(NavigationContext);
126
+ const BottomSheet: React.FC<ModalParams> = ({children, onDismiss}) => {
95
127
  const snapPoints = useMemo(() => ['50%', '90%'], []);
96
128
  const {bottom} = useSafeAreaInsets();
97
129
  const bottomSheetRef = useRef<BottomSheetModalMethods>(null);
@@ -104,11 +136,6 @@ const BottomSheet: React.FC<any> = props => {
104
136
  };
105
137
  }, []);
106
138
 
107
- const handleComponent = () => (
108
- <View style={styles.indicatorContainer}>
109
- <View style={[styles.indicator, {backgroundColor: theme.colors.card}]} />
110
- </View>
111
- );
112
139
  const backdropComponent = (backdropProps: any) => (
113
140
  <BottomSheetBackdrop
114
141
  disappearsOnIndex={-1}
@@ -122,23 +149,22 @@ const BottomSheet: React.FC<any> = props => {
122
149
  <BottomSheetModal
123
150
  ref={bottomSheetRef}
124
151
  snapPoints={snapPoints}
125
- handleHeight={24}
126
152
  onDismiss={() => onDismiss?.(mountedRef.current)}
127
- handleComponent={handleComponent}
153
+ handleComponent={null}
128
154
  backdropComponent={backdropComponent}>
129
- <View style={[styles.bottomSheetContainer, {paddingBottom: bottom}]}>
130
- {children}
131
- </View>
155
+ <View style={{paddingBottom: bottom}}>{children}</View>
132
156
  </BottomSheetModal>
133
157
  </SafeAreaView>
134
158
  );
135
159
  };
136
160
 
161
+ ModalScreen.defaultProps = {
162
+ barrierDismissible: false,
163
+ };
164
+
137
165
  const styles = StyleSheet.create({
138
166
  container: {flex: 1, flexDirection: 'row'},
139
167
  modalContent: {
140
- borderRadius: Radius.M,
141
- overflow: 'hidden',
142
168
  maxWidth: '100%',
143
169
  maxHeight: '80%',
144
170
  },
@@ -153,23 +179,22 @@ const styles = StyleSheet.create({
153
179
  flex: 1,
154
180
  minHeight: '10%',
155
181
  },
156
- bottomSheetContainer: {
182
+ sheetContainer: {
183
+ height: '100%',
184
+ width: '100%',
157
185
  borderTopLeftRadius: Radius.M,
158
186
  borderTopRightRadius: Radius.M,
159
187
  overflow: 'hidden',
160
- backgroundColor: 'blue',
161
188
  },
162
189
  indicatorContainer: {
163
190
  width: '100%',
164
- height: 4,
165
- position: 'absolute',
166
- top: -8,
167
- flexDirection: 'row',
191
+ paddingTop: Spacing.S,
192
+ alignItems: 'center',
168
193
  justifyContent: 'center',
169
194
  },
170
195
  indicator: {
171
196
  width: 64,
172
- height: '100%',
197
+ height: 4,
173
198
  borderRadius: Radius.S,
174
199
  },
175
200
  });
@@ -1,6 +1,7 @@
1
1
  import {NavigationProp} from '@react-navigation/native';
2
2
  import {NavigationOptions} from './types';
3
- import {HeaderRightAction} from './Components';
3
+ import {HeaderRightAction} from './index';
4
+ import {getOptions} from './utils';
4
5
 
5
6
  class Navigation {
6
7
  instance: NavigationProp<any>;
@@ -13,9 +14,10 @@ class Navigation {
13
14
  if (params.headerRight) {
14
15
  const headerRight = params.headerRight?.();
15
16
  if (headerRight.type !== HeaderRightAction) {
16
- console.error(
17
+ console.warn(
17
18
  'headerRight not return element type of HeaderRightAction, Please migrate to use HeaderRightAction of kits.',
18
19
  );
20
+ return;
19
21
  }
20
22
  }
21
23
  };
@@ -27,6 +29,7 @@ class Navigation {
27
29
  setOptions = (params: NavigationOptions) => {
28
30
  this.verifyParams(params);
29
31
  params = this.filterParams(params);
32
+ params = getOptions(params);
30
33
  this.instance.setOptions(params);
31
34
  };
32
35
  }
@@ -1,13 +1,18 @@
1
1
  import {StyleSheet, TouchableOpacity} from 'react-native';
2
2
  import React, {useContext} from 'react';
3
- import {Icon, NavigationContext, NavigationButtonProps} from '../index';
3
+ import {NavigationButtonProps} from './types';
4
+ import {ApplicationContext} from './index';
5
+ import {Icon} from '../Icon';
4
6
 
5
- const NavigationButton: React.FC<NavigationButtonProps> = props => {
6
- const {icon, tintColor, onPress} = props;
7
- const {theme} = useContext(NavigationContext);
7
+ const NavigationButton: React.FC<NavigationButtonProps> = ({
8
+ icon,
9
+ tintColor,
10
+ onPress,
11
+ }) => {
12
+ const {theme} = useContext(ApplicationContext);
8
13
  return (
9
14
  <TouchableOpacity style={styles.container} onPress={onPress}>
10
- <Icon name={icon} color={tintColor ?? theme.colors.text} />
15
+ <Icon source={icon} color={tintColor ?? theme.colors.text.default} />
11
16
  </TouchableOpacity>
12
17
  );
13
18
  };
@@ -1,10 +1,6 @@
1
- import {
2
- defaultContext,
3
- NavigationContainerProps,
4
- SafeAreaProvider,
5
- } from '../index';
6
1
  import React, {createContext, useRef} from 'react';
7
2
  import {BottomSheetModalProvider} from '@gorhom/bottom-sheet';
3
+ import {SafeAreaProvider} from 'react-native-safe-area-context';
8
4
  import {
9
5
  NavigationContainer as ReactNavigationContainer,
10
6
  NavigationContainerRef,
@@ -14,17 +10,24 @@ import StackScreen from './StackScreen';
14
10
  import ModalScreen from './ModalScreen';
15
11
  import Navigator from './Navigator';
16
12
  import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
13
+ import {GridSystem, useGridSystem} from '../Layout';
14
+ import {defaultContext, defaultTheme} from '../Consts';
15
+ import {NavigationContainerProps} from './types';
17
16
 
18
17
  const Stack = createStackNavigator();
19
18
 
20
- const NavigationContext = createContext(defaultContext);
19
+ const ApplicationContext = createContext(defaultContext);
21
20
  const NavigationContainer: React.FC<NavigationContainerProps> = ({
22
21
  screen,
23
22
  theme,
24
23
  onDismiss,
24
+ screenOptions,
25
+ hideBackFirst,
25
26
  }) => {
27
+ const grid = useGridSystem();
26
28
  const navigationRef = React.useRef<NavigationContainerRef>(null);
27
29
  const navigator = useRef(new Navigator(navigationRef));
30
+ const themed: any = theme;
28
31
 
29
32
  const goBack = () => {
30
33
  const canGoBack = navigationRef?.current?.canGoBack();
@@ -38,18 +41,18 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
38
41
  return (
39
42
  <SafeAreaProvider>
40
43
  <BottomSheetModalProvider>
41
- <NavigationContext.Provider
44
+ <ApplicationContext.Provider
42
45
  value={{theme, navigator: navigator.current}}>
43
46
  <ReactNavigationContainer
44
- theme={theme}
47
+ theme={themed}
45
48
  ref={navigator.current?.ref}
46
49
  independent={true}>
47
- <Stack.Navigator initialRouteName="Stack">
50
+ <Stack.Navigator initialRouteName="Stack" headerMode="screen">
48
51
  <Stack.Screen
49
52
  name="Stack"
50
53
  component={StackScreen}
51
- initialParams={{screen}}
52
- options={getStackOptions(theme, goBack)}
54
+ initialParams={{screen, hideBackFirst}}
55
+ options={{...getStackOptions(theme, goBack), ...screenOptions}}
53
56
  />
54
57
  <Stack.Screen
55
58
  name="Dialog"
@@ -65,10 +68,11 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
65
68
  />
66
69
  </Stack.Navigator>
67
70
  </ReactNavigationContainer>
68
- </NavigationContext.Provider>
71
+ </ApplicationContext.Provider>
69
72
  </BottomSheetModalProvider>
73
+ {grid.isDevMode && <GridSystem />}
70
74
  </SafeAreaProvider>
71
75
  );
72
76
  };
73
77
 
74
- export {NavigationContext, NavigationContainer};
78
+ export {ApplicationContext, NavigationContainer};
@@ -1,10 +1,10 @@
1
- import React from 'react';
1
+ import React, {useLayoutEffect} from 'react';
2
2
  import {ScreenParams} from './types';
3
3
  import Navigation from './Navigation';
4
4
 
5
5
  const StackScreen: React.FC<any> = props => {
6
6
  const {route, navigation} = props;
7
- const {screen: Component}: ScreenParams = route.params;
7
+ const {screen: Component, hideBackFirst}: ScreenParams = route.params;
8
8
 
9
9
  const params = {
10
10
  ...route.params,
@@ -13,6 +13,12 @@ const StackScreen: React.FC<any> = props => {
13
13
 
14
14
  delete params.screen;
15
15
 
16
+ useLayoutEffect(() => {
17
+ if (hideBackFirst && !navigation?.canGoBack()) {
18
+ navigation?.setOptions({headerLeft: null});
19
+ }
20
+ }, []);
21
+
16
22
  return <Component {...params} />;
17
23
  };
18
24
 
@@ -1,10 +1,12 @@
1
- import {NavigationContainer, NavigationContext} from './NavigationContainer';
2
- import ScreenContainer from './ScreenContainer';
1
+ import {NavigationContainer, ApplicationContext} from './NavigationContainer';
2
+ import ScreenContainer from '../Layout/ScreenContainer';
3
3
  import NavigationButton from './NavigationButton';
4
+ import {HeaderRightAction} from './Components';
4
5
 
5
6
  export {
6
7
  NavigationContainer,
7
- NavigationContext,
8
+ ApplicationContext,
8
9
  ScreenContainer,
9
10
  NavigationButton,
11
+ HeaderRightAction,
10
12
  };