@momo-kits/foundation 0.80.9 → 0.81.2

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.
@@ -1,12 +1,11 @@
1
1
  import React, {Fragment, useContext, useEffect, useState} from 'react';
2
2
  import {
3
- Alert,
4
3
  Animated,
5
4
  DeviceEventEmitter,
6
5
  Platform,
7
6
  StatusBar,
8
7
  StyleSheet,
9
- TouchableOpacity as TouchableRN,
8
+ TouchableOpacity,
10
9
  View,
11
10
  } from 'react-native';
12
11
  import {TouchableOpacity as TouchableGesture} from 'react-native-gesture-handler';
@@ -14,6 +13,7 @@ import {ApplicationContext} from './index';
14
13
  import {Colors, Radius, Spacing, Styles} from '../Consts';
15
14
  import {Image} from '../Image';
16
15
  import {
16
+ HeaderAnimatedProps,
17
17
  HeaderBackgroundProps,
18
18
  HeaderBackProps,
19
19
  HeaderToolkitProps,
@@ -24,7 +24,8 @@ import {scaleSize, Text} from '../Text';
24
24
  import {Icon} from '../Icon';
25
25
  import {PopupNotify} from '../Popup';
26
26
 
27
- const Touchable = Platform.OS === 'android' ? TouchableGesture : TouchableRN;
27
+ const Touchable =
28
+ Platform.OS === 'android' ? TouchableGesture : TouchableOpacity;
28
29
 
29
30
  const styles = StyleSheet.create({
30
31
  navigationButton: {
@@ -208,7 +209,7 @@ const HeaderBackground: React.FC<HeaderBackgroundProps> = ({
208
209
  headerImage = undefined;
209
210
  }
210
211
  const opacity = animatedValue?.interpolate({
211
- inputRange: [0, 200],
212
+ inputRange: [0, 114],
212
213
  outputRange: [0, 1],
213
214
  extrapolate: 'clamp',
214
215
  });
@@ -274,8 +275,7 @@ const HeaderRightAction: React.FC<any> = ({children, ...restProps}) => {
274
275
  const validateType = (child: React.ReactElement) => {
275
276
  const valid = child?.type === NavigationButton || child?.type == Fragment;
276
277
  if (__DEV__ && !valid) {
277
- Alert.alert(
278
- 'Rule',
278
+ console.warn(
279
279
  'HeaderRightAction contains element type of NavigationButton, Please check again.',
280
280
  );
281
281
  }
@@ -416,6 +416,46 @@ const HeaderToolkitAction: React.FC<any> = ({tintColor}) => {
416
416
  return <View />;
417
417
  };
418
418
 
419
+ const HeaderAnimated: React.FC<HeaderAnimatedProps> = ({
420
+ animatedValue,
421
+ image,
422
+ onPress,
423
+ }) => {
424
+ const scale = animatedValue.interpolate({
425
+ inputRange: [-300, 0, 300],
426
+ outputRange: [4, 1, 1],
427
+ extrapolate: 'clamp',
428
+ });
429
+ const opacity = animatedValue.interpolate({
430
+ inputRange: [0, 150, 300],
431
+ outputRange: [1, 0.5, 0],
432
+ extrapolate: 'clamp',
433
+ });
434
+ const translateY = animatedValue.interpolate({
435
+ inputRange: [-300, 0],
436
+ outputRange: [-80, -2],
437
+ extrapolate: 'clamp',
438
+ });
439
+
440
+ return (
441
+ <TouchableOpacity onPress={onPress}>
442
+ <Animated.View
443
+ style={{
444
+ height: 210,
445
+ opacity: opacity,
446
+ transform: [{scale}, {translateY}],
447
+ }}>
448
+ <Image
449
+ source={{
450
+ uri: image,
451
+ }}
452
+ style={{width: '100%', height: '100%'}}
453
+ />
454
+ </Animated.View>
455
+ </TouchableOpacity>
456
+ );
457
+ };
458
+
419
459
  export {
420
460
  NavigationButton,
421
461
  HeaderTitle,
@@ -424,4 +464,5 @@ export {
424
464
  HeaderRightAction,
425
465
  HeaderToolkitAction,
426
466
  HeaderCustom,
467
+ HeaderAnimated,
427
468
  };
@@ -1,11 +1,12 @@
1
- import React, {useContext, useEffect, useMemo, useRef} from 'react';
1
+ import React, {useContext, useEffect, useMemo, useRef, useState} from 'react';
2
2
  import {
3
+ Dimensions,
4
+ Keyboard,
3
5
  KeyboardAvoidingView,
4
6
  Platform,
5
7
  Pressable,
6
8
  StyleSheet,
7
9
  View,
8
- Keyboard,
9
10
  } from 'react-native';
10
11
  import {SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
11
12
  import {
@@ -90,6 +91,7 @@ const Modal: React.FC<ModalParams> = props => {
90
91
  const BottomSheet: React.FC<BottomSheetParams> = props => {
91
92
  const insets = useSafeAreaInsets();
92
93
  const {theme, navigator} = useContext(ApplicationContext);
94
+ const [keyboardSnap, setKeyboardSnap] = useState(0);
93
95
  const {screen, options, snapPoint}: BottomSheetParams = props.route.params;
94
96
  const Component = useRef(screen).current;
95
97
  const navigation = new Navigation(props.navigation, theme);
@@ -102,28 +104,41 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
102
104
 
103
105
  const snapPoints = useMemo(() => {
104
106
  if (snapPoint) {
105
- return [snapPoint];
107
+ const current = parseInt(snapPoint) + keyboardSnap * 100;
108
+ return [`${current}%`];
106
109
  }
107
110
  return ['50%', '70%', '90%'];
108
- }, []);
111
+ }, [keyboardSnap]);
109
112
 
110
113
  const bottomSheetRef = useRef<any>(null);
111
114
  const mountedRef = useRef(true);
112
115
 
113
116
  let backgroundColor = theme.colors.background.default;
117
+ let bottomInset = keyboardSnap * Dimensions.get('window').height;
118
+ if (bottomInset > 16) {
119
+ bottomInset -= 16;
120
+ }
114
121
  if (options?.surface) {
115
122
  backgroundColor = theme.colors.background.surface;
116
123
  }
117
124
 
118
125
  useEffect(() => {
119
- const keyboardDidShow = Keyboard.addListener('keyboardDidShow', () =>
120
- bottomSheetRef.current?.expand(),
121
- );
126
+ const keyboardDidShow = Keyboard.addListener('keyboardDidShow', e => {
127
+ setKeyboardSnap(
128
+ e.endCoordinates.height / Dimensions.get('window').height,
129
+ );
130
+ bottomSheetRef.current?.expand();
131
+ });
132
+
133
+ const keyboardDidHide = Keyboard.addListener('keyboardDidHide', () => {
134
+ setKeyboardSnap(0);
135
+ });
122
136
 
123
137
  bottomSheetRef.current?.present();
124
138
  return () => {
125
139
  mountedRef.current = false;
126
140
  keyboardDidShow.remove();
141
+ keyboardDidHide.remove();
127
142
  };
128
143
  }, []);
129
144
 
@@ -145,6 +160,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
145
160
  navigator?.pop();
146
161
  }
147
162
  }}
163
+ bottomInset={bottomInset}
148
164
  handleComponent={null}
149
165
  backdropComponent={backdropComponent}>
150
166
  <BottomSheetView accessibilityLabel={'BottomSheet'}>
@@ -193,6 +209,7 @@ const BottomSheet: React.FC<BottomSheetParams> = props => {
193
209
  />
194
210
  );
195
211
  },
212
+ headerTintColor: theme.colors.text.default,
196
213
  headerBackground: () => (
197
214
  <HeaderBackground backgroundColor={backgroundColor} />
198
215
  ),
@@ -1,5 +1,5 @@
1
+ import React from 'react';
1
2
  import {NavigationProp} from '@react-navigation/native';
2
- import {Alert} from 'react-native';
3
3
  import {NavigationOptions, Theme} from './types';
4
4
  import {HeaderRightAction} from './index';
5
5
  import {getOptions} from './utils';
@@ -16,14 +16,12 @@ class Navigation {
16
16
 
17
17
  private filterParams = (params: NavigationOptions) => {
18
18
  if (params.headerRight) {
19
- const headerRight = params.headerRight?.();
19
+ const headerRight = params.headerRight?.({}) as React.ReactElement;
20
20
  const type = headerRight?.type;
21
21
  if (type !== HeaderRightAction && type !== HeaderToolkitAction) {
22
- Alert.alert(
23
- 'Rule',
22
+ console.warn(
24
23
  'headerRight contains element type of HeaderRightAction | HeaderToolkitAction, Please check again.',
25
24
  );
26
- delete params.headerRight;
27
25
  }
28
26
  }
29
27
  return params;
@@ -93,12 +93,12 @@ const NavigationContainer: React.FC<NavigationContainerProps> = ({
93
93
  name="Stack"
94
94
  component={StackScreen}
95
95
  initialParams={{screen}}
96
- options={{...getStackOptions(theme), ...options}}
96
+ options={{...getStackOptions(), ...options}}
97
97
  />
98
98
  <Stack.Screen
99
99
  name="Dialog"
100
100
  component={StackScreen}
101
- options={getDialogOptions(theme)}
101
+ options={getDialogOptions()}
102
102
  initialParams={{screen}}
103
103
  />
104
104
  <Stack.Screen
@@ -1,24 +1,31 @@
1
1
  import {NavigationContainer} from './NavigationContainer';
2
2
  import Screen from '../Layout/Screen';
3
3
  import {
4
- HeaderRightAction,
5
4
  NavigationButton,
6
- HeaderToolkitAction,
7
5
  HeaderTitle,
6
+ HeaderLeft,
7
+ HeaderBackground,
8
+ HeaderRightAction,
9
+ HeaderToolkitAction,
10
+ HeaderCustom,
11
+ HeaderAnimated,
8
12
  } from './Components';
9
13
  import BottomTab from './BottomTab';
10
14
  import {createContext} from 'react';
11
15
  import {defaultContext} from '../Consts';
12
16
 
13
17
  const ApplicationContext = createContext(defaultContext);
14
-
15
18
  export {
16
19
  NavigationContainer,
17
20
  ApplicationContext,
18
21
  Screen,
22
+ BottomTab,
19
23
  NavigationButton,
24
+ HeaderTitle,
25
+ HeaderLeft,
26
+ HeaderBackground,
20
27
  HeaderRightAction,
21
28
  HeaderToolkitAction,
22
- HeaderTitle,
23
- BottomTab,
29
+ HeaderCustom,
30
+ HeaderAnimated,
24
31
  };
@@ -1,4 +1,5 @@
1
1
  import {Animated} from 'react-native';
2
+ import {StackNavigationOptions} from '@react-navigation/stack';
2
3
  import React from 'react';
3
4
  import Navigator from './Navigator';
4
5
  import {PopupNotifyProps} from '../Popup/types';
@@ -119,19 +120,15 @@ export type NavigationButtonProps = {
119
120
  accessibilityLabel?: string;
120
121
  };
121
122
 
122
- export type NavigationOptions = {
123
+ export interface NavigationOptions extends StackNavigationOptions {
123
124
  preventBack?: PopupNotifyProps;
124
125
  onPressLeftHeader?: () => void;
125
126
  surface?: boolean;
126
- headerTransparent?: boolean;
127
127
  hiddenBack?: boolean;
128
- title?: string;
129
- headerTitle?: (props?: any) => React.ReactElement;
130
128
  headerTitleAlign?: 'left' | 'center';
131
129
  customTitle?: TitleCustomProps;
132
- headerRight?: (props?: any) => React.ReactElement;
133
130
  animatedValue?: Animated.Value;
134
- };
131
+ }
135
132
 
136
133
  export interface HeaderBackProps extends NavigationButtonProps {
137
134
  preventBack?: PopupNotifyProps;
@@ -164,6 +161,12 @@ export type HeaderToolkitProps = {
164
161
  onAction?: (action: string) => void;
165
162
  };
166
163
 
164
+ export type HeaderAnimatedProps = {
165
+ animatedValue: Animated.Value;
166
+ image: string;
167
+ onPress?: () => void;
168
+ };
169
+
167
170
  export type BottomTabItemProps = {
168
171
  name: string;
169
172
  label: string;
@@ -182,3 +185,8 @@ export type BottomTabProps = {
182
185
  focus?: any;
183
186
  };
184
187
  };
188
+
189
+ export type AnimatedHeader = {
190
+ type: 'default' | 'surface';
191
+ component?: (props?: any) => React.ReactElement;
192
+ };
@@ -13,35 +13,24 @@ import {
13
13
  import {NavigationOptions, Theme} from './types';
14
14
  import {Colors} from '../Consts';
15
15
 
16
- const getTintColor = (theme: Theme): any => {
17
- if (theme.assets?.headerBackground) {
18
- return {
19
- headerTintColor: Colors.black_01,
20
- };
21
- }
22
- return {
23
- headerTintColor: theme.colors.text.default,
24
- };
25
- };
26
-
27
- const getStackOptions = (theme: Theme): StackNavigationOptions => {
16
+ const getStackOptions = (): StackNavigationOptions => {
28
17
  return {
29
18
  headerTitleAlign: 'left',
30
19
  headerTitle: HeaderTitle,
31
- headerBackground: HeaderBackground,
20
+ headerBackground: (props: any) => <HeaderBackground {...props} />,
32
21
  headerLeft: (props: any) => <HeaderLeft {...props} />,
33
22
  headerRight: (props: any) => <HeaderToolkitAction {...props} />,
34
- ...getTintColor(theme),
23
+ headerTintColor: Colors.black_01,
35
24
  };
36
25
  };
37
26
 
38
- const getDialogOptions = (theme: Theme): StackNavigationOptions => {
27
+ const getDialogOptions = (): StackNavigationOptions => {
39
28
  return {
40
29
  headerTitleAlign: 'left',
41
30
  headerTitle: HeaderTitle,
42
31
  headerLeft: (props: any) => <HeaderLeft {...props} />,
43
- headerBackground: HeaderBackground,
44
- ...getTintColor(theme),
32
+ headerBackground: (props: any) => <HeaderBackground {...props} />,
33
+ headerTintColor: Colors.black_01,
45
34
  ...TransitionPresets.ModalTransition,
46
35
  };
47
36
  };
@@ -72,8 +61,6 @@ const getModalOptions = (): StackNavigationOptions => {
72
61
  };
73
62
 
74
63
  const getOptions = (params: NavigationOptions, theme: Theme) => {
75
- let backgroundProps: any;
76
- let titleProps: any;
77
64
  let options = {};
78
65
 
79
66
  if (
@@ -99,36 +86,24 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
99
86
  if (params.surface) {
100
87
  options = {
101
88
  ...options,
102
- ...getTintColor({
103
- ...theme,
104
- assets: {...theme.assets, headerBackground: undefined},
105
- }),
106
- };
107
- backgroundProps = {
108
- image: null,
109
- backgroundColor: theme.colors.background.surface,
110
- useBorder: true,
89
+ headerTintColor: theme.colors.text.default,
90
+ headerBackground: () => (
91
+ <HeaderBackground
92
+ image={null}
93
+ backgroundColor={theme.colors.background.surface}
94
+ useBorder={true}
95
+ />
96
+ ),
111
97
  };
112
98
  } else {
113
99
  options = {
114
100
  ...options,
115
- ...getTintColor(theme),
101
+ headerTintColor: Colors.black_01,
116
102
  headerBackground: HeaderBackground,
117
103
  };
118
104
  }
119
105
  }
120
106
 
121
- if (params.animatedValue) {
122
- backgroundProps = {...backgroundProps, animatedValue: params.animatedValue};
123
- titleProps = {animatedValue: params.animatedValue};
124
- options = {
125
- ...options,
126
- headerTitle: (props: any) => {
127
- return <HeaderTitle {...titleProps} {...props} />;
128
- },
129
- };
130
- }
131
-
132
107
  if (params.customTitle) {
133
108
  options = {
134
109
  ...options,
@@ -139,13 +114,6 @@ const getOptions = (params: NavigationOptions, theme: Theme) => {
139
114
  };
140
115
  }
141
116
 
142
- if (backgroundProps) {
143
- options = {
144
- ...options,
145
- headerBackground: () => <HeaderBackground {...backgroundProps} />,
146
- };
147
- }
148
-
149
117
  return {
150
118
  ...params,
151
119
  ...options,
@@ -152,6 +152,10 @@ const Spacing = {
152
152
  M: 12,
153
153
  L: 16,
154
154
  XL: 24,
155
+ XXL: 32,
156
+ Size48: 48,
157
+ Size56: 56,
158
+ Size64: 64,
155
159
  };
156
160
 
157
161
  const Radius = {
package/Image/index.tsx CHANGED
@@ -1,4 +1,4 @@
1
- import React, {useContext, useState} from 'react';
1
+ import React, {useContext, useRef, useState} from 'react';
2
2
  import {StyleProp, StyleSheet, View, ViewStyle} from 'react-native';
3
3
  import FastImage from 'react-native-fast-image';
4
4
  import styles from './styles';
@@ -14,6 +14,8 @@ export interface ImageProps extends FastImagePropsWithoutStyle {
14
14
  accessibilityLabel?: string;
15
15
  }
16
16
 
17
+ type Status = 'success' | 'loading' | 'error';
18
+
17
19
  const Image: React.FC<ImageProps> = ({
18
20
  style,
19
21
  source,
@@ -21,19 +23,20 @@ const Image: React.FC<ImageProps> = ({
21
23
  ...rest
22
24
  }) => {
23
25
  const {theme} = useContext(ApplicationContext);
24
- const [loading, setLoading] = useState(rest.loading);
25
- const [fail, setFail] = useState(false);
26
+ const error = useRef(false);
27
+ const [status, setStatus] = useState<Status>(
28
+ rest.loading ? 'loading' : 'success',
29
+ );
26
30
 
27
31
  /**
28
32
  * render content loading | fail | rendered
29
- * @returns {JSX.Element}
30
33
  */
31
34
  const renderContent = () => {
32
- if (loading || fail) {
35
+ if (status == 'loading' || status == 'error') {
33
36
  let content = (
34
37
  <Skeleton style={[StyleSheet.absoluteFill, styles.image]} />
35
38
  );
36
- if (fail) {
39
+ if (status == 'error') {
37
40
  content = (
38
41
  <View style={Styles.flexCenter}>
39
42
  <Icon source="media_fail" color={theme.colors.text.disable} />
@@ -63,12 +66,19 @@ const Image: React.FC<ImageProps> = ({
63
66
  {...rest}
64
67
  source={source}
65
68
  style={styles.image}
66
- onLoad={() => {
67
- setFail(false);
68
- setLoading(rest.loading);
69
+ onLoadStart={() => {
70
+ error.current = false;
71
+ }}
72
+ onLoadEnd={() => {
73
+ if (error.current) {
74
+ setStatus('error');
75
+ } else {
76
+ setStatus('success');
77
+ }
78
+ }}
79
+ onError={() => {
80
+ error.current = true;
69
81
  }}
70
- onLoadEnd={() => setLoading(false)}
71
- onError={() => setFail(true)}
72
82
  />
73
83
  {renderContent()}
74
84
  </View>
package/Input/Input.tsx CHANGED
@@ -35,6 +35,7 @@ const Input = forwardRef(
35
35
  loading,
36
36
  leadingIcon,
37
37
  leadingIconColor,
38
+ style,
38
39
  ...props
39
40
  }: InputProps,
40
41
  ref,
@@ -43,6 +44,7 @@ const Input = forwardRef(
43
44
  const [focused, setFocused] = useState(false);
44
45
  const [haveValue, setHaveValue] = useState(!!value || !!props.defaultValue);
45
46
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
47
+ const accessibilityLabel = `Input/${floatingValue ?? placeholder}`;
46
48
 
47
49
  const onClearText = () => {
48
50
  inputRef?.current?.clear();
@@ -112,7 +114,7 @@ const Input = forwardRef(
112
114
  )}
113
115
  <TextInput
114
116
  {...props}
115
- accessibilityLabel={`TextInput`}
117
+ accessibilityLabel={accessibilityLabel}
116
118
  editable={!disabled}
117
119
  textAlignVertical="center"
118
120
  ref={inputRef}
@@ -153,8 +155,8 @@ const Input = forwardRef(
153
155
 
154
156
  return (
155
157
  <View
156
- style={styles.wrapper}
157
- accessibilityLabel={`Input/${floatingValue}`}>
158
+ style={[style, styles.wrapper]}
159
+ accessibilityLabel={accessibilityLabel}>
158
160
  {renderInputView()}
159
161
  <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
160
162
  </View>
@@ -25,10 +25,13 @@ const InputDropDown = ({
25
25
  loading,
26
26
  leadingIcon,
27
27
  leadingIconColor,
28
+ style,
28
29
  ...props
29
30
  }: InputDropDownProps) => {
30
31
  const {theme} = useContext(ApplicationContext);
31
32
  const full = !!value || !!placeholder;
33
+ const accessibilityLabel = `InputDropDown/${floatingValue ?? placeholder}`;
34
+
32
35
  const renderIcon = (color: string | undefined) => {
33
36
  if (loading) {
34
37
  return <Loader type={'spinner'} color={color} />;
@@ -79,7 +82,7 @@ const InputDropDown = ({
79
82
  <TextInput
80
83
  {...props}
81
84
  onPressIn={onPress}
82
- accessibilityLabel={`TextInput`}
85
+ accessibilityLabel={accessibilityLabel}
83
86
  editable={false}
84
87
  textAlignVertical="top"
85
88
  style={[
@@ -105,8 +108,8 @@ const InputDropDown = ({
105
108
  return (
106
109
  <TouchableOpacity
107
110
  onPress={onPress}
108
- style={full && styles.wrapper}
109
- accessibilityLabel={`InputDropDown/${floatingValue}`}>
111
+ style={[style, full && styles.wrapper]}
112
+ accessibilityLabel={accessibilityLabel}>
110
113
  {renderInputView()}
111
114
  <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
112
115
  </TouchableOpacity>
@@ -29,6 +29,7 @@ const InputMoney = forwardRef(
29
29
  iconColor,
30
30
  required,
31
31
  errorSpacing,
32
+ style,
32
33
  ...props
33
34
  }: InputMoneyProps,
34
35
  ref,
@@ -37,6 +38,8 @@ const InputMoney = forwardRef(
37
38
  const [focused, setFocused] = useState(false);
38
39
  const inputRef = (ref as React.RefObject<TextInput>) ?? useRef<TextInput>();
39
40
  const [value, setValue] = useState('');
41
+ const accessibilityLabel = `InputMoney/${floatingValue}`;
42
+
40
43
  const onClearText = () => {
41
44
  inputRef?.current?.clear();
42
45
  setValue('');
@@ -91,7 +94,7 @@ const InputMoney = forwardRef(
91
94
  <View style={styles.inputView}>
92
95
  <TextInput
93
96
  {...props}
94
- accessibilityLabel={`TextInput`}
97
+ accessibilityLabel={accessibilityLabel}
95
98
  editable={!disabled}
96
99
  textAlignVertical="top"
97
100
  ref={inputRef}
@@ -131,8 +134,8 @@ const InputMoney = forwardRef(
131
134
 
132
135
  return (
133
136
  <View
134
- style={styles.wrapper}
135
- accessibilityLabel={`InputMoney/${floatingValue}`}>
137
+ style={[style, styles.wrapper]}
138
+ accessibilityLabel={accessibilityLabel}>
136
139
  {renderInputView()}
137
140
  <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
138
141
  </View>
@@ -1,7 +1,6 @@
1
1
  import React, {FC, useContext, useEffect, useRef, useState} from 'react';
2
2
  import {
3
3
  Animated,
4
- KeyboardType,
5
4
  NativeSyntheticEvent,
6
5
  TextInput,
7
6
  TextInputFocusEventData,
@@ -69,6 +68,7 @@ const InputOTP: FC<InputOTPProps> = ({
69
68
  onFocus,
70
69
  onBlur,
71
70
  dataType = 'number',
71
+ style,
72
72
  ...props
73
73
  }) => {
74
74
  const MAX_LENGTH = 10;
@@ -76,6 +76,7 @@ const InputOTP: FC<InputOTPProps> = ({
76
76
  const [focused, setFocused] = useState(false);
77
77
  const inputRef = useRef<TextInput>(null);
78
78
  const {theme} = useContext(ApplicationContext);
79
+ const accessibilityLabel = `InputOTP/${floatingValue ?? placeholder}`;
79
80
 
80
81
  const onFocusInput = () => {
81
82
  setFocused(true);
@@ -157,9 +158,6 @@ const InputOTP: FC<InputOTPProps> = ({
157
158
  };
158
159
 
159
160
  const renderInputView = () => {
160
- let placeholderColor = theme.colors.text.hint;
161
- const keyboardType: KeyboardType =
162
- dataType === 'number' ? 'number-pad' : 'default';
163
161
  return (
164
162
  <View
165
163
  style={[
@@ -182,16 +180,16 @@ const InputOTP: FC<InputOTPProps> = ({
182
180
  <View style={styles.inputView}>
183
181
  <TextInput
184
182
  {...props}
185
- accessibilityLabel={`TextInput`}
183
+ accessibilityLabel={accessibilityLabel}
186
184
  ref={inputRef}
187
185
  value={value}
188
186
  onChangeText={_onChangeText}
189
- keyboardType={keyboardType}
187
+ keyboardType={dataType === 'number' ? 'number-pad' : 'default'}
190
188
  onFocus={onFocusInput}
191
189
  onBlur={onBlurInput}
192
190
  style={{opacity: 0}}
193
191
  selectionColor={theme.colors.primary}
194
- placeholderTextColor={placeholderColor}
192
+ placeholderTextColor={theme.colors.text.hint}
195
193
  />
196
194
  </View>
197
195
  </View>
@@ -202,8 +200,8 @@ const InputOTP: FC<InputOTPProps> = ({
202
200
  <TouchableOpacity
203
201
  activeOpacity={1}
204
202
  onPress={onFocusInput}
205
- style={styles.otpWrapper}
206
- accessibilityLabel={`Input/${floatingValue}`}>
203
+ style={[style, styles.otpWrapper]}
204
+ accessibilityLabel={accessibilityLabel}>
207
205
  {renderInputView()}
208
206
  <ErrorView errorMessage={errorMessage} errorSpacing={errorSpacing} />
209
207
  </TouchableOpacity>