@momo-kits/foundation 1.0.13 → 1.0.15
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 +1 -1
- package/CheckBox/index.tsx +2 -1
- package/Icon/index.tsx +1 -0
- package/IconButton/index.tsx +1 -0
- package/Image/index.tsx +11 -2
- package/Input/Input.tsx +2 -5
- package/Input/InputMoney.tsx +1 -1
- package/Input/InputSearch.tsx +5 -4
- package/Input/InputTextArea.tsx +1 -1
- package/Input/common.tsx +2 -3
- package/Input/index.tsx +0 -1
- package/Layout/Card.tsx +87 -0
- package/Layout/GridSystem.tsx +19 -4
- package/Layout/ScreenContainer.tsx +55 -16
- package/Layout/{ScreenSection.tsx → Section.tsx} +51 -25
- package/Layout/index.ts +14 -10
- package/Layout/types.ts +11 -2
- package/Layout/utils.ts +2 -35
- package/Navigation/Components.tsx +23 -17
- package/Navigation/ModalScreen.tsx +4 -2
- package/Navigation/NavigationButton.tsx +2 -0
- package/Navigation/NavigationContainer.tsx +2 -3
- package/Navigation/StackScreen.tsx +0 -1
- package/Navigation/types.ts +6 -2
- package/Popup/PopupNotify.tsx +6 -5
- package/Popup/PopupPromotion.tsx +2 -2
- package/Radio/index.tsx +1 -0
- package/Skeleton/index.tsx +2 -3
- package/Switch/index.tsx +1 -0
- package/Text/index.tsx +12 -2
- package/package.json +1 -1
- package/Layout/SectionItem.tsx +0 -63
package/Button/index.tsx
CHANGED
|
@@ -10,7 +10,6 @@ import {Text} from '../Text';
|
|
|
10
10
|
import {Typography} from '../Text/types';
|
|
11
11
|
import {Colors} from '../Consts';
|
|
12
12
|
import styles from './styles';
|
|
13
|
-
import {Image} from '../Image';
|
|
14
13
|
import {Icon} from '../Icon';
|
|
15
14
|
|
|
16
15
|
export interface ButtonProps extends TouchableOpacityProps {
|
|
@@ -224,6 +223,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
224
223
|
return (
|
|
225
224
|
<TouchableOpacity
|
|
226
225
|
{...rest}
|
|
226
|
+
accessibilityLabel={`Button/${title}`}
|
|
227
227
|
activeOpacity={activeOpacity}
|
|
228
228
|
onPress={onPressButton}
|
|
229
229
|
style={buttonStyle}>
|
package/CheckBox/index.tsx
CHANGED
|
@@ -35,6 +35,7 @@ const CheckBox: FC<CheckBoxProps> = props => {
|
|
|
35
35
|
};
|
|
36
36
|
return (
|
|
37
37
|
<TouchableOpacity
|
|
38
|
+
accessibilityLabel={`CheckBox/${label}`}
|
|
38
39
|
activeOpacity={0.8}
|
|
39
40
|
onPress={onChangeValue}
|
|
40
41
|
disabled={disabled}
|
|
@@ -48,7 +49,7 @@ const CheckBox: FC<CheckBoxProps> = props => {
|
|
|
48
49
|
/>
|
|
49
50
|
)}
|
|
50
51
|
</View>
|
|
51
|
-
<Text typography={'description_default'}>{label}</Text>
|
|
52
|
+
{!!label && <Text typography={'description_default'}>{label}</Text>}
|
|
52
53
|
</TouchableOpacity>
|
|
53
54
|
);
|
|
54
55
|
};
|
package/Icon/index.tsx
CHANGED
package/IconButton/index.tsx
CHANGED
package/Image/index.tsx
CHANGED
|
@@ -11,9 +11,15 @@ import {FastImagePropsWithoutStyle} from './types';
|
|
|
11
11
|
export interface ImageProps extends FastImagePropsWithoutStyle {
|
|
12
12
|
style?: StyleProp<ViewStyle>;
|
|
13
13
|
loading?: boolean;
|
|
14
|
+
accessibilityLabel?: string;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
const Image: React.FC<ImageProps> = ({
|
|
17
|
+
const Image: React.FC<ImageProps> = ({
|
|
18
|
+
style,
|
|
19
|
+
source,
|
|
20
|
+
accessibilityLabel,
|
|
21
|
+
...rest
|
|
22
|
+
}) => {
|
|
17
23
|
const {theme} = useContext(ApplicationContext);
|
|
18
24
|
const [loading, setLoading] = useState(rest.loading);
|
|
19
25
|
const [fail, setFail] = useState(false);
|
|
@@ -48,7 +54,9 @@ const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
|
|
|
48
54
|
};
|
|
49
55
|
|
|
50
56
|
return (
|
|
51
|
-
<View
|
|
57
|
+
<View
|
|
58
|
+
style={[styles.container, style]}
|
|
59
|
+
accessibilityLabel={`Image/${accessibilityLabel ?? source}`}>
|
|
52
60
|
<FastImage
|
|
53
61
|
{...rest}
|
|
54
62
|
source={source}
|
|
@@ -68,4 +76,5 @@ const Image: React.FC<ImageProps> = ({style, source, ...rest}) => {
|
|
|
68
76
|
Image.defaultProps = {
|
|
69
77
|
loading: true,
|
|
70
78
|
};
|
|
79
|
+
|
|
71
80
|
export {Image};
|
package/Input/Input.tsx
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
} from 'react-native';
|
|
9
9
|
import {ApplicationContext} from '../Navigation';
|
|
10
10
|
import styles from './styles';
|
|
11
|
-
import {Image} from '../Image';
|
|
12
11
|
import {ErrorView, FloatingView, getBorderColor, getSizeStyle} from './common';
|
|
13
12
|
import {InputProps} from './index';
|
|
14
13
|
import {Icon} from '../Icon';
|
|
@@ -112,16 +111,14 @@ const Input: FC<InputProps> = ({
|
|
|
112
111
|
/>
|
|
113
112
|
</TouchableOpacity>
|
|
114
113
|
)}
|
|
115
|
-
{icon &&
|
|
116
|
-
<Icon icon={iconTintColor} source={icon} style={styles.icon} />
|
|
117
|
-
)}
|
|
114
|
+
{icon && <Icon color={iconTintColor} source={icon} size={24} />}
|
|
118
115
|
</View>
|
|
119
116
|
</View>
|
|
120
117
|
);
|
|
121
118
|
};
|
|
122
119
|
|
|
123
120
|
return (
|
|
124
|
-
<View style={styles.wrapper}>
|
|
121
|
+
<View style={styles.wrapper} accessibilityLabel={`Input`}>
|
|
125
122
|
{renderInputView()}
|
|
126
123
|
<ErrorView errorMessage={errorMessage} />
|
|
127
124
|
</View>
|
package/Input/InputMoney.tsx
CHANGED
package/Input/InputSearch.tsx
CHANGED
|
@@ -22,7 +22,6 @@ const InputSearch: FC<InputSearchProps> = ({
|
|
|
22
22
|
icon,
|
|
23
23
|
buttonText = 'Hủy',
|
|
24
24
|
showButtonText = true,
|
|
25
|
-
showIcon = true,
|
|
26
25
|
showBorder = true,
|
|
27
26
|
style,
|
|
28
27
|
...props
|
|
@@ -104,7 +103,7 @@ const InputSearch: FC<InputSearchProps> = ({
|
|
|
104
103
|
/>
|
|
105
104
|
</TouchableOpacity>
|
|
106
105
|
)}
|
|
107
|
-
{
|
|
106
|
+
{icon || (
|
|
108
107
|
<View style={{flexDirection: 'row'}}>
|
|
109
108
|
<View
|
|
110
109
|
style={[
|
|
@@ -116,7 +115,7 @@ const InputSearch: FC<InputSearchProps> = ({
|
|
|
116
115
|
/>
|
|
117
116
|
<Icon
|
|
118
117
|
color={iconTintColor}
|
|
119
|
-
source={icon}
|
|
118
|
+
source={icon as string}
|
|
120
119
|
style={styles.iconSearchInput}
|
|
121
120
|
/>
|
|
122
121
|
</View>
|
|
@@ -125,7 +124,9 @@ const InputSearch: FC<InputSearchProps> = ({
|
|
|
125
124
|
);
|
|
126
125
|
};
|
|
127
126
|
return (
|
|
128
|
-
<View
|
|
127
|
+
<View
|
|
128
|
+
style={[style, styles.searchInputContainer]}
|
|
129
|
+
accessibilityLabel={`InputSearch`}>
|
|
129
130
|
<View
|
|
130
131
|
style={[
|
|
131
132
|
getBorderColor(),
|
package/Input/InputTextArea.tsx
CHANGED
|
@@ -138,7 +138,7 @@ const InputTextArea: FC<InputTextAreaProps> = props => {
|
|
|
138
138
|
};
|
|
139
139
|
|
|
140
140
|
return (
|
|
141
|
-
<View style={styles.wrapper}>
|
|
141
|
+
<View style={styles.wrapper} accessibilityLabel={`InputTextArea`}>
|
|
142
142
|
{renderInputView()}
|
|
143
143
|
<ErrorView errorMessage={errorMessage} />
|
|
144
144
|
</View>
|
package/Input/common.tsx
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {View} from 'react-native';
|
|
2
2
|
import styles from './styles';
|
|
3
3
|
import {Text} from '../Text';
|
|
4
|
-
import {Image} from '../Image';
|
|
5
4
|
import React, {FC, useContext} from 'react';
|
|
6
5
|
import {ApplicationContext} from '../Navigation';
|
|
7
6
|
import {Icon} from '../Icon';
|
|
@@ -99,10 +98,10 @@ export const FloatingView: FC<FloatingViewProps> = ({
|
|
|
99
98
|
</Text>
|
|
100
99
|
)}
|
|
101
100
|
</Text>
|
|
102
|
-
{floatingIcon
|
|
101
|
+
{floatingIcon || (
|
|
103
102
|
<Icon
|
|
104
103
|
color={floatingIconTintColor}
|
|
105
|
-
source={floatingIcon}
|
|
104
|
+
source={floatingIcon as string}
|
|
106
105
|
size={16}
|
|
107
106
|
style={styles.floatingIcon}
|
|
108
107
|
/>
|
package/Input/index.tsx
CHANGED
package/Layout/Card.tsx
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
|
|
4
|
+
import {CardProps, GridContextProps} from './types';
|
|
5
|
+
import {GridContext} from './index';
|
|
6
|
+
|
|
7
|
+
const Card: React.FC<CardProps> = ({
|
|
8
|
+
widthSpan = 12,
|
|
9
|
+
heightSpan,
|
|
10
|
+
usePadding,
|
|
11
|
+
children,
|
|
12
|
+
style,
|
|
13
|
+
}) => {
|
|
14
|
+
const grid = useContext(GridContext);
|
|
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
|
+
const numberOfColumns = 12;
|
|
39
|
+
const gutterSize = 8;
|
|
40
|
+
let margin = 0;
|
|
41
|
+
if (usePadding) {
|
|
42
|
+
margin = 12;
|
|
43
|
+
}
|
|
44
|
+
const widthSection = grid.getSizeSpan(widthSpan) - margin * 2;
|
|
45
|
+
const totalGutterSize = gutterSize * (numberOfColumns - 1);
|
|
46
|
+
const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
|
|
47
|
+
const gridContext: GridContextProps = {
|
|
48
|
+
numberOfColumns,
|
|
49
|
+
gutterSize,
|
|
50
|
+
margin,
|
|
51
|
+
sizePerSpan,
|
|
52
|
+
getSizeSpan: span => {
|
|
53
|
+
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<View
|
|
59
|
+
accessibilityLabel={`Card`}
|
|
60
|
+
style={{
|
|
61
|
+
...styles,
|
|
62
|
+
width: grid.getSizeSpan(widthSpan),
|
|
63
|
+
height: heightSpan ? grid.getSizeSpan(heightSpan) : undefined,
|
|
64
|
+
paddingHorizontal: margin,
|
|
65
|
+
overflow: 'hidden',
|
|
66
|
+
margin: undefined,
|
|
67
|
+
marginTop: undefined,
|
|
68
|
+
marginBottom: undefined,
|
|
69
|
+
marginLeft: undefined,
|
|
70
|
+
marginRight: undefined,
|
|
71
|
+
}}>
|
|
72
|
+
<GridContext.Provider value={gridContext}>
|
|
73
|
+
{children}
|
|
74
|
+
</GridContext.Provider>
|
|
75
|
+
{__DEV__ && renderOverlay()}
|
|
76
|
+
</View>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
Card.defaultProps = {
|
|
81
|
+
widthSpan: 12,
|
|
82
|
+
usePadding: false,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
Card.displayName = 'Card';
|
|
86
|
+
|
|
87
|
+
export default Card;
|
package/Layout/GridSystem.tsx
CHANGED
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
2
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
3
|
-
import {StyleSheet, View} from 'react-native';
|
|
3
|
+
import {Dimensions, StyleSheet, View} from 'react-native';
|
|
4
4
|
import {ApplicationContext} from '../Navigation';
|
|
5
|
-
import {useGridSystem} from './index';
|
|
6
5
|
import {Colors, Spacing} from '../Consts';
|
|
6
|
+
import {GridContextProps} from './types';
|
|
7
7
|
|
|
8
8
|
const GridSystem: React.FC = () => {
|
|
9
9
|
const {theme} = useContext(ApplicationContext);
|
|
10
|
-
const
|
|
10
|
+
const numberOfColumns = 12;
|
|
11
|
+
const gutterSize = 12;
|
|
12
|
+
const margin = 12;
|
|
13
|
+
const widthSection = Dimensions.get('window').width - margin * 2;
|
|
14
|
+
const totalGutterSize = gutterSize * (numberOfColumns - 1);
|
|
15
|
+
const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
|
|
16
|
+
|
|
17
|
+
const grid: GridContextProps = {
|
|
18
|
+
numberOfColumns,
|
|
19
|
+
gutterSize,
|
|
20
|
+
margin,
|
|
21
|
+
sizePerSpan,
|
|
22
|
+
getSizeSpan: span => {
|
|
23
|
+
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
24
|
+
},
|
|
25
|
+
};
|
|
11
26
|
const insets = useSafeAreaInsets();
|
|
12
27
|
|
|
13
28
|
const list = [];
|
|
@@ -24,7 +39,7 @@ const GridSystem: React.FC = () => {
|
|
|
24
39
|
insets,
|
|
25
40
|
{
|
|
26
41
|
borderColor: theme.colors.error.primary,
|
|
27
|
-
marginHorizontal: grid.
|
|
42
|
+
marginHorizontal: grid.margin,
|
|
28
43
|
},
|
|
29
44
|
]}>
|
|
30
45
|
{list.map((i, index) => {
|
|
@@ -4,35 +4,57 @@ import {SafeAreaView} from 'react-native-safe-area-context';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import {ScreenContainerProps} from '../Navigation/types';
|
|
6
6
|
import {Spacing, Styles} from '../Consts';
|
|
7
|
-
import {
|
|
8
|
-
import {Image} from '../Image';
|
|
7
|
+
import {Section, validateChildren} from './index';
|
|
9
8
|
|
|
10
9
|
const ScreenContainer: React.FC<ScreenContainerProps> = ({
|
|
11
10
|
children,
|
|
12
11
|
edges,
|
|
13
12
|
enableKeyboardAvoidingView,
|
|
14
13
|
scrollable,
|
|
14
|
+
scrollY,
|
|
15
|
+
headerBackground,
|
|
15
16
|
scrollViewProps,
|
|
16
|
-
|
|
17
|
+
footerComponent: Footer,
|
|
17
18
|
}) => {
|
|
19
|
+
let marginHeader = 0;
|
|
20
|
+
let handleScroll;
|
|
21
|
+
let imageAnimatedStyle = {};
|
|
18
22
|
let Component: any = View;
|
|
19
23
|
const headerHeight = useHeaderHeight();
|
|
20
24
|
if (scrollable) {
|
|
21
25
|
Component = Animated.ScrollView;
|
|
22
26
|
}
|
|
27
|
+
if (scrollY) {
|
|
28
|
+
marginHeader = useHeaderHeight();
|
|
29
|
+
imageAnimatedStyle = {
|
|
30
|
+
transform: [
|
|
31
|
+
{
|
|
32
|
+
scale: scrollY.interpolate?.({
|
|
33
|
+
inputRange: [-300, 0, 1],
|
|
34
|
+
outputRange: [1.75, 1, 1],
|
|
35
|
+
extrapolate: 'clamp',
|
|
36
|
+
}),
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
handleScroll = Animated.event(
|
|
41
|
+
[{nativeEvent: {contentOffset: {y: scrollY}}}],
|
|
42
|
+
{useNativeDriver: true},
|
|
43
|
+
);
|
|
44
|
+
}
|
|
23
45
|
|
|
24
46
|
/**
|
|
25
47
|
* build content for screen
|
|
26
48
|
*/
|
|
27
49
|
const renderContent = () => {
|
|
28
|
-
const results = validateChildren(children,
|
|
50
|
+
const results = validateChildren(children, Section);
|
|
29
51
|
if (Array.isArray(results)) {
|
|
30
52
|
return results.map((item, index) => {
|
|
31
53
|
return (
|
|
32
54
|
<View
|
|
33
|
-
key={`
|
|
55
|
+
key={`Section${index}`}
|
|
34
56
|
style={{
|
|
35
|
-
|
|
57
|
+
marginTop: item.props?.useMargin ? Spacing.M : 0,
|
|
36
58
|
flex: item.props?.expanded ? 1 : undefined,
|
|
37
59
|
}}>
|
|
38
60
|
{item}
|
|
@@ -44,7 +66,28 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
|
|
|
44
66
|
};
|
|
45
67
|
|
|
46
68
|
return (
|
|
47
|
-
<SafeAreaView
|
|
69
|
+
<SafeAreaView
|
|
70
|
+
style={Styles.flex}
|
|
71
|
+
edges={edges}
|
|
72
|
+
accessibilityLabel={`ScreenContainer`}>
|
|
73
|
+
<View
|
|
74
|
+
style={{
|
|
75
|
+
position: 'absolute',
|
|
76
|
+
height: 300,
|
|
77
|
+
width: '100%',
|
|
78
|
+
}}>
|
|
79
|
+
{headerBackground || (
|
|
80
|
+
<Animated.Image
|
|
81
|
+
source={{
|
|
82
|
+
uri: headerBackground,
|
|
83
|
+
}}
|
|
84
|
+
style={{
|
|
85
|
+
aspectRatio: 1.3,
|
|
86
|
+
...imageAnimatedStyle,
|
|
87
|
+
}}
|
|
88
|
+
/>
|
|
89
|
+
)}
|
|
90
|
+
</View>
|
|
48
91
|
<KeyboardAvoidingView
|
|
49
92
|
style={Styles.flex}
|
|
50
93
|
keyboardVerticalOffset={headerHeight}
|
|
@@ -53,17 +96,13 @@ const ScreenContainer: React.FC<ScreenContainerProps> = ({
|
|
|
53
96
|
ios: 'padding',
|
|
54
97
|
android: undefined,
|
|
55
98
|
})}>
|
|
56
|
-
<Component
|
|
57
|
-
{
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
uri: headerImage,
|
|
61
|
-
}}
|
|
62
|
-
style={{width: '100%', height: 300}}
|
|
63
|
-
/>
|
|
64
|
-
)}
|
|
99
|
+
<Component
|
|
100
|
+
{...scrollViewProps}
|
|
101
|
+
onScroll={handleScroll}
|
|
102
|
+
style={[Styles.flex, {marginTop: marginHeader}]}>
|
|
65
103
|
{renderContent()}
|
|
66
104
|
</Component>
|
|
105
|
+
{Footer && <Section>{Footer}</Section>}
|
|
67
106
|
</KeyboardAvoidingView>
|
|
68
107
|
</SafeAreaView>
|
|
69
108
|
);
|
|
@@ -1,11 +1,31 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import {View} from 'react-native';
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
2
|
+
import {Dimensions, View} from 'react-native';
|
|
3
|
+
import {validateChildren} from './utils';
|
|
4
|
+
import Card from './Card';
|
|
5
|
+
import {GridContextProps, SectionProps} from './types';
|
|
6
|
+
import {GridContext} from './index';
|
|
6
7
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
8
|
+
const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
|
|
9
|
+
const numberOfColumns = 12;
|
|
10
|
+
const gutterSize = 12;
|
|
11
|
+
let margin = 0;
|
|
12
|
+
if (useMargin) {
|
|
13
|
+
margin = 12;
|
|
14
|
+
}
|
|
15
|
+
let widthSection = Dimensions.get('window').width;
|
|
16
|
+
if (useMargin) widthSection = widthSection - margin * 2;
|
|
17
|
+
const totalGutterSize = gutterSize * (numberOfColumns - 1);
|
|
18
|
+
const sizePerSpan = (widthSection - totalGutterSize) / numberOfColumns;
|
|
19
|
+
|
|
20
|
+
const gridContext: GridContextProps = {
|
|
21
|
+
numberOfColumns,
|
|
22
|
+
gutterSize,
|
|
23
|
+
margin,
|
|
24
|
+
sizePerSpan,
|
|
25
|
+
getSizeSpan: span => {
|
|
26
|
+
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
27
|
+
},
|
|
28
|
+
};
|
|
9
29
|
|
|
10
30
|
/**
|
|
11
31
|
* render overlay only dev mode
|
|
@@ -40,17 +60,17 @@ const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
|
|
|
40
60
|
) => {
|
|
41
61
|
return (
|
|
42
62
|
<View
|
|
43
|
-
key={`
|
|
63
|
+
key={`Card${cursor}`}
|
|
44
64
|
style={{
|
|
45
65
|
flexDirection: 'row',
|
|
46
|
-
marginBottom: endRow ? 0 :
|
|
66
|
+
marginBottom: endRow ? 0 : gridContext.gutterSize,
|
|
47
67
|
}}>
|
|
48
68
|
{rows.map((i: React.ReactElement, index: number) => {
|
|
49
69
|
return (
|
|
50
|
-
<View
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
70
|
+
<View key={`Card${cursor}${index}`} style={{flexDirection: 'row'}}>
|
|
71
|
+
{index != 0 && (
|
|
72
|
+
<View style={{width: gridContext.gutterSize}}></View>
|
|
73
|
+
)}
|
|
54
74
|
{i}
|
|
55
75
|
</View>
|
|
56
76
|
);
|
|
@@ -79,7 +99,7 @@ const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
|
|
|
79
99
|
return previousValue + currentValue;
|
|
80
100
|
});
|
|
81
101
|
|
|
82
|
-
if (totalSpan <=
|
|
102
|
+
if (totalSpan <= gridContext.numberOfColumns) {
|
|
83
103
|
rows.push(item);
|
|
84
104
|
} else {
|
|
85
105
|
cursor += 1;
|
|
@@ -99,19 +119,25 @@ const ScreenSection: React.FC<ScreenSectionProps> = ({children}) => {
|
|
|
99
119
|
};
|
|
100
120
|
|
|
101
121
|
return (
|
|
102
|
-
<
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
122
|
+
<GridContext.Provider value={gridContext}>
|
|
123
|
+
<View
|
|
124
|
+
accessibilityLabel={`Section`}
|
|
125
|
+
style={{
|
|
126
|
+
width: gridContext.getSizeSpan(12),
|
|
127
|
+
marginHorizontal: gridContext.margin,
|
|
128
|
+
flexDirection: 'row',
|
|
129
|
+
flexWrap: 'wrap',
|
|
130
|
+
}}>
|
|
131
|
+
{renderView(validateChildren(children, Card))}
|
|
132
|
+
{__DEV__ && renderOverlay()}
|
|
133
|
+
</View>
|
|
134
|
+
</GridContext.Provider>
|
|
112
135
|
);
|
|
113
136
|
};
|
|
114
137
|
|
|
115
|
-
|
|
138
|
+
Section.displayName = 'Section';
|
|
116
139
|
|
|
117
|
-
|
|
140
|
+
Section.defaultProps = {
|
|
141
|
+
useMargin: true,
|
|
142
|
+
};
|
|
143
|
+
export default Section;
|
package/Layout/index.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import Card from './Card';
|
|
2
|
+
import Section from './Section';
|
|
3
3
|
import GridSystem from './GridSystem';
|
|
4
|
-
import {
|
|
4
|
+
import {validateChildren} from './utils';
|
|
5
|
+
import {createContext} from 'react';
|
|
6
|
+
import {GridContextProps} from './types';
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
};
|
|
8
|
+
const GridContext = createContext<GridContextProps>({
|
|
9
|
+
numberOfColumns: 12,
|
|
10
|
+
gutterSize: 12,
|
|
11
|
+
margin: 12,
|
|
12
|
+
sizePerSpan: 0,
|
|
13
|
+
getSizeSpan: span => 0,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
export {GridContext, Card, Section, GridSystem, validateChildren};
|
package/Layout/types.ts
CHANGED
|
@@ -2,11 +2,20 @@ import {ViewProps} from 'react-native';
|
|
|
2
2
|
|
|
3
3
|
type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export type GridContextProps = {
|
|
6
|
+
numberOfColumns: number;
|
|
7
|
+
gutterSize: number;
|
|
8
|
+
margin?: number;
|
|
9
|
+
sizePerSpan: number;
|
|
10
|
+
getSizeSpan: (span: number) => number;
|
|
11
|
+
};
|
|
12
|
+
export interface SectionProps extends ViewProps {
|
|
6
13
|
expanded?: boolean;
|
|
14
|
+
useMargin?: boolean;
|
|
7
15
|
}
|
|
8
16
|
|
|
9
|
-
export interface
|
|
17
|
+
export interface CardProps extends ViewProps {
|
|
10
18
|
widthSpan: SpanNumber;
|
|
11
19
|
heightSpan?: SpanNumber;
|
|
20
|
+
usePadding?: boolean;
|
|
12
21
|
}
|
package/Layout/utils.ts
CHANGED
|
@@ -1,38 +1,5 @@
|
|
|
1
|
-
import {Alert
|
|
1
|
+
import {Alert} from 'react-native';
|
|
2
2
|
import React, {ReactElement} from 'react';
|
|
3
|
-
import {GutterSize, NumberOfColumns, ScreenPadding} from '../Consts';
|
|
4
|
-
|
|
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;
|
|
18
|
-
|
|
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
|
-
};
|
|
26
|
-
|
|
27
|
-
return {
|
|
28
|
-
isDevMode,
|
|
29
|
-
gutterSize,
|
|
30
|
-
screenPadding,
|
|
31
|
-
numberOfColumns,
|
|
32
|
-
sizePerSpan,
|
|
33
|
-
getSizeSpan,
|
|
34
|
-
};
|
|
35
|
-
};
|
|
36
3
|
|
|
37
4
|
/**
|
|
38
5
|
* validate children type
|
|
@@ -80,4 +47,4 @@ const validateChildren = (
|
|
|
80
47
|
return results;
|
|
81
48
|
};
|
|
82
49
|
|
|
83
|
-
export {
|
|
50
|
+
export {validateChildren};
|
|
@@ -8,10 +8,9 @@ import {
|
|
|
8
8
|
View,
|
|
9
9
|
} from 'react-native';
|
|
10
10
|
import {ApplicationContext, NavigationButton} from './index';
|
|
11
|
-
import {Colors, Spacing, Styles} from '../Consts';
|
|
11
|
+
import {Colors, Radius, Spacing, Styles} from '../Consts';
|
|
12
12
|
import {Image} from '../Image';
|
|
13
13
|
import {HeaderBackgroundProps, TitleCustomProps} from './types';
|
|
14
|
-
import {useGridSystem} from '../Layout';
|
|
15
14
|
import {Text} from '../Text';
|
|
16
15
|
import {Icon} from '../Icon';
|
|
17
16
|
|
|
@@ -25,8 +24,10 @@ const styles = StyleSheet.create({
|
|
|
25
24
|
headerTitleContainer: {
|
|
26
25
|
alignItems: 'center',
|
|
27
26
|
justifyContent: 'center',
|
|
27
|
+
width: '100%',
|
|
28
28
|
},
|
|
29
|
-
|
|
29
|
+
circle: {width: 36, height: 36, borderRadius: 18},
|
|
30
|
+
square: {width: 36, height: 36, borderRadius: Radius.XS},
|
|
30
31
|
dotAvatar: {
|
|
31
32
|
position: 'absolute',
|
|
32
33
|
width: 12,
|
|
@@ -74,6 +75,7 @@ const HeaderTitle: React.FC<any> = props => {
|
|
|
74
75
|
return (
|
|
75
76
|
<Animated.Text
|
|
76
77
|
{...props}
|
|
78
|
+
accessibilityLabel={`HeaderTitle/${props.children}`}
|
|
77
79
|
style={[styles.title, {opacity, color: props.tintColor}]}
|
|
78
80
|
/>
|
|
79
81
|
);
|
|
@@ -94,7 +96,12 @@ const HeaderLeft: React.FC<any> = ({tintColor}) => {
|
|
|
94
96
|
|
|
95
97
|
return (
|
|
96
98
|
<View style={styles.headerLeft}>
|
|
97
|
-
<NavigationButton
|
|
99
|
+
<NavigationButton
|
|
100
|
+
icon="ic_back"
|
|
101
|
+
tintColor={tintColor}
|
|
102
|
+
onPress={goBack}
|
|
103
|
+
accessibilityLabel={'Back'}
|
|
104
|
+
/>
|
|
98
105
|
</View>
|
|
99
106
|
);
|
|
100
107
|
};
|
|
@@ -106,7 +113,9 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
106
113
|
}) => {
|
|
107
114
|
const {theme} = useContext(ApplicationContext);
|
|
108
115
|
let headerImage = theme.assets?.headerBackground;
|
|
116
|
+
let borderBottomWidth = 0;
|
|
109
117
|
if (image === null) {
|
|
118
|
+
borderBottomWidth = 1;
|
|
110
119
|
headerImage = undefined;
|
|
111
120
|
}
|
|
112
121
|
const opacity = animatedValue?.interpolate({
|
|
@@ -114,6 +123,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
114
123
|
outputRange: [0, 1],
|
|
115
124
|
extrapolate: 'clamp',
|
|
116
125
|
});
|
|
126
|
+
|
|
117
127
|
return (
|
|
118
128
|
<Animated.View
|
|
119
129
|
style={[
|
|
@@ -121,7 +131,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
121
131
|
{
|
|
122
132
|
backgroundColor: backgroundColor ?? theme.colors.background.default,
|
|
123
133
|
overflow: 'hidden',
|
|
124
|
-
borderBottomWidth:
|
|
134
|
+
borderBottomWidth: borderBottomWidth,
|
|
125
135
|
borderColor: theme.colors.border.default,
|
|
126
136
|
opacity,
|
|
127
137
|
},
|
|
@@ -129,7 +139,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
129
139
|
<StatusBar
|
|
130
140
|
barStyle={headerImage || theme.dark ? 'light-content' : 'dark-content'}
|
|
131
141
|
/>
|
|
132
|
-
{headerImage
|
|
142
|
+
{headerImage || (
|
|
133
143
|
<Image style={styles.headerBackground} source={{uri: headerImage}} />
|
|
134
144
|
)}
|
|
135
145
|
</Animated.View>
|
|
@@ -140,17 +150,17 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
|
140
150
|
title,
|
|
141
151
|
subTitle,
|
|
142
152
|
image,
|
|
153
|
+
imageShape = 'circle',
|
|
143
154
|
content,
|
|
144
155
|
tintColor,
|
|
145
156
|
dotColor,
|
|
146
157
|
}) => {
|
|
147
|
-
const
|
|
148
|
-
|
|
158
|
+
const avatarStyle = imageShape == 'circle' ? styles.square : styles.square;
|
|
149
159
|
const header = (
|
|
150
160
|
<View style={Styles.row}>
|
|
151
161
|
<View>
|
|
152
|
-
<Image source={{uri: image}} style={
|
|
153
|
-
{dotColor
|
|
162
|
+
<Image source={{uri: image}} style={avatarStyle} />
|
|
163
|
+
{dotColor || (
|
|
154
164
|
<View style={[styles.dotAvatar, {backgroundColor: dotColor}]} />
|
|
155
165
|
)}
|
|
156
166
|
</View>
|
|
@@ -164,11 +174,7 @@ const HeaderCustom: React.FC<TitleCustomProps> = ({
|
|
|
164
174
|
</View>
|
|
165
175
|
</View>
|
|
166
176
|
);
|
|
167
|
-
return
|
|
168
|
-
<View style={[styles.headerTitleContainer, {width: getSizeSpan(10)}]}>
|
|
169
|
-
{content ?? header}
|
|
170
|
-
</View>
|
|
171
|
-
);
|
|
177
|
+
return <View style={styles.headerTitleContainer}>{content ?? header}</View>;
|
|
172
178
|
};
|
|
173
179
|
|
|
174
180
|
const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
|
|
@@ -214,11 +220,11 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
|
|
|
214
220
|
borderWidth: backgroundColor ? 0.5 : 0,
|
|
215
221
|
},
|
|
216
222
|
]}>
|
|
217
|
-
<TouchableOpacity>
|
|
223
|
+
<TouchableOpacity accessibilityLabel={'Toolkit/More'}>
|
|
218
224
|
<Icon color={tintColor} source="navigation_more_horiz" size={20} />
|
|
219
225
|
</TouchableOpacity>
|
|
220
226
|
<View style={[styles.divider, {backgroundColor: tintColor}]} />
|
|
221
|
-
<TouchableOpacity>
|
|
227
|
+
<TouchableOpacity accessibilityLabel={'Toolkit/Close'}>
|
|
222
228
|
<Icon
|
|
223
229
|
color={tintColor}
|
|
224
230
|
source="16_navigation_close_circle"
|
|
@@ -63,7 +63,7 @@ const Modal: React.FC<ModalParams> = ({navigation, route}) => {
|
|
|
63
63
|
style={styles.modalSpaceVertical}
|
|
64
64
|
onPress={() => onDismiss()}
|
|
65
65
|
/>
|
|
66
|
-
<View style={styles.modalContent}>
|
|
66
|
+
<View style={styles.modalContent} accessibilityLabel={'Modal'}>
|
|
67
67
|
<Component {...params} />
|
|
68
68
|
</View>
|
|
69
69
|
<Pressable
|
|
@@ -128,7 +128,9 @@ const BottomSheet: React.FC<BottomSheetParams> = ({navigation, route}) => {
|
|
|
128
128
|
}}
|
|
129
129
|
handleComponent={null}
|
|
130
130
|
backdropComponent={backdropComponent}>
|
|
131
|
-
<View
|
|
131
|
+
<View
|
|
132
|
+
style={{paddingBottom: bottom}}
|
|
133
|
+
accessibilityLabel={'BottomSheet'}>
|
|
132
134
|
<View style={[styles.sheetContainer, {backgroundColor}]}>
|
|
133
135
|
<View style={styles.indicatorContainer}>
|
|
134
136
|
<View
|
|
@@ -11,6 +11,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
|
11
11
|
onPress,
|
|
12
12
|
backgroundColor,
|
|
13
13
|
useBorder = true,
|
|
14
|
+
accessibilityLabel,
|
|
14
15
|
}) => {
|
|
15
16
|
const {theme} = useContext(ApplicationContext);
|
|
16
17
|
if (!backgroundColor && tintColor != Colors.black_01) {
|
|
@@ -19,6 +20,7 @@ const NavigationButton: React.FC<NavigationButtonProps> = ({
|
|
|
19
20
|
|
|
20
21
|
return (
|
|
21
22
|
<TouchableOpacity
|
|
23
|
+
accessibilityLabel={`NavigationButton/${accessibilityLabel}`}
|
|
22
24
|
style={[
|
|
23
25
|
styles.container,
|
|
24
26
|
{
|
|
@@ -10,7 +10,7 @@ import StackScreen from './StackScreen';
|
|
|
10
10
|
import ModalScreen from './ModalScreen';
|
|
11
11
|
import Navigator from './Navigator';
|
|
12
12
|
import {getDialogOptions, getModalOptions, getStackOptions} from './utils';
|
|
13
|
-
import {GridSystem
|
|
13
|
+
import {GridSystem} from '../Layout';
|
|
14
14
|
import {defaultContext} from '../Consts';
|
|
15
15
|
import {NavigationContainerProps} from './types';
|
|
16
16
|
|
|
@@ -22,7 +22,6 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
22
22
|
theme,
|
|
23
23
|
options,
|
|
24
24
|
}) => {
|
|
25
|
-
const grid = useGridSystem();
|
|
26
25
|
const navigationRef = React.useRef<NavigationContainerRef>(null);
|
|
27
26
|
const navigator = useRef(new Navigator(navigationRef));
|
|
28
27
|
|
|
@@ -75,7 +74,7 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
75
74
|
</ReactNavigationContainer>
|
|
76
75
|
</ApplicationContext.Provider>
|
|
77
76
|
</BottomSheetModalProvider>
|
|
78
|
-
{
|
|
77
|
+
{__DEV__ && <GridSystem />}
|
|
79
78
|
</SafeAreaProvider>
|
|
80
79
|
);
|
|
81
80
|
};
|
package/Navigation/types.ts
CHANGED
|
@@ -71,9 +71,11 @@ export type NavigationContainerProps = {
|
|
|
71
71
|
export interface ScreenContainerProps extends ViewProps {
|
|
72
72
|
edges?: any[];
|
|
73
73
|
enableKeyboardAvoidingView?: boolean;
|
|
74
|
-
|
|
74
|
+
headerBackground?: string;
|
|
75
|
+
scrollable?: boolean;
|
|
76
|
+
scrollY?: Animated.Value;
|
|
75
77
|
scrollViewProps?: ScrollViewProps;
|
|
76
|
-
|
|
78
|
+
footerComponent?: React.ElementType;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
export type ScreenParams = {
|
|
@@ -100,6 +102,7 @@ export type NavigationButtonProps = {
|
|
|
100
102
|
backgroundColor?: string;
|
|
101
103
|
useBorder?: boolean;
|
|
102
104
|
onPress: () => void;
|
|
105
|
+
accessibilityLabel?: string;
|
|
103
106
|
};
|
|
104
107
|
|
|
105
108
|
export type NavigationOptions = {
|
|
@@ -121,6 +124,7 @@ export type TitleCustomProps = {
|
|
|
121
124
|
title?: string;
|
|
122
125
|
subTitle?: string;
|
|
123
126
|
image?: string;
|
|
127
|
+
imageShape?: 'circle' | 'square';
|
|
124
128
|
dotColor?: string;
|
|
125
129
|
tintColor?: string;
|
|
126
130
|
content?: React.ReactNode;
|
package/Popup/PopupNotify.tsx
CHANGED
|
@@ -36,11 +36,11 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
36
36
|
const renderRow = () => {
|
|
37
37
|
return (
|
|
38
38
|
<View style={Styles.row}>
|
|
39
|
-
{secondary?.title
|
|
39
|
+
{secondary?.title || (
|
|
40
40
|
<>
|
|
41
41
|
<View style={Styles.flex}>
|
|
42
42
|
<Button
|
|
43
|
-
title={secondary
|
|
43
|
+
title={secondary?.title as string}
|
|
44
44
|
type="text"
|
|
45
45
|
size="medium"
|
|
46
46
|
onPress={() => {
|
|
@@ -73,11 +73,11 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
73
73
|
onAction(primary.onPress);
|
|
74
74
|
}}
|
|
75
75
|
/>
|
|
76
|
-
{secondary?.title
|
|
76
|
+
{secondary?.title || (
|
|
77
77
|
<>
|
|
78
78
|
<View style={styles.buttonSpace} />
|
|
79
79
|
<Button
|
|
80
|
-
title={secondary
|
|
80
|
+
title={secondary?.title as string}
|
|
81
81
|
type="text"
|
|
82
82
|
size="medium"
|
|
83
83
|
onPress={() => {
|
|
@@ -132,6 +132,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
132
132
|
|
|
133
133
|
return (
|
|
134
134
|
<View
|
|
135
|
+
accessibilityLabel={'PopupNotify'}
|
|
135
136
|
style={[
|
|
136
137
|
styles.container,
|
|
137
138
|
{backgroundColor: theme.colors.background.surface},
|
|
@@ -146,7 +147,7 @@ const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
|
146
147
|
{description}
|
|
147
148
|
</Text>
|
|
148
149
|
</View>
|
|
149
|
-
{information
|
|
150
|
+
{information || (
|
|
150
151
|
<View style={styles.information}>
|
|
151
152
|
<Text
|
|
152
153
|
typography={'description_xs'}
|
package/Popup/PopupPromotion.tsx
CHANGED
|
@@ -38,7 +38,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({image, onClose}) => {
|
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
return (
|
|
41
|
-
|
|
41
|
+
<View accessibilityLabel={'PopupPromotion'}>
|
|
42
42
|
<Image
|
|
43
43
|
style={styles.container}
|
|
44
44
|
source={{
|
|
@@ -46,7 +46,7 @@ const PopupPromotion: React.FC<PopupPromotionProps> = ({image, onClose}) => {
|
|
|
46
46
|
}}
|
|
47
47
|
/>
|
|
48
48
|
{buildCloseIcon()}
|
|
49
|
-
|
|
49
|
+
</View>
|
|
50
50
|
);
|
|
51
51
|
};
|
|
52
52
|
|
package/Radio/index.tsx
CHANGED
package/Skeleton/index.tsx
CHANGED
|
@@ -2,9 +2,8 @@ import React, {useEffect, useMemo, useRef, useState} from 'react';
|
|
|
2
2
|
import {Animated, Easing, Platform, StyleSheet, View} from 'react-native';
|
|
3
3
|
import LinearGradient from 'react-native-linear-gradient';
|
|
4
4
|
import {SkeletonTypes} from './types';
|
|
5
|
-
import {Styles} from '../Consts';
|
|
5
|
+
import {Colors, Styles} from '../Consts';
|
|
6
6
|
import styles from './styles';
|
|
7
|
-
import {Colors} from '@momo-kits/foundation';
|
|
8
7
|
|
|
9
8
|
const Skeleton: React.FC<SkeletonTypes> = ({style}) => {
|
|
10
9
|
const [width, setWidth] = useState(0);
|
|
@@ -42,7 +41,7 @@ const Skeleton: React.FC<SkeletonTypes> = ({style}) => {
|
|
|
42
41
|
}
|
|
43
42
|
};
|
|
44
43
|
return (
|
|
45
|
-
<View style={[styles.container, style]}>
|
|
44
|
+
<View style={[styles.container, style]} accessibilityLabel={'Skeleton'}>
|
|
46
45
|
<View
|
|
47
46
|
onLayout={e => onLayout(e.nativeEvent.layout.width)}
|
|
48
47
|
style={[Styles.flex, {backgroundColor: PRIMARY_COLOR}]}>
|
package/Switch/index.tsx
CHANGED
package/Text/index.tsx
CHANGED
|
@@ -3,6 +3,7 @@ import {Text as RNText, TextProps as RNTextProps} from 'react-native';
|
|
|
3
3
|
import styles from './styles';
|
|
4
4
|
import {Typography, TypographyWeight} from './types';
|
|
5
5
|
import {ApplicationContext} from '../Navigation';
|
|
6
|
+
import {GridContext} from '../Layout';
|
|
6
7
|
|
|
7
8
|
const SFProText: TypographyWeight = {
|
|
8
9
|
100: 'Thin',
|
|
@@ -40,6 +41,7 @@ const FontStyle: {[key: string]: string} = {
|
|
|
40
41
|
export interface TextProps extends RNTextProps {
|
|
41
42
|
typography: Typography;
|
|
42
43
|
color?: string;
|
|
44
|
+
widthSpan?: number;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
const Text: React.FC<TextProps> = ({
|
|
@@ -47,8 +49,10 @@ const Text: React.FC<TextProps> = ({
|
|
|
47
49
|
color,
|
|
48
50
|
children,
|
|
49
51
|
style,
|
|
52
|
+
widthSpan,
|
|
50
53
|
...rest
|
|
51
54
|
}) => {
|
|
55
|
+
const grid = useContext(GridContext);
|
|
52
56
|
const {theme} = useContext(ApplicationContext);
|
|
53
57
|
|
|
54
58
|
const getTypoStyle = (typo: Typography) => {
|
|
@@ -83,11 +87,17 @@ const Text: React.FC<TextProps> = ({
|
|
|
83
87
|
};
|
|
84
88
|
|
|
85
89
|
const textStyle = getTypoStyle(typography);
|
|
86
|
-
|
|
90
|
+
const spanStyle = widthSpan ? {width: grid.getSizeSpan(widthSpan)} : {};
|
|
87
91
|
return (
|
|
88
92
|
<RNText
|
|
89
93
|
{...rest}
|
|
90
|
-
|
|
94
|
+
accessibilityLabel={`Text/${children}`}
|
|
95
|
+
style={[
|
|
96
|
+
style,
|
|
97
|
+
textStyle,
|
|
98
|
+
spanStyle,
|
|
99
|
+
{color: color ?? theme.colors.text.default},
|
|
100
|
+
]}>
|
|
91
101
|
{children ?? ''}
|
|
92
102
|
</RNText>
|
|
93
103
|
);
|
package/package.json
CHANGED
package/Layout/SectionItem.tsx
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
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;
|