@momo-kits/foundation 0.167.1-beta.1 → 0.167.1-beta.10

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.
@@ -16,7 +16,16 @@ import {
16
16
  import { Image } from '../../Image';
17
17
  import { Icon } from '../../Icon';
18
18
  import { Skeleton } from '../../Skeleton';
19
- import { AnimatedCompatValue, useNormalizedSharedValue } from '../utils';
19
+ import {
20
+ AnimatedCompatValue,
21
+ isWhiteListDesignSystem,
22
+ useNormalizedSharedValue,
23
+ } from '../utils';
24
+
25
+ const useHeaderFontFamily = (): string => {
26
+ const context = useContext<any>(MiniAppContext);
27
+ return isWhiteListDesignSystem(context) ? 'MoMoTrustDisplay' : 'SFProText';
28
+ };
20
29
 
21
30
  type HeaderTitleInterpolate = {
22
31
  inputRange: number[];
@@ -37,6 +46,7 @@ const HeaderTitle: React.FC<
37
46
  HeaderTitleExtraProps & { [key: string]: any }
38
47
  > = props => {
39
48
  const context = useContext<any>(MiniAppContext);
49
+ const headerFontFamily = useHeaderFontFamily();
40
50
 
41
51
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
42
52
 
@@ -85,7 +95,7 @@ const HeaderTitle: React.FC<
85
95
  fontFamily: exportFontFamily(
86
96
  'bold',
87
97
  'action_xs_bold',
88
- 'MoMoTrustDisplay',
98
+ headerFontFamily,
89
99
  ),
90
100
  color: props.tintColor,
91
101
  },
@@ -130,6 +140,7 @@ const TitleUser: React.FC<TitleUserProps> = ({
130
140
  isLoading,
131
141
  }) => {
132
142
  const { theme } = useContext(ApplicationContext);
143
+ const headerFontFamily = useHeaderFontFamily();
133
144
  const maxWidth = Dimensions.get('window').width - 172;
134
145
  const getShortName = (name: string) => {
135
146
  const words = name.split(' ');
@@ -378,7 +389,7 @@ const TitleUser: React.FC<TitleUserProps> = ({
378
389
  <View style={Styles.row}>
379
390
  <Text
380
391
  typography="action_xs_bold"
381
- fontFamily='MoMoTrustDisplay'
392
+ fontFamily={headerFontFamily}
382
393
  color={tintColor}
383
394
  numberOfLines={1}
384
395
  >
@@ -412,6 +423,7 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
412
423
  onPress,
413
424
  isLoading,
414
425
  }) => {
426
+ const headerFontFamily = useHeaderFontFamily();
415
427
  const maxWidth = Dimensions.get('window').width - 172;
416
428
  const renderShimmer = () => {
417
429
  return (
@@ -448,9 +460,12 @@ const TitleLocation: React.FC<TitleLocationProps> = ({
448
460
  </Text>
449
461
  )}
450
462
  <View style={Styles.row}>
451
- <Text typography="action_xs_bold"
452
- fontFamily='MoMoTrustDisplay'
453
- color={tintColor} numberOfLines={1}>
463
+ <Text
464
+ typography="action_xs_bold"
465
+ fontFamily={headerFontFamily}
466
+ color={tintColor}
467
+ numberOfLines={1}
468
+ >
454
469
  {location}
455
470
  </Text>
456
471
  <Icon
@@ -477,6 +492,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
477
492
  onPress,
478
493
  isLoading,
479
494
  }) => {
495
+ const headerFontFamily = useHeaderFontFamily();
480
496
  const { width } = Dimensions.get('screen');
481
497
  const maxWidth = Dimensions.get('window').width - 172;
482
498
  const startWidth = width * 0.25;
@@ -512,8 +528,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
512
528
  style={{ maxWidth: startWidth }}
513
529
  color={tintColor}
514
530
  numberOfLines={1}
515
- fontFamily='MoMoTrustDisplay'
516
-
531
+ fontFamily={headerFontFamily}
517
532
  >
518
533
  {start}
519
534
  </Text>
@@ -529,8 +544,7 @@ const TitleJourney: React.FC<TitleJourneyProps> = ({
529
544
  typography="action_xs_bold"
530
545
  color={tintColor}
531
546
  numberOfLines={1}
532
- fontFamily='MoMoTrustDisplay'
533
-
547
+ fontFamily={headerFontFamily}
534
548
  >
535
549
  {end}
536
550
  </Text>
@@ -17,10 +17,14 @@ import { DeviceEventEmitter } from 'react-native';
17
17
  import StackScreen from './StackScreen';
18
18
  import ModalScreen from './ModalScreen';
19
19
  import Navigator from './Navigator';
20
- import { getModalOptions, getStackOptions, useNativeCanGoBack } from './utils';
20
+ import {
21
+ getModalOptions,
22
+ getStackOptions,
23
+ isWhiteListDesignSystem,
24
+ useNativeCanGoBack,
25
+ } from './utils';
21
26
  import { NavigationContainerProps } from './types';
22
27
  import { ApplicationContext, MiniAppContext } from '../Context';
23
- import { useDefaultRegularFontFamily } from '../Consts/designSystemFont';
24
28
  import Localize from './Localize';
25
29
  import { Colors, defaultTheme } from '../Consts';
26
30
  import { HeaderLeft } from './Components/HeaderLeft';
@@ -103,8 +107,10 @@ const Navigation: React.FC<any> = ({
103
107
  const navigator = useRef(new Navigator(navigationRef, isReady));
104
108
  const [showGrid, setShowGrid] = useState(false);
105
109
  const insets = useSafeAreaInsets();
106
- const defaultRegularFontFamily = useDefaultRegularFontFamily();
107
110
  const syncCanGoBack = useNativeCanGoBack();
111
+ const isWhiteList = isWhiteListDesignSystem(context);
112
+ const fontFamily = isWhiteList ? 'MomoTrustSans' : 'SFProText';
113
+ const navigationFontFamily = isWhiteList ? 'MomoTrustSans-Regular' : 'SFProText';
108
114
  let headerBackground = context?.designSystemConfig?.config?.headerBar;
109
115
  let headerGradient = theme.colors?.gradient;
110
116
 
@@ -156,6 +162,7 @@ const Navigation: React.FC<any> = ({
156
162
  navigator: navigator.current,
157
163
  theme: {
158
164
  ...theme,
165
+ font: fontFamily,
159
166
  colors: {
160
167
  ...theme.colors,
161
168
  gradient: headerGradient,
@@ -183,19 +190,19 @@ const Navigation: React.FC<any> = ({
183
190
  },
184
191
  fonts: {
185
192
  regular: {
186
- fontFamily: defaultRegularFontFamily,
193
+ fontFamily: navigationFontFamily,
187
194
  fontWeight: '400',
188
195
  },
189
196
  medium: {
190
- fontFamily: defaultRegularFontFamily,
197
+ fontFamily: navigationFontFamily,
191
198
  fontWeight: '400',
192
199
  },
193
200
  bold: {
194
- fontFamily: defaultRegularFontFamily,
201
+ fontFamily: navigationFontFamily,
195
202
  fontWeight: '400',
196
203
  },
197
204
  heavy: {
198
- fontFamily: defaultRegularFontFamily,
205
+ fontFamily: navigationFontFamily,
199
206
  fontWeight: '400',
200
207
  },
201
208
  },
@@ -3,7 +3,6 @@ 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';
7
6
  import Localize from './Localize';
8
7
  import { defaultTheme } from '../Consts';
9
8
  import {
@@ -11,7 +10,7 @@ import {
11
10
  NavigationContainerRef,
12
11
  NavigationIndependentTree,
13
12
  } from '@react-navigation/native';
14
- import { getModalOptions } from './utils';
13
+ import { getModalOptions, isWhiteListDesignSystem } from './utils';
15
14
  import { createStackNavigator } from '@react-navigation/stack';
16
15
  import ModalScreen from './ModalScreen';
17
16
  import { View } from 'react-native';
@@ -43,7 +42,6 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
43
42
  const isReady = useRef(false);
44
43
  const navigator = useRef(new Navigator(navigationRef, isReady, true));
45
44
  const [currentContext, setCurrentContext] = useState({});
46
- const defaultRegularFontFamily = useDefaultRegularFontFamily();
47
45
 
48
46
  useEffect(() => {
49
47
  const sub = maxApi?.observer?.('font_scale_config', (data: any) => {
@@ -80,6 +78,9 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
80
78
  ...context,
81
79
  ...currentContext,
82
80
  };
81
+ const isWhiteList = isWhiteListDesignSystem(mergedContext);
82
+ const fontFamily = isWhiteList ? 'MomoTrustSans' : 'SFProText';
83
+ const navigationFontFamily = isWhiteList ? 'MomoTrustSans-Regular' : 'SFProText';
83
84
 
84
85
  return (
85
86
  <View style={{ height: height ?? '100%', minHeight: 1 }}>
@@ -90,6 +91,7 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
90
91
  navigator: navigator.current,
91
92
  theme: {
92
93
  ...theme,
94
+ font: fontFamily,
93
95
  colors: {
94
96
  ...theme.colors,
95
97
  gradient: headerGradient,
@@ -116,19 +118,19 @@ const WidgetContainer: React.FC<WidgetContainerProps> = ({
116
118
  },
117
119
  fonts: {
118
120
  regular: {
119
- fontFamily: defaultRegularFontFamily,
121
+ fontFamily: navigationFontFamily,
120
122
  fontWeight: '400',
121
123
  },
122
124
  medium: {
123
- fontFamily: defaultRegularFontFamily,
125
+ fontFamily: navigationFontFamily,
124
126
  fontWeight: '400',
125
127
  },
126
128
  bold: {
127
- fontFamily: defaultRegularFontFamily,
129
+ fontFamily: navigationFontFamily,
128
130
  fontWeight: '400',
129
131
  },
130
132
  heavy: {
131
- fontFamily: defaultRegularFontFamily,
133
+ fontFamily: navigationFontFamily,
132
134
  fontWeight: '400',
133
135
  },
134
136
  },
@@ -475,6 +475,9 @@ const SwipeBackHaptic = () => {
475
475
  return null;
476
476
  };
477
477
 
478
+ const isWhiteListDesignSystem = (context: any): boolean =>
479
+ context?.designSystemConfig?.isWhiteListDesignSystem === true;
480
+
478
481
  export {
479
482
  getStackOptions,
480
483
  getModalOptions,
@@ -487,4 +490,5 @@ export {
487
490
  useNativeCanGoBack,
488
491
  useNormalizedSharedValue,
489
492
  SwipeBackHaptic,
493
+ isWhiteListDesignSystem,
490
494
  };
package/Consts/index.ts CHANGED
@@ -2,4 +2,3 @@ export * from './colors+spacing+radius';
2
2
  export * from './theme';
3
3
  export * from './styles';
4
4
  export const GRIDVIEW = false;
5
- export * from './designSystemFont';
package/Consts/theme.ts CHANGED
@@ -51,7 +51,7 @@ const defaultTheme: Theme = {
51
51
  container: Colors.blue_08,
52
52
  },
53
53
  },
54
- font: 'MomoTrustSans',
54
+ font: 'SFProText',
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: 'MomoTrustSans',
108
+ font: 'SFProText',
109
109
  assets: {},
110
110
  };
111
111
 
@@ -4,13 +4,16 @@ import React, {
4
4
  useContext,
5
5
  useEffect,
6
6
  useImperativeHandle,
7
+ useLayoutEffect,
7
8
  useRef,
8
9
  useState,
9
10
  } from 'react';
10
11
  import {
11
12
  NativeSyntheticEvent,
13
+ Platform,
12
14
  TextInput,
13
15
  TextInputFocusEventData,
16
+ TextInputSelectionChangeEventData,
14
17
  TouchableOpacity,
15
18
  View,
16
19
  } from 'react-native';
@@ -32,9 +35,124 @@ import {
32
35
  } from './common';
33
36
  import { InputMoneyProps } from './index';
34
37
  import styles from './styles';
35
- import { formatNumberToMoney } from './utils';
36
38
  import SystemTextInput from './SystemTextInput';
37
39
 
40
+ type Selection = { start: number; end: number };
41
+ type Edit = { start: number; end: number; inserted: string };
42
+
43
+ const countDigits = (text: string) => text.replace(/\D/g, '').length;
44
+
45
+ const groupDigits = (digits: string) =>
46
+ digits.replace(/\B(?=(\d{3})+(?!\d))/g, '.');
47
+
48
+ // Caret position right after the `digitIndex`-th digit of `display`.
49
+ const caretFromDigitIndex = (display: string, digitIndex: number) => {
50
+ let count = 0;
51
+ for (let i = 0; i < display.length && count < digitIndex; i++) {
52
+ if (/\d/.test(display[i])) {
53
+ count += 1;
54
+ if (count === digitIndex) return i + 1;
55
+ }
56
+ }
57
+ return 0;
58
+ };
59
+
60
+ // Finds which range of `old` was replaced to produce `next`. `selection` is
61
+ // the pre-edit selection on iOS and already the post-edit caret on Android,
62
+ // where onSelectionChange fires before onChangeText.
63
+ const detectEdit = (old: string, next: string, selection: Selection): Edit => {
64
+ const { start, end } = selection;
65
+ const removed = old.length - next.length;
66
+ const preEdit: Edit[] = [
67
+ {
68
+ start,
69
+ end,
70
+ inserted: next.slice(start, next.length - (old.length - end)),
71
+ },
72
+ { start: start - removed, end: start, inserted: '' },
73
+ { start, end: start + removed, inserted: '' },
74
+ ];
75
+ const postEdit: Edit[] = [];
76
+ const tail = next.length - start;
77
+ if (start === end && tail <= old.length) {
78
+ let prefix = 0;
79
+ while (
80
+ prefix < Math.min(start, old.length - tail) &&
81
+ old[prefix] === next[prefix]
82
+ ) {
83
+ prefix += 1;
84
+ }
85
+ postEdit.push({
86
+ start: prefix,
87
+ end: old.length - tail,
88
+ inserted: next.slice(prefix, start),
89
+ });
90
+ }
91
+ const candidates =
92
+ Platform.OS === 'android'
93
+ ? [...postEdit, ...preEdit]
94
+ : [...preEdit, ...postEdit];
95
+ const match = candidates.find(
96
+ e =>
97
+ e.start >= 0 &&
98
+ e.end >= e.start &&
99
+ e.end <= old.length &&
100
+ old.slice(0, e.start) + e.inserted + old.slice(e.end) === next,
101
+ );
102
+ if (match) return match;
103
+
104
+ let prefix = 0;
105
+ while (
106
+ prefix < Math.min(old.length, next.length) &&
107
+ old[prefix] === next[prefix]
108
+ ) {
109
+ prefix += 1;
110
+ }
111
+ let suffix = 0;
112
+ while (
113
+ suffix < Math.min(old.length, next.length) - prefix &&
114
+ old[old.length - 1 - suffix] === next[next.length - 1 - suffix]
115
+ ) {
116
+ suffix += 1;
117
+ }
118
+ return {
119
+ start: prefix,
120
+ end: old.length - suffix,
121
+ inserted: next.slice(prefix, next.length - suffix),
122
+ };
123
+ };
124
+
125
+ // Applies `edit` to the digits of `display`. Separators and currency are never
126
+ // deleted: removing a separator deletes the digit before it instead, removing
127
+ // only the currency leaves the digits untouched.
128
+ const applyEdit = (display: string, edit: Edit, digitLimit: number) => {
129
+ const digits = display.replace(/\D/g, '');
130
+ let left = countDigits(display.slice(0, edit.start));
131
+ let removed = countDigits(display.slice(edit.start, edit.end));
132
+ const inserted = edit.inserted.replace(/\D/g, '');
133
+ if (
134
+ !removed &&
135
+ !inserted &&
136
+ left > 0 &&
137
+ display.slice(edit.start, edit.end).includes('.')
138
+ ) {
139
+ left -= 1;
140
+ removed = 1;
141
+ }
142
+ const next = digits.slice(0, left) + inserted + digits.slice(left + removed);
143
+ const trimmed = next.replace(/^0+(?=\d)/, '');
144
+ if ((!removed && !inserted) || trimmed.length > digitLimit) {
145
+ return { digits, caretDigit: left };
146
+ }
147
+ return {
148
+ digits: trimmed,
149
+ caretDigit: Math.max(
150
+ 0,
151
+ left + inserted.length - (next.length - trimmed.length),
152
+ ),
153
+ };
154
+ };
155
+
38
156
  const InputMoney = forwardRef(
39
157
  (
40
158
  {
@@ -73,7 +191,14 @@ const InputMoney = forwardRef(
73
191
  const [focused, setFocused] = useState(false);
74
192
  const [displayValue, setDisplayValue] = useState('');
75
193
  const [numericValue, setNumericValue] = useState('');
76
- const [lastDisplayValue, setLastDisplayValue] = useState('');
194
+ const [commitCount, setCommitCount] = useState(0);
195
+ const displayRef = useRef('');
196
+ const selectionRef = useRef<Selection>({ start: 0, end: 0 });
197
+ // Caret to push to native once the committed text is rendered.
198
+ const pendingCaretRef = useRef<number | null>(null);
199
+ // Caret the native input reports for the raw, unformatted text. On iOS that
200
+ // event lands after onChangeText and must not override the formatted caret.
201
+ const rawCaretRef = useRef<number | null>(null);
77
202
  const inputRef = useRef<TextInput>(null);
78
203
  const componentName = 'InputMoney';
79
204
 
@@ -91,25 +216,36 @@ const InputMoney = forwardRef(
91
216
 
92
217
  useEffect(() => {
93
218
  if (value !== undefined && typeof value === 'string') {
94
- const cleanValue = value.replace(/\D/g, '');
219
+ const cleanValue = value.replace(/\D/g, '').replace(/^0+(?=\d)/, '');
95
220
  if (cleanValue !== numericValue) {
96
- setNumericValue(cleanValue);
97
- updateDisplayValue(cleanValue);
221
+ commit(cleanValue, cleanValue.length);
98
222
  }
99
223
  }
100
224
  }, [value]);
101
225
 
102
- useEffect(() => {
103
- setLastDisplayValue(displayValue);
104
- }, [displayValue]);
105
-
106
- const updateDisplayValue = (numeric: string) => {
107
- if (!numeric) {
108
- setDisplayValue('');
109
- return;
226
+ // Always set the caret imperatively: a controlled `selection` prop is only
227
+ // sent to native when it differs from the last native selection, so it is
228
+ // skipped whenever a stale selection event already reported the same value.
229
+ useLayoutEffect(() => {
230
+ const caret = pendingCaretRef.current;
231
+ if (caret === null) return;
232
+ pendingCaretRef.current = null;
233
+ if (inputRef.current?.isFocused()) {
234
+ inputRef.current.setSelection(caret, caret);
110
235
  }
111
- const formatted = formatNumberToMoney(Number(numeric));
112
- setDisplayValue(formatted ? `${formatted}${currency}` : '');
236
+ }, [commitCount]);
237
+
238
+ const commit = (digits: string, caretDigit: number) => {
239
+ const display = digits ? `${groupDigits(digits)}${currency}` : '';
240
+ const caret = caretFromDigitIndex(display, caretDigit);
241
+ const changed = digits !== numericValue;
242
+ displayRef.current = display;
243
+ selectionRef.current = { start: caret, end: caret };
244
+ pendingCaretRef.current = caret;
245
+ setCommitCount(count => count + 1);
246
+ setDisplayValue(display);
247
+ setNumericValue(digits);
248
+ return changed;
113
249
  };
114
250
 
115
251
  const parseInputText = (text: string): string => {
@@ -119,47 +255,49 @@ const InputMoney = forwardRef(
119
255
  return textWithoutCurrency.replace(/[^\d]/g, '');
120
256
  };
121
257
 
122
- const updateNumericValue = (val: string) => {
123
- let next = val.replace(/[^\d]/g, '');
124
- if (next.length > digitLimit) next = next.slice(0, digitLimit);
125
- if (/^\d*$/.test(next)) {
126
- setNumericValue(next);
127
- updateDisplayValue(next);
128
- onChangeText?.(next);
129
- }
130
- };
131
-
132
258
  const onClearText = () => {
133
259
  inputRef?.current?.clear();
134
260
  inputRef.current?.setNativeProps({ text: '' });
135
- setDisplayValue('');
136
- setNumericValue('');
261
+ commit('', 0);
137
262
  onChangeText?.('');
138
263
  };
139
264
 
140
265
  const _onChangeText = (text: string) => {
141
- if (!text) {
142
- setDisplayValue('');
143
- setNumericValue('');
144
- onChangeText?.('');
266
+ let digits = '';
267
+ let caretDigit = 0;
268
+ rawCaretRef.current = 0;
269
+ if (text) {
270
+ const edit = detectEdit(displayRef.current, text, selectionRef.current);
271
+ rawCaretRef.current = edit.start + edit.inserted.length;
272
+ ({ digits, caretDigit } = applyEdit(
273
+ displayRef.current,
274
+ edit,
275
+ digitLimit,
276
+ ));
277
+ }
278
+ if (commit(digits, caretDigit)) {
279
+ onChangeText?.(digits);
280
+ }
281
+ };
282
+
283
+ // Keeps the caret out of the currency suffix.
284
+ const _onSelectionChange = (
285
+ e: NativeSyntheticEvent<TextInputSelectionChangeEventData>,
286
+ ) => {
287
+ props.onSelectionChange?.(e);
288
+ const { start, end } = e.nativeEvent.selection;
289
+ const rawCaret = rawCaretRef.current;
290
+ rawCaretRef.current = null;
291
+ if (start === end && start === rawCaret) {
145
292
  return;
146
293
  }
147
- if (text.length < lastDisplayValue.length) {
148
- const lastChar = lastDisplayValue.charAt(lastDisplayValue.length - 1);
149
- const isRemovingCurrency =
150
- lastDisplayValue.endsWith(currency) || lastChar === ' ';
151
- const isRemovingDot = lastChar === '.';
152
- if (isRemovingCurrency || isRemovingDot) {
153
- const currentNumericValue = numericValue;
154
- if (currentNumericValue.length > 0) {
155
- const newNumericValue = currentNumericValue.slice(0, -1);
156
- updateNumericValue(newNumericValue);
157
- return;
158
- }
159
- }
294
+ const display = displayRef.current;
295
+ const max = display ? display.length - currency.length : 0;
296
+ const clamped = { start: Math.min(start, max), end: Math.min(end, max) };
297
+ selectionRef.current = clamped;
298
+ if (clamped.start !== start || clamped.end !== end) {
299
+ inputRef.current?.setSelection(clamped.start, clamped.end);
160
300
  }
161
- const newNumericValue = parseInputText(text);
162
- updateNumericValue(newNumericValue);
163
301
  };
164
302
 
165
303
  const _onFocus = (e: NativeSyntheticEvent<TextInputFocusEventData>) => {
@@ -174,13 +312,16 @@ const InputMoney = forwardRef(
174
312
 
175
313
  const _setText = (text: string) => {
176
314
  if (!text) {
177
- setDisplayValue('');
178
- setNumericValue('');
315
+ commit('', 0);
179
316
  onChangeText?.('');
180
317
  return;
181
318
  }
182
- const newNumericValue = parseInputText(text);
183
- updateNumericValue(newNumericValue);
319
+ const digits = parseInputText(text)
320
+ .replace(/^0+(?=\d)/, '')
321
+ .slice(0, digitLimit);
322
+ if (commit(digits, digits.length)) {
323
+ onChangeText?.(digits);
324
+ }
184
325
  };
185
326
 
186
327
  useImperativeHandle(ref, () => {
@@ -247,6 +388,7 @@ const InputMoney = forwardRef(
247
388
  textBreakStrategy="highQuality"
248
389
  value={displayValue}
249
390
  onChangeText={_onChangeText}
391
+ onSelectionChange={_onSelectionChange}
250
392
  onFocus={_onFocus}
251
393
  onBlur={_onBlur}
252
394
  placeholder={placeholder}
package/Text/index.tsx CHANGED
@@ -7,10 +7,6 @@ import {
7
7
  MiniAppContext,
8
8
  SkeletonContext,
9
9
  } from '../Context';
10
- import {
11
- NEW_DEFAULT_FONT_FAMILY,
12
- useResolvedFontFamily,
13
- } from '../Consts/designSystemFont';
14
10
  import { scaleSize, useScaleSize } from './utils';
15
11
  import { Skeleton } from '../Skeleton';
16
12
 
@@ -118,8 +114,7 @@ const TypoStyles = (typo: Typography, newFontFamily?: string) => {
118
114
  const typoStyle = styleSheet[typo] ?? styleSheet.paragraph_default;
119
115
  const { fontWeight, fontSize, fontStyle, lineHeight } = typoStyle;
120
116
  const style = FontStyle[fontStyle ?? 'normal'];
121
- const font = useResolvedFontFamily(newFontFamily ?? theme.font);
122
- const resolvedDefaultFamily = useResolvedFontFamily(NEW_DEFAULT_FONT_FAMILY);
117
+ const font = newFontFamily ?? theme.font;
123
118
  let fontFamily: string;
124
119
 
125
120
  switch (font) {
@@ -148,11 +143,7 @@ const TypoStyles = (typo: Typography, newFontFamily?: string) => {
148
143
  break;
149
144
  }
150
145
  default: {
151
- fontFamily = `${resolvedDefaultFamily}-${
152
- resolvedDefaultFamily === NEW_DEFAULT_FONT_FAMILY
153
- ? MomoTrustSans[fontWeight]
154
- : SFProText[fontWeight]
155
- }`;
146
+ fontFamily = `${font}-${SFProText[fontWeight]}${style}`;
156
147
  }
157
148
  }
158
149
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.167.1-beta.1",
3
+ "version": "0.167.1-beta.10",
4
4
  "description": "React Native Component Kits",
5
5
  "main": "index.ts",
6
6
  "scripts": {},
@@ -1,38 +0,0 @@
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`;