@momo-kits/foundation 1.0.0 → 1.0.1

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 (62) hide show
  1. package/ActivityIndicator.tsx +244 -0
  2. package/Button/index.tsx +94 -164
  3. package/Button/types.ts +12 -3
  4. package/CheckBox/index.tsx +57 -0
  5. package/CheckBox/styles.ts +14 -0
  6. package/CheckBox/types.ts +7 -0
  7. package/Consts/colors+spacing+radius.ts +6 -4
  8. package/Consts/index.ts +4 -73
  9. package/Consts/styles.ts +1 -1
  10. package/Consts/theme.ts +65 -0
  11. package/ContentLoader/index.tsx +8 -11
  12. package/Icon/index.tsx +11 -11
  13. package/Icon/types.ts +1 -4
  14. package/IconButton/index.tsx +52 -72
  15. package/IconButton/styles.ts +19 -0
  16. package/IconButton/types.ts +1 -2
  17. package/Image/index.tsx +19 -18
  18. package/Image/types.ts +0 -1
  19. package/Input/TextArea.tsx +202 -0
  20. package/Input/index.tsx +200 -0
  21. package/Input/styles.ts +92 -0
  22. package/Input/types.ts +23 -0
  23. package/Layout/GridSystem.tsx +109 -0
  24. package/Layout/ScreenContainer.tsx +78 -0
  25. package/Layout/ScreenSection.tsx +104 -0
  26. package/Layout/SectionItem.tsx +60 -0
  27. package/Layout/index.ts +11 -5
  28. package/Layout/types.ts +6 -33
  29. package/Layout/utils.ts +55 -23
  30. package/Navigation/Components.tsx +16 -8
  31. package/Navigation/ModalScreen.tsx +35 -25
  32. package/Navigation/Navigation.ts +2 -2
  33. package/Navigation/NavigationButton.tsx +5 -3
  34. package/Navigation/NavigationContainer.tsx +59 -17
  35. package/Navigation/StackScreen.tsx +8 -2
  36. package/Navigation/index.ts +5 -3
  37. package/Navigation/types.ts +53 -36
  38. package/Navigation/utils.tsx +20 -18
  39. package/Radio/index.tsx +34 -0
  40. package/Radio/styles.ts +11 -0
  41. package/Radio/types.ts +7 -0
  42. package/Switch/index.tsx +37 -0
  43. package/Switch/styles.ts +23 -0
  44. package/Switch/types.ts +5 -0
  45. package/Text/index.tsx +36 -120
  46. package/Text/styles.ts +24 -23
  47. package/Text/types.ts +2 -0
  48. package/index.ts +18 -1
  49. package/package.json +1 -1
  50. package/publish.sh +8 -6
  51. package/CheckBox/index.js +0 -74
  52. package/CheckBox/styles.js +0 -3
  53. package/Layout/Row.tsx +0 -42
  54. package/Layout/Screen.tsx +0 -68
  55. package/Layout/Section.tsx +0 -30
  56. package/Layout/View.tsx +0 -84
  57. package/Layout/styles.ts +0 -24
  58. package/Navigation/ScreenContainer.tsx +0 -38
  59. package/SizedBox/index.js +0 -23
  60. package/SizedBox/styles.js +0 -7
  61. package/TextInput/index.js +0 -225
  62. package/TextInput/styles.js +0 -55
