@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.
- package/Button/index.tsx +118 -171
- package/CheckBox/index.tsx +63 -0
- package/CheckBox/styles.ts +14 -0
- package/CheckBox/types.ts +10 -0
- package/Consts/colors+spacing+radius.ts +6 -4
- package/Consts/index.ts +4 -73
- package/Consts/styles.ts +1 -1
- package/Consts/theme.ts +121 -0
- package/ContentLoader/index.tsx +9 -13
- package/Icon/index.tsx +14 -11
- package/Icon/types.ts +1 -4
- package/IconButton/index.tsx +67 -67
- package/IconButton/styles.ts +19 -0
- package/Image/index.tsx +22 -21
- package/Image/types.ts +0 -1
- package/Input/Input.tsx +161 -0
- package/Input/TextArea.tsx +162 -0
- package/Input/common.tsx +70 -0
- package/Input/index.tsx +26 -0
- package/Input/styles.ts +92 -0
- package/Layout/GridSystem.tsx +109 -0
- package/Layout/ScreenContainer.tsx +84 -0
- package/Layout/ScreenSection.tsx +117 -0
- package/Layout/SectionItem.tsx +63 -0
- package/Layout/index.ts +11 -5
- package/Layout/types.ts +6 -33
- package/Layout/utils.ts +69 -23
- package/Navigation/Components.tsx +42 -9
- package/Navigation/ModalScreen.tsx +65 -40
- package/Navigation/Navigation.ts +5 -2
- package/Navigation/NavigationButton.tsx +10 -5
- package/Navigation/NavigationContainer.tsx +17 -13
- package/Navigation/StackScreen.tsx +8 -2
- package/Navigation/index.ts +5 -3
- package/Navigation/types.ts +72 -38
- package/Navigation/utils.tsx +37 -14
- package/Playground/index.tsx +132 -0
- package/Playground/styles.ts +16 -0
- package/Playground/types.ts +15 -0
- package/Popup/PopupNotify.tsx +210 -0
- package/Popup/PopupPromotion.tsx +66 -0
- package/Popup/index.tsx +4 -0
- package/Popup/types.ts +23 -0
- package/Radio/index.tsx +42 -0
- package/Radio/styles.ts +12 -0
- package/Radio/types.ts +7 -0
- package/Switch/index.tsx +35 -0
- package/Switch/styles.ts +23 -0
- package/Switch/types.ts +5 -0
- package/Text/index.tsx +36 -118
- package/Text/styles.ts +24 -23
- package/Text/types.ts +5 -12
- package/index.ts +21 -4
- package/package.json +3 -4
- package/Button/types.ts +0 -18
- package/CheckBox/index.js +0 -74
- package/CheckBox/styles.js +0 -3
- package/IconButton/types.ts +0 -17
- package/Layout/Row.tsx +0 -42
- package/Layout/Screen.tsx +0 -68
- package/Layout/Section.tsx +0 -30
- package/Layout/View.tsx +0 -84
- package/Layout/styles.ts +0 -24
- package/Navigation/ScreenContainer.tsx +0 -38
- package/SizedBox/index.js +0 -23
- package/SizedBox/styles.js +0 -7
- package/TextInput/index.js +0 -225
- 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
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
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 {
|
|
6
|
+
export {
|
|
7
|
+
SectionItem,
|
|
8
|
+
ScreenSection,
|
|
9
|
+
GridSystem,
|
|
10
|
+
useGridSystem,
|
|
11
|
+
validateChildren,
|
|
12
|
+
};
|
package/Layout/types.ts
CHANGED
|
@@ -1,39 +1,12 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
7
|
-
|
|
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
|
|
28
|
-
|
|
29
|
-
|
|
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
|
|
3
|
-
import {
|
|
1
|
+
import {Alert, Dimensions} from 'react-native';
|
|
2
|
+
import React, {ReactElement} from 'react';
|
|
3
|
+
import {GutterSize, NumberOfColumns, ScreenPadding} from '../Consts';
|
|
4
4
|
|
|
5
|
-
|
|
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
|
-
|
|
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
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
|
15
|
-
|
|
|
16
|
-
|
|
|
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
|
-
|
|
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
|
-
|
|
30
|
-
|
|
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 {
|
|
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<
|
|
15
|
-
|
|
16
|
-
|
|
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
|
|
24
|
-
|
|
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.
|
|
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<
|
|
22
|
-
const {
|
|
23
|
-
const {
|
|
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 (
|
|
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 {...
|
|
56
|
-
<
|
|
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<
|
|
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={
|
|
153
|
+
handleComponent={null}
|
|
128
154
|
backdropComponent={backdropComponent}>
|
|
129
|
-
<View style={
|
|
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
|
-
|
|
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
|
-
|
|
165
|
-
|
|
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:
|
|
197
|
+
height: 4,
|
|
173
198
|
borderRadius: Radius.S,
|
|
174
199
|
},
|
|
175
200
|
});
|
package/Navigation/Navigation.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {NavigationProp} from '@react-navigation/native';
|
|
2
2
|
import {NavigationOptions} from './types';
|
|
3
|
-
import {HeaderRightAction} from './
|
|
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.
|
|
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 {
|
|
3
|
+
import {NavigationButtonProps} from './types';
|
|
4
|
+
import {ApplicationContext} from './index';
|
|
5
|
+
import {Icon} from '../Icon';
|
|
4
6
|
|
|
5
|
-
const NavigationButton: React.FC<NavigationButtonProps> =
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
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
|
|
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
|
-
<
|
|
44
|
+
<ApplicationContext.Provider
|
|
42
45
|
value={{theme, navigator: navigator.current}}>
|
|
43
46
|
<ReactNavigationContainer
|
|
44
|
-
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
|
-
</
|
|
71
|
+
</ApplicationContext.Provider>
|
|
69
72
|
</BottomSheetModalProvider>
|
|
73
|
+
{grid.isDevMode && <GridSystem />}
|
|
70
74
|
</SafeAreaProvider>
|
|
71
75
|
);
|
|
72
76
|
};
|
|
73
77
|
|
|
74
|
-
export {
|
|
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
|
|
package/Navigation/index.ts
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import {NavigationContainer,
|
|
2
|
-
import ScreenContainer from '
|
|
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
|
-
|
|
8
|
+
ApplicationContext,
|
|
8
9
|
ScreenContainer,
|
|
9
10
|
NavigationButton,
|
|
11
|
+
HeaderRightAction,
|
|
10
12
|
};
|