@momo-kits/foundation 0.81.49 → 0.81.51-beta.0

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.
Files changed (73) hide show
  1. package/Application/BottomSheet.tsx +216 -0
  2. package/Application/BottomTab/BottomTabBar.tsx +278 -0
  3. package/Application/{BottomTab.tsx → BottomTab/index.tsx} +42 -18
  4. package/Application/Components.tsx +356 -91
  5. package/Application/Localize.ts +44 -0
  6. package/Application/ModalScreen.tsx +14 -185
  7. package/Application/Navigation.ts +5 -19
  8. package/Application/NavigationContainer.tsx +62 -72
  9. package/Application/Navigator.ts +154 -48
  10. package/Application/StackScreen.tsx +289 -32
  11. package/Application/constants.ts +9 -0
  12. package/Application/index.ts +13 -15
  13. package/Application/types.ts +81 -35
  14. package/Application/utils.tsx +76 -30
  15. package/Assets/icon_bank.json +1 -1
  16. package/Badge/Badge.tsx +1 -1
  17. package/Badge/BadgeDotAnimation.tsx +95 -0
  18. package/Badge/index.tsx +2 -1
  19. package/Badge/styles.ts +50 -6
  20. package/Button/index.tsx +44 -26
  21. package/CheckBox/index.tsx +37 -26
  22. package/CheckBox/types.ts +5 -3
  23. package/Consts/colors+spacing+radius.ts +14 -0
  24. package/Icon/index.tsx +9 -8
  25. package/Icon/types.ts +2 -2
  26. package/IconButton/index.tsx +24 -14
  27. package/Image/index.tsx +23 -8
  28. package/Image/types.ts +2 -0
  29. package/Input/Input.tsx +116 -26
  30. package/Input/InputDropDown.tsx +66 -51
  31. package/Input/InputMoney.tsx +106 -15
  32. package/Input/InputOTP.tsx +49 -26
  33. package/Input/InputSearch.tsx +252 -99
  34. package/Input/InputTextArea.tsx +26 -6
  35. package/Input/TextTyping.tsx +113 -0
  36. package/Input/common.tsx +48 -22
  37. package/Input/index.tsx +112 -77
  38. package/Input/styles.ts +48 -11
  39. package/Input/utils.ts +1 -1
  40. package/Layout/Card.tsx +4 -3
  41. package/Layout/FloatingButton.tsx +168 -0
  42. package/Layout/GridSystem.tsx +1 -1
  43. package/Layout/ItemList.tsx +3 -2
  44. package/Layout/Screen.tsx +242 -121
  45. package/Layout/Section.tsx +4 -3
  46. package/Layout/styles.ts +11 -13
  47. package/Layout/types.ts +1 -1
  48. package/Layout/utils.ts +4 -4
  49. package/Loader/index.tsx +2 -0
  50. package/Pagination/PaginationScroll.tsx +2 -2
  51. package/Pagination/styles.ts +1 -1
  52. package/Popup/PopupNotify.tsx +57 -46
  53. package/Popup/PopupPromotion.tsx +6 -8
  54. package/Popup/types.ts +1 -7
  55. package/Radio/index.tsx +35 -20
  56. package/Radio/types.ts +5 -3
  57. package/Switch/index.tsx +32 -18
  58. package/Switch/types.ts +5 -3
  59. package/Tag/index.tsx +9 -2
  60. package/Tag/styles.ts +3 -2
  61. package/Tag/types.ts +12 -0
  62. package/Text/index.tsx +24 -5
  63. package/Text/styles.ts +8 -8
  64. package/Text/types.ts +19 -1
  65. package/Title/index.tsx +170 -103
  66. package/Title/styles.ts +36 -9
  67. package/Title/types.ts +16 -48
  68. package/code-scanner.js +125 -16
  69. package/index.ts +7 -0
  70. package/migrate_typo.js +56 -0
  71. package/package.json +10 -9
  72. package/publish.sh +16 -21
  73. package/tsconfig.json +1 -1
