@momo-kits/foundation 0.75.1-beta.8 → 0.76.1-beta.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.
- package/{Navigation → Application}/BottomTab.tsx +19 -6
- package/{Navigation → Application}/Components.tsx +24 -15
- package/{Navigation → Application}/ModalScreen.tsx +17 -13
- package/{Navigation → Application}/Navigation.ts +5 -5
- package/{Navigation → Application}/NavigationContainer.tsx +3 -3
- package/{Navigation → Application}/StackScreen.tsx +7 -7
- package/{Navigation → Application}/index.ts +7 -3
- package/{Navigation → Application}/types.ts +23 -5
- package/{Navigation → Application}/utils.tsx +4 -6
- package/Assets/icon.json +6 -0
- package/Button/index.tsx +1 -1
- package/CheckBox/index.tsx +1 -1
- package/Consts/theme.ts +1 -1
- package/Divider/index.tsx +1 -1
- package/Icon/index.tsx +2 -2
- package/IconButton/index.tsx +1 -1
- package/Image/index.tsx +4 -2
- package/Input/Input.tsx +2 -1
- package/Input/InputMoney.tsx +2 -1
- package/Input/InputSearch.tsx +4 -2
- package/Input/InputTextArea.tsx +20 -19
- package/Input/common.tsx +1 -1
- package/Input/index.tsx +2 -0
- package/Layout/Card.tsx +108 -54
- package/Layout/GridSystem.tsx +4 -2
- package/Layout/Item.tsx +60 -0
- package/Layout/Screen.tsx +188 -0
- package/Layout/Section.tsx +12 -9
- package/Layout/index.ts +2 -1
- package/Layout/types.ts +7 -7
- package/Layout/utils.ts +46 -16
- package/Pagination/Dot.tsx +1 -1
- package/Pagination/PaginationDot.tsx +1 -1
- package/Pagination/PaginationNumber.tsx +1 -2
- package/Pagination/PaginationScroll.tsx +2 -1
- package/Pagination/PaginationWhiteDot.tsx +1 -1
- package/Popup/PopupNotify.tsx +1 -1
- package/Popup/PopupPromotion.tsx +1 -1
- package/Radio/index.tsx +1 -1
- package/Switch/index.tsx +1 -1
- package/Tag/index.tsx +3 -1
- package/Text/index.tsx +5 -4
- package/Text/utils.ts +14 -0
- package/index.ts +9 -2
- package/package.json +40 -40
- package/publish.sh +2 -5
- package/Layout/ScreenContainer.tsx +0 -122
- package/Navigation/Observer.ts +0 -79
- /package/{Navigation → Application}/NavigationButton.tsx +0 -0
- /package/{Navigation → Application}/Navigator.ts +0 -0
package/Input/InputTextArea.tsx
CHANGED
|
@@ -8,7 +8,6 @@ import {
|
|
|
8
8
|
} from 'react-native';
|
|
9
9
|
import styles from './styles';
|
|
10
10
|
import {Text} from '../Text';
|
|
11
|
-
import {ApplicationContext} from '../Navigation';
|
|
12
11
|
import {
|
|
13
12
|
DEFAULT_HEIGHT,
|
|
14
13
|
ErrorView,
|
|
@@ -18,26 +17,26 @@ import {
|
|
|
18
17
|
} from './common';
|
|
19
18
|
import {InputTextAreaProps} from './index';
|
|
20
19
|
import {Icon} from '../Icon';
|
|
20
|
+
import {ApplicationContext} from '../Application';
|
|
21
21
|
|
|
22
|
-
const InputTextArea: FC<InputTextAreaProps> =
|
|
22
|
+
const InputTextArea: FC<InputTextAreaProps> = ({
|
|
23
|
+
errorMessage,
|
|
24
|
+
onChangeText,
|
|
25
|
+
floatingIconColor,
|
|
26
|
+
floatingIcon,
|
|
27
|
+
floatingValue,
|
|
28
|
+
onFocus,
|
|
29
|
+
onBlur,
|
|
30
|
+
disabled,
|
|
31
|
+
value,
|
|
32
|
+
defaultValue,
|
|
33
|
+
height,
|
|
34
|
+
placeholder,
|
|
35
|
+
maxLength,
|
|
36
|
+
required,
|
|
37
|
+
...props
|
|
38
|
+
}) => {
|
|
23
39
|
const {theme} = useContext(ApplicationContext);
|
|
24
|
-
const {
|
|
25
|
-
errorMessage,
|
|
26
|
-
onChangeText,
|
|
27
|
-
floatingIconColor,
|
|
28
|
-
floatingIcon,
|
|
29
|
-
floatingValue,
|
|
30
|
-
onFocus,
|
|
31
|
-
onBlur,
|
|
32
|
-
disabled,
|
|
33
|
-
value,
|
|
34
|
-
defaultValue,
|
|
35
|
-
height,
|
|
36
|
-
placeholder,
|
|
37
|
-
maxLength,
|
|
38
|
-
required,
|
|
39
|
-
} = props;
|
|
40
|
-
|
|
41
40
|
const [focused, setFocused] = useState(false);
|
|
42
41
|
const [inputValue, setInputValue] = useState(defaultValue ?? '');
|
|
43
42
|
const inputRef = useRef<any>(null);
|
|
@@ -101,6 +100,8 @@ const InputTextArea: FC<InputTextAreaProps> = props => {
|
|
|
101
100
|
<View style={styles.rowArea}>
|
|
102
101
|
<View style={styles.textAreaView}>
|
|
103
102
|
<TextInput
|
|
103
|
+
{...props}
|
|
104
|
+
accessibilityLabel={`TextInput`}
|
|
104
105
|
ref={inputRef}
|
|
105
106
|
editable={!disabled}
|
|
106
107
|
textAlignVertical="top"
|
package/Input/common.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import {View} from 'react-native';
|
|
|
2
2
|
import styles from './styles';
|
|
3
3
|
import {Text} from '../Text';
|
|
4
4
|
import React, {FC, useContext} from 'react';
|
|
5
|
-
import {ApplicationContext} from '../
|
|
5
|
+
import {ApplicationContext} from '../Application';
|
|
6
6
|
import {Icon} from '../Icon';
|
|
7
7
|
import {Styles} from '../Consts';
|
|
8
8
|
|
package/Input/index.tsx
CHANGED
|
@@ -89,6 +89,8 @@ export interface InputSearchProps extends InputPropsOmitForSearch {
|
|
|
89
89
|
* Defaults to `true` if not provided.
|
|
90
90
|
*/
|
|
91
91
|
showBorder?: boolean;
|
|
92
|
+
|
|
93
|
+
onPressButtonText?: () => void;
|
|
92
94
|
}
|
|
93
95
|
|
|
94
96
|
export interface InputMoneyProps extends InputPropsWithoutPlaceholder {}
|
package/Layout/Card.tsx
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import {View} from 'react-native';
|
|
3
|
-
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import {Dimensions, View} from 'react-native';
|
|
3
|
+
import {useGridSystem, validateChildren} from './utils';
|
|
4
4
|
import {CardProps, GridContextProps} from './types';
|
|
5
5
|
import {GridContext} from './index';
|
|
6
6
|
import {GRIDVIEW} from '../Consts';
|
|
7
|
+
import Item from './Item';
|
|
8
|
+
|
|
9
|
+
const Card: React.FC<CardProps> = ({children, style}) => {
|
|
10
|
+
const {numberOfColumns} = useGridSystem();
|
|
7
11
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}) => {
|
|
15
|
-
const grid = useContext(GridContext);
|
|
12
|
+
const gutterSize = 8;
|
|
13
|
+
const margin = 12;
|
|
14
|
+
|
|
15
|
+
const widthSection = Dimensions.get('window').width - margin * 2;
|
|
16
|
+
const totalGutterSize = gutterSize * (numberOfColumns - 1);
|
|
17
|
+
const sizePerSpan = (widthSection - totalGutterSize - 24) / numberOfColumns;
|
|
16
18
|
|
|
19
|
+
const gridContext: GridContextProps = {
|
|
20
|
+
numberOfColumns,
|
|
21
|
+
gutterSize,
|
|
22
|
+
margin,
|
|
23
|
+
sizePerSpan,
|
|
24
|
+
getSizeSpan: span => {
|
|
25
|
+
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
26
|
+
},
|
|
27
|
+
};
|
|
17
28
|
/**
|
|
18
|
-
* render overlay
|
|
29
|
+
* render overlay only dev mode
|
|
19
30
|
*/
|
|
20
31
|
const renderOverlay = () => {
|
|
21
32
|
return (
|
|
@@ -34,55 +45,98 @@ const Card: React.FC<CardProps> = ({
|
|
|
34
45
|
);
|
|
35
46
|
};
|
|
36
47
|
|
|
37
|
-
|
|
48
|
+
/**
|
|
49
|
+
* build a row view in side session
|
|
50
|
+
* @param rows
|
|
51
|
+
* @param cursor
|
|
52
|
+
* @param endRow
|
|
53
|
+
*/
|
|
54
|
+
const addRowView = (
|
|
55
|
+
rows: any[],
|
|
56
|
+
cursor: number = 0,
|
|
57
|
+
endRow: boolean = false,
|
|
58
|
+
) => {
|
|
59
|
+
return (
|
|
60
|
+
<View
|
|
61
|
+
key={`Item${cursor}`}
|
|
62
|
+
style={{
|
|
63
|
+
flexDirection: 'row',
|
|
64
|
+
marginBottom: endRow ? 0 : gridContext.gutterSize,
|
|
65
|
+
}}>
|
|
66
|
+
{rows.map((i: React.ReactElement, index: number) => {
|
|
67
|
+
return (
|
|
68
|
+
<View key={`Item${cursor}${index}`} style={{flexDirection: 'row'}}>
|
|
69
|
+
{index != 0 && (
|
|
70
|
+
<View style={{width: gridContext.gutterSize}}></View>
|
|
71
|
+
)}
|
|
72
|
+
{i}
|
|
73
|
+
</View>
|
|
74
|
+
);
|
|
75
|
+
})}
|
|
76
|
+
</View>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* render children content for card
|
|
82
|
+
* @param children
|
|
83
|
+
*/
|
|
84
|
+
const renderView = (
|
|
85
|
+
children: any,
|
|
86
|
+
): React.ReactElement | React.ReactElement[] => {
|
|
87
|
+
const element: React.ReactElement | React.ReactElement[] = [];
|
|
88
|
+
if (Array.isArray(children)) {
|
|
89
|
+
let cursor = 0;
|
|
90
|
+
let rows: any[] = [];
|
|
91
|
+
for (let i = 0; i < children.length; ++i) {
|
|
92
|
+
const item = children[i];
|
|
93
|
+
const totalSpan = rows
|
|
94
|
+
.concat([item])
|
|
95
|
+
.map(i => i.props?.widthSpan)
|
|
96
|
+
.reduce((previousValue, currentValue) => {
|
|
97
|
+
return previousValue + currentValue;
|
|
98
|
+
});
|
|
38
99
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
100
|
+
if (totalSpan <= gridContext.numberOfColumns) {
|
|
101
|
+
rows.push(item);
|
|
102
|
+
} else {
|
|
103
|
+
cursor += 1;
|
|
104
|
+
element.push(addRowView(rows, cursor));
|
|
105
|
+
rows = [item];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (i == children.length - 1) {
|
|
109
|
+
cursor += 1;
|
|
110
|
+
element.push(addRowView(rows, cursor, true));
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
element.push(children);
|
|
115
|
+
}
|
|
116
|
+
return element;
|
|
56
117
|
};
|
|
57
118
|
|
|
58
119
|
return (
|
|
59
|
-
<
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
{GRIDVIEW && renderOverlay()}
|
|
77
|
-
</View>
|
|
120
|
+
<GridContext.Provider value={gridContext}>
|
|
121
|
+
<View
|
|
122
|
+
accessibilityLabel={`Card`}
|
|
123
|
+
style={[
|
|
124
|
+
style,
|
|
125
|
+
{
|
|
126
|
+
width: widthSection,
|
|
127
|
+
marginHorizontal: gridContext.margin,
|
|
128
|
+
padding: 12,
|
|
129
|
+
flexDirection: 'row',
|
|
130
|
+
flexWrap: 'wrap',
|
|
131
|
+
},
|
|
132
|
+
]}>
|
|
133
|
+
{renderView(validateChildren(children, [Item]))}
|
|
134
|
+
{GRIDVIEW && renderOverlay()}
|
|
135
|
+
</View>
|
|
136
|
+
</GridContext.Provider>
|
|
78
137
|
);
|
|
79
138
|
};
|
|
80
139
|
|
|
81
|
-
Card.defaultProps = {
|
|
82
|
-
widthSpan: 12,
|
|
83
|
-
usePadding: false,
|
|
84
|
-
};
|
|
85
|
-
|
|
86
140
|
Card.displayName = 'Card';
|
|
87
141
|
|
|
88
142
|
export default Card;
|
package/Layout/GridSystem.tsx
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
2
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
3
3
|
import {Dimensions, StyleSheet, View} from 'react-native';
|
|
4
|
-
import {ApplicationContext} from '../
|
|
4
|
+
import {ApplicationContext} from '../Application';
|
|
5
5
|
import {Colors, Spacing} from '../Consts';
|
|
6
6
|
import {GridContextProps} from './types';
|
|
7
|
+
import {useGridSystem} from './utils';
|
|
7
8
|
|
|
8
9
|
const GridSystem: React.FC = () => {
|
|
9
10
|
const {theme} = useContext(ApplicationContext);
|
|
10
|
-
const numberOfColumns =
|
|
11
|
+
const {numberOfColumns} = useGridSystem();
|
|
12
|
+
|
|
11
13
|
const gutterSize = 12;
|
|
12
14
|
const margin = 12;
|
|
13
15
|
const widthSection = Dimensions.get('window').width - margin * 2;
|
package/Layout/Item.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import React, {useContext} from 'react';
|
|
2
|
+
import {View} from 'react-native';
|
|
3
|
+
|
|
4
|
+
import {ItemProps} from './types';
|
|
5
|
+
import {GridContext} from './index';
|
|
6
|
+
import {GRIDVIEW} from '../Consts';
|
|
7
|
+
|
|
8
|
+
const Item: React.FC<ItemProps> = ({
|
|
9
|
+
widthSpan,
|
|
10
|
+
heightSpan,
|
|
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
|
+
return (
|
|
37
|
+
<View
|
|
38
|
+
accessibilityLabel={`Item`}
|
|
39
|
+
style={[
|
|
40
|
+
style,
|
|
41
|
+
{
|
|
42
|
+
width: grid.getSizeSpan(widthSpan ?? grid.numberOfColumns),
|
|
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
|
+
]}>
|
|
52
|
+
{children}
|
|
53
|
+
{GRIDVIEW && renderOverlay()}
|
|
54
|
+
</View>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
Item.displayName = 'Item';
|
|
59
|
+
|
|
60
|
+
export default Item;
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Animated,
|
|
3
|
+
KeyboardAvoidingView,
|
|
4
|
+
Platform,
|
|
5
|
+
Text,
|
|
6
|
+
View,
|
|
7
|
+
} from 'react-native';
|
|
8
|
+
import {useHeaderHeight} from '@react-navigation/stack';
|
|
9
|
+
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
10
|
+
import React, {useContext, useEffect, useRef} from 'react';
|
|
11
|
+
import {ScreenProps} from '../Application/types';
|
|
12
|
+
import {Spacing, Styles} from '../Consts';
|
|
13
|
+
import {Card, Section, validateChildren} from './index';
|
|
14
|
+
import {ApplicationContext} from '../Application';
|
|
15
|
+
import Navigation from '../Application/Navigation';
|
|
16
|
+
import {HeaderTitle} from '../Application/Components';
|
|
17
|
+
|
|
18
|
+
const Screen: React.FC<ScreenProps> = ({
|
|
19
|
+
children,
|
|
20
|
+
enableKeyboardAvoidingView = false,
|
|
21
|
+
scrollable = false,
|
|
22
|
+
navigation,
|
|
23
|
+
marginHeader,
|
|
24
|
+
useAnimatedHeader = false,
|
|
25
|
+
useExtendedHeader = false,
|
|
26
|
+
headerBackground,
|
|
27
|
+
scrollViewProps,
|
|
28
|
+
footerComponent: Footer,
|
|
29
|
+
}) => {
|
|
30
|
+
const animatedValue = useRef<Animated.Value | undefined>(undefined);
|
|
31
|
+
const {theme} = useContext(ApplicationContext);
|
|
32
|
+
const insets = useSafeAreaInsets();
|
|
33
|
+
const headerTransparent = useAnimatedHeader || useExtendedHeader;
|
|
34
|
+
|
|
35
|
+
let handleScroll;
|
|
36
|
+
let imageAnimatedStyle = {};
|
|
37
|
+
let opacity;
|
|
38
|
+
let Component: any = View;
|
|
39
|
+
animatedValue.current = undefined;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* automatic margin content if use header transparent
|
|
43
|
+
*/
|
|
44
|
+
if (headerTransparent) {
|
|
45
|
+
animatedValue.current = new Animated.Value(0);
|
|
46
|
+
marginHeader = marginHeader ?? useHeaderHeight();
|
|
47
|
+
if (useExtendedHeader) {
|
|
48
|
+
headerBackground = theme.assets?.headerBackground;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
let title = {};
|
|
54
|
+
if (useExtendedHeader) {
|
|
55
|
+
title = {headerTitle: HeaderTitle};
|
|
56
|
+
}
|
|
57
|
+
navigation?.setOptions({
|
|
58
|
+
animatedValue: animatedValue.current,
|
|
59
|
+
headerTransparent,
|
|
60
|
+
...title,
|
|
61
|
+
});
|
|
62
|
+
}, [useExtendedHeader, useAnimatedHeader]);
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* animated for header stack when used bottom tab
|
|
66
|
+
*/
|
|
67
|
+
useEffect(() => {
|
|
68
|
+
const current: any = navigation;
|
|
69
|
+
if (headerTransparent) {
|
|
70
|
+
return current?.addListener?.('focus', () => {
|
|
71
|
+
const stackNavigation = new Navigation(current?.getParent(), theme);
|
|
72
|
+
stackNavigation?.setOptions({
|
|
73
|
+
animatedValue: animatedValue.current,
|
|
74
|
+
headerTransparent: true,
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}, [useAnimatedHeader, useExtendedHeader, navigation]);
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* animated when use scroll && animated value
|
|
82
|
+
*/
|
|
83
|
+
if (scrollable) {
|
|
84
|
+
Component = Animated.ScrollView;
|
|
85
|
+
if (useAnimatedHeader) {
|
|
86
|
+
opacity = animatedValue.current?.interpolate({
|
|
87
|
+
inputRange: [0, 100],
|
|
88
|
+
outputRange: [1, 0],
|
|
89
|
+
extrapolate: 'clamp',
|
|
90
|
+
});
|
|
91
|
+
imageAnimatedStyle = {
|
|
92
|
+
transform: [
|
|
93
|
+
{
|
|
94
|
+
scale: animatedValue.current?.interpolate?.({
|
|
95
|
+
inputRange: [-300, 0, 1],
|
|
96
|
+
outputRange: [1.75, 1, 1],
|
|
97
|
+
extrapolate: 'clamp',
|
|
98
|
+
}),
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
};
|
|
102
|
+
handleScroll = Animated.event(
|
|
103
|
+
[
|
|
104
|
+
{
|
|
105
|
+
nativeEvent: {
|
|
106
|
+
contentOffset: {y: animatedValue.current as Animated.Value},
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
],
|
|
110
|
+
{useNativeDriver: true},
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* build content for screen
|
|
117
|
+
*/
|
|
118
|
+
const renderContent = () => {
|
|
119
|
+
const results = validateChildren(children, [Section, Card]);
|
|
120
|
+
if (Array.isArray(results)) {
|
|
121
|
+
return results.map((item, index) => {
|
|
122
|
+
const space = item.props?.useMargin === false ? 0 : Spacing.M;
|
|
123
|
+
return (
|
|
124
|
+
<View
|
|
125
|
+
key={`ScreenItem${index}`}
|
|
126
|
+
style={{
|
|
127
|
+
marginTop: space,
|
|
128
|
+
flex: item.props?.expanded ? 1 : undefined,
|
|
129
|
+
}}>
|
|
130
|
+
{item}
|
|
131
|
+
</View>
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return results;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
return (
|
|
139
|
+
<View style={Styles.flex} accessibilityLabel={`ScreenContainer`}>
|
|
140
|
+
<View
|
|
141
|
+
style={{
|
|
142
|
+
position: 'absolute',
|
|
143
|
+
maxHeight: 215,
|
|
144
|
+
width: '100%',
|
|
145
|
+
overflow: 'hidden',
|
|
146
|
+
}}>
|
|
147
|
+
{!!headerBackground && (
|
|
148
|
+
<Animated.Image
|
|
149
|
+
source={{
|
|
150
|
+
uri: headerBackground,
|
|
151
|
+
}}
|
|
152
|
+
style={{
|
|
153
|
+
opacity: opacity ?? 1,
|
|
154
|
+
aspectRatio: 1.75,
|
|
155
|
+
...imageAnimatedStyle,
|
|
156
|
+
}}
|
|
157
|
+
/>
|
|
158
|
+
)}
|
|
159
|
+
</View>
|
|
160
|
+
<KeyboardAvoidingView
|
|
161
|
+
style={Styles.flex}
|
|
162
|
+
enabled={enableKeyboardAvoidingView}
|
|
163
|
+
behavior={Platform.select({
|
|
164
|
+
ios: 'padding',
|
|
165
|
+
android: undefined,
|
|
166
|
+
})}>
|
|
167
|
+
<Component
|
|
168
|
+
{...scrollViewProps}
|
|
169
|
+
onScroll={handleScroll}
|
|
170
|
+
style={[Styles.flex, {marginTop: marginHeader}]}>
|
|
171
|
+
{renderContent()}
|
|
172
|
+
</Component>
|
|
173
|
+
{Footer && (
|
|
174
|
+
<View
|
|
175
|
+
style={{
|
|
176
|
+
paddingTop: Spacing.S,
|
|
177
|
+
paddingBottom: insets.bottom + Spacing.S,
|
|
178
|
+
backgroundColor: theme.colors.background.surface,
|
|
179
|
+
}}>
|
|
180
|
+
<Section>{Footer}</Section>
|
|
181
|
+
</View>
|
|
182
|
+
)}
|
|
183
|
+
</KeyboardAvoidingView>
|
|
184
|
+
</View>
|
|
185
|
+
);
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export default Screen;
|
package/Layout/Section.tsx
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import {Dimensions, View} from 'react-native';
|
|
3
|
-
import {validateChildren} from './utils';
|
|
4
|
-
import Card from './Card';
|
|
3
|
+
import {useGridSystem, validateChildren} from './utils';
|
|
5
4
|
import {GridContextProps, SectionProps} from './types';
|
|
6
5
|
import {GridContext} from './index';
|
|
7
6
|
import {GRIDVIEW} from '../Consts';
|
|
7
|
+
import Item from './Item';
|
|
8
|
+
|
|
9
|
+
const Section: React.FC<SectionProps> = ({
|
|
10
|
+
children,
|
|
11
|
+
useMargin = true,
|
|
12
|
+
backgroundColor,
|
|
13
|
+
}) => {
|
|
14
|
+
const {numberOfColumns} = useGridSystem();
|
|
8
15
|
|
|
9
|
-
const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
|
|
10
|
-
const numberOfColumns = 12;
|
|
11
16
|
const gutterSize = 12;
|
|
12
17
|
let margin = 0;
|
|
13
18
|
if (useMargin) {
|
|
@@ -124,12 +129,13 @@ const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
|
|
|
124
129
|
<View
|
|
125
130
|
accessibilityLabel={`Section`}
|
|
126
131
|
style={{
|
|
127
|
-
width:
|
|
132
|
+
width: widthSection,
|
|
128
133
|
marginHorizontal: gridContext.margin,
|
|
129
134
|
flexDirection: 'row',
|
|
130
135
|
flexWrap: 'wrap',
|
|
136
|
+
backgroundColor: backgroundColor,
|
|
131
137
|
}}>
|
|
132
|
-
{renderView(validateChildren(children,
|
|
138
|
+
{renderView(validateChildren(children, [Item]))}
|
|
133
139
|
{GRIDVIEW && renderOverlay()}
|
|
134
140
|
</View>
|
|
135
141
|
</GridContext.Provider>
|
|
@@ -138,7 +144,4 @@ const Section: React.FC<SectionProps> = ({children, useMargin = true}) => {
|
|
|
138
144
|
|
|
139
145
|
Section.displayName = 'Section';
|
|
140
146
|
|
|
141
|
-
Section.defaultProps = {
|
|
142
|
-
useMargin: true,
|
|
143
|
-
};
|
|
144
147
|
export default Section;
|
package/Layout/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import GridSystem from './GridSystem';
|
|
|
4
4
|
import {validateChildren} from './utils';
|
|
5
5
|
import {createContext} from 'react';
|
|
6
6
|
import {GridContextProps} from './types';
|
|
7
|
+
import Item from './Item';
|
|
7
8
|
|
|
8
9
|
const GridContext = createContext<GridContextProps>({
|
|
9
10
|
numberOfColumns: 12,
|
|
@@ -13,4 +14,4 @@ const GridContext = createContext<GridContextProps>({
|
|
|
13
14
|
getSizeSpan: span => 0,
|
|
14
15
|
});
|
|
15
16
|
|
|
16
|
-
export {GridContext, Card, Section, GridSystem, validateChildren};
|
|
17
|
+
export {GridContext, Card, Section, GridSystem, validateChildren, Item};
|
package/Layout/types.ts
CHANGED
|
@@ -40,22 +40,22 @@ export interface SectionProps extends ViewProps {
|
|
|
40
40
|
* Defaults to `false` if not provided.
|
|
41
41
|
*/
|
|
42
42
|
useMargin?: boolean;
|
|
43
|
+
|
|
44
|
+
backgroundColor?: string;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
export interface
|
|
47
|
+
export interface ItemProps extends ViewProps {
|
|
46
48
|
/**
|
|
47
49
|
* Represents the width of the Card component in terms of span numbers (1-12).
|
|
48
50
|
*/
|
|
49
|
-
widthSpan
|
|
51
|
+
widthSpan?: SpanNumber;
|
|
50
52
|
|
|
51
53
|
/**
|
|
52
54
|
* Optional. Represents the height of the Card component in terms of span numbers (1-12).
|
|
53
55
|
*/
|
|
54
56
|
heightSpan?: SpanNumber;
|
|
57
|
+
}
|
|
55
58
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
* Defaults to `false` if not provided.
|
|
59
|
-
*/
|
|
60
|
-
usePadding?: boolean;
|
|
59
|
+
export interface CardProps extends ViewProps {
|
|
60
|
+
background?: string;
|
|
61
61
|
}
|