@momo-kits/foundation 0.168.1-beta.9 → 0.168.1-rn862.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.
@@ -333,7 +333,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
333
333
  onRequestClose={() => {
334
334
  onDismiss();
335
335
  }}
336
- style={StyleSheet.absoluteFillObject}
336
+ style={StyleSheet.absoluteFill}
337
337
  isModalKit={true}
338
338
  >
339
339
  <KeyboardAvoidingView
@@ -347,7 +347,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
347
347
  style={styles.container}
348
348
  >
349
349
  <Pressable
350
- style={StyleSheet.absoluteFillObject}
350
+ style={StyleSheet.absoluteFill}
351
351
  onPress={() => {
352
352
  action.current = 'touch';
353
353
  onDismiss();
@@ -133,7 +133,7 @@ const Modal: React.FC<ModalParams> = props => {
133
133
  transparent
134
134
  visible={true}
135
135
  onRequestClose={onDismiss}
136
- style={StyleSheet.absoluteFillObject}
136
+ style={StyleSheet.absoluteFill}
137
137
  isModalKit={true}
138
138
  >
139
139
  <KeyboardAvoidingView
@@ -141,7 +141,7 @@ const Modal: React.FC<ModalParams> = props => {
141
141
  behavior={Platform.OS === 'ios' ? 'padding' : undefined}
142
142
  >
143
143
  <Pressable
144
- style={StyleSheet.absoluteFillObject}
144
+ style={StyleSheet.absoluteFill}
145
145
  onPress={() => onDismiss(undefined, barrierDismissible)}
146
146
  >
147
147
  <Animated.View style={[styles.overlayContent, { opacity }]} />
package/Divider/index.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { useContext } from 'react';
2
- import { View, ViewStyle } from 'react-native';
2
+ import { StyleProp, View, ViewStyle } from 'react-native';
3
3
  import { ApplicationContext } from '../Context';
4
4
  import { Spacing } from '../Consts';
5
5
  import { DashDivider } from './DashDivider';
@@ -8,7 +8,7 @@ export interface DividerProps {
8
8
  /**
9
9
  * Custom styles for divider
10
10
  */
11
- style?: ViewStyle;
11
+ style?: StyleProp<ViewStyle>;
12
12
 
13
13
  /**
14
14
  * Enable margin vertical 4px
@@ -30,13 +30,13 @@ const Divider: React.FC<DividerProps> = ({
30
30
  return (
31
31
  <View
32
32
  style={[
33
- style,
34
33
  {
35
34
  height: 1,
36
35
  width: '100%',
37
36
  backgroundColor: theme.colors.border.default,
38
37
  marginVertical: useMargin ? Spacing.XS : 0,
39
38
  },
39
+ style,
40
40
  ]}
41
41
  />
42
42
  );
package/Image/index.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import React, { useContext, useRef, useState } from 'react';
2
- import { StyleSheet, View } from 'react-native';
2
+ import { Image as RNImage, StyleSheet, View } from 'react-native';
3
3
  import FastImage from 'react-native-fast-image';
4
4
  import styles from './styles';
5
5
  import {
@@ -23,6 +23,10 @@ export const getImageName = (source: any): string => {
23
23
  return '';
24
24
  };
25
25
 
26
+ const isDataUriSource = (source: any): boolean => {
27
+ return typeof source?.uri === 'string' && source.uri.startsWith('data:');
28
+ };
29
+
26
30
  const Image: React.FC<ImageProps> = ({
27
31
  style,
28
32
  source,
@@ -43,6 +47,7 @@ const Image: React.FC<ImageProps> = ({
43
47
  const [status, setStatus] = useState<Status>('success');
44
48
 
45
49
  const showBaseLineDebug = context?.features?.showBaseLineDebug ?? false;
50
+ const useFastImage = !isDataUriSource(source);
46
51
 
47
52
  let accessibilityLabel: any = `img|${getImageName(source)}`;
48
53
  if (component?.componentId) {
@@ -79,6 +84,46 @@ const Image: React.FC<ImageProps> = ({
79
84
  return children;
80
85
  };
81
86
 
87
+ if (!useFastImage) {
88
+ return (
89
+ <RNImage
90
+ {...rest}
91
+ {...{
92
+ accessibilityLabel: rest.accessibilityLabel ?? accessibilityLabel,
93
+ }}
94
+ source={source}
95
+ style={[
96
+ styles.container,
97
+ style,
98
+ showBaseLineDebug && styles.debugBaseLine,
99
+ ]}
100
+ onLoadStart={() => {
101
+ error.current = false;
102
+ if (status !== 'loading' && loading) {
103
+ setStatus('loading');
104
+ }
105
+ }}
106
+ onLoad={() => {
107
+ error.current = false;
108
+ }}
109
+ onLoadEnd={() => {
110
+ let current: Status = 'success';
111
+ if (error.current) {
112
+ current = 'error';
113
+ }
114
+ setStatus(prevState =>
115
+ prevState !== current ? current : prevState,
116
+ );
117
+ }}
118
+ onError={() => {
119
+ error.current = true;
120
+ }}
121
+ >
122
+ {renderContent()}
123
+ </RNImage>
124
+ );
125
+ }
126
+
82
127
  return (
83
128
  <FastImage
84
129
  {...rest}
@@ -37,6 +37,8 @@ import SystemTextInput from './SystemTextInput';
37
37
 
38
38
  const moneyFormatter = new Intl.NumberFormat('vi-VN');
39
39
 
40
+ // Finds the common prefix and suffix of `old` and `text`; `size` counts the
41
+ // characters removed plus inserted between them.
40
42
  const findEdit = (old: string, text: string) => {
41
43
  let start = 0;
42
44
  while (start < text.length && old[start] === text[start]) {
@@ -127,8 +129,11 @@ const InputMoney = forwardRef(
127
129
  setLastDisplayValue(displayValue);
128
130
  }, [displayValue]);
129
131
 
132
+ // The selection only rides along with the render that reformats the text,
133
+ // then it is released so the user can move the caret freely.
130
134
  useEffect(() => {
131
135
  if (!caretSelection) return;
136
+ // A newer keystroke may already have queued its own selection; keep it.
132
137
  setCaretSelection(current =>
133
138
  current === caretSelection ? undefined : current,
134
139
  );
@@ -138,6 +143,9 @@ const InputMoney = forwardRef(
138
143
  const next = numeric ? moneyFormatter.format(Number(numeric)) : '';
139
144
  setDisplayValue(next);
140
145
 
146
+ // Android moves the caret proportionally when the text is replaced, so
147
+ // it lands before the typed digit once a separator is added. Send the
148
+ // caret together with the text, keeping the same digits after it.
141
149
  const digitsAfter = caretDigitsAfter.current;
142
150
  caretDigitsAfter.current = undefined;
143
151
  if (Platform.OS !== 'android' || digitsAfter === undefined) return;
@@ -179,6 +187,9 @@ const InputMoney = forwardRef(
179
187
  return;
180
188
  }
181
189
  const digits = parseInputText(text);
190
+ // When typing outpaces JS (slow devices) native rejects the stale
191
+ // formatted text and keeps the raw one, so the edit may apply to either.
192
+ // Pick the one that differs from the new text by a single edit.
182
193
  const raw = lastRawText.current;
183
194
  lastRawText.current = text;
184
195
  const formattedEdit = findEdit(lastDisplayValue, text);
@@ -188,6 +199,7 @@ const InputMoney = forwardRef(
188
199
  caretDigitsAfter.current = parseInputText(
189
200
  text.slice(text.length - suffix),
190
201
  ).length;
202
+ // Deleting a separator removes the digit before it.
191
203
  if (text.length < old.length && digits === numericValue) {
192
204
  const index = parseInputText(text.slice(0, start)).length - 1;
193
205
  if (index >= 0) {
@@ -198,11 +210,6 @@ const InputMoney = forwardRef(
198
210
  updateNumericValue(digits);
199
211
  };
200
212
 
201
- const focusAtEnd = () => {
202
- inputRef.current?.focus();
203
- inputRef.current?.setSelection(displayValue.length, displayValue.length);
204
- };
205
-
206
213
  const _onFocus = (e: TextInputFocusEvent) => {
207
214
  setFocused(true);
208
215
  onFocus?.(e);
@@ -272,7 +279,7 @@ const InputMoney = forwardRef(
272
279
  />
273
280
  <Pressable
274
281
  style={[styles.inputView, styles.moneyInputView]}
275
- onPress={focusAtEnd}
282
+ onPress={() => inputRef.current?.focus()}
276
283
  disabled={disabled}
277
284
  >
278
285
  <SystemTextInput
@@ -284,6 +291,8 @@ const InputMoney = forwardRef(
284
291
  disabled: disabled,
285
292
  ...props.accessibilityState,
286
293
  }}
294
+ // No width: the input sizes to its text natively, so the
295
+ // currency follows it without waiting for JS.
287
296
  style={[textStyle, styles.moneyTextInput, { color: textColor }]}
288
297
  allowFontScaling={false}
289
298
  textBreakStrategy="highQuality"
package/Input/styles.ts CHANGED
@@ -223,8 +223,9 @@ export default StyleSheet.create({
223
223
  },
224
224
  moneyTextInput: {
225
225
  flexShrink: 1,
226
+ height: '100%',
226
227
  paddingLeft: 0,
227
228
  paddingRight: Spacing.XXS,
228
- paddingVertical: 0,
229
+ paddingVertical: Spacing.S,
229
230
  },
230
231
  });
package/package.json CHANGED
@@ -1,38 +1,40 @@
1
1
  {
2
2
  "name": "@momo-kits/foundation",
3
- "version": "0.168.1-beta.9",
3
+ "version": "0.168.1-rn862.1",
4
4
  "description": "React Native Component Kits",
5
- "main": "index.ts",
6
- "scripts": {},
7
5
  "keywords": [
8
6
  "@momo-kits/foundation"
9
7
  ],
8
+ "license": "MoMo",
9
+ "main": "index.ts",
10
+ "publishConfig": {
11
+ "registry": "https://registry.npmjs.org/"
12
+ },
13
+ "scripts": {},
10
14
  "dependencies": {
11
- "react-native-fast-image": "git+https://oauth2:TGi6oBj-LdzsKpLXQSoH@gitlab.mservice.com.vn/momo-platform/public/react-native-fast-image.git#v8.11.0",
12
15
  "@react-navigation/bottom-tabs": "7.4.2",
13
16
  "@react-navigation/core": "7.12.1",
14
17
  "@react-navigation/elements": "2.5.2",
15
18
  "@react-navigation/native": "7.1.14",
16
19
  "@react-navigation/routers": "7.4.1",
17
20
  "@react-navigation/stack": "7.4.2",
18
- "react-native-gesture-handler": "2.27.1",
19
- "react-native-linear-gradient": "git+https://oauth2:TGi6oBj-LdzsKpLXQSoH@gitlab.mservice.com.vn/momo-platform/public/react-native-linear-gradient#v3.0.0",
20
- "react-native-reanimated": "4.2.2",
21
- "react-native-worklets": "0.6.1",
22
- "react-native-safe-area-context": "5.5.2",
23
- "react-native-reserved-regions": "0.2.0",
24
21
  "@shopify/flash-list": "2.1.0",
25
- "lottie-react-native": "7.2.4"
26
- },
27
- "peerDependencies": {
28
- "react-native": "*",
29
- "react-native-worklets": "0.6.1"
22
+ "lottie-react-native": "7.3.6",
23
+ "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",
24
+ "react-native-gesture-handler": "2.31.0",
25
+ "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",
26
+ "react-native-reanimated": "4.5.3",
27
+ "react-native-reserved-regions": "0.2.0",
28
+ "react-native-safe-area-context": "5.7.0"
30
29
  },
31
30
  "devDependencies": {
32
- "@types/color": "3.0.6"
33
- },
34
- "publishConfig": {
35
- "registry": "https://registry.npmjs.org/"
31
+ "@types/color": "3.0.6",
32
+ "react-native-reanimated": "4.5.3",
33
+ "react-native-worklets": "0.11.3"
36
34
  },
37
- "license": "MoMo"
35
+ "peerDependencies": {
36
+ "react-native": "*",
37
+ "react-native-reanimated": ">=4.5.0",
38
+ "react-native-worklets": ">=0.11.0"
39
+ }
38
40
  }