@momo-kits/foundation 0.77.1-optimzie.4 → 0.77.1-optimzie.6
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/BottomTabBar.tsx +9 -13
- package/Application/BottomTab/index.tsx +14 -10
- package/Application/Components.tsx +7 -4
- package/Application/ModalScreen.tsx +19 -22
- package/Application/types.ts +3 -2
- package/Application/utils.tsx +1 -5
- package/Button/index.tsx +5 -5
- package/Input/InputMoney.tsx +0 -1
- package/Input/common.tsx +0 -7
- package/Input/index.tsx +7 -0
- package/Layout/FloatingButton.tsx +1 -1
- package/Layout/Screen.tsx +21 -10
- package/package.json +1 -1
|
@@ -293,21 +293,19 @@ export default function BottomTabBar({
|
|
|
293
293
|
);
|
|
294
294
|
|
|
295
295
|
const renderCenterComponent = useCallback(() => {
|
|
296
|
-
const renderFloatingButton = () => {
|
|
297
|
-
if (typeof floatingButton?.icon == 'string') {
|
|
298
|
-
return <Icon source={floatingButton?.icon} size={32} color={'white'} />;
|
|
299
|
-
} else if (floatingButton?.icon) {
|
|
300
|
-
return floatingButton?.icon;
|
|
301
|
-
} else {
|
|
302
|
-
return null;
|
|
303
|
-
}
|
|
304
|
-
};
|
|
305
296
|
if (floatingButton?.icon && state.routes.length !== 4) {
|
|
306
297
|
console.warn(
|
|
307
298
|
"Can't render floating button with icon when routes length is not 4",
|
|
308
299
|
);
|
|
309
300
|
return null;
|
|
310
301
|
}
|
|
302
|
+
const renderFloatingButton = () => {
|
|
303
|
+
if (typeof floatingButton?.icon == 'string') {
|
|
304
|
+
return <Icon source={floatingButton?.icon} size={32} color={'white'} />;
|
|
305
|
+
}
|
|
306
|
+
return floatingButton?.icon;
|
|
307
|
+
};
|
|
308
|
+
|
|
311
309
|
return (
|
|
312
310
|
<View style={{flex: 1}}>
|
|
313
311
|
<TouchableOpacity
|
|
@@ -370,8 +368,6 @@ export default function BottomTabBar({
|
|
|
370
368
|
}),
|
|
371
369
|
},
|
|
372
370
|
],
|
|
373
|
-
// Absolutely position the tab bar so that the content is below it
|
|
374
|
-
// This is needed to avoid gap at bottom when the tab bar is hidden
|
|
375
371
|
position: isTabBarHidden ? 'absolute' : (null as any),
|
|
376
372
|
},
|
|
377
373
|
{
|
|
@@ -430,8 +426,8 @@ const styles = StyleSheet.create({
|
|
|
430
426
|
justifyContent: 'center',
|
|
431
427
|
height: 48,
|
|
432
428
|
width: 48,
|
|
433
|
-
borderRadius:
|
|
434
|
-
top: -
|
|
429
|
+
borderRadius: 24,
|
|
430
|
+
top: -10,
|
|
435
431
|
},
|
|
436
432
|
indicator: {
|
|
437
433
|
height: 2,
|
|
@@ -10,21 +10,26 @@ import {Text} from '../../Text';
|
|
|
10
10
|
import {ApplicationContext} from '../index';
|
|
11
11
|
import StackScreen from '../StackScreen';
|
|
12
12
|
import {BottomTabProps, NavigationScreenProps} from '../types';
|
|
13
|
-
import {getStackOptions} from '../utils';
|
|
13
|
+
import {getOptions, getStackOptions} from '../utils';
|
|
14
14
|
import BottomTabBar from './BottomTabBar';
|
|
15
15
|
|
|
16
16
|
const Tab = createBottomTabNavigator();
|
|
17
17
|
const Stack = createStackNavigator();
|
|
18
18
|
|
|
19
19
|
const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
|
|
20
|
+
const {theme} = useContext(ApplicationContext);
|
|
21
|
+
let options = {};
|
|
22
|
+
if (route.params?.options) {
|
|
23
|
+
options = getOptions(route.params?.options, theme);
|
|
24
|
+
}
|
|
20
25
|
if (route.params?.nested) {
|
|
21
26
|
return (
|
|
22
27
|
<Stack.Navigator>
|
|
23
28
|
<Stack.Screen
|
|
24
29
|
name="Stack"
|
|
25
30
|
component={StackScreen}
|
|
26
|
-
initialParams={{screen: route.params?.screen}}
|
|
27
|
-
options={{...getStackOptions()
|
|
31
|
+
initialParams={{screen: route.params?.screen, options}}
|
|
32
|
+
options={{...getStackOptions()}}
|
|
28
33
|
/>
|
|
29
34
|
</Stack.Navigator>
|
|
30
35
|
);
|
|
@@ -35,7 +40,7 @@ const TabScreen: React.FC<NavigationScreenProps> = ({route}) => {
|
|
|
35
40
|
<Stack.Screen
|
|
36
41
|
name="Stack"
|
|
37
42
|
component={StackScreen}
|
|
38
|
-
initialParams={{screen: route.params?.screen}}
|
|
43
|
+
initialParams={{screen: route.params?.screen, options}}
|
|
39
44
|
options={{...getStackOptions(), ...route.params?.options}}
|
|
40
45
|
/>
|
|
41
46
|
</Stack.Navigator>
|
|
@@ -83,6 +88,8 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
83
88
|
},
|
|
84
89
|
}}>
|
|
85
90
|
{tabs.map(item => {
|
|
91
|
+
const isNum = !isNaN(parseInt(`${item?.badgeLabel}`));
|
|
92
|
+
const isDot = typeof item?.badgeLabel == 'string' && !item?.badgeLabel;
|
|
86
93
|
return (
|
|
87
94
|
<Tab.Screen
|
|
88
95
|
key={item.name}
|
|
@@ -113,12 +120,9 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
113
120
|
fontWeight: 'bold',
|
|
114
121
|
alignSelf: 'center',
|
|
115
122
|
fontFamily: `${theme.font}-Bold`,
|
|
116
|
-
left:
|
|
117
|
-
top:
|
|
118
|
-
backgroundColor:
|
|
119
|
-
typeof item?.badgeLabel === 'string'
|
|
120
|
-
? Colors.orange_03
|
|
121
|
-
: Colors.red_03,
|
|
123
|
+
left: isDot ? 8 : 4,
|
|
124
|
+
top: isDot ? -2 : -6,
|
|
125
|
+
backgroundColor: isNum ? Colors.orange_03 : Colors.red_03,
|
|
122
126
|
},
|
|
123
127
|
tabBarIcon: ({color}) => (
|
|
124
128
|
<Icon source={item.icon} color={color} size={28} />
|
|
@@ -183,15 +183,18 @@ const HeaderLeft: React.FC<HeaderBackProps> = ({
|
|
|
183
183
|
|
|
184
184
|
const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
185
185
|
image,
|
|
186
|
-
backgroundColor,
|
|
187
186
|
animatedValue,
|
|
188
|
-
|
|
187
|
+
useSurface = false,
|
|
189
188
|
}) => {
|
|
190
189
|
const {theme} = useContext(ApplicationContext);
|
|
191
190
|
let headerImage = theme.assets?.headerBackground;
|
|
191
|
+
let backgroundColor;
|
|
192
192
|
if (image === null) {
|
|
193
193
|
headerImage = undefined;
|
|
194
194
|
}
|
|
195
|
+
if (useSurface) {
|
|
196
|
+
backgroundColor = theme.colors.background.surface;
|
|
197
|
+
}
|
|
195
198
|
const opacity = animatedValue?.interpolate({
|
|
196
199
|
inputRange: [0, 114],
|
|
197
200
|
outputRange: [0, 1],
|
|
@@ -203,9 +206,9 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
203
206
|
style={[
|
|
204
207
|
Styles.flex,
|
|
205
208
|
{
|
|
206
|
-
backgroundColor
|
|
209
|
+
backgroundColor,
|
|
207
210
|
overflow: 'hidden',
|
|
208
|
-
borderBottomWidth:
|
|
211
|
+
borderBottomWidth: useSurface ? 1 : 0,
|
|
209
212
|
borderColor: theme.colors.border.default,
|
|
210
213
|
opacity,
|
|
211
214
|
},
|
|
@@ -90,6 +90,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
90
90
|
options,
|
|
91
91
|
footerComponent,
|
|
92
92
|
flatListProps,
|
|
93
|
+
backgroundColor,
|
|
93
94
|
}: BottomSheetParams = props.route.params;
|
|
94
95
|
|
|
95
96
|
const navigation = new Navigation(props.navigation, theme);
|
|
@@ -127,6 +128,9 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
127
128
|
options?.title ?? options?.customTitle?.title ?? '',
|
|
128
129
|
handleClose,
|
|
129
130
|
)}
|
|
131
|
+
modalStyle={{
|
|
132
|
+
backgroundColor: backgroundColor ?? theme.colors.background.surface,
|
|
133
|
+
}}
|
|
130
134
|
FooterComponent={footerDefault(footerComponent)}>
|
|
131
135
|
<View style={styles.bottomSheetContainer}>
|
|
132
136
|
<Screen {...props} {...params} />
|
|
@@ -141,7 +145,7 @@ const headerDefault = (title: string, onClose: () => void) => {
|
|
|
141
145
|
<View style={styles.header}>
|
|
142
146
|
<Text
|
|
143
147
|
style={styles.textOption}
|
|
144
|
-
numberOfLines={
|
|
148
|
+
numberOfLines={1}
|
|
145
149
|
typography="header_default_bold">
|
|
146
150
|
{title ?? ''}
|
|
147
151
|
</Text>
|
|
@@ -154,16 +158,18 @@ const headerDefault = (title: string, onClose: () => void) => {
|
|
|
154
158
|
|
|
155
159
|
const footerDefault = (footerComponent: React.ReactNode) => {
|
|
156
160
|
const insets = useSafeAreaInsets();
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
161
|
+
if (footerComponent) {
|
|
162
|
+
return (
|
|
163
|
+
<View
|
|
164
|
+
style={{
|
|
165
|
+
marginBottom: Math.min(insets.bottom, 21),
|
|
166
|
+
paddingHorizontal: Spacing.M,
|
|
167
|
+
paddingVertical: Spacing.S,
|
|
168
|
+
}}>
|
|
169
|
+
{footerComponent}
|
|
170
|
+
</View>
|
|
171
|
+
);
|
|
172
|
+
}
|
|
167
173
|
};
|
|
168
174
|
|
|
169
175
|
const styles = StyleSheet.create({
|
|
@@ -204,9 +210,6 @@ const styles = StyleSheet.create({
|
|
|
204
210
|
},
|
|
205
211
|
bottomSheetContainer: {
|
|
206
212
|
width: '100%',
|
|
207
|
-
backgroundColor: 'white',
|
|
208
|
-
borderTopRightRadius: 16,
|
|
209
|
-
borderTopLeftRadius: 16,
|
|
210
213
|
},
|
|
211
214
|
header: {
|
|
212
215
|
height: 50,
|
|
@@ -219,15 +222,9 @@ const styles = StyleSheet.create({
|
|
|
219
222
|
color: '#303233',
|
|
220
223
|
textAlign: 'center',
|
|
221
224
|
fontWeight: 'bold',
|
|
222
|
-
paddingHorizontal:
|
|
223
|
-
},
|
|
224
|
-
imageOption: {
|
|
225
|
-
height: 1,
|
|
226
|
-
backgroundColor: '#ebebeb',
|
|
227
|
-
width: '100%',
|
|
228
|
-
position: 'absolute',
|
|
229
|
-
bottom: 1,
|
|
225
|
+
paddingHorizontal: Spacing.L,
|
|
230
226
|
},
|
|
227
|
+
|
|
231
228
|
buttonClose: {
|
|
232
229
|
padding: 12,
|
|
233
230
|
position: 'absolute',
|
package/Application/types.ts
CHANGED
|
@@ -119,6 +119,7 @@ export interface ModalParams extends ScreenParams {
|
|
|
119
119
|
export interface BottomSheetParams extends ScreenParams {
|
|
120
120
|
[key: string]: any;
|
|
121
121
|
onDismiss?: () => void;
|
|
122
|
+
backgroundColor?: string;
|
|
122
123
|
footerComponent?: React.ReactNode;
|
|
123
124
|
flatListProps?: FlatListProps<any>;
|
|
124
125
|
}
|
|
@@ -165,9 +166,8 @@ export interface HeaderBackProps extends NavigationButtonProps {
|
|
|
165
166
|
|
|
166
167
|
export type HeaderBackgroundProps = {
|
|
167
168
|
image?: string | null;
|
|
168
|
-
backgroundColor?: string | null;
|
|
169
169
|
animatedValue?: Animated.Value;
|
|
170
|
-
|
|
170
|
+
useSurface?: boolean;
|
|
171
171
|
};
|
|
172
172
|
|
|
173
173
|
export type TitleCustomProps = {
|
|
@@ -223,4 +223,5 @@ export type FloatingButtonProps = {
|
|
|
223
223
|
export type AnimatedHeader = {
|
|
224
224
|
type: 'default' | 'surface';
|
|
225
225
|
component?: (props?: any) => React.ReactElement;
|
|
226
|
+
headerTitle?: (props?: any) => React.ReactElement;
|
|
226
227
|
};
|
package/Application/utils.tsx
CHANGED
|
@@ -100,11 +100,7 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
|
|
|
100
100
|
...options,
|
|
101
101
|
headerTintColor: theme.colors.text.default,
|
|
102
102
|
headerBackground: () => (
|
|
103
|
-
<HeaderBackground
|
|
104
|
-
image={null}
|
|
105
|
-
backgroundColor={theme.colors.background.surface}
|
|
106
|
-
useBorder={true}
|
|
107
|
-
/>
|
|
103
|
+
<HeaderBackground image={null} useSurface={true} />
|
|
108
104
|
),
|
|
109
105
|
};
|
|
110
106
|
} else {
|
package/Button/index.tsx
CHANGED
|
@@ -58,7 +58,7 @@ export interface ButtonProps extends TouchableOpacityProps {
|
|
|
58
58
|
/**
|
|
59
59
|
* If true, the icon of button will use the tint color provided by its container.
|
|
60
60
|
*/
|
|
61
|
-
|
|
61
|
+
tintColor?: string;
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* If true, the icon of button will use be show indicator loading.
|
|
@@ -76,7 +76,7 @@ export interface ButtonProps extends TouchableOpacityProps {
|
|
|
76
76
|
const Button: FC<ButtonProps> = ({
|
|
77
77
|
type = 'primary',
|
|
78
78
|
size = 'large',
|
|
79
|
-
|
|
79
|
+
tintColor = null,
|
|
80
80
|
full = true,
|
|
81
81
|
iconRight,
|
|
82
82
|
iconLeft,
|
|
@@ -231,7 +231,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
231
231
|
const renderLeading = () => {
|
|
232
232
|
const iconSize = getIconSize();
|
|
233
233
|
const marginRight = getIconSpace();
|
|
234
|
-
const color =
|
|
234
|
+
const color = tintColor ?? getTextColor();
|
|
235
235
|
|
|
236
236
|
if (loading) {
|
|
237
237
|
return (
|
|
@@ -245,7 +245,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
245
245
|
borderRadius: Spacing.M,
|
|
246
246
|
},
|
|
247
247
|
]}>
|
|
248
|
-
<Loader type="spinner" color={
|
|
248
|
+
<Loader type="spinner" color={getTextColor()} />
|
|
249
249
|
</View>
|
|
250
250
|
);
|
|
251
251
|
}
|
|
@@ -266,7 +266,7 @@ const Button: FC<ButtonProps> = ({
|
|
|
266
266
|
* render trailing
|
|
267
267
|
*/
|
|
268
268
|
const renderTrailing = () => {
|
|
269
|
-
const color =
|
|
269
|
+
const color = tintColor ?? getTextColor();
|
|
270
270
|
const marginLeft = getIconSpace();
|
|
271
271
|
|
|
272
272
|
if (iconRight) {
|
package/Input/InputMoney.tsx
CHANGED
package/Input/common.tsx
CHANGED
|
@@ -16,13 +16,6 @@ type FloatingViewProps = {
|
|
|
16
16
|
style?: ViewStyle;
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
export interface InputRef {
|
|
20
|
-
focus: () => void;
|
|
21
|
-
blur: () => void;
|
|
22
|
-
clear: () => void;
|
|
23
|
-
setText: (text: string) => void;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
19
|
export const DEFAULT_HEIGHT = scaleSize(104);
|
|
27
20
|
export const MAX_LENGTH = 300;
|
|
28
21
|
|
package/Input/index.tsx
CHANGED
|
@@ -6,6 +6,13 @@ import InputOTP from './InputOTP';
|
|
|
6
6
|
import InputSearch from './InputSearch';
|
|
7
7
|
import InputTextArea from './InputTextArea';
|
|
8
8
|
|
|
9
|
+
export interface InputRef {
|
|
10
|
+
focus: () => void;
|
|
11
|
+
blur: () => void;
|
|
12
|
+
clear: () => void;
|
|
13
|
+
setText: (text: string) => void;
|
|
14
|
+
}
|
|
15
|
+
|
|
9
16
|
export interface InputProps extends TextInputProps {
|
|
10
17
|
/**
|
|
11
18
|
* Optional. Defines the size of the Input component.
|
|
@@ -45,7 +45,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
45
45
|
if (!label) return;
|
|
46
46
|
|
|
47
47
|
const listener = animatedValue?.addListener(({value}) => {
|
|
48
|
-
if (value !== lastOffset.current) {
|
|
48
|
+
if (value !== lastOffset.current && value > 0) {
|
|
49
49
|
const direction = value > lastOffset.current ? 'down' : 'up';
|
|
50
50
|
lastOffset.current = value;
|
|
51
51
|
if (lastDirection.current !== direction) {
|
package/Layout/Screen.tsx
CHANGED
|
@@ -89,6 +89,10 @@ export interface ScreenProps extends ViewProps {
|
|
|
89
89
|
*/
|
|
90
90
|
floatingButtonProps?: Omit<FloatingButtonProps, 'animatedValue' | 'bottom'>;
|
|
91
91
|
|
|
92
|
+
/**
|
|
93
|
+
* optional animated value
|
|
94
|
+
*/
|
|
95
|
+
animatedValue?: Animated.Value;
|
|
92
96
|
/**
|
|
93
97
|
* Optional. If `true`, the screen content is using grid layout by span.
|
|
94
98
|
*/
|
|
@@ -111,10 +115,13 @@ const Screen = forwardRef(
|
|
|
111
115
|
headerType = 'default',
|
|
112
116
|
floatingButtonProps,
|
|
113
117
|
useGridLayout = true,
|
|
118
|
+
animatedValue: animated,
|
|
114
119
|
}: ScreenProps,
|
|
115
120
|
ref,
|
|
116
121
|
) => {
|
|
117
|
-
const animatedValue = useRef<Animated.Value>(
|
|
122
|
+
const animatedValue = useRef<Animated.Value>(
|
|
123
|
+
animated ?? new Animated.Value(0),
|
|
124
|
+
);
|
|
118
125
|
const {theme} = useContext(ApplicationContext);
|
|
119
126
|
const insets = useSafeAreaInsets();
|
|
120
127
|
const heightHeader = useHeaderHeight();
|
|
@@ -151,18 +158,27 @@ const Screen = forwardRef(
|
|
|
151
158
|
};
|
|
152
159
|
if (animatedHeader.type == 'surface') {
|
|
153
160
|
styleAnimatedHeader = {
|
|
154
|
-
|
|
161
|
+
...styleAnimatedHeader,
|
|
155
162
|
headerBackground: (props: any) => (
|
|
156
163
|
<HeaderBackground
|
|
157
164
|
{...props}
|
|
158
165
|
image={null}
|
|
159
|
-
|
|
160
|
-
useBorder={true}
|
|
166
|
+
useSurface={true}
|
|
161
167
|
animatedValue={animatedValue.current}
|
|
162
168
|
/>
|
|
163
169
|
),
|
|
164
170
|
};
|
|
165
171
|
}
|
|
172
|
+
if (animatedHeader.headerTitle) {
|
|
173
|
+
styleAnimatedHeader = {
|
|
174
|
+
...styleAnimatedHeader,
|
|
175
|
+
headerTitle: (props: any) =>
|
|
176
|
+
animatedHeader.headerTitle?.({
|
|
177
|
+
...props,
|
|
178
|
+
animatedValue: animatedValue.current,
|
|
179
|
+
}),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
166
182
|
navigation?.setOptions(styleAnimatedHeader);
|
|
167
183
|
}
|
|
168
184
|
}, [animatedHeader]);
|
|
@@ -185,12 +201,7 @@ const Screen = forwardRef(
|
|
|
185
201
|
headerShown: true,
|
|
186
202
|
headerTintColor: theme.colors.text.default,
|
|
187
203
|
headerBackground: (props: any) => (
|
|
188
|
-
<HeaderBackground
|
|
189
|
-
{...props}
|
|
190
|
-
image={null}
|
|
191
|
-
backgroundColor={theme.colors.background.surface}
|
|
192
|
-
useBorder={true}
|
|
193
|
-
/>
|
|
204
|
+
<HeaderBackground {...props} image={null} useSurface={true} />
|
|
194
205
|
),
|
|
195
206
|
headerTitle: (props: any) => <HeaderTitle {...props} />,
|
|
196
207
|
};
|