@momo-kits/foundation 0.165.1-sp.4 → 0.165.2-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/BottomTab/index.tsx +11 -12
- package/Application/Components/HeaderAnimated.tsx +18 -2
- package/Application/Components/HeaderLeft.tsx +1 -1
- package/Application/Components/HeaderTitle.tsx +18 -14
- package/Application/NavigationContainer.tsx +16 -6
- package/Application/WidgetContainer.tsx +6 -4
- package/Application/types.ts +3 -0
- package/Button/index.tsx +12 -0
- package/Consts/designSystemFont.ts +38 -0
- package/Consts/index.ts +1 -0
- package/Consts/theme.ts +3 -3
- package/Input/InputMoney.tsx +3 -2
- package/Input/InputPhoneNumber.tsx +11 -3
- package/Input/InputSearch.tsx +8 -2
- package/Input/InputTextArea.tsx +3 -1
- package/Input/TextTyping.tsx +3 -1
- package/Layout/FloatingButton.tsx +6 -5
- package/Layout/Screen.tsx +37 -3
- package/Loader/DotLoader.tsx +2 -0
- package/Loader/Spinner.tsx +2 -0
- package/Text/index.tsx +39 -3
- package/Title/index.tsx +8 -2
- package/Title/styles.ts +0 -1
- package/package.json +1 -1
|
@@ -233,18 +233,17 @@ const BottomTab: React.FC<BottomTabProps> = ({
|
|
|
233
233
|
});
|
|
234
234
|
}, [itemWidth, indicatorAnimated]);
|
|
235
235
|
|
|
236
|
-
//
|
|
237
|
-
//
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
// );
|
|
236
|
+
// Focus, not mount: pushing a screen from a tab leaves BottomTab mounted but blurred, and
|
|
237
|
+
// onFocus only fires on tab changes.
|
|
238
|
+
useFocusEffect(
|
|
239
|
+
React.useCallback(() => {
|
|
240
|
+
NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(
|
|
241
|
+
activeIndex.current !== 0,
|
|
242
|
+
);
|
|
243
|
+
return () =>
|
|
244
|
+
NativeModules?.MiniAppModule?.setShouldUseFloatingArrowBack?.(false);
|
|
245
|
+
}, []),
|
|
246
|
+
);
|
|
248
247
|
|
|
249
248
|
const onFocus = (e: any) => {
|
|
250
249
|
activeIndex.current = tabs.findIndex(i => e.target.includes(i.name));
|
|
@@ -10,10 +10,20 @@ import { Image } from '../../Image';
|
|
|
10
10
|
import { Colors } from '../../Consts';
|
|
11
11
|
import { useNormalizedSharedValue } from '../utils';
|
|
12
12
|
|
|
13
|
+
const ASPECT_RATIOS: Record<
|
|
14
|
+
NonNullable<HeaderAnimatedProps['aspectRatio']>,
|
|
15
|
+
number
|
|
16
|
+
> = {
|
|
17
|
+
'16/9': 16 / 9,
|
|
18
|
+
'3/2': 3 / 2,
|
|
19
|
+
'1/1': 1 / 1,
|
|
20
|
+
};
|
|
21
|
+
|
|
13
22
|
const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
14
23
|
animatedValue,
|
|
15
24
|
image,
|
|
16
25
|
useScale = true,
|
|
26
|
+
aspectRatio = '16/9',
|
|
17
27
|
children,
|
|
18
28
|
}) => {
|
|
19
29
|
const sharedValue = useNormalizedSharedValue(animatedValue);
|
|
@@ -40,7 +50,13 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
|
40
50
|
});
|
|
41
51
|
|
|
42
52
|
return (
|
|
43
|
-
<Animated.View
|
|
53
|
+
<Animated.View
|
|
54
|
+
style={[
|
|
55
|
+
styles.container,
|
|
56
|
+
{ aspectRatio: ASPECT_RATIOS[aspectRatio] },
|
|
57
|
+
animatedStyle,
|
|
58
|
+
]}
|
|
59
|
+
>
|
|
44
60
|
{children ?? (
|
|
45
61
|
<Image
|
|
46
62
|
source={{
|
|
@@ -54,7 +70,7 @@ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
|
|
|
54
70
|
};
|
|
55
71
|
|
|
56
72
|
const styles = StyleSheet.create({
|
|
57
|
-
container: { width: '100%'
|
|
73
|
+
container: { width: '100%' },
|
|
58
74
|
verifiedDot: {
|
|
59
75
|
width: 4,
|
|
60
76
|
height: 4,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BackHandler, StyleSheet, View } from 'react-native';
|
|
2
|
-
import { HeaderBackProps } from '../types';
|
|
2
|
+
import type { HeaderBackProps } from '../types';
|
|
3
3
|
import React, { useCallback, useContext, useEffect } from 'react';
|
|
4
4
|
import { ApplicationContext, MiniAppContext } from '../../Context';
|
|
5
5
|
import { PopupNotify } from '../../Popup';
|
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
import React, { useContext } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
Dimensions,
|
|
4
|
-
StyleSheet,
|
|
5
|
-
TouchableOpacity,
|
|
6
|
-
View,
|
|
7
|
-
} from 'react-native';
|
|
2
|
+
import { Dimensions, StyleSheet, TouchableOpacity, View } from 'react-native';
|
|
8
3
|
import Animated, {
|
|
9
4
|
Extrapolation,
|
|
10
5
|
interpolate,
|
|
@@ -21,10 +16,7 @@ import {
|
|
|
21
16
|
import { Image } from '../../Image';
|
|
22
17
|
import { Icon } from '../../Icon';
|
|
23
18
|
import { Skeleton } from '../../Skeleton';
|
|
24
|
-
import {
|
|
25
|
-
AnimatedCompatValue,
|
|
26
|
-
useNormalizedSharedValue,
|
|
27
|
-
} from '../utils';
|
|
19
|
+
import { AnimatedCompatValue, useNormalizedSharedValue } from '../utils';
|
|
28
20
|
|
|
29
21
|
type HeaderTitleInterpolate = {
|
|
30
22
|
inputRange: number[];
|
|
@@ -41,7 +33,9 @@ type HeaderTitleExtraProps = {
|
|
|
41
33
|
/**
|
|
42
34
|
* default header title used for nav
|
|
43
35
|
*/
|
|
44
|
-
const HeaderTitle: React.FC<
|
|
36
|
+
const HeaderTitle: React.FC<
|
|
37
|
+
HeaderTitleExtraProps & { [key: string]: any }
|
|
38
|
+
> = props => {
|
|
45
39
|
const context = useContext<any>(MiniAppContext);
|
|
46
40
|
|
|
47
41
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
@@ -86,10 +80,13 @@ const HeaderTitle: React.FC<HeaderTitleExtraProps & { [key: string]: any }> = pr
|
|
|
86
80
|
{
|
|
87
81
|
fontSize: useScaleSize(15),
|
|
88
82
|
lineHeight: useScaleSize(22),
|
|
89
|
-
fontWeight: 'bold',
|
|
90
83
|
},
|
|
91
84
|
{
|
|
92
|
-
fontFamily: exportFontFamily(
|
|
85
|
+
fontFamily: exportFontFamily(
|
|
86
|
+
'bold',
|
|
87
|
+
'action_xs_bold',
|
|
88
|
+
'MoMoTrustDisplay',
|
|
89
|
+
),
|
|
93
90
|
color: props.tintColor,
|
|
94
91
|
},
|
|
95
92
|
animatedStyle,
|
|
@@ -381,6 +378,7 @@ const TitleUser: React.FC<TitleUserProps> = ({
|
|
|
381
378
|
<View style={Styles.row}>
|
|
382
379
|
<Text
|
|
383
380
|
typography="action_xs_bold"
|
|
381
|
+
fontFamily='MoMoTrustDisplay'
|
|
384
382
|
color={tintColor}
|
|
385
383
|
numberOfLines={1}
|
|
386
384
|
>
|
|
@@ -450,7 +448,9 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
|
|
|
450
448
|
</Text>
|
|
451
449
|
)}
|
|
452
450
|
<View style={Styles.row}>
|
|
453
|
-
<Text typography="action_xs_bold"
|
|
451
|
+
<Text typography="action_xs_bold"
|
|
452
|
+
fontFamily='MoMoTrustDisplay'
|
|
453
|
+
color={tintColor} numberOfLines={1}>
|
|
454
454
|
{location}
|
|
455
455
|
</Text>
|
|
456
456
|
<Icon
|
|
@@ -512,6 +512,8 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
512
512
|
style={{ maxWidth: startWidth }}
|
|
513
513
|
color={tintColor}
|
|
514
514
|
numberOfLines={1}
|
|
515
|
+
fontFamily='MoMoTrustDisplay'
|
|
516
|
+
|
|
515
517
|
>
|
|
516
518
|
{start}
|
|
517
519
|
</Text>
|
|
@@ -527,6 +529,8 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
|
|
|
527
529
|
typography="action_xs_bold"
|
|
528
530
|
color={tintColor}
|
|
529
531
|
numberOfLines={1}
|
|
532
|
+
fontFamily='MoMoTrustDisplay'
|
|
533
|
+
|
|
530
534
|
>
|
|
531
535
|
{end}
|
|
532
536
|
</Text>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { useContext, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
SafeAreaInsetsContext,
|
|
3
4
|
SafeAreaProvider,
|
|
4
5
|
useSafeAreaInsets,
|
|
5
6
|
} from 'react-native-safe-area-context';
|
|
@@ -19,12 +20,14 @@ import Navigator from './Navigator';
|
|
|
19
20
|
import { getModalOptions, getStackOptions, useNativeCanGoBack } from './utils';
|
|
20
21
|
import { NavigationContainerProps } from './types';
|
|
21
22
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
23
|
+
import { useDefaultRegularFontFamily } from '../Consts/designSystemFont';
|
|
22
24
|
import Localize from './Localize';
|
|
23
25
|
import { Colors, defaultTheme } from '../Consts';
|
|
24
26
|
import { HeaderLeft } from './Components/HeaderLeft';
|
|
25
27
|
import { HeaderRight } from './Components/HeaderRight';
|
|
26
28
|
import { HeaderTitle } from './Components/HeaderTitle';
|
|
27
29
|
import { HeaderBackground } from './Components/HeaderBackground';
|
|
30
|
+
import { type EdgeInsets } from 'react-native-safe-area-context';
|
|
28
31
|
|
|
29
32
|
const Stack = createStackNavigator();
|
|
30
33
|
|
|
@@ -61,8 +64,15 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
|
|
|
61
64
|
},
|
|
62
65
|
};
|
|
63
66
|
|
|
67
|
+
const parentInsets = useContext(SafeAreaInsetsContext);
|
|
68
|
+
|
|
64
69
|
return (
|
|
65
|
-
<SafeAreaProvider
|
|
70
|
+
<SafeAreaProvider
|
|
71
|
+
initialMetrics={{
|
|
72
|
+
insets: parentInsets as EdgeInsets,
|
|
73
|
+
frame: { x: 0, y: 0, width: 0, height: 0 },
|
|
74
|
+
}}
|
|
75
|
+
>
|
|
66
76
|
<MiniAppContext.Provider value={mergedContext}>
|
|
67
77
|
<Navigation
|
|
68
78
|
screen={screen}
|
|
@@ -93,8 +103,8 @@ const Navigation: React.FC<any> = ({
|
|
|
93
103
|
const navigator = useRef(new Navigator(navigationRef, isReady));
|
|
94
104
|
const [showGrid, setShowGrid] = useState(false);
|
|
95
105
|
const insets = useSafeAreaInsets();
|
|
106
|
+
const defaultRegularFontFamily = useDefaultRegularFontFamily();
|
|
96
107
|
const syncCanGoBack = useNativeCanGoBack();
|
|
97
|
-
|
|
98
108
|
let headerBackground = context?.designSystemConfig?.config?.headerBar;
|
|
99
109
|
let headerGradient = theme.colors?.gradient;
|
|
100
110
|
|
|
@@ -173,19 +183,19 @@ const Navigation: React.FC<any> = ({
|
|
|
173
183
|
},
|
|
174
184
|
fonts: {
|
|
175
185
|
regular: {
|
|
176
|
-
fontFamily:
|
|
186
|
+
fontFamily: defaultRegularFontFamily,
|
|
177
187
|
fontWeight: '400',
|
|
178
188
|
},
|
|
179
189
|
medium: {
|
|
180
|
-
fontFamily:
|
|
190
|
+
fontFamily: defaultRegularFontFamily,
|
|
181
191
|
fontWeight: '400',
|
|
182
192
|
},
|
|
183
193
|
bold: {
|
|
184
|
-
fontFamily:
|
|
194
|
+
fontFamily: defaultRegularFontFamily,
|
|
185
195
|
fontWeight: '400',
|
|
186
196
|
},
|
|
187
197
|
heavy: {
|
|
188
|
-
fontFamily:
|
|
198
|
+
fontFamily: defaultRegularFontFamily,
|
|
189
199
|
fontWeight: '400',
|
|
190
200
|
},
|
|
191
201
|
},
|
|
@@ -3,6 +3,7 @@ import { SafeAreaProvider } from 'react-native-safe-area-context';
|
|
|
3
3
|
import Navigator from './Navigator';
|
|
4
4
|
import { WidgetContainerProps } from './types';
|
|
5
5
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
6
|
+
import { useDefaultRegularFontFamily } from '../Consts/designSystemFont';
|
|
6
7
|
import Localize from './Localize';
|
|
7
8
|
import { defaultTheme } from '../Consts';
|
|
8
9
|
import {
|
|
@@ -42,6 +43,7 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
42
43
|
const isReady = useRef(false);
|
|
43
44
|
const navigator = useRef(new Navigator(navigationRef, isReady, true));
|
|
44
45
|
const [currentContext, setCurrentContext] = useState({});
|
|
46
|
+
const defaultRegularFontFamily = useDefaultRegularFontFamily();
|
|
45
47
|
|
|
46
48
|
useEffect(() => {
|
|
47
49
|
const sub = maxApi?.observer?.('font_scale_config', (data: any) => {
|
|
@@ -114,19 +116,19 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
|
|
|
114
116
|
},
|
|
115
117
|
fonts: {
|
|
116
118
|
regular: {
|
|
117
|
-
fontFamily:
|
|
119
|
+
fontFamily: defaultRegularFontFamily,
|
|
118
120
|
fontWeight: '400',
|
|
119
121
|
},
|
|
120
122
|
medium: {
|
|
121
|
-
fontFamily:
|
|
123
|
+
fontFamily: defaultRegularFontFamily,
|
|
122
124
|
fontWeight: '400',
|
|
123
125
|
},
|
|
124
126
|
bold: {
|
|
125
|
-
fontFamily:
|
|
127
|
+
fontFamily: defaultRegularFontFamily,
|
|
126
128
|
fontWeight: '400',
|
|
127
129
|
},
|
|
128
130
|
heavy: {
|
|
129
|
-
fontFamily:
|
|
131
|
+
fontFamily: defaultRegularFontFamily,
|
|
130
132
|
fontWeight: '400',
|
|
131
133
|
},
|
|
132
134
|
},
|
package/Application/types.ts
CHANGED
|
@@ -229,6 +229,8 @@ export type HeaderTitleProps = {
|
|
|
229
229
|
data: TitleUserProps | TitleLocationProps | TitleJourneyProps;
|
|
230
230
|
};
|
|
231
231
|
|
|
232
|
+
export type HeaderType = 'default' | 'extended' | 'none';
|
|
233
|
+
|
|
232
234
|
export interface NavigationOptions
|
|
233
235
|
extends Omit<StackNavigationOptions, 'headerRight' | 'headerTitle'> {
|
|
234
236
|
preventBack?: PopupNotifyProps;
|
|
@@ -302,6 +304,7 @@ export interface HeaderAnimatedProps extends ViewProps {
|
|
|
302
304
|
animatedValue: Animated.Value | SharedValue<number>;
|
|
303
305
|
image: string;
|
|
304
306
|
useScale?: boolean;
|
|
307
|
+
aspectRatio?: '16/9' | '3/2' | '1/1';
|
|
305
308
|
}
|
|
306
309
|
|
|
307
310
|
export type BottomTabItemProps = {
|
package/Button/index.tsx
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { FC, useContext, useRef } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
Platform,
|
|
3
4
|
StyleSheet,
|
|
4
5
|
TouchableOpacity,
|
|
5
6
|
TouchableOpacityProps,
|
|
@@ -283,6 +284,17 @@ const Button: FC<ButtonProps> = ({
|
|
|
283
284
|
{ keypath: 'base pink 2.Ellipse 1.Stroke 1', color: textColor },
|
|
284
285
|
]}
|
|
285
286
|
style={[style, { borderRadius: Spacing.M }]}
|
|
287
|
+
webStyle={
|
|
288
|
+
Platform.OS === 'web'
|
|
289
|
+
? {
|
|
290
|
+
width: iconSize,
|
|
291
|
+
height: iconSize,
|
|
292
|
+
marginRight: isLeft ? space : 0,
|
|
293
|
+
marginLeft: isLeft ? 0 : space,
|
|
294
|
+
borderRadius: Spacing.M,
|
|
295
|
+
}
|
|
296
|
+
: undefined
|
|
297
|
+
}
|
|
286
298
|
/>
|
|
287
299
|
);
|
|
288
300
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
import { MiniAppContext } from '../Context';
|
|
3
|
+
|
|
4
|
+
export const NEW_DEFAULT_FONT_FAMILY = 'MomoTrustSans';
|
|
5
|
+
export const LEGACY_DEFAULT_FONT_FAMILY = 'SFProText';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Font thuoc bo design system moi. Ngoai whitelist thi ha het ve font cu:
|
|
9
|
+
* MoMoTrustDisplay chi duoc dung tu commit header title 5bfde6251 (DS-791),
|
|
10
|
+
* truoc do header lay font theo theme.
|
|
11
|
+
*/
|
|
12
|
+
const NEW_FONT_FAMILIES = [NEW_DEFAULT_FONT_FAMILY, 'MoMoTrustDisplay'];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Cờ whitelist design system, host đẩy xuống qua `decorateProps`
|
|
16
|
+
* (`designSystemConfig.isWhiteListDesignSystem`). Ngoài whitelist thì kit giữ
|
|
17
|
+
* nguyên font cũ.
|
|
18
|
+
*/
|
|
19
|
+
export const useIsDesignSystemWhiteList = (): boolean => {
|
|
20
|
+
const context = useContext<any>(MiniAppContext);
|
|
21
|
+
return context?.designSystemConfig?.isWhiteListDesignSystem === true;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Hạ font mặc định mới về font cũ khi user không nằm trong whitelist.
|
|
26
|
+
* Font do caller chỉ định tường minh (MoMoSignature, AlegreyaSans...) giữ nguyên.
|
|
27
|
+
*/
|
|
28
|
+
export const useResolvedFontFamily = (font: string): string => {
|
|
29
|
+
const isWhiteList = useIsDesignSystemWhiteList();
|
|
30
|
+
if (NEW_FONT_FAMILIES.includes(font) && !isWhiteList) {
|
|
31
|
+
return LEGACY_DEFAULT_FONT_FAMILY;
|
|
32
|
+
}
|
|
33
|
+
return font;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/** Tên file font Regular tương ứng với nhánh whitelist đang áp dụng. */
|
|
37
|
+
export const useDefaultRegularFontFamily = (): string =>
|
|
38
|
+
`${useResolvedFontFamily(NEW_DEFAULT_FONT_FAMILY)}-Regular`;
|
package/Consts/index.ts
CHANGED
package/Consts/theme.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Context, Theme} from '../Application/types';
|
|
1
|
+
import type {Context, Theme} from '../Application/types';
|
|
2
2
|
import {Colors} from './colors+spacing+radius';
|
|
3
3
|
|
|
4
4
|
const defaultTheme: Theme = {
|
|
@@ -51,7 +51,7 @@ const defaultTheme: Theme = {
|
|
|
51
51
|
container: Colors.blue_08,
|
|
52
52
|
},
|
|
53
53
|
},
|
|
54
|
-
font: '
|
|
54
|
+
font: 'MomoTrustSans',
|
|
55
55
|
assets: {},
|
|
56
56
|
};
|
|
57
57
|
|
|
@@ -105,7 +105,7 @@ const defaultDarkTheme: Theme = {
|
|
|
105
105
|
container: Colors.blue_08,
|
|
106
106
|
},
|
|
107
107
|
},
|
|
108
|
-
font: '
|
|
108
|
+
font: 'MomoTrustSans',
|
|
109
109
|
assets: {},
|
|
110
110
|
};
|
|
111
111
|
|
package/Input/InputMoney.tsx
CHANGED
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
MiniAppContext,
|
|
22
22
|
} from '../Context';
|
|
23
23
|
import { Icon } from '../Icon';
|
|
24
|
-
import { useScaleSize } from '../Text';
|
|
24
|
+
import { useScaleSize, exportFontFamily } from '../Text';
|
|
25
25
|
import { Spacing } from '../Consts';
|
|
26
26
|
import {
|
|
27
27
|
ErrorView,
|
|
@@ -69,6 +69,7 @@ const InputMoney = forwardRef(
|
|
|
69
69
|
const context = useContext<any>(MiniAppContext);
|
|
70
70
|
const scaleHeight = useScaleSize(size === 'small' ? 48 : 56);
|
|
71
71
|
const scaledFontSize = useScaleSize(20);
|
|
72
|
+
const inputFontFamily = exportFontFamily('bold');
|
|
72
73
|
const [focused, setFocused] = useState(false);
|
|
73
74
|
const [displayValue, setDisplayValue] = useState('');
|
|
74
75
|
const [numericValue, setNumericValue] = useState('');
|
|
@@ -236,7 +237,7 @@ const InputMoney = forwardRef(
|
|
|
236
237
|
height: '100%',
|
|
237
238
|
fontSize: scaledFontSize,
|
|
238
239
|
paddingVertical: Spacing.S,
|
|
239
|
-
|
|
240
|
+
fontFamily: inputFontFamily,
|
|
240
241
|
},
|
|
241
242
|
{
|
|
242
243
|
color: textColor,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
} from '../Context';
|
|
22
22
|
import { Colors, Spacing, Styles } from '../Consts';
|
|
23
23
|
import { Icon } from '../Icon';
|
|
24
|
-
import { useScaleSize, Text } from '../Text';
|
|
24
|
+
import { useScaleSize, Text, exportFontFamily } from '../Text';
|
|
25
25
|
import {
|
|
26
26
|
ErrorView,
|
|
27
27
|
getBorderColor,
|
|
@@ -128,13 +128,21 @@ const InputPhoneNumber = forwardRef(
|
|
|
128
128
|
let dividerHeight = 24;
|
|
129
129
|
let size14 = useScaleSize(14);
|
|
130
130
|
let size18 = useScaleSize(18);
|
|
131
|
+
const semiboldFontFamily = exportFontFamily('semibold');
|
|
132
|
+
const boldFontFamily = exportFontFamily('bold');
|
|
131
133
|
let typography: Typography;
|
|
132
134
|
if (size === 'small') {
|
|
133
|
-
inputTextStyles = {
|
|
135
|
+
inputTextStyles = {
|
|
136
|
+
fontSize: size14,
|
|
137
|
+
fontFamily: semiboldFontFamily,
|
|
138
|
+
};
|
|
134
139
|
dividerHeight = 24;
|
|
135
140
|
typography = 'header_s_semibold';
|
|
136
141
|
} else {
|
|
137
|
-
inputTextStyles = {
|
|
142
|
+
inputTextStyles = {
|
|
143
|
+
fontSize: size18,
|
|
144
|
+
fontFamily: boldFontFamily,
|
|
145
|
+
};
|
|
138
146
|
dividerHeight = 32;
|
|
139
147
|
typography = 'header_m_bold';
|
|
140
148
|
}
|
package/Input/InputSearch.tsx
CHANGED
|
@@ -23,7 +23,7 @@ import {
|
|
|
23
23
|
MiniAppContext,
|
|
24
24
|
} from '../Context';
|
|
25
25
|
import { Icon } from '../Icon';
|
|
26
|
-
import { Text, useScaleSize } from '../Text';
|
|
26
|
+
import { Text, useScaleSize, exportFontFamily } from '../Text';
|
|
27
27
|
import { InputRef, InputSearchProps } from './index';
|
|
28
28
|
import styles from './styles';
|
|
29
29
|
import { Styles } from '../Consts';
|
|
@@ -36,6 +36,7 @@ const TextTyping: FC<any> = ({
|
|
|
36
36
|
}) => {
|
|
37
37
|
const textRef = useRef<TextInput>(null);
|
|
38
38
|
const scaledFontSize = useScaleSize(12);
|
|
39
|
+
const typingFontFamily = exportFontFamily('regular');
|
|
39
40
|
|
|
40
41
|
const currentIndex = useRef<number>(0);
|
|
41
42
|
const currentCharIndex = useRef<number>(0);
|
|
@@ -108,7 +109,10 @@ const TextTyping: FC<any> = ({
|
|
|
108
109
|
|
|
109
110
|
return (
|
|
110
111
|
<TextInput
|
|
111
|
-
style={[
|
|
112
|
+
style={[
|
|
113
|
+
styles.inputStyle,
|
|
114
|
+
{ fontSize: scaledFontSize, fontFamily: typingFontFamily },
|
|
115
|
+
]}
|
|
112
116
|
ref={textRef}
|
|
113
117
|
editable={false}
|
|
114
118
|
autoCorrect={false}
|
|
@@ -145,6 +149,7 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
|
|
|
145
149
|
const { theme } = useContext(ApplicationContext);
|
|
146
150
|
const context = useContext<any>(MiniAppContext);
|
|
147
151
|
const scaledFontSize = useScaleSize(14);
|
|
152
|
+
const searchFontFamily = exportFontFamily('regular');
|
|
148
153
|
|
|
149
154
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
150
155
|
|
|
@@ -231,6 +236,7 @@ const InputSearch: ForwardRefRenderFunction<InputRef, InputSearchProps> = (
|
|
|
231
236
|
{
|
|
232
237
|
fontSize: scaledFontSize,
|
|
233
238
|
color: theme.colors.text.default,
|
|
239
|
+
fontFamily: searchFontFamily,
|
|
234
240
|
},
|
|
235
241
|
]}
|
|
236
242
|
value={value}
|
package/Input/InputTextArea.tsx
CHANGED
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
} from 'react-native';
|
|
16
16
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
17
17
|
import { Icon } from '../Icon';
|
|
18
|
-
import { Text, useScaleSize } from '../Text';
|
|
18
|
+
import { Text, useScaleSize, exportFontFamily } from '../Text';
|
|
19
19
|
import { Spacing } from '../Consts';
|
|
20
20
|
import { ErrorView, FloatingView, getBorderColor, MAX_LENGTH } from './common';
|
|
21
21
|
import { InputTextAreaProps } from './index';
|
|
@@ -59,6 +59,7 @@ const InputTextArea = forwardRef(
|
|
|
59
59
|
|
|
60
60
|
const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
|
|
61
61
|
const scaledFontSize = useScaleSize(14);
|
|
62
|
+
const inputFontFamily = exportFontFamily('regular');
|
|
62
63
|
const [focused, setFocused] = useState(false);
|
|
63
64
|
const [inputValue, setInputValue] = useState(defaultValue ?? '');
|
|
64
65
|
const inputRef = useRef<TextInput | null>(null);
|
|
@@ -164,6 +165,7 @@ const InputTextArea = forwardRef(
|
|
|
164
165
|
paddingRight: Spacing.XS,
|
|
165
166
|
paddingVertical: Spacing.XS,
|
|
166
167
|
fontSize: scaledFontSize,
|
|
168
|
+
fontFamily: inputFontFamily,
|
|
167
169
|
},
|
|
168
170
|
{
|
|
169
171
|
color: textColor,
|
package/Input/TextTyping.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import React, { FC, memo, useEffect, useRef } from 'react';
|
|
3
3
|
import { Platform, TextInput, TextStyle } from 'react-native';
|
|
4
4
|
import { Colors } from '../Consts';
|
|
5
|
-
import { useScaleSize } from '../Text';
|
|
5
|
+
import { useScaleSize, exportFontFamily } from '../Text';
|
|
6
6
|
|
|
7
7
|
export interface TextTypingProps {
|
|
8
8
|
data: string[];
|
|
@@ -19,6 +19,7 @@ const TextTyping: FC<TextTypingProps> = ({
|
|
|
19
19
|
}) => {
|
|
20
20
|
const textRef = useRef<TextInput>(null);
|
|
21
21
|
const scaledFontSize = useScaleSize(12);
|
|
22
|
+
const inputFontFamily = exportFontFamily('regular');
|
|
22
23
|
|
|
23
24
|
const currentIndex = useRef<number>(0);
|
|
24
25
|
const currentCharIndex = useRef<number>(0);
|
|
@@ -95,6 +96,7 @@ const TextTyping: FC<TextTypingProps> = ({
|
|
|
95
96
|
{
|
|
96
97
|
color: Colors.black_12,
|
|
97
98
|
fontSize: scaledFontSize,
|
|
99
|
+
fontFamily: inputFontFamily,
|
|
98
100
|
height: Platform.select({
|
|
99
101
|
android: 60,
|
|
100
102
|
ios: 36,
|
|
@@ -14,7 +14,7 @@ import Animated, {
|
|
|
14
14
|
} from 'react-native-reanimated';
|
|
15
15
|
import { ApplicationContext } from '../Context';
|
|
16
16
|
import { Icon } from '../Icon';
|
|
17
|
-
import { useScaleSize } from '../Text';
|
|
17
|
+
import { useScaleSize, exportFontFamily } from '../Text';
|
|
18
18
|
import {
|
|
19
19
|
AnimatedCompatValue,
|
|
20
20
|
useNormalizedSharedValue,
|
|
@@ -48,6 +48,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
48
48
|
const sharedValue = useNormalizedSharedValue(animatedValue);
|
|
49
49
|
const scaledFontSize = useScaleSize(16);
|
|
50
50
|
const scaledLineHeight = useScaleSize(22);
|
|
51
|
+
const labelFontFamily = exportFontFamily('bold');
|
|
51
52
|
const maxWidth = useSharedValue(0);
|
|
52
53
|
const minWidth = size === 'small' ? 36 : 48;
|
|
53
54
|
const opacityAnimated = useSharedValue(0);
|
|
@@ -63,7 +64,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
63
64
|
|
|
64
65
|
useAnimatedReaction(
|
|
65
66
|
() => sharedValue.value,
|
|
66
|
-
|
|
67
|
+
value => {
|
|
67
68
|
'worklet';
|
|
68
69
|
if (!label || !enabled) return;
|
|
69
70
|
if (value !== lastOffset.value && value > 0) {
|
|
@@ -76,7 +77,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
76
77
|
widthAnimated.value = withTiming(
|
|
77
78
|
minWidth,
|
|
78
79
|
{ duration: 100 },
|
|
79
|
-
|
|
80
|
+
finished => {
|
|
80
81
|
if (finished) runOnJS(setShowText)(false);
|
|
81
82
|
},
|
|
82
83
|
);
|
|
@@ -85,7 +86,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
85
86
|
widthAnimated.value = withTiming(
|
|
86
87
|
maxWidth.value,
|
|
87
88
|
{ duration: 100 },
|
|
88
|
-
|
|
89
|
+
finished => {
|
|
89
90
|
if (finished) runOnJS(setShowText)(true);
|
|
90
91
|
},
|
|
91
92
|
);
|
|
@@ -162,6 +163,7 @@ export const FloatingButton: React.FC<FloatingButtonProps> = ({
|
|
|
162
163
|
fontSize: scaledFontSize,
|
|
163
164
|
lineHeight: scaledLineHeight,
|
|
164
165
|
color: 'white',
|
|
166
|
+
fontFamily: labelFontFamily,
|
|
165
167
|
},
|
|
166
168
|
labelStyle,
|
|
167
169
|
]}
|
|
@@ -188,6 +190,5 @@ const styles = StyleSheet.create({
|
|
|
188
190
|
},
|
|
189
191
|
label: {
|
|
190
192
|
marginLeft: 8,
|
|
191
|
-
fontWeight: '700',
|
|
192
193
|
},
|
|
193
194
|
});
|
package/Layout/Screen.tsx
CHANGED
|
@@ -26,7 +26,10 @@ import {
|
|
|
26
26
|
ViewProps,
|
|
27
27
|
} from 'react-native';
|
|
28
28
|
import { useSharedValue, withTiming } from 'react-native-reanimated';
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
useSafeAreaFrame,
|
|
31
|
+
useSafeAreaInsets,
|
|
32
|
+
} from 'react-native-safe-area-context';
|
|
30
33
|
import { ApplicationContext, ScreenContext } from '../Context';
|
|
31
34
|
import Navigation from '../Application/Navigation';
|
|
32
35
|
import {
|
|
@@ -96,6 +99,14 @@ export interface ScreenProps extends ViewProps {
|
|
|
96
99
|
*/
|
|
97
100
|
footerComponent?: ReactNode;
|
|
98
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Optional. If `true`, the footer is inset by the standard horizontal margin
|
|
104
|
+
* (12pt each side). Set `false` for a footer that should span the full width —
|
|
105
|
+
* e.g. one that already carries its own horizontal padding.
|
|
106
|
+
* Defaults to `true`, on every platform.
|
|
107
|
+
*/
|
|
108
|
+
marginFooter?: boolean;
|
|
109
|
+
|
|
99
110
|
/**
|
|
100
111
|
* Optional. Background color of the screen.
|
|
101
112
|
*/
|
|
@@ -104,7 +115,7 @@ export interface ScreenProps extends ViewProps {
|
|
|
104
115
|
/**
|
|
105
116
|
* Optional. layout card offset overlap header banner.
|
|
106
117
|
*/
|
|
107
|
-
layoutOffset?: -8 | -24 | -56;
|
|
118
|
+
layoutOffset?: -8 | -24 | -56 | number;
|
|
108
119
|
|
|
109
120
|
/**
|
|
110
121
|
* Optional. Width of the right header.
|
|
@@ -174,6 +185,7 @@ const Screen = forwardRef(
|
|
|
174
185
|
scrollViewProps,
|
|
175
186
|
headerComponent: Header,
|
|
176
187
|
footerComponent: Footer,
|
|
188
|
+
marginFooter = true,
|
|
177
189
|
layoutOffset = -56,
|
|
178
190
|
headerRightWidth = 73,
|
|
179
191
|
backgroundColor,
|
|
@@ -196,6 +208,7 @@ const Screen = forwardRef(
|
|
|
196
208
|
const { theme, navigator } = useContext(ApplicationContext);
|
|
197
209
|
const screen: any = useContext(ScreenContext);
|
|
198
210
|
const insets = useSafeAreaInsets();
|
|
211
|
+
const frame = useSafeAreaFrame();
|
|
199
212
|
const heightHeader = useHeaderHeight();
|
|
200
213
|
|
|
201
214
|
/**
|
|
@@ -608,12 +621,31 @@ const Screen = forwardRef(
|
|
|
608
621
|
}
|
|
609
622
|
};
|
|
610
623
|
|
|
624
|
+
// Cap the screen container height so a scrollable body with a sticky footer
|
|
625
|
+
// can't push the footer past the visible frame (web previews measure the
|
|
626
|
+
// safe-area frame from the seeded SafeAreaProvider metrics). Subtract the
|
|
627
|
+
// bottom tab bar when present and the header unless it's an animated/extended
|
|
628
|
+
// header (those overlay rather than offset the body).
|
|
629
|
+
const getHeight = () => {
|
|
630
|
+
let newHeight = frame.height;
|
|
631
|
+
if (isTab) {
|
|
632
|
+
newHeight -= 64 + Math.min(insets.bottom, 21);
|
|
633
|
+
}
|
|
634
|
+
if (!animatedHeader && headerType !== 'extended') {
|
|
635
|
+
newHeight -= heightHeader;
|
|
636
|
+
}
|
|
637
|
+
return newHeight;
|
|
638
|
+
};
|
|
639
|
+
|
|
611
640
|
return (
|
|
612
641
|
<View
|
|
613
642
|
style={[
|
|
614
643
|
Styles.flex,
|
|
615
644
|
{
|
|
616
645
|
backgroundColor: backgroundColor ?? theme.colors.background.default,
|
|
646
|
+
// Web-only cap so a scrollable body with a sticky footer can't push
|
|
647
|
+
// the footer past the frame. Native handles this without a cap.
|
|
648
|
+
maxHeight: Platform.OS === 'web' ? getHeight() : undefined,
|
|
617
649
|
},
|
|
618
650
|
]}
|
|
619
651
|
>
|
|
@@ -679,7 +711,9 @@ const Screen = forwardRef(
|
|
|
679
711
|
},
|
|
680
712
|
]}
|
|
681
713
|
>
|
|
682
|
-
|
|
714
|
+
{/* The footer inset is a caller decision, not a platform one — a footer
|
|
715
|
+
that carries its own horizontal padding passes `marginFooter={false}`. */}
|
|
716
|
+
<Section useMargin={marginFooter}>{Footer}</Section>
|
|
683
717
|
</View>
|
|
684
718
|
)}
|
|
685
719
|
</KeyboardAvoidingView>
|
package/Loader/DotLoader.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { FC, useContext } from 'react';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
2
3
|
import AnimatedLottieView from 'lottie-react-native';
|
|
3
4
|
import animation from '../Assets/DotAnimation.json';
|
|
4
5
|
import { ApplicationContext } from '../Context';
|
|
@@ -29,6 +30,7 @@ const DotLoader: FC<LoaderProps> = ({ color, style }) => {
|
|
|
29
30
|
<AnimatedLottieView
|
|
30
31
|
source={source}
|
|
31
32
|
style={[{ width: 52, height: 18 }, style]}
|
|
33
|
+
webStyle={Platform.OS === 'web' ? { width: 52, height: 18 } : undefined}
|
|
32
34
|
autoPlay
|
|
33
35
|
/>
|
|
34
36
|
);
|
package/Loader/Spinner.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import React, { FC, useContext } from 'react';
|
|
2
|
+
import { Platform } from 'react-native';
|
|
2
3
|
import AnimatedLottieView from 'lottie-react-native';
|
|
3
4
|
import animation from '../Assets/SpinnerAnimation.json';
|
|
4
5
|
import { hexToRGBA } from './utils';
|
|
@@ -21,6 +22,7 @@ const Spinner: FC<LoaderProps> = ({ color, style }) => {
|
|
|
21
22
|
<AnimatedLottieView
|
|
22
23
|
source={source}
|
|
23
24
|
style={[{ width: 24, height: 24 }, style]}
|
|
25
|
+
webStyle={Platform.OS === 'web' ? { width: 24, height: 24 } : undefined}
|
|
24
26
|
autoPlay
|
|
25
27
|
/>
|
|
26
28
|
);
|
package/Text/index.tsx
CHANGED
|
@@ -7,6 +7,10 @@ import {
|
|
|
7
7
|
MiniAppContext,
|
|
8
8
|
SkeletonContext,
|
|
9
9
|
} from '../Context';
|
|
10
|
+
import {
|
|
11
|
+
NEW_DEFAULT_FONT_FAMILY,
|
|
12
|
+
useResolvedFontFamily,
|
|
13
|
+
} from '../Consts/designSystemFont';
|
|
10
14
|
import { scaleSize, useScaleSize } from './utils';
|
|
11
15
|
import { Skeleton } from '../Skeleton';
|
|
12
16
|
|
|
@@ -52,6 +56,20 @@ const BarlowCondensed: TypographyWeight = {
|
|
|
52
56
|
bold: 'Bold',
|
|
53
57
|
};
|
|
54
58
|
|
|
59
|
+
const MomoTrustSans: TypographyWeight = {
|
|
60
|
+
100: 'ExtraLight',
|
|
61
|
+
200: 'ExtraLight',
|
|
62
|
+
300: 'Light',
|
|
63
|
+
400: 'Regular',
|
|
64
|
+
500: 'Medium',
|
|
65
|
+
600: 'SemiBold',
|
|
66
|
+
700: 'Bold',
|
|
67
|
+
800: 'ExtraBold',
|
|
68
|
+
900: 'ExtraBold',
|
|
69
|
+
normal: 'Regular',
|
|
70
|
+
bold: 'Bold',
|
|
71
|
+
};
|
|
72
|
+
|
|
55
73
|
const FontStyle: { [key: string]: string } = {
|
|
56
74
|
italic: 'Italic',
|
|
57
75
|
normal: '',
|
|
@@ -100,7 +118,8 @@ const TypoStyles = (typo: Typography, newFontFamily?: string) => {
|
|
|
100
118
|
const typoStyle = styleSheet[typo] ?? styleSheet.paragraph_default;
|
|
101
119
|
const { fontWeight, fontSize, fontStyle, lineHeight } = typoStyle;
|
|
102
120
|
const style = FontStyle[fontStyle ?? 'normal'];
|
|
103
|
-
const font = newFontFamily ?? theme.font;
|
|
121
|
+
const font = useResolvedFontFamily(newFontFamily ?? theme.font);
|
|
122
|
+
const resolvedDefaultFamily = useResolvedFontFamily(NEW_DEFAULT_FONT_FAMILY);
|
|
104
123
|
let fontFamily: string;
|
|
105
124
|
|
|
106
125
|
switch (font) {
|
|
@@ -108,6 +127,10 @@ const TypoStyles = (typo: Typography, newFontFamily?: string) => {
|
|
|
108
127
|
fontFamily = `${font}-${SFProText[fontWeight]}${style}`;
|
|
109
128
|
break;
|
|
110
129
|
}
|
|
130
|
+
case 'MomoTrustSans': {
|
|
131
|
+
fontFamily = `${font}-${MomoTrustSans[fontWeight]}`;
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
111
134
|
case 'AlegreyaSans': {
|
|
112
135
|
fontFamily = `${font}-${AlegreyaSans[fontWeight]}${style}`;
|
|
113
136
|
break;
|
|
@@ -125,7 +148,11 @@ const TypoStyles = (typo: Typography, newFontFamily?: string) => {
|
|
|
125
148
|
break;
|
|
126
149
|
}
|
|
127
150
|
default: {
|
|
128
|
-
fontFamily =
|
|
151
|
+
fontFamily = `${resolvedDefaultFamily}-${
|
|
152
|
+
resolvedDefaultFamily === NEW_DEFAULT_FONT_FAMILY
|
|
153
|
+
? MomoTrustSans[fontWeight]
|
|
154
|
+
: SFProText[fontWeight]
|
|
155
|
+
}`;
|
|
129
156
|
}
|
|
130
157
|
}
|
|
131
158
|
|
|
@@ -135,7 +162,10 @@ const TypoStyles = (typo: Typography, newFontFamily?: string) => {
|
|
|
135
162
|
fontSize: useScaleSize(fontSize),
|
|
136
163
|
lineHeight: useScaleSize(lineHeight),
|
|
137
164
|
fontStyle,
|
|
138
|
-
|
|
165
|
+
// fontFamily da mang san weight. Tren Android, ReactFontManager doi
|
|
166
|
+
// `fonts/<family>_bold.ttf` khi fontWeight >= 700; file do khong ton tai nen
|
|
167
|
+
// font se roi ve font he thong. Bo fontWeight de Android dung dung file.
|
|
168
|
+
fontWeight: undefined,
|
|
139
169
|
};
|
|
140
170
|
};
|
|
141
171
|
|
|
@@ -216,6 +246,12 @@ const exportFontFamily = (
|
|
|
216
246
|
typography = 'body_default_regular';
|
|
217
247
|
break;
|
|
218
248
|
|
|
249
|
+
case 'semibold':
|
|
250
|
+
case 'Semibold':
|
|
251
|
+
case 'SemiBold':
|
|
252
|
+
typography = 'header_s_semibold';
|
|
253
|
+
break;
|
|
254
|
+
|
|
219
255
|
default: {
|
|
220
256
|
typography = 'body_default_regular';
|
|
221
257
|
break;
|
package/Title/index.tsx
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
ViewStyle,
|
|
7
7
|
} from 'react-native';
|
|
8
8
|
import { Icon } from '../Icon';
|
|
9
|
-
import { useScaleSize, Text } from '../Text';
|
|
9
|
+
import { useScaleSize, Text, exportFontFamily } from '../Text';
|
|
10
10
|
import { useComponentId } from '../Application';
|
|
11
11
|
import { ApplicationContext, MiniAppContext } from '../Context';
|
|
12
12
|
import { Badge } from '../Badge';
|
|
@@ -75,6 +75,7 @@ const Title: FC<TitleProps> = ({
|
|
|
75
75
|
[key: string]: any;
|
|
76
76
|
} = { ...styles, ...dynamicStyles };
|
|
77
77
|
const typography = `${type}_${size}`;
|
|
78
|
+
const titleFontFamily = exportFontFamily('bold');
|
|
78
79
|
const isSection = type === 'section';
|
|
79
80
|
const numberOfLines = showTrailingAction || !!badgeLabel ? 1 : 2;
|
|
80
81
|
const buttonTypo: Typography =
|
|
@@ -129,6 +130,7 @@ const Title: FC<TitleProps> = ({
|
|
|
129
130
|
numberOfLines={numberOfLines}
|
|
130
131
|
style={[
|
|
131
132
|
styleSheet[typography],
|
|
133
|
+
{ fontFamily: titleFontFamily },
|
|
132
134
|
styles.title,
|
|
133
135
|
{
|
|
134
136
|
maxWidth:
|
|
@@ -256,7 +258,11 @@ const Title: FC<TitleProps> = ({
|
|
|
256
258
|
allowFontScaling={false}
|
|
257
259
|
accessibilityLabel={componentId + '|title-text'}
|
|
258
260
|
numberOfLines={numberOfLines}
|
|
259
|
-
style={[
|
|
261
|
+
style={[
|
|
262
|
+
styleSheet[typography],
|
|
263
|
+
{ fontFamily: titleFontFamily },
|
|
264
|
+
styles.title,
|
|
265
|
+
]}
|
|
260
266
|
>
|
|
261
267
|
{title}
|
|
262
268
|
</RNText>
|
package/Title/styles.ts
CHANGED