@momo-kits/foundation 0.162.3-test.2 → 0.163.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/Application/NavigationContainer.tsx +17 -55
- package/Application/ScaleSizeProvider.tsx +4 -5
- package/Application/WidgetContainer.tsx +9 -6
- package/Application/types.ts +1 -2
- package/Context/index.ts +4 -6
- package/IconButton/index.tsx +28 -6
- package/IconButton/styles.ts +15 -7
- package/Input/Input.tsx +12 -1
- package/Input/InputPhoneNumber.tsx +12 -1
- package/Layout/Screen.tsx +27 -2
- package/Text/utils.ts +9 -11
- package/package.json +3 -3
|
@@ -16,10 +16,9 @@ import { DeviceEventEmitter } from 'react-native';
|
|
|
16
16
|
import StackScreen from './StackScreen';
|
|
17
17
|
import ModalScreen from './ModalScreen';
|
|
18
18
|
import Navigator from './Navigator';
|
|
19
|
-
import ScaleSizeProvider from './ScaleSizeProvider';
|
|
20
19
|
import { getModalOptions, getStackOptions } from './utils';
|
|
21
20
|
import { NavigationContainerProps } from './types';
|
|
22
|
-
import { ApplicationContext,
|
|
21
|
+
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
23
22
|
import Localize from './Localize';
|
|
24
23
|
import { Colors, defaultTheme } from '../Consts';
|
|
25
24
|
import { HeaderLeft } from './Components/HeaderLeft';
|
|
@@ -29,29 +28,6 @@ import { HeaderBackground } from './Components/HeaderBackground';
|
|
|
29
28
|
|
|
30
29
|
const Stack = createStackNavigator();
|
|
31
30
|
|
|
32
|
-
const FONT_SCALE_OBSERVER_KEY = 'font_scale_config';
|
|
33
|
-
|
|
34
|
-
// AI-GENERATED START: parse the font_scale_config first-frame seed read straight from async storage (string | {response} | object)
|
|
35
|
-
const parseSeedFontScaleConfig = (raw: any): FontScaleConfig | undefined => {
|
|
36
|
-
let data = raw;
|
|
37
|
-
if (typeof data === 'string') {
|
|
38
|
-
try {
|
|
39
|
-
data = JSON.parse(data);
|
|
40
|
-
} catch {
|
|
41
|
-
return undefined;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
data = data?.response ?? data;
|
|
45
|
-
if (!data || (data.useOSFontScale === undefined && data.userScaleRate === undefined)) {
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
return {
|
|
49
|
-
useOSFontScale: data.useOSFontScale,
|
|
50
|
-
userScaleRate: data.userScaleRate,
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
// AI-GENERATED END: parse the font_scale_config first-frame seed read straight from async storage (string | {response} | object)
|
|
54
|
-
|
|
55
31
|
const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
56
32
|
screen,
|
|
57
33
|
theme = defaultTheme,
|
|
@@ -68,11 +44,13 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
68
44
|
}) => {
|
|
69
45
|
const context = useContext<any>(MiniAppContext);
|
|
70
46
|
const [currentContext, setCurrentContext] = useState<any>({});
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
const sub = maxApi?.observer?.('font_scale_config', (data: any) => {
|
|
50
|
+
setCurrentContext((prev: any) => ({ ...prev, fontScale: data }));
|
|
51
|
+
});
|
|
52
|
+
return () => sub?.remove?.();
|
|
53
|
+
}, [maxApi]);
|
|
76
54
|
|
|
77
55
|
const mergedContext = {
|
|
78
56
|
...context,
|
|
@@ -83,34 +61,18 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
83
61
|
},
|
|
84
62
|
};
|
|
85
63
|
|
|
86
|
-
useEffect(() => {
|
|
87
|
-
const sub = maxApi?.observer?.(
|
|
88
|
-
FONT_SCALE_OBSERVER_KEY,
|
|
89
|
-
(data: FontScaleConfig) => {
|
|
90
|
-
setObserverFontScaleConfig(data ?? undefined);
|
|
91
|
-
},
|
|
92
|
-
);
|
|
93
|
-
return () => {
|
|
94
|
-
sub?.remove?.();
|
|
95
|
-
};
|
|
96
|
-
}, [maxApi]);
|
|
97
|
-
|
|
98
64
|
return (
|
|
99
65
|
<SafeAreaProvider>
|
|
100
66
|
<MiniAppContext.Provider value={mergedContext}>
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
initialParams={initialParams}
|
|
111
|
-
localize={localize}
|
|
112
|
-
/>
|
|
113
|
-
</ScaleSizeProvider>
|
|
67
|
+
<Navigation
|
|
68
|
+
screen={screen}
|
|
69
|
+
theme={theme}
|
|
70
|
+
options={options}
|
|
71
|
+
maxApi={maxApi}
|
|
72
|
+
setCurrentContext={setCurrentContext}
|
|
73
|
+
initialParams={initialParams}
|
|
74
|
+
localize={localize}
|
|
75
|
+
/>
|
|
114
76
|
</MiniAppContext.Provider>
|
|
115
77
|
</SafeAreaProvider>
|
|
116
78
|
);
|
|
@@ -1,15 +1,14 @@
|
|
|
1
|
-
import React, { FC
|
|
1
|
+
import React, { FC } from 'react';
|
|
2
2
|
import { ScaleSizeContext } from '../Context';
|
|
3
3
|
import { ScaleSizeProviderProps } from './types';
|
|
4
4
|
|
|
5
|
+
/** @deprecated Max font scale is fixed at 1.5; this provider no longer affects scaling. */
|
|
5
6
|
const ScaleSizeProvider: FC<ScaleSizeProviderProps> = ({
|
|
6
|
-
|
|
7
|
+
scaleSizeMaxRate,
|
|
7
8
|
children,
|
|
8
9
|
}) => {
|
|
9
|
-
// Inherit the config from an upper layer (e.g. app root) when the host doesn't set it via MiniAppContext.
|
|
10
|
-
const parent = useContext(ScaleSizeContext);
|
|
11
10
|
return (
|
|
12
|
-
<ScaleSizeContext.Provider value={
|
|
11
|
+
<ScaleSizeContext.Provider value={{ scaleSizeMaxRate }}>
|
|
13
12
|
{children}
|
|
14
13
|
</ScaleSizeContext.Provider>
|
|
15
14
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useContext, useRef, useState } from 'react';
|
|
1
|
+
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
3
3
|
import Navigator from './Navigator';
|
|
4
4
|
import ScaleSizeProvider from './ScaleSizeProvider';
|
|
@@ -44,6 +44,13 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
44
44
|
const navigator = useRef(new Navigator(navigationRef, isReady, true));
|
|
45
45
|
const [currentContext, setCurrentContext] = useState({});
|
|
46
46
|
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
const sub = maxApi?.observer?.('font_scale_config', (data: any) => {
|
|
49
|
+
setCurrentContext((prev: any) => ({ ...prev, fontScale: data }));
|
|
50
|
+
});
|
|
51
|
+
return () => sub?.remove?.();
|
|
52
|
+
}, [maxApi]);
|
|
53
|
+
|
|
47
54
|
let headerBackground = context?.designConfig?.headerBar;
|
|
48
55
|
let headerGradient = theme.colors?.gradient;
|
|
49
56
|
|
|
@@ -74,12 +81,9 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
74
81
|
};
|
|
75
82
|
|
|
76
83
|
return (
|
|
77
|
-
<View style={{ height: height ?? '100%', minHeight:1 }}>
|
|
84
|
+
<View style={{ height: height ?? '100%', minHeight: 1 }}>
|
|
78
85
|
<SafeAreaProvider>
|
|
79
86
|
<MiniAppContext.Provider value={mergedContext}>
|
|
80
|
-
<ScaleSizeProvider
|
|
81
|
-
fontScaleConfig={mergedContext?.fontScaleConfig}
|
|
82
|
-
>
|
|
83
87
|
<ApplicationContext.Provider
|
|
84
88
|
value={{
|
|
85
89
|
navigator: navigator.current,
|
|
@@ -157,7 +161,6 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
157
161
|
</ReactNavigationContainer>
|
|
158
162
|
</NavigationIndependentTree>
|
|
159
163
|
</ApplicationContext.Provider>
|
|
160
|
-
</ScaleSizeProvider>
|
|
161
164
|
</MiniAppContext.Provider>
|
|
162
165
|
</SafeAreaProvider>
|
|
163
166
|
</View>
|
package/Application/types.ts
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
import type { SharedValue } from 'react-native-reanimated';
|
|
11
11
|
import { PopupNotifyProps } from '../Popup/types';
|
|
12
12
|
import { InputRef, InputSearchProps } from '../Input';
|
|
13
|
-
import { FontScaleConfig } from '../Context';
|
|
14
13
|
import Navigation from './Navigation';
|
|
15
14
|
|
|
16
15
|
export type NavigationProps = {
|
|
@@ -110,7 +109,7 @@ export type Theme = {
|
|
|
110
109
|
};
|
|
111
110
|
|
|
112
111
|
export type ScaleSizeProviderProps = {
|
|
113
|
-
|
|
112
|
+
scaleSizeMaxRate?: number;
|
|
114
113
|
children: ViewProps['children'];
|
|
115
114
|
};
|
|
116
115
|
|
package/Context/index.ts
CHANGED
|
@@ -9,12 +9,10 @@ const MiniAppContext = (Platform as any).MiniAppContext ?? Context;
|
|
|
9
9
|
const ScreenContext = (Platform as any).ScreenContext ?? Context;
|
|
10
10
|
const ComponentContext = (Platform as any).ComponentContext ?? Context;
|
|
11
11
|
const SkeletonContext = createContext({ loading: false });
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
};
|
|
17
|
-
const ScaleSizeContext = createContext<FontScaleConfig>({});
|
|
12
|
+
/** @deprecated Max font scale is fixed at 1.5; this context is no longer read. */
|
|
13
|
+
const ScaleSizeContext = createContext<{ scaleSizeMaxRate?: number }>({
|
|
14
|
+
scaleSizeMaxRate: undefined,
|
|
15
|
+
});
|
|
18
16
|
const TrackingScopeContext = createContext<{ scopeName?: string }>({
|
|
19
17
|
scopeName: undefined,
|
|
20
18
|
});
|
package/IconButton/index.tsx
CHANGED
|
@@ -28,7 +28,12 @@ export interface IconButtonProps extends TouchableOpacityProps {
|
|
|
28
28
|
/**
|
|
29
29
|
* Optional. Defines the size of the IconButton.
|
|
30
30
|
*/
|
|
31
|
-
size?: 'large' | 'small';
|
|
31
|
+
size?: 'large' | 'medium' | 'small';
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Optional. Defines the shape of the IconButton.
|
|
35
|
+
*/
|
|
36
|
+
shape?: 'circle' | 'square';
|
|
32
37
|
|
|
33
38
|
/**
|
|
34
39
|
* Optional. Params auto tracking component.
|
|
@@ -40,6 +45,7 @@ const IconButton: React.FC<IconButtonProps> = ({
|
|
|
40
45
|
type = 'primary',
|
|
41
46
|
icon,
|
|
42
47
|
size,
|
|
48
|
+
shape = 'circle',
|
|
43
49
|
params,
|
|
44
50
|
...rest
|
|
45
51
|
}) => {
|
|
@@ -52,10 +58,21 @@ const IconButton: React.FC<IconButtonProps> = ({
|
|
|
52
58
|
* get size icon button
|
|
53
59
|
*/
|
|
54
60
|
const getSizeStyle = () => {
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
switch (size) {
|
|
62
|
+
case 'small':
|
|
63
|
+
return styles.small;
|
|
64
|
+
case 'medium':
|
|
65
|
+
return styles.medium;
|
|
66
|
+
default:
|
|
67
|
+
return styles.large;
|
|
57
68
|
}
|
|
58
|
-
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* get shape icon button
|
|
73
|
+
*/
|
|
74
|
+
const getShapeStyle = () => {
|
|
75
|
+
return shape === 'square' ? styles.square : styles.circle;
|
|
59
76
|
};
|
|
60
77
|
|
|
61
78
|
/**
|
|
@@ -117,8 +134,13 @@ const IconButton: React.FC<IconButtonProps> = ({
|
|
|
117
134
|
};
|
|
118
135
|
|
|
119
136
|
const activeOpacity = type === 'disabled' ? 0.75 : 0.5;
|
|
120
|
-
const buttonStyle = StyleSheet.flatten([
|
|
121
|
-
|
|
137
|
+
const buttonStyle = StyleSheet.flatten([
|
|
138
|
+
getTypeStyle(),
|
|
139
|
+
styles.base,
|
|
140
|
+
getSizeStyle(),
|
|
141
|
+
getShapeStyle(),
|
|
142
|
+
]);
|
|
143
|
+
const iconSize = size === 'small' || size === 'medium' ? 16 : 24;
|
|
122
144
|
|
|
123
145
|
return (
|
|
124
146
|
<ComponentContext.Provider
|
package/IconButton/styles.ts
CHANGED
|
@@ -2,19 +2,27 @@ import { StyleSheet } from 'react-native';
|
|
|
2
2
|
import { Radius, Colors } from '../Consts';
|
|
3
3
|
|
|
4
4
|
export default StyleSheet.create({
|
|
5
|
+
base: {
|
|
6
|
+
justifyContent: 'center',
|
|
7
|
+
alignItems: 'center',
|
|
8
|
+
},
|
|
5
9
|
large: {
|
|
6
10
|
width: 48,
|
|
7
11
|
height: 48,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
},
|
|
13
|
+
medium: {
|
|
14
|
+
width: 36,
|
|
15
|
+
height: 36,
|
|
11
16
|
},
|
|
12
17
|
small: {
|
|
13
|
-
width:
|
|
14
|
-
height:
|
|
18
|
+
width: 28,
|
|
19
|
+
height: 28,
|
|
20
|
+
},
|
|
21
|
+
circle: {
|
|
15
22
|
borderRadius: Radius.XL,
|
|
16
|
-
|
|
17
|
-
|
|
23
|
+
},
|
|
24
|
+
square: {
|
|
25
|
+
borderRadius: Radius.S,
|
|
18
26
|
},
|
|
19
27
|
debugBaseLine: { borderWidth: 1, borderColor: Colors.green_06 },
|
|
20
28
|
});
|
package/Input/Input.tsx
CHANGED
|
@@ -77,7 +77,8 @@ const Input = forwardRef(
|
|
|
77
77
|
const scaledFontSize = useScaleSize(14);
|
|
78
78
|
const scaleHeight = useScaleSize(size === 'small' ? 48 : 56);
|
|
79
79
|
const [focused, setFocused] = useState(false);
|
|
80
|
-
const
|
|
80
|
+
const [internalText, setInternalText] = useState(defaultValue || '');
|
|
81
|
+
const haveValue = value !== undefined ? !!value : !!internalText;
|
|
81
82
|
const inputRef = useRef<TextInput | null>(null);
|
|
82
83
|
const componentName = 'Input';
|
|
83
84
|
|
|
@@ -95,6 +96,9 @@ const Input = forwardRef(
|
|
|
95
96
|
};
|
|
96
97
|
|
|
97
98
|
const _onChangeText = (text: string) => {
|
|
99
|
+
if (value === undefined) {
|
|
100
|
+
setInternalText(text);
|
|
101
|
+
}
|
|
98
102
|
onChangeText?.(text);
|
|
99
103
|
};
|
|
100
104
|
|
|
@@ -109,6 +113,13 @@ const Input = forwardRef(
|
|
|
109
113
|
};
|
|
110
114
|
|
|
111
115
|
const _setText = (text: string) => {
|
|
116
|
+
if (__DEV__ && value !== undefined) {
|
|
117
|
+
console.error(
|
|
118
|
+
`${componentName}: calling ref.setText() on a controlled input (\`value\` is provided) is an anti-pattern. ` +
|
|
119
|
+
'It creates two sources of truth: setText will be overridden by React on the next render. ' +
|
|
120
|
+
'Update the state behind `value` instead.',
|
|
121
|
+
);
|
|
122
|
+
}
|
|
112
123
|
inputRef?.current?.setNativeProps({ text });
|
|
113
124
|
_onChangeText(text);
|
|
114
125
|
};
|
|
@@ -69,7 +69,8 @@ const InputPhoneNumber = forwardRef(
|
|
|
69
69
|
const context = useContext<any>(MiniAppContext);
|
|
70
70
|
const scaleHeight = useScaleSize(size === 'small' ? 48 : 56);
|
|
71
71
|
const [focused, setFocused] = useState(false);
|
|
72
|
-
const
|
|
72
|
+
const [internalText, setInternalText] = useState(defaultValue || '');
|
|
73
|
+
const haveValue = value !== undefined ? !!value : !!internalText;
|
|
73
74
|
const inputRef = useRef<TextInput | null>(null);
|
|
74
75
|
const componentName = 'InputPhoneNumber';
|
|
75
76
|
|
|
@@ -86,6 +87,9 @@ const InputPhoneNumber = forwardRef(
|
|
|
86
87
|
};
|
|
87
88
|
|
|
88
89
|
const _onChangeText = (text: string) => {
|
|
90
|
+
if (value === undefined) {
|
|
91
|
+
setInternalText(text);
|
|
92
|
+
}
|
|
89
93
|
onChangeText?.(text);
|
|
90
94
|
};
|
|
91
95
|
|
|
@@ -100,6 +104,13 @@ const InputPhoneNumber = forwardRef(
|
|
|
100
104
|
};
|
|
101
105
|
|
|
102
106
|
const _setText = (text: string) => {
|
|
107
|
+
if (__DEV__ && value !== undefined) {
|
|
108
|
+
console.error(
|
|
109
|
+
`${componentName}: calling ref.setText() on a controlled input (\`value\` is provided) is an anti-pattern. ` +
|
|
110
|
+
'It creates two sources of truth: setText will be overridden by React on the next render. ' +
|
|
111
|
+
'Update the state behind `value` instead.',
|
|
112
|
+
);
|
|
113
|
+
}
|
|
103
114
|
inputRef?.current?.setNativeProps({ text });
|
|
104
115
|
_onChangeText(text);
|
|
105
116
|
};
|
package/Layout/Screen.tsx
CHANGED
|
@@ -166,6 +166,13 @@ export interface ScreenProps extends ViewProps {
|
|
|
166
166
|
trackingParams?: ScreenTrackingParams;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
/**
|
|
170
|
+
* Scroll distance (px) over which the animated search header collapses from its
|
|
171
|
+
* expanded to its docked state — the input range consumed by `HeaderExtendHeader`
|
|
172
|
+
* and the settle threshold in `handleScrollEnd`.
|
|
173
|
+
*/
|
|
174
|
+
const SEARCH_HEADER_COLLAPSE_DISTANCE = 100;
|
|
175
|
+
|
|
169
176
|
const Screen = forwardRef(
|
|
170
177
|
(
|
|
171
178
|
{
|
|
@@ -195,7 +202,7 @@ const Screen = forwardRef(
|
|
|
195
202
|
ref: any,
|
|
196
203
|
) => {
|
|
197
204
|
const screenRef = useRef<View | ScrollView>(null);
|
|
198
|
-
const { width: widthDevice } = useWindowDimensions();
|
|
205
|
+
const { width: widthDevice, height: heightDevice } = useWindowDimensions();
|
|
199
206
|
const { theme } = useContext(ApplicationContext);
|
|
200
207
|
const screen: any = useContext(ScreenContext);
|
|
201
208
|
const insets = useSafeAreaInsets();
|
|
@@ -650,7 +657,25 @@ const Screen = forwardRef(
|
|
|
650
657
|
onScroll={handleScroll}
|
|
651
658
|
onScrollEndDrag={handleScrollEnd}
|
|
652
659
|
scrollEventThrottle={16}
|
|
653
|
-
style={
|
|
660
|
+
style={[
|
|
661
|
+
Styles.flex,
|
|
662
|
+
!scrollable && !Footer && !isTab && { paddingBottom: bottomInset },
|
|
663
|
+
]}
|
|
664
|
+
contentContainerStyle={[
|
|
665
|
+
scrollable && !Footer && !isTab && { paddingBottom: bottomInset },
|
|
666
|
+
// The animated search header collapses as the body scrolls. When the
|
|
667
|
+
// body is short (e.g. no search history) the ScrollView is barely
|
|
668
|
+
// scrollable, so overscroll bounce feeds the scroll-driven animation
|
|
669
|
+
// and the input jitters on its way up to the header. A ScrollView
|
|
670
|
+
// frame can never exceed the window, so forcing the content to be at
|
|
671
|
+
// least one screen plus the collapse distance guarantees the animation
|
|
672
|
+
// always has room to complete smoothly, independent of body content.
|
|
673
|
+
scrollable &&
|
|
674
|
+
inputSearchProps && {
|
|
675
|
+
minHeight: heightDevice + SEARCH_HEADER_COLLAPSE_DISTANCE,
|
|
676
|
+
},
|
|
677
|
+
scrollViewProps?.contentContainerStyle,
|
|
678
|
+
]}
|
|
654
679
|
>
|
|
655
680
|
{renderAnimatedHeader()}
|
|
656
681
|
|
package/Text/utils.ts
CHANGED
|
@@ -1,24 +1,22 @@
|
|
|
1
1
|
import { Dimensions, PixelRatio, useWindowDimensions } from 'react-native';
|
|
2
2
|
import { useContext } from 'react';
|
|
3
|
-
import {
|
|
3
|
+
import { MiniAppContext } from '../Context';
|
|
4
4
|
|
|
5
5
|
const deviceWidth = Dimensions.get('window').width;
|
|
6
6
|
const DEFAULT_SCREEN_SIZE = 375;
|
|
7
7
|
const MAX_FONT_SCALE = 1.5;
|
|
8
8
|
const MAX_DEVICE_SCALE = 5;
|
|
9
9
|
|
|
10
|
-
const useScaleSize = (size: number,
|
|
11
|
-
const
|
|
12
|
-
|
|
10
|
+
const useScaleSize = (size: number, scaleRate?: number) => {
|
|
11
|
+
const context = useContext<any>(MiniAppContext);
|
|
12
|
+
if (context?.fontScale?.useOSScaleRate === false) {
|
|
13
|
+
return size * (context.fontScale.userScaleRate ?? 1);
|
|
14
|
+
}
|
|
13
15
|
const fontScale = PixelRatio.getFontScale();
|
|
14
16
|
const { width } = useWindowDimensions();
|
|
15
17
|
const deviceScale = width / DEFAULT_SCREEN_SIZE;
|
|
16
18
|
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
if (!useOSFontScale) {
|
|
20
|
-
return customRate > 1 ? customRate * size : size;
|
|
21
|
-
}
|
|
19
|
+
const maxScaleRate = scaleRate ?? MAX_FONT_SCALE;
|
|
22
20
|
|
|
23
21
|
let fontSizeDeviceScale = size;
|
|
24
22
|
let fontSizeOSScale = size;
|
|
@@ -32,8 +30,8 @@ const useScaleSize = (size: number, userScaleRate?: number) => {
|
|
|
32
30
|
|
|
33
31
|
if (fontScale > 1) {
|
|
34
32
|
fontSizeOSScale = Math.min(
|
|
35
|
-
|
|
36
|
-
fontSizeOSScale *
|
|
33
|
+
fontSizeOSScale * fontScale,
|
|
34
|
+
fontSizeOSScale * maxScaleRate,
|
|
37
35
|
);
|
|
38
36
|
}
|
|
39
37
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/foundation",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.163.1-beta.1",
|
|
4
4
|
"description": "React Native Component Kits",
|
|
5
5
|
"main": "index.ts",
|
|
6
6
|
"scripts": {},
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"@momo-kits/foundation"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"react-native-fast-image": "git+https://oauth2:
|
|
11
|
+
"react-native-fast-image": "git+https://oauth2:k_r5y_gV6sX9-TqQxgcd@gitlab.mservice.com.vn/momo-platform/public/react-native-fast-image.git#v8.11.0",
|
|
12
12
|
"@react-navigation/bottom-tabs": "7.4.2",
|
|
13
13
|
"@react-navigation/core": "7.12.1",
|
|
14
14
|
"@react-navigation/elements": "2.5.2",
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@react-navigation/routers": "7.4.1",
|
|
17
17
|
"@react-navigation/stack": "7.4.2",
|
|
18
18
|
"react-native-gesture-handler": "2.27.1",
|
|
19
|
-
"react-native-linear-gradient": "git+https://oauth2:
|
|
19
|
+
"react-native-linear-gradient": "git+https://oauth2:k_r5y_gV6sX9-TqQxgcd@gitlab.mservice.com.vn/momo-platform/public/react-native-linear-gradient#v3.0.0",
|
|
20
20
|
"react-native-reanimated": "4.2.2",
|
|
21
21
|
"react-native-safe-area-context": "5.5.2",
|
|
22
22
|
"@shopify/flash-list": "2.1.0",
|