-
-
Notifications
You must be signed in to change notification settings - Fork 2k
/
TextInputAffix.tsx
126 lines (113 loc) · 2.45 KB
/
TextInputAffix.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import React from 'react';
import color from 'color';
import {
Text,
StyleSheet,
StyleProp,
TextStyle,
LayoutChangeEvent,
Animated,
} from 'react-native';
import { withTheme } from '../../../core/theming';
import { AdornmentSide } from './enums';
const AFFIX_OFFSET = 12;
type Props = {
text: string;
onLayout?: (event: LayoutChangeEvent) => void;
textStyle?: StyleProp<TextStyle>;
/**
* @optional
*/
theme: ReactNativePaper.Theme;
};
type ContextState = {
topPosition: number | null;
onLayout?: (event: LayoutChangeEvent) => void;
visible?: Animated.Value;
textStyle?: StyleProp<TextStyle>;
side: AdornmentSide;
paddingHorizontal?: number | string;
};
const AffixContext = React.createContext<ContextState>({
textStyle: { fontFamily: '', color: '' },
topPosition: null,
side: AdornmentSide.Left,
});
const AffixAdornment: React.FunctionComponent<
{
affix: React.ReactNode;
testID: string;
} & ContextState
> = ({
affix,
side,
textStyle,
topPosition,
onLayout,
visible,
paddingHorizontal,
}) => {
return (
<AffixContext.Provider
value={{
side,
textStyle,
topPosition,
onLayout,
visible,
paddingHorizontal,
}}
>
{affix}
</AffixContext.Provider>
);
};
const TextInputAffix = ({ text, textStyle: labelStyle, theme }: Props) => {
const {
textStyle,
onLayout,
topPosition,
side,
visible,
paddingHorizontal,
} = React.useContext(AffixContext);
const textColor = color(theme.colors.text)
.alpha(theme.dark ? 0.7 : 0.54)
.rgb()
.string();
const offset =
typeof paddingHorizontal === 'number' ? paddingHorizontal : AFFIX_OFFSET;
const style = {
top: topPosition,
[side]: offset,
};
return (
<Animated.View
style={[
styles.container,
style,
{
opacity:
visible?.interpolate({
inputRange: [0, 1],
outputRange: [1, 0],
}) || 1,
},
]}
onLayout={onLayout}
>
<Text style={[{ color: textColor }, textStyle, labelStyle]}>{text}</Text>
</Animated.View>
);
};
TextInputAffix.displayName = 'TextInput.Affix';
const styles = StyleSheet.create({
container: {
position: 'absolute',
justifyContent: 'center',
alignItems: 'center',
},
});
export default withTheme(TextInputAffix);
// @component-docs ignore-next-line
export { TextInputAffix, AffixAdornment };