@momo-kits/foundation 0.77.8 → 0.78.2
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/BottomTab.tsx +13 -3
- package/Application/Components.tsx +51 -4
- package/Application/ModalScreen.tsx +43 -15
- package/Application/Navigation.ts +4 -2
- package/Application/NavigationContainer.tsx +22 -1
- package/Application/index.ts +8 -2
- package/Application/types.ts +19 -15
- package/Application/utils.tsx +13 -0
- package/Assets/DotAnimation.json +256 -0
- package/Assets/SpinnerAnimation.json +1027 -0
- package/Button/index.tsx +25 -14
- package/CheckBox/index.tsx +29 -24
- package/CheckBox/styles.ts +1 -1
- package/CheckBox/types.ts +1 -1
- package/Consts/styles.ts +0 -26
- package/Divider/index.tsx +2 -0
- package/Input/Input.tsx +126 -106
- package/Input/InputMoney.tsx +118 -110
- package/Input/InputSearch.tsx +129 -134
- package/Input/InputTextArea.tsx +126 -118
- package/Input/common.tsx +11 -5
- package/Input/index.tsx +12 -0
- package/Layout/Card.tsx +9 -2
- package/Layout/GridSystem.tsx +1 -1
- package/Layout/Item.tsx +15 -2
- package/Layout/Screen.tsx +76 -8
- package/Layout/Section.tsx +36 -3
- package/Layout/index.ts +1 -1
- package/Layout/types.ts +0 -37
- package/Layout/utils.ts +6 -9
- package/Loader/DotLoader.tsx +37 -0
- package/Loader/Loader.tsx +13 -0
- package/Loader/ProgressBar.tsx +44 -0
- package/Loader/Spinner.tsx +29 -0
- package/Loader/index.tsx +4 -0
- package/Loader/styles.ts +10 -0
- package/Loader/types.ts +35 -0
- package/Loader/utils.ts +25 -0
- package/Pagination/PaginationNumber.tsx +1 -2
- package/Pagination/PaginationWhiteDot.tsx +1 -3
- package/Popup/PopupNotify.tsx +11 -17
- package/Popup/PopupPromotion.tsx +19 -13
- package/Popup/types.ts +9 -1
- package/Radio/index.tsx +1 -1
- package/Skeleton/types.ts +3 -0
- package/Text/index.tsx +1 -16
- package/Text/utils.ts +1 -1
- package/code-scanner.js +51 -0
- package/index.ts +2 -0
- package/package.json +8 -4
- package/tsconfig.json +25 -0
- package/Application/NavigationButton.tsx +0 -54
package/Input/InputTextArea.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {forwardRef, useContext, useRef, useState} from 'react';
|
|
2
2
|
import {
|
|
3
3
|
NativeSyntheticEvent,
|
|
4
4
|
TextInput,
|
|
@@ -19,134 +19,142 @@ import {InputTextAreaProps} from './index';
|
|
|
19
19
|
import {Icon} from '../Icon';
|
|
20
20
|
import {ApplicationContext} from '../Application';
|
|
21
21
|
|
|
22
|
-
const InputTextArea
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
22
|
+
const InputTextArea = forwardRef(
|
|
23
|
+
(
|
|
24
|
+
{
|
|
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
|
+
errorSpacing,
|
|
40
|
+
...props
|
|
41
|
+
}: InputTextAreaProps,
|
|
42
|
+
ref,
|
|
43
|
+
) => {
|
|
44
|
+
const {theme} = useContext(ApplicationContext);
|
|
45
|
+
const [focused, setFocused] = useState(false);
|
|
46
|
+
const [inputValue, setInputValue] = useState(defaultValue ?? '');
|
|
47
|
+
const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
|
|
43
48
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
const onClearText = () => {
|
|
50
|
+
inputRef?.current?.clear();
|
|
51
|
+
_onChangeText('');
|
|
52
|
+
};
|
|
48
53
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
54
|
+
const _onChangeText = (text: string) => {
|
|
55
|
+
onChangeText?.(text);
|
|
56
|
+
setInputValue(text);
|
|
57
|
+
};
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
59
|
+
const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
60
|
+
setFocused(true);
|
|
61
|
+
onFocus?.(e);
|
|
62
|
+
};
|
|
58
63
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
const _onBlur = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
|
|
65
|
+
setFocused(false);
|
|
66
|
+
onBlur?.(e);
|
|
67
|
+
};
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
69
|
+
const renderCountingView = () => {
|
|
70
|
+
return (
|
|
71
|
+
<View style={styles.countingView}>
|
|
72
|
+
<Text color={theme.colors.text.hint} typography={'description_xs'}>
|
|
73
|
+
{`${inputValue.length}/${maxLength}`}
|
|
74
|
+
</Text>
|
|
75
|
+
</View>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
const renderInputView = () => {
|
|
79
|
+
const disabledColor = theme.colors.text.disable;
|
|
80
|
+
let textColor = theme.colors.text.default;
|
|
81
|
+
let placeholderColor = theme.colors.text.hint;
|
|
77
82
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
83
|
+
if (disabled) {
|
|
84
|
+
textColor = disabledColor;
|
|
85
|
+
placeholderColor = disabledColor;
|
|
86
|
+
}
|
|
82
87
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
/>
|
|
125
|
-
</View>
|
|
126
|
-
{focused && inputValue.length > 0 && (
|
|
127
|
-
<TouchableOpacity style={styles.iconWrapper} onPress={onClearText}>
|
|
128
|
-
<Icon
|
|
129
|
-
source="24_navigation_close_circle_full"
|
|
130
|
-
size={16}
|
|
131
|
-
color={theme.colors.text.hint}
|
|
88
|
+
return (
|
|
89
|
+
<View
|
|
90
|
+
style={[
|
|
91
|
+
styles.textAreaWrapper,
|
|
92
|
+
{
|
|
93
|
+
height: height || DEFAULT_HEIGHT,
|
|
94
|
+
backgroundColor: theme.colors.background.surface,
|
|
95
|
+
},
|
|
96
|
+
getBorderColor(theme, focused, errorMessage, disabled),
|
|
97
|
+
]}>
|
|
98
|
+
<FloatingView
|
|
99
|
+
floatingValue={floatingValue}
|
|
100
|
+
floatingIconColor={floatingIconColor}
|
|
101
|
+
disabled={disabled}
|
|
102
|
+
floatingIcon={floatingIcon}
|
|
103
|
+
required={required}
|
|
104
|
+
/>
|
|
105
|
+
<View style={styles.rowArea}>
|
|
106
|
+
<View style={styles.textAreaView}>
|
|
107
|
+
<TextInput
|
|
108
|
+
{...props}
|
|
109
|
+
accessibilityLabel={`TextInput`}
|
|
110
|
+
ref={inputRef}
|
|
111
|
+
editable={!disabled}
|
|
112
|
+
textAlignVertical="top"
|
|
113
|
+
style={[
|
|
114
|
+
styles.textArea,
|
|
115
|
+
{
|
|
116
|
+
color: textColor,
|
|
117
|
+
},
|
|
118
|
+
]}
|
|
119
|
+
maxLength={maxLength}
|
|
120
|
+
textBreakStrategy="highQuality"
|
|
121
|
+
multiline={true}
|
|
122
|
+
value={value}
|
|
123
|
+
onChangeText={_onChangeText}
|
|
124
|
+
onFocus={_onFocus}
|
|
125
|
+
onBlur={_onBlur}
|
|
126
|
+
placeholder={placeholder}
|
|
127
|
+
selectionColor={theme.colors.primary}
|
|
128
|
+
placeholderTextColor={placeholderColor}
|
|
132
129
|
/>
|
|
133
|
-
</
|
|
134
|
-
|
|
130
|
+
</View>
|
|
131
|
+
{focused && inputValue.length > 0 && (
|
|
132
|
+
<TouchableOpacity
|
|
133
|
+
style={styles.iconWrapper}
|
|
134
|
+
onPress={onClearText}>
|
|
135
|
+
<Icon
|
|
136
|
+
source="24_navigation_close_circle_full"
|
|
137
|
+
size={16}
|
|
138
|
+
color={theme.colors.text.hint}
|
|
139
|
+
/>
|
|
140
|
+
</TouchableOpacity>
|
|
141
|
+
)}
|
|
142
|
+
</View>
|
|
143
|
+
{renderCountingView()}
|
|
135
144
|
</View>
|
|
136
|
-
|
|
145
|
+
);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
return (
|
|
149
|
+
<View
|
|
150
|
+
style={styles.wrapper}
|
|
151
|
+
accessibilityLabel={`InputTextArea/${floatingValue}`}>
|
|
152
|
+
{renderInputView()}
|
|
153
|
+
<ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
|
|
137
154
|
</View>
|
|
138
155
|
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return (
|
|
142
|
-
<View
|
|
143
|
-
style={styles.wrapper}
|
|
144
|
-
accessibilityLabel={`InputTextArea/${floatingValue}`}>
|
|
145
|
-
{renderInputView()}
|
|
146
|
-
<ErrorView errorMessage={errorMessage} />
|
|
147
|
-
</View>
|
|
148
|
-
);
|
|
149
|
-
};
|
|
156
|
+
},
|
|
157
|
+
);
|
|
150
158
|
|
|
151
159
|
InputTextArea.defaultProps = {
|
|
152
160
|
maxLength: MAX_LENGTH,
|
package/Input/common.tsx
CHANGED
|
@@ -5,6 +5,7 @@ import React, {FC, useContext} from 'react';
|
|
|
5
5
|
import {ApplicationContext} from '../Application';
|
|
6
6
|
import {Icon} from '../Icon';
|
|
7
7
|
import {Styles} from '../Consts';
|
|
8
|
+
import {Theme} from '../Application/types';
|
|
8
9
|
|
|
9
10
|
type FloatingViewProps = {
|
|
10
11
|
floatingValue?: string;
|
|
@@ -18,12 +19,11 @@ export const DEFAULT_HEIGHT = 112;
|
|
|
18
19
|
export const MAX_LENGTH = 300;
|
|
19
20
|
|
|
20
21
|
export const getBorderColor = (
|
|
22
|
+
theme: Theme,
|
|
21
23
|
focused: boolean,
|
|
22
24
|
errorMessage?: string,
|
|
23
25
|
disabled?: boolean,
|
|
24
26
|
) => {
|
|
25
|
-
const {theme} = useContext(ApplicationContext);
|
|
26
|
-
|
|
27
27
|
let borderColor = theme.colors.border.default;
|
|
28
28
|
|
|
29
29
|
if (focused) {
|
|
@@ -47,7 +47,10 @@ export const getSizeStyle = (size?: 'small' | 'large') => {
|
|
|
47
47
|
}
|
|
48
48
|
return styles.container;
|
|
49
49
|
};
|
|
50
|
-
export const ErrorView: FC<{errorMessage?: string}> = ({
|
|
50
|
+
export const ErrorView: FC<{errorMessage?: string; errorSpacing?: boolean}> = ({
|
|
51
|
+
errorMessage,
|
|
52
|
+
errorSpacing,
|
|
53
|
+
}) => {
|
|
51
54
|
const {theme} = useContext(ApplicationContext);
|
|
52
55
|
const errorColor = theme.colors.error.primary;
|
|
53
56
|
if (errorMessage) {
|
|
@@ -59,14 +62,17 @@ export const ErrorView: FC<{errorMessage?: string}> = ({errorMessage}) => {
|
|
|
59
62
|
<Text
|
|
60
63
|
style={Styles.flex}
|
|
61
64
|
color={errorColor}
|
|
62
|
-
numberOfLines={
|
|
65
|
+
numberOfLines={2}
|
|
63
66
|
typography={'description_s'}>
|
|
64
67
|
{errorMessage}
|
|
65
68
|
</Text>
|
|
66
69
|
</View>
|
|
67
70
|
);
|
|
68
71
|
}
|
|
69
|
-
|
|
72
|
+
if (errorSpacing) {
|
|
73
|
+
return <View style={[styles.errorView, {height: 18}]} />;
|
|
74
|
+
}
|
|
75
|
+
return <View />;
|
|
70
76
|
};
|
|
71
77
|
|
|
72
78
|
export const FloatingView: FC<FloatingViewProps> = ({
|
package/Input/index.tsx
CHANGED
|
@@ -52,6 +52,18 @@ export interface InputProps extends TextInputProps {
|
|
|
52
52
|
* Defaults to `false` if not provided.
|
|
53
53
|
*/
|
|
54
54
|
required?: boolean;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Optional. If `true`,
|
|
58
|
+
* include spacing when Input not have error message.
|
|
59
|
+
* Defaults to `false` if not provided.
|
|
60
|
+
*/
|
|
61
|
+
errorSpacing?: boolean;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* If true, the icon of input will use be show indicator loading.
|
|
65
|
+
*/
|
|
66
|
+
loading?: boolean;
|
|
55
67
|
}
|
|
56
68
|
|
|
57
69
|
type InputPropsWithoutSizeAndIcon = Omit<
|
package/Layout/Card.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
|
-
import {Dimensions, View} from 'react-native';
|
|
2
|
+
import {Dimensions, View, ViewProps} from 'react-native';
|
|
3
3
|
import {useGridSystem, validateChildren} from './utils';
|
|
4
|
-
import {
|
|
4
|
+
import {GridContextProps} from './types';
|
|
5
5
|
import {GridContext, GridSystem} from './index';
|
|
6
6
|
import Item from './Item';
|
|
7
7
|
import {Image} from '../Image';
|
|
@@ -9,6 +9,13 @@ import {ApplicationContext} from '../Application';
|
|
|
9
9
|
import styles from './styles';
|
|
10
10
|
import {Colors, Spacing} from '../Consts';
|
|
11
11
|
|
|
12
|
+
export interface CardProps extends ViewProps {
|
|
13
|
+
/**
|
|
14
|
+
* Optional. Background image for the card.
|
|
15
|
+
*/
|
|
16
|
+
backgroundImage?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
12
19
|
const Card: React.FC<CardProps> = ({children, style, backgroundImage}) => {
|
|
13
20
|
const {showGrid} = useContext(ApplicationContext);
|
|
14
21
|
const {numberOfColumns} = useGridSystem();
|
package/Layout/GridSystem.tsx
CHANGED
|
@@ -51,7 +51,7 @@ const GridSystem: React.FC<any> = ({
|
|
|
51
51
|
bottom: Spacing.M,
|
|
52
52
|
},
|
|
53
53
|
]}>
|
|
54
|
-
{list.map((
|
|
54
|
+
{list.map((_, index) => {
|
|
55
55
|
return (
|
|
56
56
|
<View style={{flexDirection: 'row'}} key={index.toString()}>
|
|
57
57
|
{index != -0 && <View style={{width: grid.gutterSize}} />}
|
package/Layout/Item.tsx
CHANGED
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
|
-
import {View} from 'react-native';
|
|
2
|
+
import {View, ViewProps} from 'react-native';
|
|
3
3
|
|
|
4
|
-
import {ItemProps} from './types';
|
|
5
4
|
import {GridContext} from './index';
|
|
6
5
|
import {ApplicationContext} from '../Application';
|
|
7
6
|
import styles from './styles';
|
|
8
7
|
|
|
8
|
+
type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
9
|
+
|
|
10
|
+
export interface ItemProps extends ViewProps {
|
|
11
|
+
/**
|
|
12
|
+
* Represents the width of the Card component in terms of span numbers (1-12).
|
|
13
|
+
*/
|
|
14
|
+
widthSpan?: SpanNumber;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Optional. Represents the height of the Card component in terms of span numbers (1-12).
|
|
18
|
+
*/
|
|
19
|
+
heightSpan?: SpanNumber;
|
|
20
|
+
}
|
|
21
|
+
|
|
9
22
|
const Item: React.FC<ItemProps> = ({
|
|
10
23
|
widthSpan,
|
|
11
24
|
heightSpan,
|
package/Layout/Screen.tsx
CHANGED
|
@@ -1,13 +1,70 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Animated,
|
|
3
|
+
KeyboardAvoidingView,
|
|
4
|
+
Platform,
|
|
5
|
+
ScrollViewProps,
|
|
6
|
+
View,
|
|
7
|
+
ViewProps,
|
|
8
|
+
} from 'react-native';
|
|
2
9
|
import {useHeaderHeight} from '@react-navigation/stack';
|
|
3
10
|
import {useSafeAreaInsets} from 'react-native-safe-area-context';
|
|
4
|
-
import React, {useContext, useEffect, useRef} from 'react';
|
|
5
|
-
import {ScreenProps} from '../Application/types';
|
|
11
|
+
import React, {ReactNode, useContext, useEffect, useRef} from 'react';
|
|
6
12
|
import {Spacing, Styles} from '../Consts';
|
|
7
13
|
import {Card, Section, validateChildren} from './index';
|
|
8
|
-
import {ApplicationContext} from '../Application';
|
|
14
|
+
import {ApplicationContext, HeaderTitle} from '../Application';
|
|
9
15
|
import Navigation from '../Application/Navigation';
|
|
10
|
-
|
|
16
|
+
|
|
17
|
+
export interface ScreenProps extends ViewProps {
|
|
18
|
+
/**
|
|
19
|
+
* Optional. Navigation object for handling navigation actions.
|
|
20
|
+
*/
|
|
21
|
+
navigation?: Navigation;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Optional. If `true`, enable keyboard avoiding view for the screen.
|
|
25
|
+
*/
|
|
26
|
+
enableKeyboardAvoidingView?: boolean;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Optional. Background color of the header.
|
|
30
|
+
*/
|
|
31
|
+
headerBackground?: string;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Optional. If `true`, the screen content is scrollable.
|
|
35
|
+
*/
|
|
36
|
+
scrollable?: boolean;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Optional. If `true`, use an animated header for the screen.
|
|
40
|
+
*/
|
|
41
|
+
useAnimatedHeader?: boolean;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Optional. If `true`, use an extended header for the screen.
|
|
45
|
+
*/
|
|
46
|
+
useExtendedHeader?: boolean;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Optional. Props for the underlying ScrollView component when `scrollable` is `true`.
|
|
50
|
+
*/
|
|
51
|
+
scrollViewProps?: ScrollViewProps;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Optional. ReactNode representing the footer component of the screen.
|
|
55
|
+
*/
|
|
56
|
+
footerComponent?: ReactNode;
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Optional. Margin for the header component.
|
|
60
|
+
*/
|
|
61
|
+
marginHeader?: number;
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Optional. Background color of the screen.
|
|
65
|
+
*/
|
|
66
|
+
backgroundColor?: string;
|
|
67
|
+
}
|
|
11
68
|
|
|
12
69
|
const Screen: React.FC<ScreenProps> = ({
|
|
13
70
|
children,
|
|
@@ -70,7 +127,6 @@ const Screen: React.FC<ScreenProps> = ({
|
|
|
70
127
|
const stackNavigation = new Navigation(current?.getParent(), theme);
|
|
71
128
|
stackNavigation?.setOptions({
|
|
72
129
|
animatedValue: animatedValue.current,
|
|
73
|
-
headerTransparent: true,
|
|
74
130
|
});
|
|
75
131
|
});
|
|
76
132
|
}
|
|
@@ -130,8 +186,20 @@ const Screen: React.FC<ScreenProps> = ({
|
|
|
130
186
|
</View>
|
|
131
187
|
);
|
|
132
188
|
});
|
|
189
|
+
} else {
|
|
190
|
+
const item: any = children;
|
|
191
|
+
const space = item?.props?.useMargin === false ? 0 : Spacing.M;
|
|
192
|
+
return (
|
|
193
|
+
<View
|
|
194
|
+
key={`ScreenItem`}
|
|
195
|
+
style={{
|
|
196
|
+
marginTop: space,
|
|
197
|
+
flex: item?.props?.expanded ? 1 : undefined,
|
|
198
|
+
}}>
|
|
199
|
+
{children}
|
|
200
|
+
</View>
|
|
201
|
+
);
|
|
133
202
|
}
|
|
134
|
-
return results;
|
|
135
203
|
};
|
|
136
204
|
|
|
137
205
|
return (
|
|
@@ -176,7 +244,7 @@ const Screen: React.FC<ScreenProps> = ({
|
|
|
176
244
|
<View
|
|
177
245
|
style={{
|
|
178
246
|
paddingTop: Spacing.S,
|
|
179
|
-
paddingBottom: insets.bottom + Spacing.S,
|
|
247
|
+
paddingBottom: Math.min(insets.bottom, 20) + Spacing.S,
|
|
180
248
|
backgroundColor: theme.colors.background.surface,
|
|
181
249
|
}}>
|
|
182
250
|
<Section>{Footer}</Section>
|
package/Layout/Section.tsx
CHANGED
|
@@ -1,13 +1,37 @@
|
|
|
1
1
|
import React, {useContext} from 'react';
|
|
2
|
-
import {Dimensions, View} from 'react-native';
|
|
2
|
+
import {Dimensions, View, ViewProps} from 'react-native';
|
|
3
3
|
import {useGridSystem, validateChildren} from './utils';
|
|
4
|
-
import {GridContextProps
|
|
4
|
+
import {GridContextProps} from './types';
|
|
5
5
|
import {GridContext} from './index';
|
|
6
6
|
import Item from './Item';
|
|
7
7
|
import {ApplicationContext} from '../Application';
|
|
8
8
|
import styles from './styles';
|
|
9
9
|
import {Image} from '../Image';
|
|
10
10
|
|
|
11
|
+
export interface SectionProps extends ViewProps {
|
|
12
|
+
/**
|
|
13
|
+
* Optional. If `true`, the Section component will be displayed in an expanded state.
|
|
14
|
+
* Defaults to `false` if not provided.
|
|
15
|
+
*/
|
|
16
|
+
expanded?: boolean;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Optional. If `true`, margin will be applied to the Section component.
|
|
20
|
+
* Defaults to `false` if not provided.
|
|
21
|
+
*/
|
|
22
|
+
useMargin?: boolean;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Optional. Background color for the Section component.
|
|
26
|
+
*/
|
|
27
|
+
backgroundColor?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Optional. Background image for the Section component.
|
|
31
|
+
*/
|
|
32
|
+
backgroundImage?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
11
35
|
const Section: React.FC<SectionProps> = ({
|
|
12
36
|
children,
|
|
13
37
|
useMargin = true,
|
|
@@ -116,7 +140,16 @@ const Section: React.FC<SectionProps> = ({
|
|
|
116
140
|
};
|
|
117
141
|
|
|
118
142
|
return (
|
|
119
|
-
<GridContext.Provider
|
|
143
|
+
<GridContext.Provider
|
|
144
|
+
value={{
|
|
145
|
+
numberOfColumns,
|
|
146
|
+
gutterSize,
|
|
147
|
+
margin,
|
|
148
|
+
sizePerSpan,
|
|
149
|
+
getSizeSpan: span => {
|
|
150
|
+
return span * sizePerSpan + (span - 1) * gutterSize;
|
|
151
|
+
},
|
|
152
|
+
}}>
|
|
120
153
|
<View
|
|
121
154
|
accessibilityLabel={`Section`}
|
|
122
155
|
style={{
|
package/Layout/index.ts
CHANGED
package/Layout/types.ts
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import {ViewProps} from 'react-native';
|
|
2
|
-
|
|
3
|
-
type SpanNumber = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12;
|
|
4
|
-
|
|
5
1
|
export type GridContextProps = {
|
|
6
2
|
/**
|
|
7
3
|
* Represents the number of columns in the grid.
|
|
@@ -28,36 +24,3 @@ export type GridContextProps = {
|
|
|
28
24
|
*/
|
|
29
25
|
getSizeSpan: (span: number) => number;
|
|
30
26
|
};
|
|
31
|
-
export interface SectionProps extends ViewProps {
|
|
32
|
-
/**
|
|
33
|
-
* Optional. If `true`, the Section component will be displayed in an expanded state.
|
|
34
|
-
* Defaults to `false` if not provided.
|
|
35
|
-
*/
|
|
36
|
-
expanded?: boolean;
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Optional. If `true`, margin will be applied to the Section component.
|
|
40
|
-
* Defaults to `false` if not provided.
|
|
41
|
-
*/
|
|
42
|
-
useMargin?: boolean;
|
|
43
|
-
|
|
44
|
-
backgroundColor?: string;
|
|
45
|
-
|
|
46
|
-
backgroundImage?: string;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export interface ItemProps extends ViewProps {
|
|
50
|
-
/**
|
|
51
|
-
* Represents the width of the Card component in terms of span numbers (1-12).
|
|
52
|
-
*/
|
|
53
|
-
widthSpan?: SpanNumber;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Optional. Represents the height of the Card component in terms of span numbers (1-12).
|
|
57
|
-
*/
|
|
58
|
-
heightSpan?: SpanNumber;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export interface CardProps extends ViewProps {
|
|
62
|
-
backgroundImage?: string;
|
|
63
|
-
}
|
package/Layout/utils.ts
CHANGED
|
@@ -62,15 +62,12 @@ const useGridSystem = () => {
|
|
|
62
62
|
);
|
|
63
63
|
|
|
64
64
|
useEffect(() => {
|
|
65
|
-
const subscription: any = Dimensions.addEventListener(
|
|
66
|
-
'
|
|
67
|
-
(
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
},
|
|
73
|
-
);
|
|
65
|
+
const subscription: any = Dimensions.addEventListener('change', () => {
|
|
66
|
+
const newColumns = Dimensions.get('window').width > 600 ? 24 : 12;
|
|
67
|
+
if (newColumns != numberOfColumns) {
|
|
68
|
+
setNumberOfColumns(newColumns);
|
|
69
|
+
}
|
|
70
|
+
});
|
|
74
71
|
return () => subscription?.remove();
|
|
75
72
|
}, []);
|
|
76
73
|
|