@momo-kits/foundation 0.77.1-optimzie.5 → 0.77.1-optimzie.7
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.
|
@@ -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} />
|
|
@@ -193,7 +193,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
|
|
|
193
193
|
headerImage = undefined;
|
|
194
194
|
}
|
|
195
195
|
if (useSurface) {
|
|
196
|
-
backgroundColor = theme.colors.background.
|
|
196
|
+
backgroundColor = theme.colors.background.surface;
|
|
197
197
|
}
|
|
198
198
|
const opacity = animatedValue?.interpolate({
|
|
199
199
|
inputRange: [0, 114],
|
|
@@ -85,11 +85,13 @@ const Modal: React.FC<ModalParams> = props => {
|
|
|
85
85
|
|
|
86
86
|
const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
87
87
|
const {theme, navigator} = useContext(ApplicationContext);
|
|
88
|
+
const insets = useSafeAreaInsets();
|
|
89
|
+
|
|
88
90
|
const {
|
|
89
91
|
screen: Screen,
|
|
90
92
|
options,
|
|
91
93
|
footerComponent,
|
|
92
|
-
|
|
94
|
+
scrollViewProps,
|
|
93
95
|
backgroundColor,
|
|
94
96
|
}: BottomSheetParams = props.route.params;
|
|
95
97
|
|
|
@@ -101,14 +103,59 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
101
103
|
};
|
|
102
104
|
|
|
103
105
|
delete params.screen;
|
|
104
|
-
const
|
|
106
|
+
const modalRef = useRef<Modalize>(null);
|
|
105
107
|
|
|
106
108
|
useEffect(() => {
|
|
107
|
-
|
|
109
|
+
modalRef.current?.open();
|
|
108
110
|
}, []);
|
|
109
111
|
|
|
110
112
|
const handleClose = () => {
|
|
111
|
-
|
|
113
|
+
modalRef?.current?.close();
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* build header
|
|
118
|
+
* @param title
|
|
119
|
+
* @param onClose
|
|
120
|
+
*/
|
|
121
|
+
const headerDefault = (title: string, onClose: () => void) => {
|
|
122
|
+
return (
|
|
123
|
+
<View
|
|
124
|
+
style={[
|
|
125
|
+
styles.header,
|
|
126
|
+
{borderBottomColor: theme.colors.border.default},
|
|
127
|
+
]}>
|
|
128
|
+
<View style={styles.iconButton} />
|
|
129
|
+
<Text
|
|
130
|
+
style={styles.textOption}
|
|
131
|
+
numberOfLines={1}
|
|
132
|
+
typography="header_default_bold">
|
|
133
|
+
{title ?? ''}
|
|
134
|
+
</Text>
|
|
135
|
+
<TouchableOpacity style={styles.iconButton} onPress={onClose}>
|
|
136
|
+
<Icon source="navigation_close" />
|
|
137
|
+
</TouchableOpacity>
|
|
138
|
+
</View>
|
|
139
|
+
);
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* build footer
|
|
144
|
+
* @param footerComponent
|
|
145
|
+
*/
|
|
146
|
+
const footerDefault = (footerComponent: React.ReactNode) => {
|
|
147
|
+
if (footerComponent) {
|
|
148
|
+
return (
|
|
149
|
+
<View
|
|
150
|
+
style={{
|
|
151
|
+
marginBottom: Math.min(insets.bottom, 21),
|
|
152
|
+
paddingHorizontal: Spacing.M,
|
|
153
|
+
paddingVertical: Spacing.S,
|
|
154
|
+
}}>
|
|
155
|
+
{footerComponent}
|
|
156
|
+
</View>
|
|
157
|
+
);
|
|
158
|
+
}
|
|
112
159
|
};
|
|
113
160
|
|
|
114
161
|
return (
|
|
@@ -121,9 +168,12 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
121
168
|
onClosed={() => {
|
|
122
169
|
navigator?.pop();
|
|
123
170
|
}}
|
|
124
|
-
|
|
125
|
-
withHandle={
|
|
126
|
-
|
|
171
|
+
handlePosition="inside"
|
|
172
|
+
withHandle={true}
|
|
173
|
+
disableScrollIfPossible={true}
|
|
174
|
+
modalTopOffset={insets.top}
|
|
175
|
+
ref={modalRef}
|
|
176
|
+
scrollViewProps={scrollViewProps}
|
|
127
177
|
HeaderComponent={headerDefault(
|
|
128
178
|
options?.title ?? options?.customTitle?.title ?? '',
|
|
129
179
|
handleClose,
|
|
@@ -140,40 +190,6 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
140
190
|
);
|
|
141
191
|
};
|
|
142
192
|
|
|
143
|
-
const headerDefault = (title: string, onClose: () => void) => {
|
|
144
|
-
return (
|
|
145
|
-
<View style={styles.header}>
|
|
146
|
-
<Text
|
|
147
|
-
style={styles.textOption}
|
|
148
|
-
numberOfLines={1}
|
|
149
|
-
typography="header_default_bold">
|
|
150
|
-
{title ?? ''}
|
|
151
|
-
</Text>
|
|
152
|
-
<TouchableOpacity style={styles.buttonClose} onPress={onClose}>
|
|
153
|
-
<Icon source="navigation_close" />
|
|
154
|
-
</TouchableOpacity>
|
|
155
|
-
</View>
|
|
156
|
-
);
|
|
157
|
-
};
|
|
158
|
-
|
|
159
|
-
const footerDefault = (footerComponent: React.ReactNode) => {
|
|
160
|
-
const insets = useSafeAreaInsets();
|
|
161
|
-
return (
|
|
162
|
-
<View
|
|
163
|
-
style={{
|
|
164
|
-
marginBottom: Math.min(insets.bottom, 21),
|
|
165
|
-
paddingHorizontal: 12,
|
|
166
|
-
}}>
|
|
167
|
-
{footerComponent && (
|
|
168
|
-
<>
|
|
169
|
-
{footerComponent}
|
|
170
|
-
<View style={{height: Spacing.S}} />
|
|
171
|
-
</>
|
|
172
|
-
)}
|
|
173
|
-
</View>
|
|
174
|
-
);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
193
|
const styles = StyleSheet.create({
|
|
178
194
|
container: {flex: 1, flexDirection: 'row'},
|
|
179
195
|
modalContent: {
|
|
@@ -214,10 +230,12 @@ const styles = StyleSheet.create({
|
|
|
214
230
|
width: '100%',
|
|
215
231
|
},
|
|
216
232
|
header: {
|
|
217
|
-
|
|
233
|
+
marginTop: 10,
|
|
234
|
+
height: 56,
|
|
218
235
|
width: '100%',
|
|
219
236
|
alignItems: 'center',
|
|
220
|
-
|
|
237
|
+
flexDirection: 'row',
|
|
238
|
+
borderBottomWidth: 1,
|
|
221
239
|
},
|
|
222
240
|
textOption: {
|
|
223
241
|
fontSize: 16,
|
|
@@ -225,12 +243,14 @@ const styles = StyleSheet.create({
|
|
|
225
243
|
textAlign: 'center',
|
|
226
244
|
fontWeight: 'bold',
|
|
227
245
|
paddingHorizontal: Spacing.L,
|
|
246
|
+
flex: 1,
|
|
228
247
|
},
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
248
|
+
iconButton: {
|
|
249
|
+
width: 24,
|
|
250
|
+
height: 24,
|
|
251
|
+
alignItems: 'center',
|
|
252
|
+
justifyContent: 'center',
|
|
253
|
+
marginHorizontal: Spacing.M,
|
|
234
254
|
},
|
|
235
255
|
icon: {
|
|
236
256
|
width: 24,
|
package/Application/types.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {StackNavigationOptions} from '@react-navigation/stack';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import {Animated,
|
|
3
|
+
import {Animated, ScrollViewProps, ViewProps} from 'react-native';
|
|
4
4
|
import {PopupNotifyProps} from '../Popup/types';
|
|
5
5
|
import Navigation from './Navigation';
|
|
6
6
|
import Navigator from './Navigator';
|
|
@@ -121,7 +121,7 @@ export interface BottomSheetParams extends ScreenParams {
|
|
|
121
121
|
onDismiss?: () => void;
|
|
122
122
|
backgroundColor?: string;
|
|
123
123
|
footerComponent?: React.ReactNode;
|
|
124
|
-
|
|
124
|
+
scrollViewProps?: ScrollViewProps;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
export type NavigationButtonProps = {
|
|
@@ -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) {
|