@@ -1,41 +1,39 @@
1
+ import {Platform} from 'react-native';
2
+ import {createContext} from 'react';
1
3
  import {NavigationContainer} from './NavigationContainer';
4
+ import Localize from './Localize';
2
5
  import Screen from '../Layout/Screen';
3
6
  import {
4
7
  HeaderAnimated,
5
8
  HeaderBackground,
6
9
  HeaderCustom,
7
- HeaderLeft,
8
- HeaderRightAction,
9
10
  HeaderTitle,
10
- HeaderToolkitAction,
11
11
  NavigationButton,
12
+ HeaderRightAction,
12
13
  } from './Components';
13
14
  import BottomTab from './BottomTab';
14
- import {createContext} from 'react';
15
15
  import {defaultContext} from '../Consts';
16
- import {MiniAppInfo} from './types';
17
16
 
17
+ const Context = createContext({});
18
18
  const ApplicationContext = createContext(defaultContext);
19
- const MiniAppContext = createContext<MiniAppInfo>({
20
- appId: '',
21
- buildNumber: 0,
22
- code: '',
23
- toolkitConfig: {},
24
- fromCode: '',
25
- });
19
+
20
+ const MiniAppContext = (Platform as any).MiniAppContext ?? createContext({});
21
+ const ScreenContext = (Platform as any).ScreenContext ?? createContext({});
22
+ const ComponentContext = (Platform as any).ComponentContext ?? Context;
26
23
 
27
24
  export {
28
25
  ApplicationContext,
29
26
  MiniAppContext,
27
+ ScreenContext,
28
+ ComponentContext,
30
29
  NavigationContainer,
30
+ Localize,
31
31
  Screen,
32
32
  BottomTab,
33
33
  NavigationButton,
34
+ HeaderRightAction,
34
35
  HeaderTitle,
35
- HeaderLeft,
36
36
  HeaderBackground,
37
- HeaderRightAction,
38
- HeaderToolkitAction,
39
37
  HeaderCustom,
40
38
  HeaderAnimated,
41
39
  };
@@ -1,9 +1,15 @@
1
- import {Animated} from 'react-native';
1
+ import {EventArg} from '@react-navigation/core';
2
2
  import {StackNavigationOptions} from '@react-navigation/stack';
3
3
  import React from 'react';
4
- import Navigator from './Navigator';
4
+ import {Animated, ViewProps} from 'react-native';
5
5
  import {PopupNotifyProps} from '../Popup/types';
6
+ import Localize from './Localize';
6
7
  import Navigation from './Navigation';
8
+ import Navigator from './Navigator';
9
+ import {
10
+ NavigationActionCallbackErrorEnum,
11
+ NavigationActionCallbackStatusEnum,
12
+ } from './constants';
7
13
 
8
14
  type Screen = React.ComponentType<NavigationScreenProps>;
9
15
 
@@ -70,16 +76,6 @@ export type Context = {
70
76
  translate?: (key: string) => string;
71
77
  };
72
78
 