@@ -0,0 +1,104 @@
1
+ import React from 'react';
2
+ import {View} from 'react-native';
3
+ import {useGridSystem, validateChildren} from './utils';
4
+ import SectionItem from './SectionItem';
5
+ import {ScreenSectionProps} from './types';
6
+
7
+ const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
8
+ const grid = useGridSystem();
9
+
10
+ const renderOverlay = () => {
11
+ return (
12
+ <View
13
+ pointerEvents={'none'}
14
+ style={{
15
+ position: 'absolute',
16
+ top: 0,
17
+ bottom: 0,
18
+ left: 0,
19
+ right: 0,
20
+ borderColor: 'red',
21
+ borderWidth: 1,
22
+ }}
23
+ />
24
+ );
25
+ };
26
+
27
+ const addRowView = (
28
+ rows: any[],
29
+ cursor: number = 0,
30
+ endRow: boolean = false,
31
+ ) => {
32
+ return (
33
+ <View
34
+ key={`SectionItem${cursor}`}
35
+ style={{
36
+ flexDirection: 'row',
37
+ marginBottom: endRow ? 0 : grid.gutterSize,
38
+ }}>
39
+ {rows.map((i: React.ReactElement, index: number) => {
40
+ return (
41
+ <View
42
+ key={`SectionItem${cursor}${index}`}
43
+ style={{flexDirection: 'row'}}>
44
+ {index != 0 && <View style={{width: grid.gutterSize}}></View>}
45
+ {i}
46
+ </View>
47
+ );
48
+ })}
49
+ </View>
50
+ );
51
+ };
52
+
53
+ const renderView = (
54
+ children: any,
55
+ ): React.ReactElement | React.ReactElement[] => {
56
+ const element: React.ReactElement | React.ReactElement[] = [];
57
+ if (Array.isArray(children)) {
58
+ let cursor = 0;
59
+ let rows: any[] = [];
60
+ for (let i = 0; i < children.length; ++i) {
61
+ const item = children[i];
62
+ const totalSpan = rows
63
+ .concat([item])
64
+ .map(i => i.props?.widthSpan)
65
+ .reduce((previousValue, currentValue) => {
66
+ return previousValue + currentValue;
67
+ });
68
+
69
+ if (totalSpan <= grid.numberOfColumns) {
70
+ rows.push(item);
71
+ } else {
72
+ cursor += 1;
73
+ element.push(addRowView(rows, cursor));
74
+ rows = [item];
75
+ }
76
+
77
+ if (i == children.length - 1) {
78
+ cursor += 1;
79
+ element.push(addRowView(rows, cursor, true));
80
+ }
81
+ }
82
+ } else {
83
+ element.push(children);
84
+ }
85
+ return element;
86
+ };
87
+
88
+ return (
89
+ <View
90
+ style={{
91
+ width: grid.getSizeSpan(),
92
+ marginHorizontal: grid.screenPadding,
93
+ flexDirection: 'row',
94
+ flexWrap: 'wrap',
95
+ }}>
96
+ {renderView(validateChildren(children, SectionItem))}
97
+ {grid.isDevMode && renderOverlay()}
98
+ </View>
99
+ );
100
+ };
101
+
102
+ ScreenSection.displayName = 'ScreenSection';
103
+
104
+ export default ScreenSection;
@@ -0,0 +1,60 @@
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
+ const renderOverlay = () => {
17
+ return (
18
+ <View
19
+ pointerEvents={'none'}
20
+ style={{
21
+ position: 'absolute',
22
+ top: 0,
23
+ bottom: 0,
24
+ left: 0,
25
+ right: 0,
26
+ borderColor: 'red',
27
+ borderWidth: 1,
28
+ }}
29
+ />
30
+ );
31
+ };
32
+
33
+ const styles: any = style ?? {};
34
+
35
+ return (
36
+ <View
37
+ style={{
38
+ ...styles,
39
+ width: grid.getSizeSpan(widthSpan),
40
+ height: heightSpan ? grid.getSizeSpan(heightSpan) : undefined,
41
+ overflow: 'hidden',
42
+ margin: undefined,
43
+ marginTop: undefined,
44
+ marginBottom: undefined,
45
+ marginLeft: undefined,
46
+ marginRight: undefined,
47
+ }}>
48
+ {children}
49
+ {grid.isDevMode && renderOverlay()}
50
+ </View>
51
+ );
52
+ };
53
+
54
+ SectionItem.defaultProps = {
55
+ widthSpan: 12,
56
+ };
57
+
58
+ SectionItem.displayName = 'SectionItem';
59
+
60
+ 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,69 @@
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
+ const useGridSystem = (useMargin: boolean = true) => {
6
+ const isDevMode = false;
7
+ const gutterSize = GutterSize;
8
+ const screenPadding = useMargin ? ScreenPadding : 0;
9
+ const numberOfColumns = NumberOfColumns;
10
+ const widthDevice = Dimensions.get('window').width;
11
+ const parentWidth = widthDevice - screenPadding * 2;
12
+ const totalGutterSize = gutterSize * (numberOfColumns - 1);
13
+ const sizePerSpan = (parentWidth - totalGutterSize) / numberOfColumns;
6
14
 
7
- export const DEFAULT_SCREEN_PADDING = 12;
15
+ const getSizeSpan = (span: number = numberOfColumns): number => {
16
+ return span * sizePerSpan + (span - 1) * gutterSize;
17
+ };
8
18
 
9
- export const DEFAULT_GUTTER = 12;
10
- export const validateChildren = (
11
- children: ReactElement<any, string | JSXElementConstructor<any>> & ReactNode,
12
- childrenType:
19
+ return {
20
+ isDevMode,
21
+ gutterSize,
22
+ screenPadding,
23
+ numberOfColumns,
24
+ sizePerSpan,
25
+ getSizeSpan,
26
+ };
27
+ };
28
+ const validateChildren = (
29
+ children:
30
+ | React.ReactElement<any, string | React.JSXElementConstructor<any>>
13
31
  | string
14
- | FC<MMSectionProps>
15
- | JSXElementConstructor<any>
16
- | FC<any>,
32
+ | number
33
+ | {}
34
+ | Iterable<React.ReactNode>
35
+ | React.ReactPortal
36
+ | null
37
+ | undefined
38
+ | boolean,
39
+ childrenType: React.FC<any>,
17
40
  ) => {
41
+ if (!__DEV__) return children;
42
+ let results: React.ReactElement[] = [];
18
43
  if (Array.isArray(children)) {
19
- return children?.map((child: ReactElement) => {
44
+ results = children?.filter((child: ReactElement) => {
20
45
  if (child?.type === childrenType) {
21
46
  return child;
47
+ } else {
48
+ Alert.alert(
49
+ 'Component Kits',
50
+ `Wrong children type for this component, expected is ${childrenType.displayName}.`,
51
+ );
22
52
  }
23
- console.error(
24
- 'Wrong children type for this container, please check document.',
25
- );
26
- return null;
27
53
  });
28
54
  } else {
29
- if (children?.type === childrenType) {
30
- return children;
55
+ const singleChild: any = children;
56
+ if (singleChild?.type === childrenType) {
57
+ results = [singleChild];
58
+ } else {
59
+ Alert.alert(
60
+ 'Component Kits',
61
+ `Wrong children type for this component, expected is ${childrenType.displayName}.`,
62
+ );
31
63
  }
32
- console.error(
33
- 'Wrong children type for this container, please check document.',
34
- );
35
- return null;
36
64
  }
65
+
66
+ return results;
37
67
  };
68
+
69
+ export {useGridSystem, validateChildren};
@@ -1,6 +1,8 @@
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';
4
6
 
5
7
  const styles = StyleSheet.create({
6
8
  headerBackground: {
@@ -11,17 +13,23 @@ const styles = StyleSheet.create({
11
13
  },
12
14
  });
13
15
 
14
- const HeaderBackground: React.FC<any> = () => {
15
- const {theme} = useContext(NavigationContext);
16
- const source: any = theme.assets?.headerBackground;
16
+ const HeaderBackground = () => {
17
+ const {theme} = useContext(ApplicationContext);
17
18
  return (
18
19
  <View
19
20
  style={[
20
21
  Styles.flex,
21
- {backgroundColor: theme.colors.background, overflow: 'hidden'},
22
+ {backgroundColor: theme.colors.background.surface, overflow: 'hidden'},
22
23
  ]}>
23
- <StatusBar barStyle="light-content" />
24
- <Image style={styles.headerBackground} source={source} />
24
+ {theme.assets?.headerBackground && (
25
+ <>
26
+ <StatusBar barStyle="light-content" />
27
+ <Image
28
+ style={styles.headerBackground}
29
+ source={{uri: theme.assets?.headerBackground}}
30
+ />
31
+ </>
32
+ )}
25
33
  </View>
26
34
  );
27
35
  };
@@ -29,7 +37,7 @@ const HeaderBackground: React.FC<any> = () => {
29
37
  const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
30
38
  const validType = (item: any) => {
31
39
  if (item.type !== NavigationButton) {
32
- console.error(
40
+ console.warn(
33
41
  'element type of NavigationButton, Please migrate to use NavigationButton of kits.',
34
42
  );
35
43
  }
@@ -6,20 +6,17 @@ 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 {ApplicationContext, NavigationContainer} from './index';
20
16
 
21
17
  const ModalScreen: React.FC<any> = props => {
22
18
  const {navigation, route} = props;
19
+ const {theme} = useContext(ApplicationContext);
23
20
  const {isBottomSheet, screen, onRequestClose}: ModalParams = route.params;
24
21
  const Component = useRef(screen).current;
25
22
  const params = {
@@ -53,7 +50,16 @@ const ModalScreen: React.FC<any> = props => {
53
50
  if (isBottomSheet) {
54
51
  return (
55
52
  <BottomSheet {...props} onDismiss={onDismiss}>
56
- <Component {...params} />
53
+ <View style={{height: '100%'}}>
54
+ <NavigationContainer
55
+ theme={{...theme, assets: undefined}}
56
+ screen={props => <Component {...params} {...props} />}
57
+ onDismiss={() => {
58
+ navigation.pop();
59
+ }}
60
+ isBottomSheet={isBottomSheet}
61
+ />
62
+ </View>
57
63
  </BottomSheet>
58
64
  );
59
65
  }
@@ -89,9 +95,8 @@ const ModalScreen: React.FC<any> = props => {
89
95
  );
90
96
  };
91
97
 
92
- const BottomSheet: React.FC<any> = props => {
93
- const {children, onDismiss}: ModalParams = props;
94
- const {theme} = useContext(NavigationContext);
98
+ const BottomSheet: React.FC<ModalParams> = ({children, onDismiss}) => {
99
+ const {theme} = useContext(ApplicationContext);
95
100
  const snapPoints = useMemo(() => ['50%', '90%'], []);
96
101
  const {bottom} = useSafeAreaInsets();
97
102
  const bottomSheetRef = useRef<BottomSheetModalMethods>(null);
@@ -105,8 +110,14 @@ const BottomSheet: React.FC<any> = props => {
105
110
  }, []);
106
111
 
107
112
  const handleComponent = () => (
108
- <View style={styles.indicatorContainer}>
109
- <View style={[styles.indicator, {backgroundColor: theme.colors.card}]} />
113
+ <View
114
+ style={[
115
+ styles.indicatorContainer,
116
+ {backgroundColor: theme.colors.background.surface},
117
+ ]}>
118
+ <View
119
+ style={[styles.indicator, {backgroundColor: theme.colors.text.disable}]}
120
+ />
110
121
  </View>
111
122
  );
112
123
  const backdropComponent = (backdropProps: any) => (
@@ -126,7 +137,11 @@ const BottomSheet: React.FC<any> = props => {
126
137
  onDismiss={() => onDismiss?.(mountedRef.current)}
127
138
  handleComponent={handleComponent}
128
139
  backdropComponent={backdropComponent}>
129
- <View style={[styles.bottomSheetContainer, {paddingBottom: bottom}]}>
140
+ <View
141
+ style={{
142
+ paddingBottom: bottom,
143
+ backgroundColor: theme.colors.background.default,
144
+ }}>
130
145
  {children}
131
146
  </View>
132
147
  </BottomSheetModal>
@@ -153,23 +168,18 @@ const styles = StyleSheet.create({
153
168
  flex: 1,
154
169
  minHeight: '10%',
155
170
  },
156
- bottomSheetContainer: {
171
+ indicatorContainer: {
172
+ width: '100%',
173
+ paddingTop: Spacing.S,
157
174
  borderTopLeftRadius: Radius.M,
158
175
  borderTopRightRadius: Radius.M,
159
176
  overflow: 'hidden',
160
- backgroundColor: 'blue',
161
- },
162
- indicatorContainer: {
163
- width: '100%',
164
- height: 4,
165
- position: 'absolute',
166
- top: -8,
167
- flexDirection: 'row',
168
177
  justifyContent: 'center',
178
+ alignItems: 'center',
169
179
  },
170
180
  indicator: {
171
181
  width: 64,
172
- height: '100%',
182
+ height: 4,
173
183
  borderRadius: Radius.S,
174
184
  },
175
185
  });
@@ -1,6 +1,6 @@
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
4
 
5
5
  class Navigation {
6
6
  instance: NavigationProp<any>;
@@ -13,7 +13,7 @@ class Navigation {
13
13
  if (params.headerRight) {
14
14
  const headerRight = params.headerRight?.();
15
15
  if (headerRight.type !== HeaderRightAction) {
16
- console.error(
16
+ console.warn(
17
17
  'headerRight not return element type of HeaderRightAction, Please migrate to use HeaderRightAction of kits.',
18
18
  );
19
19
  }
@@ -1,13 +1,15 @@
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
7
  const NavigationButton: React.FC<NavigationButtonProps> = props => {
6
8
  const {icon, tintColor, onPress} = props;
7
- const {theme} = useContext(NavigationContext);
9
+ const {theme} = useContext(ApplicationContext);
8
10
  return (
9
11
  <TouchableOpacity style={styles.container} onPress={onPress}>
10
- <Icon name={icon} color={tintColor ?? theme.colors.text} />
12
+ <Icon source={icon} color={tintColor ?? theme.colors.text.default} />
11
13
  </TouchableOpacity>
12
14
  );
13
15
  };
@@ -1,31 +1,50 @@
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,
11
7
  } from '@react-navigation/native';
12
- import {createStackNavigator} from '@react-navigation/stack';
8
+ import {
9
+ createStackNavigator,
10
+ StackNavigationOptions,
11
+ } from '@react-navigation/stack';
13
12
  import StackScreen from './StackScreen';
14
13
  import ModalScreen from './ModalScreen';
15
14
  import Navigator from './Navigator';
16
15
  import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
16
+ import {GridSystem, useGridSystem} from '../Layout';
17
+ import {defaultContext, defaultTheme} from '../Consts';
18
+ import {NavigationContainerProps} from './types';
19
+ import {HeaderRightAction, NavigationButton} from './index';
17
20
 
18
21
  const Stack = createStackNavigator();
19
22
 
20
- const NavigationContext = createContext(defaultContext);
23
+ const ApplicationContext = createContext(defaultContext);
21
24
  const NavigationContainer: React.FC<NavigationContainerProps> = ({
22
25
  screen,
23
26
  theme,
24
27
  onDismiss,
28
+ isBottomSheet,
25
29
  }) => {
30
+ const grid = useGridSystem();
26
31
  const navigationRef = React.useRef<NavigationContainerRef>(null);
27
32
  const navigator = useRef(new Navigator(navigationRef));
28
-
33
+ const themed: any = theme;
34
+ let options: StackNavigationOptions = {};
35
+ if (isBottomSheet) {
36
+ options = {
37
+ headerRight: (props: any) => (
38
+ <HeaderRightAction {...props}>
39
+ <NavigationButton
40
+ icon="24_navigation_close"
41
+ {...props}
42
+ onPress={onDismiss}
43
+ />
44
+ </HeaderRightAction>
45
+ ),
46
+ };
47
+ }
29
48
  const goBack = () => {
30
49
  const canGoBack = navigationRef?.current?.canGoBack();
31
50
  if (canGoBack) {
@@ -38,24 +57,41 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
38
57
  return (
39
58
  <SafeAreaProvider>
40
59
  <BottomSheetModalProvider>
41
- <NavigationContext.Provider
60
+ <ApplicationContext.Provider
42
61
  value={{theme, navigator: navigator.current}}>
43
62
  <ReactNavigationContainer
44
- theme={theme}
63
+ theme={themed}
45
64
  ref={navigator.current?.ref}
46
65
  independent={true}>
47
- <Stack.Navigator initialRouteName="Stack">
66
+ <Stack.Navigator initialRouteName="Stack" headerMode="screen">
48
67
  <Stack.Screen
49
68
  name="Stack"
50
69
  component={StackScreen}
51
- initialParams={{screen}}
52
- options={getStackOptions(theme, goBack)}
70
+ initialParams={{screen, isBottomSheet}}
71
+ options={getStackOptions(theme, {
72
+ headerLeft: (props: any) => (
73
+ <NavigationButton
74
+ icon="ic_back"
75
+ {...props}
76
+ onPress={goBack}
77
+ />
78
+ ),
79
+ ...options,
80
+ })}
53
81
  />
54
82
  <Stack.Screen
55
83
  name="Dialog"
56
84
  component={StackScreen}
57
- options={getDialogOptions(theme, goBack)}
58
- initialParams={{screen}}
85
+ options={getDialogOptions(theme, {
86
+ headerLeft: props => (
87
+ <NavigationButton
88
+ icon="ic_back"
89
+ {...props}
90
+ onPress={goBack}
91
+ />
92
+ ),
93
+ })}
94
+ initialParams={{screen, isBottomSheet}}
59
95
  />
60
96
  <Stack.Screen
61
97
  name="Modal"
@@ -65,10 +101,16 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
65
101
  />
66
102
  </Stack.Navigator>
67
103
  </ReactNavigationContainer>
68
- </NavigationContext.Provider>
104
+ </ApplicationContext.Provider>
69
105
  </BottomSheetModalProvider>
106
+ {grid.isDevMode && <GridSystem />}
70
107
  </SafeAreaProvider>
71
108
  );
72
109
  };
73
110
 
74
- export {NavigationContext, NavigationContainer};
111
+ NavigationContainer.defaultProps = {
112
+ theme: defaultTheme,
113
+ isBottomSheet: false,
114
+ };
115
+
116
+ 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, isBottomSheet}: 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 (isBottomSheet && !navigation?.canGoBack()) {
18
+ navigation?.setOptions({headerLeft: null});
19
+ }
20
+ }, []);
21
+
16
22
  return <Component {...params} />;
17
23
  };
18
24