@momo-kits/foundation 0.74.2-react-native.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.tsx +120 -0
- package/Application/Components.tsx +534 -0
- package/Application/ModalScreen.tsx +268 -0
- package/Application/Navigation.ts +50 -0
- package/Application/NavigationContainer.tsx +120 -0
- package/Application/Navigator.ts +131 -0
- package/Application/StackScreen.tsx +71 -0
- package/Application/index.ts +41 -0
- package/Application/types.ts +216 -0
- package/Application/utils.tsx +151 -0
- package/Assets/DotAnimation.json +256 -0
- package/Assets/SpinnerAnimation.json +1027 -0
- package/Assets/icon.json +4031 -0
- package/Assets/icon_bank.json +506 -0
- package/Assets/language.json +202 -0
- package/Badge/Badge.tsx +56 -0
- package/Badge/BadgeDot.tsx +11 -0
- package/Badge/BadgeRibbon.tsx +125 -0
- package/Badge/Shape.tsx +29 -0
- package/Badge/index.tsx +7 -0
- package/Badge/styles.ts +58 -0
- package/Badge/types.ts +63 -0
- package/Button/index.tsx +310 -0
- package/Button/styles.ts +60 -0
- package/CheckBox/index.tsx +65 -0
- package/CheckBox/styles.ts +15 -0
- package/CheckBox/types.ts +38 -0
- package/Consts/colors+spacing+radius.ts +218 -0
- package/Consts/index.ts +4 -0
- package/Consts/styles.ts +52 -0
- package/Consts/theme.ts +125 -0
- package/Divider/index.tsx +21 -0
- package/Icon/index.tsx +41 -0
- package/Icon/types.ts +27 -0
- package/IconButton/index.tsx +139 -0
- package/IconButton/styles.ts +19 -0
- package/Image/index.tsx +83 -0
- package/Image/styles.ts +5 -0
- package/Image/types.ts +5 -0
- package/Input/Input.tsx +192 -0
- package/Input/InputDropDown.tsx +114 -0
- package/Input/InputMoney.tsx +163 -0
- package/Input/InputOTP.tsx +235 -0
- package/Input/InputSearch.tsx +151 -0
- package/Input/InputTextArea.tsx +159 -0
- package/Input/common.tsx +129 -0
- package/Input/index.tsx +251 -0
- package/Input/styles.ts +160 -0
- package/Input/utils.ts +69 -0
- package/Layout/Card.tsx +180 -0
- package/Layout/GridSystem.tsx +136 -0
- package/Layout/Item.tsx +56 -0
- package/Layout/ItemList.tsx +55 -0
- package/Layout/ItemSectionList.tsx +39 -0
- package/Layout/Screen.tsx +355 -0
- package/Layout/Section.tsx +179 -0
- package/Layout/index.ts +29 -0
- package/Layout/styles.ts +97 -0
- package/Layout/types.ts +23 -0
- package/Layout/utils.ts +55 -0
- package/Loader/DotLoader.tsx +37 -0
- package/Loader/Loader.tsx +13 -0
- package/Loader/ProgressBar.tsx +44 -0
- package/Loader/Spinner.tsx +28 -0
- package/Loader/index.tsx +4 -0
- package/Loader/styles.ts +10 -0
- package/Loader/types.ts +35 -0
- package/Loader/utils.ts +25 -0
- package/Pagination/Dot.tsx +16 -0
- package/Pagination/PaginationDot.tsx +38 -0
- package/Pagination/PaginationNumber.tsx +24 -0
- package/Pagination/PaginationScroll.tsx +88 -0
- package/Pagination/PaginationWhiteDot.tsx +35 -0
- package/Pagination/index.tsx +25 -0
- package/Pagination/styles.ts +50 -0
- package/Pagination/types.ts +40 -0
- package/Popup/PopupNotify.tsx +266 -0
- package/Popup/PopupPromotion.tsx +120 -0
- package/Popup/index.tsx +4 -0
- package/Popup/types.ts +87 -0
- package/Radio/index.tsx +64 -0
- package/Radio/styles.ts +11 -0
- package/Radio/types.ts +38 -0
- package/Skeleton/index.tsx +72 -0
- package/Skeleton/styles.ts +5 -0
- package/Skeleton/types.ts +6 -0
- package/Switch/index.tsx +37 -0
- package/Switch/styles.ts +23 -0
- package/Switch/types.ts +26 -0
- package/Tag/index.tsx +79 -0
- package/Tag/styles.ts +24 -0
- package/Tag/types.ts +36 -0
- package/Text/index.tsx +110 -0
- package/Text/styles.ts +73 -0
- package/Text/types.ts +34 -0
- package/Text/utils.ts +14 -0
- package/Title/index.tsx +132 -0
- package/Title/styles.ts +52 -0
- package/Title/types.ts +52 -0
- package/code-scanner.js +51 -0
- package/index.ts +51 -0
- package/package.json +36 -0
- package/publish.sh +23 -0
- package/tsconfig.json +24 -0
- package/verify.js +44 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import React, {useContext, useEffect, useRef, useState} from 'react';
|
|
2
|
+
import {ScrollView, StyleSheet, TouchableOpacity, View} from 'react-native';
|
|
3
|
+
import {PopupNotifyProps} from './types';
|
|
4
|
+
import {Radius, Spacing, Styles} from '../Consts';
|
|
5
|
+
import {Image} from '../Image';
|
|
6
|
+
import {Text} from '../Text';
|
|
7
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
8
|
+
import {Button} from '../Button';
|
|
9
|
+
import {Icon} from '../Icon';
|
|
10
|
+
|
|
11
|
+
const PopupNotify: React.FC<PopupNotifyProps> = ({
|
|
12
|
+
id,
|
|
13
|
+
image,
|
|
14
|
+
title = 'Title',
|
|
15
|
+
description = 'Description',
|
|
16
|
+
error,
|
|
17
|
+
secondary,
|
|
18
|
+
primary,
|
|
19
|
+
buttonDirection = 'row',
|
|
20
|
+
onIconClose,
|
|
21
|
+
}) => {
|
|
22
|
+
const context = useContext(MiniAppContext);
|
|
23
|
+
const {theme, navigator, translate} = useContext(ApplicationContext);
|
|
24
|
+
const [scrollContent, setScrollContent] = useState(false);
|
|
25
|
+
const closeAction = useRef('touch_outside');
|
|
26
|
+
|
|
27
|
+
let descriptionStyle = {};
|
|
28
|
+
let Description: any = View;
|
|
29
|
+
if (scrollContent) {
|
|
30
|
+
Description = ScrollView;
|
|
31
|
+
descriptionStyle = {height: 80};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* tracking
|
|
36
|
+
*/
|
|
37
|
+
useEffect(() => {
|
|
38
|
+
const routes = navigator?.ref.current?.getRootState()?.routes || [];
|
|
39
|
+
const routesLength = routes.length;
|
|
40
|
+
let screen_name = routes?.[0]?.params?.screen?.name;
|
|
41
|
+
if (routesLength > 1) {
|
|
42
|
+
screen_name = routes[routesLength - 2]?.params?.screen?.name;
|
|
43
|
+
}
|
|
44
|
+
const tracking = {
|
|
45
|
+
...context,
|
|
46
|
+
screen_name,
|
|
47
|
+
component_type: 'popup',
|
|
48
|
+
component_name: id,
|
|
49
|
+
error_code: error ? error : undefined,
|
|
50
|
+
};
|
|
51
|
+
navigator?.maxApi?.trackEvent?.('service_component_displayed', {
|
|
52
|
+
...tracking,
|
|
53
|
+
trigger_id: '111012100000000000',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
return () => {
|
|
57
|
+
navigator?.maxApi?.trackEvent?.('service_popup_dismissed', {
|
|
58
|
+
...tracking,
|
|
59
|
+
trigger_id: '111154100000000001',
|
|
60
|
+
action_type: closeAction.current,
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
}, []);
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* on action popup
|
|
67
|
+
* @param callback
|
|
68
|
+
*/
|
|
69
|
+
const onAction = (callback?: () => void) => {
|
|
70
|
+
navigator?.pop();
|
|
71
|
+
callback?.();
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* build main action of popup
|
|
76
|
+
*/
|
|
77
|
+
const buildAction = () => {
|
|
78
|
+
const renderRow = () => {
|
|
79
|
+
return (
|
|
80
|
+
<View style={Styles.row}>
|
|
81
|
+
{!!secondary?.title && (
|
|
82
|
+
<>
|
|
83
|
+
<View style={Styles.flex}>
|
|
84
|
+
<Button
|
|
85
|
+
title={secondary?.title}
|
|
86
|
+
type="text"
|
|
87
|
+
size="medium"
|
|
88
|
+
onPress={() => {
|
|
89
|
+
closeAction.current = 'button_action';
|
|
90
|
+
onAction(secondary?.onPress);
|
|
91
|
+
}}
|
|
92
|
+
/>
|
|
93
|
+
</View>
|
|
94
|
+
<View style={styles.buttonSpace} />
|
|
95
|
+
</>
|
|
96
|
+
)}
|
|
97
|
+
<View style={Styles.flex}>
|
|
98
|
+
<Button
|
|
99
|
+
title={primary.title}
|
|
100
|
+
size="medium"
|
|
101
|
+
onPress={() => {
|
|
102
|
+
closeAction.current = 'button_action';
|
|
103
|
+
onAction(primary.onPress);
|
|
104
|
+
}}
|
|
105
|
+
/>
|
|
106
|
+
</View>
|
|
107
|
+
</View>
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
const renderColumn = () => {
|
|
111
|
+
return (
|
|
112
|
+
<View style={Styles.columnCenter}>
|
|
113
|
+
<Button
|
|
114
|
+
title={primary.title}
|
|
115
|
+
size="medium"
|
|
116
|
+
onPress={() => {
|
|
117
|
+
closeAction.current = 'button_action';
|
|
118
|
+
onAction(primary.onPress);
|
|
119
|
+
}}
|
|
120
|
+
/>
|
|
121
|
+
{!!secondary?.title && (
|
|
122
|
+
<>
|
|
123
|
+
<View style={styles.buttonSpace} />
|
|
124
|
+
<Button
|
|
125
|
+
title={secondary?.title}
|
|
126
|
+
type="text"
|
|
127
|
+
size="medium"
|
|
128
|
+
onPress={() => {
|
|
129
|
+
closeAction.current = 'button_action';
|
|
130
|
+
onAction(secondary?.onPress);
|
|
131
|
+
}}
|
|
132
|
+
/>
|
|
133
|
+
</>
|
|
134
|
+
)}
|
|
135
|
+
</View>
|
|
136
|
+
);
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
if (buttonDirection == 'auto') {
|
|
140
|
+
if (
|
|
141
|
+
secondary?.title &&
|
|
142
|
+
(secondary.title.length > 12 || primary.title.length > 12)
|
|
143
|
+
) {
|
|
144
|
+
return renderColumn();
|
|
145
|
+
}
|
|
146
|
+
return renderRow();
|
|
147
|
+
}
|
|
148
|
+
if (buttonDirection == 'row') {
|
|
149
|
+
return renderRow();
|
|
150
|
+
}
|
|
151
|
+
return renderColumn();
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* build close action
|
|
156
|
+
*/
|
|
157
|
+
const buildCloseIcon = () => {
|
|
158
|
+
return (
|
|
159
|
+
<TouchableOpacity
|
|
160
|
+
style={styles.iconCloseContainer}
|
|
161
|
+
onPress={() => {
|
|
162
|
+
closeAction.current = 'icon_close';
|
|
163
|
+
onAction(onIconClose);
|
|
164
|
+
}}>
|
|
165
|
+
<View
|
|
166
|
+
style={[
|
|
167
|
+
styles.iconClose,
|
|
168
|
+
{
|
|
169
|
+
backgroundColor: theme.colors.text.default,
|
|
170
|
+
borderColor: theme.colors.background.surface,
|
|
171
|
+
},
|
|
172
|
+
]}>
|
|
173
|
+
<Icon
|
|
174
|
+
source="navigation_close"
|
|
175
|
+
color={theme.colors.background.surface}
|
|
176
|
+
size={14}
|
|
177
|
+
/>
|
|
178
|
+
</View>
|
|
179
|
+
</TouchableOpacity>
|
|
180
|
+
);
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<View
|
|
185
|
+
style={[
|
|
186
|
+
styles.container,
|
|
187
|
+
{backgroundColor: theme.colors.background.surface},
|
|
188
|
+
]}>
|
|
189
|
+
{!!image && <Image source={{uri: image}} style={styles.image} />}
|
|
190
|
+
<View style={styles.content}>
|
|
191
|
+
<Text typography={'header_default_bold'} numberOfLines={1}>
|
|
192
|
+
{title}
|
|
193
|
+
</Text>
|
|
194
|
+
<Description style={[styles.description, descriptionStyle]}>
|
|
195
|
+
<Text
|
|
196
|
+
typography={'body_default_regular'}
|
|
197
|
+
onTextLayout={({nativeEvent: {lines}}) => {
|
|
198
|
+
const enableScroll = lines.length > 3;
|
|
199
|
+
if (enableScroll != scrollContent) {
|
|
200
|
+
setScrollContent(enableScroll);
|
|
201
|
+
}
|
|
202
|
+
}}>
|
|
203
|
+
{description}
|
|
204
|
+
</Text>
|
|
205
|
+
</Description>
|
|
206
|
+
{!!error && (
|
|
207
|
+
<View style={styles.information}>
|
|
208
|
+
<Text
|
|
209
|
+
typography={'description_xs_regular'}
|
|
210
|
+
color={theme.colors.text.hint}
|
|
211
|
+
numberOfLines={1}>
|
|
212
|
+
{translate?.('errorCode')}
|
|
213
|
+
{error}
|
|
214
|
+
</Text>
|
|
215
|
+
</View>
|
|
216
|
+
)}
|
|
217
|
+
</View>
|
|
218
|
+
<View style={styles.contentAction}>{buildAction()}</View>
|
|
219
|
+
{buildCloseIcon()}
|
|
220
|
+
</View>
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
const styles = StyleSheet.create({
|
|
225
|
+
container: {
|
|
226
|
+
borderRadius: Radius.L,
|
|
227
|
+
minWidth: '100%',
|
|
228
|
+
},
|
|
229
|
+
image: {
|
|
230
|
+
borderTopLeftRadius: Radius.L,
|
|
231
|
+
borderTopRightRadius: Radius.L,
|
|
232
|
+
aspectRatio: 1.7777,
|
|
233
|
+
overflow: 'hidden',
|
|
234
|
+
},
|
|
235
|
+
content: {padding: Spacing.XL},
|
|
236
|
+
description: {
|
|
237
|
+
marginTop: Spacing.S,
|
|
238
|
+
},
|
|
239
|
+
information: {
|
|
240
|
+
marginTop: Spacing.S,
|
|
241
|
+
},
|
|
242
|
+
contentAction: {
|
|
243
|
+
paddingHorizontal: Spacing.XL,
|
|
244
|
+
paddingBottom: Spacing.XL,
|
|
245
|
+
},
|
|
246
|
+
buttonSpace: {
|
|
247
|
+
width: Spacing.S,
|
|
248
|
+
height: Spacing.S,
|
|
249
|
+
},
|
|
250
|
+
iconCloseContainer: {
|
|
251
|
+
position: 'absolute',
|
|
252
|
+
top: -Spacing.M,
|
|
253
|
+
right: -Spacing.M,
|
|
254
|
+
padding: Spacing.XS,
|
|
255
|
+
},
|
|
256
|
+
iconClose: {
|
|
257
|
+
width: 20,
|
|
258
|
+
height: 20,
|
|
259
|
+
alignItems: 'center',
|
|
260
|
+
justifyContent: 'center',
|
|
261
|
+
borderRadius: Radius.M,
|
|
262
|
+
borderWidth: 2,
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
export default PopupNotify;
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import React, {useContext, useEffect, useRef} from 'react';
|
|
2
|
+
import {StyleSheet, TouchableOpacity, View} from 'react-native';
|
|
3
|
+
import {PopupPromotionProps} from './types';
|
|
4
|
+
import {ApplicationContext, MiniAppContext} from '../Application';
|
|
5
|
+
import {Image} from '../Image';
|
|
6
|
+
import {Radius, Spacing} from '../Consts';
|
|
7
|
+
import {Icon} from '../Icon';
|
|
8
|
+
|
|
9
|
+
const PopupPromotion: React.FC<PopupPromotionProps> = ({
|
|
10
|
+
id,
|
|
11
|
+
image,
|
|
12
|
+
onIconClose,
|
|
13
|
+
}) => {
|
|
14
|
+
const context = useContext(MiniAppContext);
|
|
15
|
+
const {theme, navigator} = useContext(ApplicationContext);
|
|
16
|
+
const closeAction = useRef('touch_outside');
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* tracking
|
|
20
|
+
*/
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
const routes = navigator?.ref.current?.getRootState()?.routes || [];
|
|
23
|
+
const routesLength = routes.length;
|
|
24
|
+
let screen_name = routes?.[0]?.params?.screen?.name;
|
|
25
|
+
if (routesLength > 1) {
|
|
26
|
+
screen_name = routes[routesLength - 2]?.params?.screen?.name;
|
|
27
|
+
}
|
|
28
|
+
const tracking = {
|
|
29
|
+
...context,
|
|
30
|
+
screen_name,
|
|
31
|
+
component_type: 'popup',
|
|
32
|
+
component_name: id,
|
|
33
|
+
};
|
|
34
|
+
navigator?.maxApi?.trackEvent?.('service_component_displayed', {
|
|
35
|
+
...tracking,
|
|
36
|
+
trigger_id: '111012100000000000',
|
|
37
|
+
});
|
|
38
|
+
return () => {
|
|
39
|
+
navigator?.maxApi?.trackEvent?.('service_popup_dismissed', {
|
|
40
|
+
...tracking,
|
|
41
|
+
trigger_id: '111154100000000001',
|
|
42
|
+
action_type: closeAction.current,
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
}, []);
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* build close action
|
|
49
|
+
*/
|
|
50
|
+
const buildCloseIcon = () => {
|
|
51
|
+
return (
|
|
52
|
+
<View style={styles.iconCloseContainer}>
|
|
53
|
+
<TouchableOpacity
|
|
54
|
+
onPress={() => {
|
|
55
|
+
closeAction.current = 'icon_close';
|
|
56
|
+
navigator?.pop();
|
|
57
|
+
onIconClose?.();
|
|
58
|
+
}}
|
|
59
|
+
style={styles.iconButton}>
|
|
60
|
+
<View
|
|
61
|
+
style={[
|
|
62
|
+
styles.iconClose,
|
|
63
|
+
{
|
|
64
|
+
backgroundColor: theme.colors.text.default,
|
|
65
|
+
borderColor: theme.colors.background.surface,
|
|
66
|
+
},
|
|
67
|
+
]}>
|
|
68
|
+
<Icon
|
|
69
|
+
source="navigation_close"
|
|
70
|
+
color={theme.colors.background.surface}
|
|
71
|
+
size={14}
|
|
72
|
+
/>
|
|
73
|
+
</View>
|
|
74
|
+
</TouchableOpacity>
|
|
75
|
+
</View>
|
|
76
|
+
);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<View>
|
|
81
|
+
<Image
|
|
82
|
+
source={{
|
|
83
|
+
uri: image,
|
|
84
|
+
}}
|
|
85
|
+
style={styles.container}
|
|
86
|
+
/>
|
|
87
|
+
{buildCloseIcon()}
|
|
88
|
+
</View>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const styles = StyleSheet.create({
|
|
93
|
+
container: {
|
|
94
|
+
aspectRatio: 0.72,
|
|
95
|
+
width: '100%',
|
|
96
|
+
},
|
|
97
|
+
iconCloseContainer: {
|
|
98
|
+
width: '100%',
|
|
99
|
+
flexDirection: 'row',
|
|
100
|
+
justifyContent: 'center',
|
|
101
|
+
marginTop: Spacing.S,
|
|
102
|
+
},
|
|
103
|
+
iconButton: {
|
|
104
|
+
padding: 8,
|
|
105
|
+
},
|
|
106
|
+
iconClose: {
|
|
107
|
+
width: 20,
|
|
108
|
+
height: 20,
|
|
109
|
+
alignItems: 'center',
|
|
110
|
+
justifyContent: 'center',
|
|
111
|
+
borderRadius: Radius.M,
|
|
112
|
+
borderWidth: 2,
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
PopupPromotion.defaultProps = {
|
|
117
|
+
image: 'https://google.com',
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
export default PopupPromotion;
|
package/Popup/index.tsx
ADDED
package/Popup/types.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import {TextStyle} from 'react-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
|
|
4
|
+
export type PopupNotifyProps = {
|
|
5
|
+
/**
|
|
6
|
+
* `id`: Optional. id component_name for tracking component.
|
|
7
|
+
*/
|
|
8
|
+
id?: string;
|
|
9
|
+
/**
|
|
10
|
+
* `image`: Optional. Represents the URL or path of the image to be displayed in the PopupNotify component.
|
|
11
|
+
*/
|
|
12
|
+
image?: string;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* `title`: Represents the title text to be displayed in the PopupNotify component.
|
|
16
|
+
*/
|
|
17
|
+
title: string;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* `description`: Represents the description text to be displayed in the PopupNotify component.
|
|
21
|
+
*/
|
|
22
|
+
description: string | React.ReactNode;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* `error`: Optional. Represents additional error text to be displayed in the PopupNotify component.
|
|
26
|
+
*/
|
|
27
|
+
error?: string;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* `secondary`: Optional. Represents the secondary action that can be performed from the PopupNotify component.
|
|
31
|
+
*/
|
|
32
|
+
secondary?: PopupAction;
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* `primary`: Represents the primary action that can be performed from the PopupNotify component.
|
|
36
|
+
*/
|
|
37
|
+
primary: PopupAction;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* `buttonDirection`: Optional. Represents the direction in which the action buttons are laid out.
|
|
41
|
+
* - 'row': Buttons are laid out horizontally.
|
|
42
|
+
* - 'column': Buttons are laid out vertically.
|
|
43
|
+
* - 'auto': The layout is automatically determined by title length.
|
|
44
|
+
*/
|
|
45
|
+
buttonDirection?: PopupActionDirection;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* `onIconClose`: Optional. A callback function that is called when the close icon in the PopupNotify component is pressed.
|
|
49
|
+
*/
|
|
50
|
+
onIconClose?: () => void;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export type PopupPromotionProps = {
|
|
54
|
+
/**
|
|
55
|
+
* `id`: Optional. id component_name for tracking component.
|
|
56
|
+
*/
|
|
57
|
+
id?: string;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* `image`: Represents the URL or path of the image to be displayed in the PopupPromotion component.
|
|
61
|
+
*/
|
|
62
|
+
image: string;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* `onClose`: Optional. A callback function that is called when the PopupPromotion component is closed.
|
|
66
|
+
*/
|
|
67
|
+
onIconClose?: () => void;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
type PopupAction = {
|
|
71
|
+
/**
|
|
72
|
+
* `title`: Represents the title text of the action button.
|
|
73
|
+
*/
|
|
74
|
+
title: string;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* `onPress`: A callback function that is called when the action button is pressed.
|
|
78
|
+
*/
|
|
79
|
+
onPress: () => void;
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export type HighlightText = {
|
|
83
|
+
text: string;
|
|
84
|
+
style: TextStyle;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
type PopupActionDirection = 'row' | 'column' | 'auto';
|
package/Radio/index.tsx
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import React, {FC, useContext} from 'react';
|
|
2
|
+
import {TouchableOpacity, View} from 'react-native';
|
|
3
|
+
|
|
4
|
+
import {RadioProps} from './types';
|
|
5
|
+
import {Text} from '../Text';
|
|
6
|
+
import styles from './styles';
|
|
7
|
+
import {ApplicationContext} from '../Application';
|
|
8
|
+
import {Spacing} from '../Consts';
|
|
9
|
+
|
|
10
|
+
const Radio: FC<RadioProps> = ({
|
|
11
|
+
value,
|
|
12
|
+
groupValue,
|
|
13
|
+
disabled,
|
|
14
|
+
onChange,
|
|
15
|
+
label,
|
|
16
|
+
style,
|
|
17
|
+
}) => {
|
|
18
|
+
const {theme} = useContext(ApplicationContext);
|
|
19
|
+
const selected = value === groupValue;
|
|
20
|
+
let disabledStyle = {};
|
|
21
|
+
let checkBoxStyle = {
|
|
22
|
+
borderWidth: 2,
|
|
23
|
+
borderColor: theme.colors.text.default,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
if (selected) {
|
|
27
|
+
checkBoxStyle = {
|
|
28
|
+
borderWidth: 6,
|
|
29
|
+
borderColor: theme.colors.primary,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (disabled) {
|
|
33
|
+
disabledStyle = {
|
|
34
|
+
borderColor: selected
|
|
35
|
+
? theme.colors.background.tonal
|
|
36
|
+
: theme.colors.text.disable,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<TouchableOpacity
|
|
42
|
+
onPress={onChange}
|
|
43
|
+
disabled={disabled}
|
|
44
|
+
style={[
|
|
45
|
+
style,
|
|
46
|
+
{
|
|
47
|
+
flexDirection: 'row',
|
|
48
|
+
alignItems: 'center',
|
|
49
|
+
},
|
|
50
|
+
]}>
|
|
51
|
+
<View
|
|
52
|
+
style={[
|
|
53
|
+
styles.radio,
|
|
54
|
+
checkBoxStyle,
|
|
55
|
+
disabledStyle,
|
|
56
|
+
{marginRight: label ? Spacing.XS : 0},
|
|
57
|
+
]}
|
|
58
|
+
/>
|
|
59
|
+
{!!label && <Text typography={'body_default_regular'}>{label}</Text>}
|
|
60
|
+
</TouchableOpacity>
|
|
61
|
+
);
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
export {Radio};
|
package/Radio/styles.ts
ADDED
package/Radio/types.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import {ViewStyle} from 'react-native';
|
|
2
|
+
|
|
3
|
+
export type RadioProps = {
|
|
4
|
+
/**
|
|
5
|
+
* `value`: Represents the value associated with the Radio component.
|
|
6
|
+
* It is used to determine whether the Radio component is selected or not in comparison with the `groupValue`.
|
|
7
|
+
*/
|
|
8
|
+
value: any;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* `disabled`: Optional. If `true`, the user won't be able to interact with the Radio component.
|
|
12
|
+
* Defaults to `false` if not provided.
|
|
13
|
+
*/
|
|
14
|
+
disabled?: boolean;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* `label`: Optional. Represents the text label displayed next to the Radio component.
|
|
18
|
+
*/
|
|
19
|
+
label?: string;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* `onChange`: A callback function that is called when the value of the Radio component changes.
|
|
23
|
+
* It is triggered when the user interacts with the Radio component.
|
|
24
|
+
*/
|
|
25
|
+
onChange: () => void;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* `groupValue`: Represents the value of the selected Radio component within a group of Radio components.
|
|
29
|
+
* The Radio component for which `value` equals `groupValue` will be selected.
|
|
30
|
+
*/
|
|
31
|
+
groupValue: any;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* `style`: Optional. Used to apply custom styling to the Radio component.
|
|
35
|
+
* Accepts an object of style properties.
|
|
36
|
+
*/
|
|
37
|
+
style?: ViewStyle;
|
|
38
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import React, {useEffect, useMemo, useRef, useState} from 'react';
|
|
2
|
+
import {Animated, Easing, Platform, StyleSheet, View} from 'react-native';
|
|
3
|
+
import LinearGradient from 'react-native-linear-gradient';
|
|
4
|
+
import {SkeletonTypes} from './types';
|
|
5
|
+
import {Colors, Styles} from '../Consts';
|
|
6
|
+
import styles from './styles';
|
|
7
|
+
|
|
8
|
+
const Skeleton: React.FC<SkeletonTypes> = ({style}) => {
|
|
9
|
+
const [width, setWidth] = useState(0);
|
|
10
|
+
const PRIMARY_COLOR = Colors.black_05;
|
|
11
|
+
const HIGHLIGHT_COLOR1 = Colors.black_05;
|
|
12
|
+
const HIGHLIGHT_COLOR2 = Colors.black_03;
|
|
13
|
+
const beginShimmerPosition = useRef(new Animated.Value(0)).current;
|
|
14
|
+
|
|
15
|
+
const shimmerColors = [HIGHLIGHT_COLOR1, HIGHLIGHT_COLOR2, HIGHLIGHT_COLOR1];
|
|
16
|
+
const linearTranslate = beginShimmerPosition.interpolate({
|
|
17
|
+
inputRange: [0, 1],
|
|
18
|
+
outputRange: [-width, width],
|
|
19
|
+
});
|
|
20
|
+
const animatedValue = useMemo(() => {
|
|
21
|
+
return Animated.loop(
|
|
22
|
+
Animated.timing(beginShimmerPosition, {
|
|
23
|
+
toValue: 1,
|
|
24
|
+
duration: 1000,
|
|
25
|
+
easing: Easing.linear,
|
|
26
|
+
useNativeDriver: Platform.OS !== 'web',
|
|
27
|
+
}),
|
|
28
|
+
);
|
|
29
|
+
}, [beginShimmerPosition]);
|
|
30
|
+
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
animatedValue.start();
|
|
33
|
+
return () => {
|
|
34
|
+
animatedValue.stop();
|
|
35
|
+
};
|
|
36
|
+
}, [animatedValue]);
|
|
37
|
+
|
|
38
|
+
const onLayout = (newWidth: number) => {
|
|
39
|
+
if (newWidth !== width) {
|
|
40
|
+
setWidth(newWidth);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
return (
|
|
44
|
+
<View style={[styles.container, style]}>
|
|
45
|
+
<View
|
|
46
|
+
onLayout={e => onLayout(e.nativeEvent.layout.width)}
|
|
47
|
+
style={[Styles.flex, {backgroundColor: PRIMARY_COLOR}]}>
|
|
48
|
+
<Animated.View
|
|
49
|
+
style={{
|
|
50
|
+
transform: [{translateX: linearTranslate}],
|
|
51
|
+
width: '60%',
|
|
52
|
+
height: '100%',
|
|
53
|
+
}}>
|
|
54
|
+
<LinearGradient
|
|
55
|
+
style={[StyleSheet.absoluteFill]}
|
|
56
|
+
colors={shimmerColors}
|
|
57
|
+
start={{
|
|
58
|
+
x: 0,
|
|
59
|
+
y: 0,
|
|
60
|
+
}}
|
|
61
|
+
end={{
|
|
62
|
+
x: 1,
|
|
63
|
+
y: 0,
|
|
64
|
+
}}
|
|
65
|
+
/>
|
|
66
|
+
</Animated.View>
|
|
67
|
+
</View>
|
|
68
|
+
</View>
|
|
69
|
+
);
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export {Skeleton};
|