@momo-kits/foundation 0.80.9 → 0.81.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/Application/Components.tsx +47 -6
- package/Application/ModalScreen.tsx +24 -7
- package/Application/Navigation.ts +3 -5
- package/Application/NavigationContainer.tsx +2 -2
- package/Application/index.ts +12 -5
- package/Application/types.ts +14 -6
- package/Application/utils.tsx +15 -47
- package/Image/index.tsx +21 -11
- package/Input/Input.tsx +5 -3
- package/Input/InputDropDown.tsx +6 -3
- package/Input/InputMoney.tsx +6 -3
- package/Input/InputOTP.tsx +7 -9
- package/Input/InputSearch.tsx +6 -9
- package/Input/InputTextArea.tsx +5 -3
- package/Input/common.tsx +2 -2
- package/Input/index.tsx +3 -1
- package/Layout/Card.tsx +13 -3
- package/Layout/Screen.tsx +223 -176
- package/Layout/styles.ts +12 -0
- package/Layout/utils.ts +2 -7
- package/Pagination/PaginationDot.tsx +6 -1
- package/Pagination/PaginationNumber.tsx +7 -4
- package/Pagination/PaginationWhiteDot.tsx +6 -1
- package/Pagination/styles.ts +3 -0
- package/Pagination/types.ts +2 -0
- package/Radio/types.ts +2 -2
- package/package.json +1 -1
package/Input/InputSearch.tsx
CHANGED
|
@@ -37,7 +37,7 @@ const InputSearch = forwardRef(
|
|
|
37
37
|
const [focused, setFocused] = useState(false);
|
|
38
38
|
const [haveValue, setHaveValue] = useState(!!value || !!defaultValue);
|
|
39
39
|
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
40
|
-
|
|
40
|
+
const accessibilityLabel = `InputMoney/${placeholder}`;
|
|
41
41
|
|
|
42
42
|
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
43
43
|
setFocused(true);
|
|
@@ -60,19 +60,16 @@ const InputSearch = forwardRef(
|
|
|
60
60
|
};
|
|
61
61
|
|
|
62
62
|
const renderInputView = () => {
|
|
63
|
-
let textColor = theme.colors.text.default;
|
|
64
|
-
let placeholderColor = theme.colors.text.hint;
|
|
65
|
-
|
|
66
63
|
return (
|
|
67
64
|
<TextInput
|
|
68
65
|
{...props}
|
|
69
|
-
accessibilityLabel={
|
|
66
|
+
accessibilityLabel={accessibilityLabel}
|
|
70
67
|
textAlignVertical="top"
|
|
71
68
|
ref={inputRef}
|
|
72
69
|
style={[
|
|
73
70
|
styles.searchInput,
|
|
74
71
|
{
|
|
75
|
-
color:
|
|
72
|
+
color: theme.colors.text.default,
|
|
76
73
|
},
|
|
77
74
|
]}
|
|
78
75
|
value={value}
|
|
@@ -81,7 +78,7 @@ const InputSearch = forwardRef(
|
|
|
81
78
|
onBlur={_onBlur}
|
|
82
79
|
placeholder={placeholder}
|
|
83
80
|
selectionColor={theme.colors.primary}
|
|
84
|
-
placeholderTextColor={
|
|
81
|
+
placeholderTextColor={theme.colors.text.hint}
|
|
85
82
|
/>
|
|
86
83
|
);
|
|
87
84
|
};
|
|
@@ -112,7 +109,7 @@ const InputSearch = forwardRef(
|
|
|
112
109
|
]}
|
|
113
110
|
/>
|
|
114
111
|
<Icon
|
|
115
|
-
color={
|
|
112
|
+
color={iconColor}
|
|
116
113
|
source={icon}
|
|
117
114
|
style={styles.iconSearchInput}
|
|
118
115
|
/>
|
|
@@ -124,7 +121,7 @@ const InputSearch = forwardRef(
|
|
|
124
121
|
return (
|
|
125
122
|
<View
|
|
126
123
|
style={[style, styles.searchInputContainer]}
|
|
127
|
-
accessibilityLabel={
|
|
124
|
+
accessibilityLabel={accessibilityLabel}>
|
|
128
125
|
<View
|
|
129
126
|
style={[
|
|
130
127
|
styles.searchInputWrapper,
|
package/Input/InputTextArea.tsx
CHANGED
|
@@ -37,6 +37,7 @@ const InputTextArea = forwardRef(
|
|
|
37
37
|
maxLength,
|
|
38
38
|
required,
|
|
39
39
|
errorSpacing,
|
|
40
|
+
style,
|
|
40
41
|
...props
|
|
41
42
|
}: InputTextAreaProps,
|
|
42
43
|
ref,
|
|
@@ -45,6 +46,7 @@ const InputTextArea = forwardRef(
|
|
|
45
46
|
const [focused, setFocused] = useState(false);
|
|
46
47
|
const [inputValue, setInputValue] = useState(defaultValue ?? '');
|
|
47
48
|
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
49
|
+
const accessibilityLabel = `InputTextArea/${floatingValue ?? placeholder}`;
|
|
48
50
|
|
|
49
51
|
const onClearText = () => {
|
|
50
52
|
inputRef?.current?.clear();
|
|
@@ -106,7 +108,7 @@ const InputTextArea = forwardRef(
|
|
|
106
108
|
<View style={styles.textAreaView}>
|
|
107
109
|
<TextInput
|
|
108
110
|
{...props}
|
|
109
|
-
accessibilityLabel={
|
|
111
|
+
accessibilityLabel={accessibilityLabel}
|
|
110
112
|
ref={inputRef}
|
|
111
113
|
editable={!disabled}
|
|
112
114
|
textAlignVertical="top"
|
|
@@ -147,8 +149,8 @@ const InputTextArea = forwardRef(
|
|
|
147
149
|
|
|
148
150
|
return (
|
|
149
151
|
<View
|
|
150
|
-
style={styles.wrapper}
|
|
151
|
-
accessibilityLabel={
|
|
152
|
+
style={[style, styles.wrapper]}
|
|
153
|
+
accessibilityLabel={accessibilityLabel}>
|
|
152
154
|
{renderInputView()}
|
|
153
155
|
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
154
156
|
</View>
|
package/Input/common.tsx
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {View, ViewStyle} from 'react-native';
|
|
2
2
|
import styles from './styles';
|
|
3
|
-
import {Text} from '../Text';
|
|
3
|
+
import {scaleSize, Text} from '../Text';
|
|
4
4
|
import React, {FC, useContext} from 'react';
|
|
5
5
|
import {ApplicationContext} from '../Application';
|
|
6
6
|
import {Icon} from '../Icon';
|
|
@@ -16,7 +16,7 @@ type FloatingViewProps = {
|
|
|
16
16
|
style?: ViewStyle;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export const DEFAULT_HEIGHT =
|
|
19
|
+
export const DEFAULT_HEIGHT = scaleSize(104);
|
|
20
20
|
export const MAX_LENGTH = 300;
|
|
21
21
|
|
|
22
22
|
export const getBorderColor = (
|
package/Input/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@ import InputSearch from './InputSearch';
|
|
|
4
4
|
import InputMoney from './InputMoney';
|
|
5
5
|
import InputOTP from './InputOTP';
|
|
6
6
|
import InputDropDown from './InputDropDown';
|
|
7
|
-
import {TextInputProps} from 'react-native';
|
|
7
|
+
import {TextInputProps, ViewStyle} from 'react-native';
|
|
8
8
|
|
|
9
9
|
export interface InputProps extends TextInputProps {
|
|
10
10
|
/**
|
|
@@ -238,6 +238,8 @@ export interface InputDropDownProps {
|
|
|
238
238
|
* Optional. Represents the color of the leading icon in the InputDropDown component.
|
|
239
239
|
*/
|
|
240
240
|
leadingIconColor?: string;
|
|
241
|
+
|
|
242
|
+
style: ViewStyle | ViewStyle[];
|
|
241
243
|
}
|
|
242
244
|
|
|
243
245
|
export {Input, InputTextArea, InputSearch, InputMoney, InputOTP, InputDropDown};
|
package/Layout/Card.tsx
CHANGED
|
@@ -7,16 +7,23 @@ import Item from './Item';
|
|
|
7
7
|
import {Image} from '../Image';
|
|
8
8
|
import {ApplicationContext} from '../Application';
|
|
9
9
|
import styles from './styles';
|
|
10
|
-
import {Colors, Spacing} from '../Consts';
|
|
10
|
+
import {Colors, Shadow, Spacing} from '../Consts';
|
|
11
11
|
|
|
12
12
|
export interface CardProps extends ViewProps {
|
|
13
13
|
/**
|
|
14
14
|
* Optional. Background image for the card.
|
|
15
15
|
*/
|
|
16
16
|
backgroundImage?: string;
|
|
17
|
+
|
|
18
|
+
useShadow?: boolean;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
const Card: React.FC<CardProps> = ({
|
|
21
|
+
const Card: React.FC<CardProps> = ({
|
|
22
|
+
children,
|
|
23
|
+
style,
|
|
24
|
+
backgroundImage,
|
|
25
|
+
useShadow = false,
|
|
26
|
+
}) => {
|
|
20
27
|
const {showGrid} = useContext(ApplicationContext);
|
|
21
28
|
const {numberOfColumns} = useGridSystem();
|
|
22
29
|
|
|
@@ -127,6 +134,7 @@ const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
|
127
134
|
return element;
|
|
128
135
|
};
|
|
129
136
|
|
|
137
|
+
const {theme} = useContext(ApplicationContext);
|
|
130
138
|
return (
|
|
131
139
|
<GridContext.Provider value={gridContext}>
|
|
132
140
|
<View
|
|
@@ -137,12 +145,14 @@ const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
|
137
145
|
{
|
|
138
146
|
width: widthSection,
|
|
139
147
|
marginHorizontal: gridContext.margin,
|
|
148
|
+
backgroundColor: theme.colors.background.surface,
|
|
140
149
|
},
|
|
150
|
+
useShadow && Shadow.Light,
|
|
141
151
|
]}>
|
|
142
152
|
{!!backgroundImage && (
|
|
143
153
|
<Image
|
|
144
154
|
source={{uri: backgroundImage}}
|
|
145
|
-
style={
|
|
155
|
+
style={styles.imageBackground}
|
|
146
156
|
/>
|
|
147
157
|
)}
|
|
148
158
|
{renderView(validateChildren(children, [Item]))}
|
package/Layout/Screen.tsx
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Animated,
|
|
3
|
+
Image,
|
|
3
4
|
KeyboardAvoidingView,
|
|
5
|
+
NativeScrollEvent,
|
|
6
|
+
NativeSyntheticEvent,
|
|
4
7
|
Platform,
|
|
5
8
|
ScrollViewProps,
|
|
6
9
|
View,
|
|
@@ -8,13 +11,26 @@ import {
|
|
|
8
11
|
} from 'react-native';
|
|
9
12
|
import {useHeaderHeight} from '@react-navigation/stack';
|
|
10
13
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
11
|
-
import React, {
|
|
12
|
-
|
|
14
|
+
import React, {
|
|
15
|
+
forwardRef,
|
|
16
|
+
ReactNode,
|
|
17
|
+
useContext,
|
|
18
|
+
useEffect,
|
|
19
|
+
useRef,
|
|
20
|
+
} from 'react';
|
|
21
|
+
import {Colors, Spacing, Styles} from '../Consts';
|
|
13
22
|
import {Card, Section, validateChildren} from './index';
|
|
14
|
-
import {
|
|
23
|
+
import {
|
|
24
|
+
ApplicationContext,
|
|
25
|
+
HeaderBackground,
|
|
26
|
+
HeaderTitle,
|
|
27
|
+
} from '../Application';
|
|
15
28
|
import Navigation from '../Application/Navigation';
|
|
29
|
+
import styles from './styles';
|
|
30
|
+
import {AnimatedHeader, NavigationOptions} from '../Application/types';
|
|
16
31
|
|
|
17
32
|
export interface ScreenProps extends ViewProps {
|
|
33
|
+
children: React.ReactNode;
|
|
18
34
|
/**
|
|
19
35
|
* Optional. Navigation object for handling navigation actions.
|
|
20
36
|
*/
|
|
@@ -25,25 +41,20 @@ export interface ScreenProps extends ViewProps {
|
|
|
25
41
|
*/
|
|
26
42
|
enableKeyboardAvoidingView?: boolean;
|
|
27
43
|
|
|
28
|
-
/**
|
|
29
|
-
* Optional. Background color of the header.
|
|
30
|
-
*/
|
|
31
|
-
headerBackground?: string;
|
|
32
|
-
|
|
33
44
|
/**
|
|
34
45
|
* Optional. If `true`, the screen content is scrollable.
|
|
35
46
|
*/
|
|
36
47
|
scrollable?: boolean;
|
|
37
48
|
|
|
38
49
|
/**
|
|
39
|
-
* Optional. If `true`, use an
|
|
50
|
+
* Optional. If `true`, use an extended header for the screen.
|
|
40
51
|
*/
|
|
41
|
-
|
|
52
|
+
useExtendedHeader?: boolean;
|
|
42
53
|
|
|
43
54
|
/**
|
|
44
|
-
* Optional.
|
|
55
|
+
* Optional. Props for the animated component or bool used top navigation animated.
|
|
45
56
|
*/
|
|
46
|
-
|
|
57
|
+
animatedHeader?: AnimatedHeader;
|
|
47
58
|
|
|
48
59
|
/**
|
|
49
60
|
* Optional. Props for the underlying ScrollView component when `scrollable` is `true`.
|
|
@@ -51,206 +62,242 @@ export interface ScreenProps extends ViewProps {
|
|
|
51
62
|
scrollViewProps?: ScrollViewProps;
|
|
52
63
|
|
|
53
64
|
/**
|
|
54
|
-
* Optional. ReactNode representing the
|
|
65
|
+
* Optional. ReactNode representing the header component of the screen.
|
|
55
66
|
*/
|
|
56
|
-
|
|
67
|
+
headerComponent?: ReactNode;
|
|
57
68
|
|
|
58
69
|
/**
|
|
59
|
-
* Optional.
|
|
70
|
+
* Optional. ReactNode representing the footer component of the screen.
|
|
60
71
|
*/
|
|
61
|
-
|
|
72
|
+
footerComponent?: ReactNode;
|
|
62
73
|
|
|
63
74
|
/**
|
|
64
75
|
* Optional. Background color of the screen.
|
|
65
76
|
*/
|
|
66
77
|
backgroundColor?: string;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
const Screen: React.FC<ScreenProps> = ({
|
|
70
|
-
children,
|
|
71
|
-
enableKeyboardAvoidingView = false,
|
|
72
|
-
scrollable = false,
|
|
73
|
-
navigation,
|
|
74
|
-
marginHeader,
|
|
75
|
-
useAnimatedHeader,
|
|
76
|
-
useExtendedHeader,
|
|
77
|
-
headerBackground,
|
|
78
|
-
scrollViewProps,
|
|
79
|
-
footerComponent: Footer,
|
|
80
|
-
backgroundColor,
|
|
81
|
-
}) => {
|
|
82
|
-
const animatedValue = useRef<Animated.Value | undefined>(undefined);
|
|
83
|
-
const {theme} = useContext(ApplicationContext);
|
|
84
|
-
const insets = useSafeAreaInsets();
|
|
85
|
-
const headerTransparent = useAnimatedHeader || useExtendedHeader;
|
|
86
|
-
|
|
87
|
-
let handleScroll;
|
|
88
|
-
let imageAnimatedStyle = {};
|
|
89
|
-
let opacity;
|
|
90
|
-
let Component: any = View;
|
|
91
|
-
animatedValue.current = undefined;
|
|
92
78
|
|
|
93
79
|
/**
|
|
94
|
-
*
|
|
80
|
+
* Optional. layout card offset overlap header banner.
|
|
95
81
|
*/
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
82
|
+
layoutOffset?: -8 | -24 | -56;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const Screen = forwardRef(
|
|
86
|
+
(
|
|
87
|
+
{
|
|
88
|
+
children,
|
|
89
|
+
enableKeyboardAvoidingView = false,
|
|
90
|
+
scrollable = false,
|
|
91
|
+
navigation,
|
|
92
|
+
useExtendedHeader,
|
|
93
|
+
animatedHeader,
|
|
94
|
+
scrollViewProps,
|
|
95
|
+
headerComponent: Header,
|
|
96
|
+
footerComponent: Footer,
|
|
97
|
+
layoutOffset = -56,
|
|
98
|
+
backgroundColor,
|
|
99
|
+
}: ScreenProps,
|
|
100
|
+
ref,
|
|
101
|
+
) => {
|
|
102
|
+
const animatedValue = useRef<Animated.Value | undefined>(undefined);
|
|
103
|
+
const {theme} = useContext(ApplicationContext);
|
|
104
|
+
const insets = useSafeAreaInsets();
|
|
105
|
+
const heightHeader = useHeaderHeight();
|
|
106
|
+
const currentTint = useRef(Colors.black_01);
|
|
107
|
+
let styleAnimatedHeader: NavigationOptions;
|
|
108
|
+
let handleScroll;
|
|
109
|
+
let headerBackground: string | undefined = undefined;
|
|
110
|
+
let Component: any = View;
|
|
111
|
+
animatedValue.current = undefined;
|
|
112
|
+
|
|
99
113
|
if (useExtendedHeader) {
|
|
100
114
|
headerBackground = theme.assets?.headerBackground;
|
|
101
115
|
}
|
|
102
|
-
}
|
|
103
116
|
|
|
104
|
-
|
|
105
|
-
if (useAnimatedHeader != undefined || useExtendedHeader != undefined) {
|
|
106
|
-
let title = {};
|
|
117
|
+
useEffect(() => {
|
|
107
118
|
if (useExtendedHeader) {
|
|
108
|
-
|
|
119
|
+
navigation?.setOptions({
|
|
120
|
+
headerTransparent: true,
|
|
121
|
+
headerBackground: () => null,
|
|
122
|
+
});
|
|
109
123
|
}
|
|
110
|
-
|
|
111
|
-
animatedValue: animatedValue.current,
|
|
112
|
-
headerTransparent: headerTransparent,
|
|
113
|
-
...title,
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
}, [useExtendedHeader, useAnimatedHeader]);
|
|
124
|
+
}, [useExtendedHeader]);
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
useEffect(() => {
|
|
127
|
+
if (animatedHeader) {
|
|
128
|
+
styleAnimatedHeader = {
|
|
129
|
+
headerTransparent: true,
|
|
130
|
+
headerBackground: (props: any) => (
|
|
131
|
+
<HeaderBackground
|
|
132
|
+
{...props}
|
|
133
|
+
animatedValue={animatedValue.current}
|
|
134
|
+
/>
|
|
135
|
+
),
|
|
136
|
+
headerTitle: (props: any) => (
|
|
137
|
+
<HeaderTitle {...props} animatedValue={animatedValue.current} />
|
|
138
|
+
),
|
|
139
|
+
};
|
|
140
|
+
if (animatedHeader.type == 'surface') {
|
|
141
|
+
styleAnimatedHeader = {
|
|
142
|
+
headerTransparent: true,
|
|
143
|
+
headerBackground: (props: any) => (
|
|
144
|
+
<HeaderBackground
|
|
145
|
+
{...props}
|
|
146
|
+
image={null}
|
|
147
|
+
backgroundColor={theme.colors.background.surface}
|
|
148
|
+
useBorder={true}
|
|
149
|
+
animatedValue={animatedValue.current}
|
|
150
|
+
/>
|
|
151
|
+
),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
navigation?.setOptions(styleAnimatedHeader);
|
|
155
|
+
const current: any = navigation;
|
|
156
|
+
const parent = current?.getParent?.();
|
|
157
|
+
if (parent) {
|
|
158
|
+
return current?.addListener?.('focus', () => {
|
|
159
|
+
const stackNavigation = new Navigation(parent, theme);
|
|
160
|
+
stackNavigation?.setOptions(styleAnimatedHeader);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}, [animatedHeader]);
|
|
132
165
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
outputRange: [1.75, 1, 1],
|
|
150
|
-
extrapolate: 'clamp',
|
|
151
|
-
}),
|
|
152
|
-
},
|
|
153
|
-
],
|
|
154
|
-
};
|
|
155
|
-
handleScroll = Animated.event(
|
|
156
|
-
[
|
|
166
|
+
/**
|
|
167
|
+
* animated when use scroll && animated value
|
|
168
|
+
*/
|
|
169
|
+
if (scrollable) {
|
|
170
|
+
Component = Animated.ScrollView;
|
|
171
|
+
handleScroll = scrollViewProps?.onScroll;
|
|
172
|
+
if (animatedHeader) {
|
|
173
|
+
animatedValue.current = new Animated.Value(0);
|
|
174
|
+
handleScroll = Animated.event(
|
|
175
|
+
[
|
|
176
|
+
{
|
|
177
|
+
nativeEvent: {
|
|
178
|
+
contentOffset: {y: animatedValue.current as Animated.Value},
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
],
|
|
157
182
|
{
|
|
158
|
-
|
|
159
|
-
|
|
183
|
+
useNativeDriver: true,
|
|
184
|
+
listener: (e: NativeSyntheticEvent<NativeScrollEvent>) => {
|
|
185
|
+
if (animatedHeader.type == 'surface') {
|
|
186
|
+
const offsetY = e.nativeEvent.contentOffset.y;
|
|
187
|
+
let color = Colors.black_01;
|
|
188
|
+
if (offsetY > 50) {
|
|
189
|
+
color = theme.colors.text.default;
|
|
190
|
+
}
|
|
191
|
+
if (color != currentTint.current) {
|
|
192
|
+
currentTint.current = color;
|
|
193
|
+
navigation?.setOptions({
|
|
194
|
+
headerTintColor: color,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
scrollViewProps?.onScroll?.(e);
|
|
160
199
|
},
|
|
161
200
|
},
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
);
|
|
201
|
+
);
|
|
202
|
+
}
|
|
165
203
|
}
|
|
166
|
-
}
|
|
167
204
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
205
|
+
/**
|
|
206
|
+
* render top navigation banner
|
|
207
|
+
*/
|
|
208
|
+
const renderHeader = () => {
|
|
209
|
+
if (typeof animatedHeader?.component === 'function') {
|
|
210
|
+
return animatedHeader?.component({
|
|
211
|
+
animatedValue: animatedValue.current,
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* build content for screen
|
|
218
|
+
*/
|
|
219
|
+
const renderContent = () => {
|
|
220
|
+
const results = validateChildren(children, [Section, Card]);
|
|
221
|
+
if (Array.isArray(results)) {
|
|
222
|
+
return results.map((item, index) => {
|
|
223
|
+
const space = item.props?.useMargin === false ? 0 : Spacing.M;
|
|
224
|
+
return (
|
|
225
|
+
<View
|
|
226
|
+
key={`ScreenItem${index}`}
|
|
227
|
+
style={{
|
|
228
|
+
marginTop: space,
|
|
229
|
+
flex: item.props?.expanded ? 1 : undefined,
|
|
230
|
+
}}>
|
|
231
|
+
{item}
|
|
232
|
+
</View>
|
|
233
|
+
);
|
|
234
|
+
});
|
|
235
|
+
} else {
|
|
236
|
+
const item: any = children;
|
|
237
|
+
const space = item?.props?.useMargin === false ? 0 : Spacing.M;
|
|
176
238
|
return (
|
|
177
239
|
<View
|
|
178
|
-
key={`ScreenItem
|
|
240
|
+
key={`ScreenItem`}
|
|
179
241
|
style={{
|
|
180
242
|
marginTop: space,
|
|
181
|
-
flex: item
|
|
243
|
+
flex: item?.props?.expanded ? 1 : undefined,
|
|
182
244
|
}}>
|
|
183
|
-
{
|
|
245
|
+
{children}
|
|
184
246
|
</View>
|
|
185
247
|
);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
const item: any = children;
|
|
189
|
-
const space = item?.props?.useMargin === false ? 0 : Spacing.M;
|
|
190
|
-
return (
|
|
191
|
-
<View
|
|
192
|
-
key={`ScreenItem`}
|
|
193
|
-
style={{
|
|
194
|
-
marginTop: space,
|
|
195
|
-
flex: item?.props?.expanded ? 1 : undefined,
|
|
196
|
-
}}>
|
|
197
|
-
{children}
|
|
198
|
-
</View>
|
|
199
|
-
);
|
|
200
|
-
}
|
|
201
|
-
};
|
|
248
|
+
}
|
|
249
|
+
};
|
|
202
250
|
|
|
203
|
-
|
|
204
|
-
<View
|
|
205
|
-
style={[Styles.flex, {backgroundColor}]}
|
|
206
|
-
accessibilityLabel={`ScreenContainer`}>
|
|
251
|
+
return (
|
|
207
252
|
<View
|
|
208
|
-
style={{
|
|
209
|
-
|
|
210
|
-
maxHeight: 215,
|
|
211
|
-
width: '100%',
|
|
212
|
-
overflow: 'hidden',
|
|
213
|
-
}}>
|
|
253
|
+
style={[Styles.flex, {backgroundColor}]}
|
|
254
|
+
accessibilityLabel={`ScreenContainer`}>
|
|
214
255
|
{!!headerBackground && (
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
/>
|
|
256
|
+
<>
|
|
257
|
+
<Image
|
|
258
|
+
source={{
|
|
259
|
+
uri: headerBackground,
|
|
260
|
+
}}
|
|
261
|
+
style={styles.extendedHeader}
|
|
262
|
+
/>
|
|
263
|
+
<View style={{height: heightHeader}} />
|
|
264
|
+
</>
|
|
225
265
|
)}
|
|
266
|
+
<KeyboardAvoidingView
|
|
267
|
+
style={Styles.flex}
|
|
268
|
+
enabled={enableKeyboardAvoidingView}
|
|
269
|
+
behavior={Platform.select({
|
|
270
|
+
ios: 'padding',
|
|
271
|
+
android: undefined,
|
|
272
|
+
})}>
|
|
273
|
+
{Header}
|
|
274
|
+
<Component
|
|
275
|
+
{...scrollViewProps}
|
|
276
|
+
ref={ref}
|
|
277
|
+
heightHeader={heightHeader}
|
|
278
|
+
showsVerticalScrollIndicator={false}
|
|
279
|
+
onScroll={handleScroll}
|
|
280
|
+
style={Styles.flex}>
|
|
281
|
+
<View
|
|
282
|
+
style={[styles.screenBanner, {maxHeight: 210 + layoutOffset}]}>
|
|
283
|
+
{renderHeader()}
|
|
284
|
+
</View>
|
|
285
|
+
{renderContent()}
|
|
286
|
+
</Component>
|
|
287
|
+
{Footer && (
|
|
288
|
+
<View
|
|
289
|
+
style={{
|
|
290
|
+
paddingTop: Spacing.S,
|
|
291
|
+
paddingBottom: Math.min(insets.bottom, 20) + Spacing.S,
|
|
292
|
+
backgroundColor: theme.colors.background.surface,
|
|
293
|
+
}}>
|
|
294
|
+
<Section>{Footer}</Section>
|
|
295
|
+
</View>
|
|
296
|
+
)}
|
|
297
|
+
</KeyboardAvoidingView>
|
|
226
298
|
</View>
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
behavior={Platform.select({
|
|
231
|
-
ios: 'padding',
|
|
232
|
-
android: undefined,
|
|
233
|
-
})}>
|
|
234
|
-
<Component
|
|
235
|
-
{...scrollViewProps}
|
|
236
|
-
showsVerticalScrollIndicator={false}
|
|
237
|
-
onScroll={handleScroll}
|
|
238
|
-
style={[Styles.flex, {marginTop: marginHeader}]}>
|
|
239
|
-
{renderContent()}
|
|
240
|
-
</Component>
|
|
241
|
-
{Footer && (
|
|
242
|
-
<View
|
|
243
|
-
style={{
|
|
244
|
-
paddingTop: Spacing.S,
|
|
245
|
-
paddingBottom: Math.min(insets.bottom, 20) + Spacing.S,
|
|
246
|
-
backgroundColor: theme.colors.background.surface,
|
|
247
|
-
}}>
|
|
248
|
-
<Section>{Footer}</Section>
|
|
249
|
-
</View>
|
|
250
|
-
)}
|
|
251
|
-
</KeyboardAvoidingView>
|
|
252
|
-
</View>
|
|
253
|
-
);
|
|
254
|
-
};
|
|
299
|
+
);
|
|
300
|
+
},
|
|
301
|
+
);
|
|
255
302
|
|
|
256
303
|
export default Screen;
|
package/Layout/styles.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
import {StyleSheet} from 'react-native';
|
|
2
|
+
import {Radius, Spacing} from '../Consts';
|
|
2
3
|
|
|
3
4
|
export default StyleSheet.create({
|
|
5
|
+
extendedHeader: {
|
|
6
|
+
aspectRatio: 1.75,
|
|
7
|
+
position: 'absolute',
|
|
8
|
+
width: '100%',
|
|
9
|
+
height: 210,
|
|
10
|
+
},
|
|
11
|
+
screenBanner: {
|
|
12
|
+
width: '100%',
|
|
13
|
+
},
|
|
4
14
|
boxGrid: {
|
|
5
15
|
position: 'absolute',
|
|
6
16
|
top: 0,
|
|
@@ -34,6 +44,7 @@ export default StyleSheet.create({
|
|
|
34
44
|
card: {
|
|
35
45
|
flexDirection: 'row',
|
|
36
46
|
flexWrap: 'wrap',
|
|
47
|
+
borderRadius: Radius.M,
|
|
37
48
|
paddingTop: undefined,
|
|
38
49
|
paddingBottom: undefined,
|
|
39
50
|
paddingLeft: undefined,
|
|
@@ -64,5 +75,6 @@ export default StyleSheet.create({
|
|
|
64
75
|
bottom: 0,
|
|
65
76
|
left: 0,
|
|
66
77
|
right: 0,
|
|
78
|
+
borderRadius: Spacing.M,
|
|
67
79
|
},
|
|
68
80
|
});
|