@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.
- package/Application/BottomSheet.tsx +2 -2
- package/Application/ModalScreen.tsx +2 -2
- package/Divider/index.tsx +3 -3
- package/Image/index.tsx +46 -1
- package/Input/InputMoney.tsx +15 -6
- package/Input/styles.ts +2 -1
- package/package.json +22 -20
|
@@ -333,7 +333,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
|
|
|
333
333
|
onRequestClose={() => {
|
|
334
334
|
onDismiss();
|
|
335
335
|
}}
|
|
336
|
-
style={StyleSheet.
|
|
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.
|
|
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.
|
|
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.
|
|
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}
|
package/Input/InputMoney.tsx
CHANGED
|
@@ -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={
|
|
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
package/package.json
CHANGED
|
@@ -1,38 +1,40 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@momo-kits/foundation",
|
|
3
|
-
"version": "0.168.1-
|
|
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.
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
"react-native": "
|
|
29
|
-
"react-native-
|
|
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
|
-
|
|
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
|
-
"
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"react-native": "*",
|
|
37
|
+
"react-native-reanimated": ">=4.5.0",
|
|
38
|
+
"react-native-worklets": ">=0.11.0"
|
|
39
|
+
}
|
|
38
40
|
}
|