73
- export type MiniAppInfo = {
74
- [key: string]: any;
75
- code: string;
76
- appId: string;
77
- buildNumber: number;
78
- flowPartnerId?: string;
79
- toolkitConfig?: any;
80
- fromCode?: string;
81
- };
82
-
83
79
  export type LocalizationObject = {
84
80
  vi: {
85
81
  [key: string]: string;
@@ -94,7 +90,8 @@ export type NavigationContainerProps = {
94
90
  options?: NavigationOptions;
95
91
  theme: Theme;
96
92
  maxApi: any;
97
- localization?: LocalizationObject;
93
+ initialParams?: any;
94
+ localize: Localize;
98
95
  };
99
96
 
100
97
  export type NavigationScreenProps = {
@@ -109,32 +106,43 @@ export type ScreenParams = {
109
106
  options?: NavigationOptions;
110
107
  };
111
108
 
112
- export interface ModalParams extends ScreenParams {
109
+ export type ModalParams = {
113
110
  [key: string]: any;
111
+ screen: React.ComponentType;
114
112
  onDismiss?: () => void;
115
113
  barrierDismissible?: boolean;
116
- }
114
+ };
117
115
 
118
- export interface BottomSheetParams extends ScreenParams {
116
+ export type BottomSheetParams = {
119
117
  [key: string]: any;
120
- onDismiss?: () => void;
121
- snapPoint?: '30%' | '50%' | '70%' | '90%' | 'content';
122
- indicatorColor?: string;
123
- }
118
+ screen: React.ComponentType;
119
+ options: {
120
+ title: string;
121
+ surface?: boolean;
122
+ };
123
+ useNativeModal?: boolean;
124
+ surface?: boolean;
125
+ onDismiss?: (type?: string) => void;
126
+ barrierDismissible?: boolean;
127
+ draggable?: boolean;
128
+ useBottomInset?: boolean;
129
+ keyboardVerticalOffset?: number;
130
+ };
124
131
 
125
132
  export type NavigationButtonProps = {
126
133
  icon: string;
127
134
  tintColor?: string;
128
135
  useBorder?: boolean;
129
136
  onPress: () => void;
130
- badgeType?: 'dot' | 'number';
137
+ badgeType?: 'dot' | 'number' | 'dot-animation';
131
138
  badgeValue?: number;
139
+ accessibilityLabel?: string;
132
140
  };
133
141
 
134
142
  export type PinnedToolType = {
135
143
  key: string;
136
144
  badgeValue?: number;
137
- badgeType?: 'number' | 'dot';
145
+ badgeType?: 'number' | 'dot' | 'dot-animation';
138
146
  };
139
147
 
140
148
  export type RuntimeToolType = {
@@ -143,18 +151,29 @@ export type RuntimeToolType = {
143
151
  key: string;
144
152
  };
145
153
 
146
- export interface NavigationOptions extends StackNavigationOptions {
154
+ export interface NavigationOptions
155
+ extends Omit<StackNavigationOptions, 'headerRight'> {
147
156
  preventBack?: PopupNotifyProps;
148
157
  onPressLeftHeader?: () => void;
149
158
  surface?: boolean;
150
159
  hiddenBack?: boolean;
151
160
  customTitle?: TitleCustomProps;
152
- toolkitParams?: {
153
- pinnedTool?: PinnedToolType;
154
- runtimeTools?: RuntimeToolType[];
155
- };
161
+ headerRight?: HeaderRightToolkit | HeaderRightActions | any;
156
162
  }
157
163
 
164
+ export type HeaderRightToolkit = {
165
+ type?: 'toolkit';
166
+ pinnedTool?: PinnedToolType;
167
+ runtimeTools?: RuntimeToolType[];
168
+ preventClose?: PopupNotifyProps;
169
+ useMore?: boolean;
170
+ };
171
+
172
+ export type HeaderRightActions = {
173
+ type?: 'icon';
174
+ buttons: NavigationButtonProps[];
175
+ };
176
+
158
177
  export interface HeaderBackProps extends NavigationButtonProps {
159
178
  preventBack?: PopupNotifyProps;
160
179
  onPressLeftHeader?: () => void;
@@ -162,9 +181,8 @@ export interface HeaderBackProps extends NavigationButtonProps {
162
181
 
163
182
  export type HeaderBackgroundProps = {
164
183
  image?: string | null;
165
- backgroundColor?: string | null;
166
184
  animatedValue?: Animated.Value;
167
- useBorder?: boolean;
185
+ useSurface?: boolean;
168
186
  };
169
187
 
170
188
  export type TitleCustomProps = {
@@ -183,20 +201,25 @@ export type HeaderToolkitProps = {
183
201
  configs: any[];
184
202
  };
185
203
 
186
- export type HeaderAnimatedProps = {
204
+ export interface HeaderAnimatedProps extends ViewProps {
187
205
  animatedValue: Animated.Value;
188
206
  image: string;
189
- onPress?: () => void;
190
- };
207
+ }
191
208
 
192
209
  export type BottomTabItemProps = {
193
210
  name: string;
194
211
  label: string;
195
212
  icon: string;
196
213
  showDot?: boolean;
197
- badgeLabel?: string;
214
+ badgeLabel?: string | number;
198
215
  screen: Screen;
199
216
  options: NavigationOptions;
217
+ initialParams?: any;
218
+ listeners?: {
219
+ tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
220
+ focus?: (e: EventArg<'focus', false, unknown>) => void;
221
+ blur?: (e: EventArg<'blur', false, unknown>) => void;
222
+ };
200
223
  };
201
224
 
202
225
  export type BottomTabProps = {
@@ -205,12 +228,35 @@ export type BottomTabProps = {
205
228
  initialRouteName?: string;
206
229
  navigation: Navigation;
207
230
  listeners?: {
208
- tabPress?: any;
209
- focus?: any;
231
+ tabPress?: (e: EventArg<'tabPress', true, undefined>) => void;
232
+ focus?: (e: EventArg<'focus', false, unknown>) => void;
233
+ blur?: (e: EventArg<'blur', false, unknown>) => void;
210
234
  };
235
+ floatingButton?: FloatingButtonProps;
236
+ };
237
+
238
+ export type FloatingButtonProps = {
239
+ container?: React.ReactNode;
240
+ icon: string | React.ReactNode;
241
+ label: string;
242
+ onPress: () => void;
211
243
  };
212
244
 
213
245
  export type AnimatedHeader = {
214
246
  type: 'default' | 'surface';
215
247
  component?: (props?: any) => React.ReactElement;
248
+ headerTitle?: (props?: any) => React.ReactElement;
249
+ };
250
+
251
+ type NavigatorActionSuccessCallbackType = {
252
+ status: NavigationActionCallbackStatusEnum.Success;
253
+ };
254
+
255
+ type NavigatorActionFailCallbackType = {
256
+ status: NavigationActionCallbackStatusEnum.Failed;
257
+ type: NavigationActionCallbackErrorEnum;
216
258
  };
259
+
260
+ export type NavigatorCallbackParamsType =
261
+ | NavigatorActionSuccessCallbackType
262
+ | NavigatorActionFailCallbackType;
@@ -7,11 +7,13 @@ import {
7
7
  HeaderBackground,
8
8
  HeaderCustom,
9
9
  HeaderLeft,
10
+ HeaderRight,
10
11
  HeaderTitle,
11
- HeaderToolkitAction,
12
12
  } from './Components';
13
- import {NavigationOptions, Theme} from './types';
13
+ import {NavigationOptions} from './types';
14
14
  import {Colors} from '../Consts';
15
+ import Navigation from './Navigation';
16
+ import {LayoutChangeEvent} from 'react-native';
15
17
 
16
18
  /**
17
19
  * default options for stack screen
@@ -22,7 +24,7 @@ const getStackOptions = (): StackNavigationOptions => {
22
24
  headerTitle: HeaderTitle,
23
25
  headerBackground: (props: any) => <HeaderBackground {...props} />,
24
26
  headerLeft: (props: any) => <HeaderLeft {...props} />,
25
- headerRight: (props: any) => <HeaderToolkitAction {...props} />,
27
+ headerRight: (props: any) => <HeaderRight {...props} />,
26
28
  headerTintColor: Colors.black_01,
27
29
  };
28
30
  };
@@ -72,39 +74,44 @@ const getModalOptions = (): StackNavigationOptions => {
72
74
  /**
73
75
  * build react-navigation options
74
76
  */
75
- const getOptions = (params: NavigationOptions, theme: Theme) => {
77
+ const getOptions = (params: NavigationOptions, navigation?: Navigation) => {
76
78
  let options = {};
77
79
 
80
+ /**
81
+ * left header factory
82
+ */
78
83
  if (
79
84
  typeof params.onPressLeftHeader === 'function' ||
80
85
  params.preventBack !== undefined ||
81
86
  typeof params.hiddenBack === 'boolean'
82
87
  ) {
88
+ let headerLeft: any = (props: any) => (
89
+ <HeaderLeft
90
+ {...props}
91
+ preventBack={params.preventBack}
92
+ onPressLeftHeader={params.onPressLeftHeader}
93
+ />
94
+ );
95
+ if (params.hiddenBack) {
96
+ headerLeft = null;
97
+ }
83
98
  options = {
84
99
  ...options,
85
- headerLeft: params.hiddenBack
86
- ? null
87
- : (props: any) => (
88
- <HeaderLeft
89
- {...props}
90
- preventBack={params.preventBack}
91
- onPressLeftHeader={params.onPressLeftHeader}
92
- />
93
- ),
100
+ headerLeft,
94
101
  };
95
102
  }
96
103
 
97
- if (typeof params.surface == 'boolean') {
104
+ /**
105
+ * surface header style
106
+ */
107
+ if (typeof params.surface === 'boolean') {
108
+ console.warn('surface options is deprecated, headerType instead in screen');
98
109
  if (params.surface) {
99
110
  options = {
100
111
  ...options,
101
- headerTintColor: theme.colors.text.default,
112
+ headerTintColor: Colors.black_17,
102
113
  headerBackground: () => (
103
- <HeaderBackground
104
- image={null}
105
- backgroundColor={theme.colors.background.surface}
106
- useBorder={true}
107
- />
114
+ <HeaderBackground image={null} useSurface={true} />
108
115
  ),
109
116
  };
110
117
  } else {
@@ -116,7 +123,13 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
116
123
  }
117
124
  }
118
125
 
126
+ /**
127
+ * custom title
128
+ */
119
129
  if (params.customTitle) {
130
+ console.warn(
131
+ 'customTitle options is deprecated, please used headerTitle instead'
132
+ );
120
133
  options = {
121
134
  ...options,
122
135
  headerTitleAlign: 'left',
@@ -126,19 +139,39 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
126
139
  };
127
140
  }
128
141
 
129
- options = {
130
- ...options,
131
- headerRight: (props: any) => {
142
+ /**
143
+ * header right
144
+ */
145
+ if (params.headerRight) {
146
+ let headerRight: any = (props: any) => {
147
+ return (
148
+ <HeaderRight
149
+ {...props}
150
+ {...params.headerRight}
151
+ onLayout={(e: LayoutChangeEvent) => {
152
+ navigation?.onHeaderRightChange?.(e.nativeEvent.layout.width);
153
+ }}
154
+ />
155
+ );
156
+ };
157
+ if (typeof params.headerRight === 'function') {
158
+ headerRight = (props: any) => {
132
159
  return (
133
- <HeaderToolkitAction
134
- preventBack={params.preventBack}
135
- pinnedTool={params.toolkitParams?.pinnedTool}
136
- runtimeTools={params.toolkitParams?.runtimeTools}
160
+ <HeaderRight
137
161
  {...props}
138
- />
162
+ onLayout={(e: LayoutChangeEvent) => {
163
+ navigation?.onHeaderRightChange?.(e.nativeEvent.layout.width);
164
+ }}>
165
+ {params.headerRight(props)}
166
+ </HeaderRight>
139
167
  );
140
- },
168
+ };
169
+ }
170
+ options = {
171
+ ...options,
172
+ headerRight,
141
173
  };
174
+ }
142
175
 
143
176
  return {
144
177
  ...params,
@@ -146,4 +179,17 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
146
179
  };
147
180
  };
148
181
 
149
- export {getStackOptions, getDialogOptions, getModalOptions, getOptions};
182
+ const formatNameLength = (name = '') => {
183
+ let formattedName = name;
184
+ if (formattedName.length > 100) {
185
+ formattedName = formattedName.substring(0, 100);
186
+ }
187
+ return formattedName;
188
+ };
189
+ export {
190
+ getStackOptions,
191
+ getDialogOptions,
192
+ getModalOptions,
193
+ getOptions,
194
+ formatNameLength,
195
+ };
@@ -503,4 +503,4 @@
503
503
  "zalopay_icon": {
504
504
  "uri": "https://static.momocdn.net/app/img/kits/icon_bank/zalopay_icon.png"
505
505
  }
506
- }
506
+ }
package/Badge/Badge.tsx CHANGED
@@ -46,7 +46,7 @@ const Badge: FC<BadgeProps> = ({label = 'Label', style, backgroundColor}) => {
46
46
 
47
47
  return (
48
48
  <View style={[style, styles.badge, {backgroundColor: badgeColor}]}>
49
- <Text color={Colors.black_01} typography={'action_xs_bold'}>
49
+ <Text color={Colors.black_01} typography={'action_xxs_bold'}>
50
50
  {formatTitle()}
51
51
  </Text>
52
52
  </View>
@@ -0,0 +1,95 @@
1
+ import React, {useEffect, useRef} from 'react';
2
+ import {Animated, View} from 'react-native';
3
+ import {BadgeDotProps} from './types';
4
+ import styles from './styles';
5
+
6
+ const DURATION = 500;
7
+
8
+ const BadgeDotAnimation = ({size, style}: BadgeDotProps) => {
9
+ // Refs for animated values
10
+ const scaleAnim = useRef(new Animated.Value(1)).current;
11
+ const waveScaleAnim = useRef(new Animated.Value(1)).current;
12
+ const waveOpacityAnim = useRef(new Animated.Value(0)).current;
13
+
14
+ const dotStyle =
15
+ size === 'small' ? styles.dotAnimationSmall : styles.dotAnimation;
16
+ const waveStyle = size === 'small' ? styles.waveSmall : styles.wave;
17
+
18
+ useEffect(() => {
19
+ // Infinite loop animation for the scale and wave effect
20
+ const animation = Animated.loop(
21
+ Animated.parallel([
22
+ // Dot pulse animation
23
+ Animated.sequence([
24
+ Animated.spring(scaleAnim, {
25
+ toValue: 1, // Scale up slightly
26
+ friction: 5, // Controls the "bounciness" of the spring
27
+ tension: 30, // Controls the "stiffness" of the spring
28
+ useNativeDriver: true,
29
+ }),
30
+ Animated.spring(scaleAnim, {
31
+ toValue: 1.1,
32
+ friction: 5,
33
+ tension: 30,
34
+ useNativeDriver: true,
35
+ }),
36
+ ]), // Wave animation
37
+ Animated.sequence([
38
+ Animated.timing(waveScaleAnim, {
39
+ toValue: 2.5,
40
+ duration: DURATION * 3,
41
+ useNativeDriver: true,
42
+ }),
43
+ Animated.timing(waveScaleAnim, {
44
+ toValue: 1, // Reset wave size
45
+ duration: 0,
46
+ useNativeDriver: true,
47
+ }),
48
+ ]), // Wave opacity animation
49
+ Animated.sequence([
50
+ Animated.timing(waveOpacityAnim, {
51
+ toValue: 0.3, // Wave becomes visible
52
+ duration: DURATION * 2,
53
+ useNativeDriver: true,
54
+ }),
55
+ Animated.timing(waveOpacityAnim, {
56
+ toValue: 0, // Wave fades out
57
+ duration: DURATION,
58
+ useNativeDriver: true,
59
+ }),
60
+ ]),
61
+ ])
62
+ );
63
+ animation.start();
64
+
65
+ return () => {
66
+ animation.stop();
67
+ };
68
+ }, []);
69
+
70
+ return (
71
+ <View style={[styles.dotAnimationContainer, style]}>
72
+ {/* Wave Animation */}
73
+ <Animated.View
74
+ style={[
75
+ waveStyle,
76
+ {
77
+ transform: [{scale: waveScaleAnim}],
78
+ opacity: waveOpacityAnim,
79
+ },
80
+ ]}
81
+ />
82
+ {/* Dot Animation */}
83
+ <Animated.View
84
+ style={[
85
+ dotStyle,
86
+ {
87
+ transform: [{scale: scaleAnim}],
88
+ },
89
+ ]}
90
+ />
91
+ </View>
92
+ );
93
+ };
94
+
95
+ export default BadgeDotAnimation;
package/Badge/index.tsx CHANGED
@@ -1,7 +1,8 @@
1
1
  import Badge from './Badge';
2
2
  import BadgeDot from './BadgeDot';
3
3
  import BadgeRibbon from './BadgeRibbon';
4
+ import BadgeDotAnimation from './BadgeDotAnimation';
4
5
  import {BadgeProps, BadgeDotProps, BadgeRibbonProps} from './types';
5
6
 
6
- export {Badge, BadgeRibbon, BadgeDot};
7
+ export {Badge, BadgeRibbon, BadgeDot, BadgeDotAnimation};
7
8
  export type {BadgeProps, BadgeDotProps, BadgeRibbonProps};
package/Badge/styles.ts CHANGED
@@ -2,6 +2,10 @@ import {StyleSheet} from 'react-native';
2
2
  import {Colors, Radius, Spacing} from '../Consts';
3
3
  import {scaleSize} from '../Text';
4
4
 
5
+ const DOT_SIZE = 16;
6
+
7
+ const DOT_SMALL_SIZE = 10;
8
+
5
9
  export default StyleSheet.create({
6
10
  badge: {
7
11
  paddingHorizontal: Spacing.XS,
@@ -15,21 +19,61 @@ export default StyleSheet.create({
15
19
  borderColor: Colors.black_01,
16
20
  alignSelf: 'baseline',
17
21
  },
22
+ dotAnimationContainer: {
23
+ position: 'relative',
24
+ alignItems: 'center',
25
+ justifyContent: 'center',
26
+ },
18
27
  dot: {
19
- width: 16,
20
- height: 16,
28
+ width: DOT_SIZE,
29
+ height: DOT_SIZE,
21
30
  borderWidth: 2,
22
31
  borderColor: Colors.black_01,
23
32
  backgroundColor: Colors.red_03,
24
- borderRadius: 8,
33
+ borderRadius: DOT_SIZE / 2,
25
34
  },
26
35
  dotSmall: {
27
- width: 10,
28
- height: 10,
36
+ width: DOT_SMALL_SIZE,
37
+ height: DOT_SMALL_SIZE,
29
38
  borderWidth: 1,
30
39
  borderColor: Colors.black_01,
31
40
  backgroundColor: Colors.red_03,
32
- borderRadius: 5,
41
+ borderRadius: DOT_SMALL_SIZE / 2,
42
+ },
43
+ dotAnimation: {
44
+ width: DOT_SIZE,
45
+ height: DOT_SIZE,
46
+ borderColor: Colors.black_01,
47
+ backgroundColor: Colors.red_03,
48
+ borderRadius: DOT_SIZE / 2,
49
+ borderWidth: 0,
50
+ },
51
+ dotAnimationSmall: {
52
+ width: DOT_SMALL_SIZE,
53
+ height: DOT_SMALL_SIZE,
54
+ borderColor: Colors.black_01,
55
+ backgroundColor: Colors.red_03,
56
+ borderRadius: DOT_SMALL_SIZE / 2,
57
+ borderWidth: 0,
58
+ },
59
+ wave: {
60
+ width: DOT_SIZE,
61
+ height: DOT_SIZE,
62
+ borderColor: Colors.black_01,
63
+ backgroundColor: Colors.red_03,
64
+ borderRadius: DOT_SIZE / 2,
65
+ opacity: 0,
66
+ position: 'absolute',
67
+ borderWidth: 0,
68
+ },
69
+ waveSmall: {
70
+ width: DOT_SMALL_SIZE,
71
+ height: DOT_SMALL_SIZE,
72
+ borderColor: Colors.black_01,
73
+ backgroundColor: Colors.red_03,
74
+ borderRadius: DOT_SMALL_SIZE / 2,
75
+ borderWidth: 0,
76
+ position: 'absolute',
33
77
  },
34
78
  ribbon: {
35
79
  alignSelf: 'baseline',