sapo-components-ui-rn 1.0.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.
- package/README.md +69 -0
- package/dist/assets/error.png +0 -0
- package/dist/assets/icon-checkbox-active.svg +4 -0
- package/dist/assets/icon-checkbox.svg +3 -0
- package/dist/assets/image_default.png +0 -0
- package/dist/assets/images/error.png +0 -0
- package/dist/assets/images/image_default.png +0 -0
- package/dist/assets/images/info.png +0 -0
- package/dist/assets/images/success.png +0 -0
- package/dist/assets/images/warning.png +0 -0
- package/dist/assets/info.png +0 -0
- package/dist/assets/success.png +0 -0
- package/dist/assets/svg/icon-checkbox-active.svg +4 -0
- package/dist/assets/svg/icon-checkbox.svg +3 -0
- package/dist/assets/warning.png +0 -0
- package/dist/components/ActivityIndicator.d.ts +28 -0
- package/dist/components/Avatar/index.d.ts +17 -0
- package/dist/components/Badge/index.d.ts +13 -0
- package/dist/components/Button/index.d.ts +23 -0
- package/dist/components/ButtonIcon/index.d.ts +18 -0
- package/dist/components/Checkbox/index.d.ts +14 -0
- package/dist/components/ChipBar/index.d.ts +16 -0
- package/dist/components/CountingDot/index.d.ts +13 -0
- package/dist/components/FloatingButton/index.d.ts +17 -0
- package/dist/components/Icon/index.d.ts +17 -0
- package/dist/components/IconSvg/index.d.ts +12 -0
- package/dist/components/Image/index.d.ts +14 -0
- package/dist/components/ProgressBar.d.ts +42 -0
- package/dist/components/RadioButton/index.d.ts +13 -0
- package/dist/components/ScaleButton/index.d.ts +4 -0
- package/dist/components/SelectionField/index.d.ts +24 -0
- package/dist/components/Spacer/index.d.ts +9 -0
- package/dist/components/Switch/Switch.d.ts +47 -0
- package/dist/components/Switch/utils.d.ts +14 -0
- package/dist/components/Text/index.d.ts +14 -0
- package/dist/components/TextInput/Addons/Outline.d.ts +15 -0
- package/dist/components/TextInput/Addons/Underline.d.ts +19 -0
- package/dist/components/TextInput/Adornment/TextInputAdornment.d.ts +43 -0
- package/dist/components/TextInput/Adornment/TextInputAffix.d.ts +72 -0
- package/dist/components/TextInput/Adornment/enums.d.ts +12 -0
- package/dist/components/TextInput/Adornment/types.d.ts +11 -0
- package/dist/components/TextInput/Adornment/utils.d.ts +11 -0
- package/dist/components/TextInput/Label/InputLabel.d.ts +4 -0
- package/dist/components/TextInput/Label/LabelBackground.d.ts +4 -0
- package/dist/components/TextInput/TextInput.d.ts +171 -0
- package/dist/components/TextInput/TextInputDefault.d.ts +4 -0
- package/dist/components/TextInput/TextInputFlat.d.ts +4 -0
- package/dist/components/TextInput/constants.d.ts +31 -0
- package/dist/components/TextInput/helpers.d.ts +95 -0
- package/dist/components/TextInput/types.d.ts +154 -0
- package/dist/components/Toast/ToastProvider.d.ts +21 -0
- package/dist/components/Toast/index.d.ts +3 -0
- package/dist/components/Typography/AnimatedText.d.ts +34 -0
- package/dist/components/Typography/StyledText.d.ts +12 -0
- package/dist/components/Typography/Text.d.ts +35 -0
- package/dist/components/Typography/types.d.ts +2 -0
- package/dist/components/View/index.d.ts +38 -0
- package/dist/components/ViewVisibleAnimated/index.d.ts +25 -0
- package/dist/constants.d.ts +1 -0
- package/dist/core/theming.d.ts +43 -0
- package/dist/icons/IconArrowDown.d.ts +4 -0
- package/dist/icons/IconCheckbox.d.ts +4 -0
- package/dist/icons/IconCheckboxActive.d.ts +4 -0
- package/dist/icons/IconClearText.d.ts +4 -0
- package/dist/icons/IconRadio.d.ts +4 -0
- package/dist/icons/IconRadioActive.d.ts +4 -0
- package/dist/icons/IconRadioDisable.d.ts +4 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.esm.js +6758 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +6823 -0
- package/dist/index.js.map +1 -0
- package/dist/styles/fonts.d.ts +78 -0
- package/dist/styles/overlay.d.ts +3 -0
- package/dist/styles/shadow.d.ts +18 -0
- package/dist/styles/themes/DarkTheme.d.ts +2 -0
- package/dist/styles/themes/LightTheme.d.ts +2 -0
- package/dist/styles/themes/index.d.ts +2 -0
- package/dist/styles/themes/tokens.d.ts +830 -0
- package/dist/theme/blue.d.ts +14 -0
- package/dist/theme/colors.d.ts +99 -0
- package/dist/theme/container-styles.d.ts +124 -0
- package/dist/theme/dimensions.d.ts +36 -0
- package/dist/theme/green.d.ts +15 -0
- package/dist/theme/icon.d.ts +5 -0
- package/dist/theme/ink.d.ts +11 -0
- package/dist/theme/orange.d.ts +14 -0
- package/dist/theme/purple.d.ts +6 -0
- package/dist/theme/red.d.ts +15 -0
- package/dist/theme/themes.d.ts +277 -0
- package/dist/theme/white.d.ts +10 -0
- package/dist/theme/yellow.d.ts +15 -0
- package/dist/types/index.d.ts +65 -0
- package/dist/types.d.ts +220 -0
- package/dist/utils/BackHandler/BackHandler.d.ts +9 -0
- package/dist/utils/BackHandler/BackHandler.native.d.ts +2 -0
- package/dist/utils/addEventListener.d.ts +12 -0
- package/dist/utils/forwardRef.d.ts +11 -0
- package/dist/utils/function-utils.d.ts +12 -0
- package/dist/utils/getContrastingColor.d.ts +2 -0
- package/dist/utils/hasTouchHandler.d.ts +5 -0
- package/dist/utils/roundLayoutSize.d.ts +1 -0
- package/dist/utils/splitStyles.d.ts +19 -0
- package/dist/utils/toast-manager.d.ts +21 -0
- package/dist/utils/useAnimatedValue.d.ts +2 -0
- package/dist/utils/useAnimatedValueArray.d.ts +2 -0
- package/dist/utils/useIsKeyboardShown.d.ts +6 -0
- package/dist/utils/useLayout.d.ts +6 -0
- package/dist/utils/useLazyRef.d.ts +2 -0
- package/package.json +104 -0
- package/src/.DS_Store +0 -0
- package/src/assets/images/error.png +0 -0
- package/src/assets/images/image_default.png +0 -0
- package/src/assets/images/info.png +0 -0
- package/src/assets/images/success.png +0 -0
- package/src/assets/images/warning.png +0 -0
- package/src/assets/svg/icon-checkbox-active.svg +4 -0
- package/src/assets/svg/icon-checkbox.svg +3 -0
- package/src/babel/.eslintrc +7 -0
- package/src/babel/index.js +63 -0
- package/src/components/.DS_Store +0 -0
- package/src/components/ActivityIndicator.tsx +238 -0
- package/src/components/Avatar/index.tsx +102 -0
- package/src/components/Badge/index.tsx +55 -0
- package/src/components/Button/index.tsx +162 -0
- package/src/components/ButtonIcon/index.tsx +98 -0
- package/src/components/Checkbox/index.tsx +107 -0
- package/src/components/ChipBar/index.tsx +112 -0
- package/src/components/CountingDot/index.tsx +63 -0
- package/src/components/FloatingButton/index.tsx +99 -0
- package/src/components/Icon/index.tsx +135 -0
- package/src/components/IconSvg/index.tsx +42 -0
- package/src/components/Image/index.tsx +127 -0
- package/src/components/ProgressBar.tsx +272 -0
- package/src/components/RadioButton/index.tsx +105 -0
- package/src/components/ScaleButton/index.tsx +17 -0
- package/src/components/SelectionField/index.tsx +166 -0
- package/src/components/Spacer/index.tsx +19 -0
- package/src/components/Switch/Switch.tsx +110 -0
- package/src/components/Switch/utils.ts +96 -0
- package/src/components/Text/index.tsx +69 -0
- package/src/components/TextInput/.DS_Store +0 -0
- package/src/components/TextInput/Addons/Outline.tsx +62 -0
- package/src/components/TextInput/Addons/Underline.tsx +71 -0
- package/src/components/TextInput/Adornment/TextInputAdornment.tsx +191 -0
- package/src/components/TextInput/Adornment/TextInputAffix.tsx +212 -0
- package/src/components/TextInput/Adornment/enums.tsx +12 -0
- package/src/components/TextInput/Adornment/types.tsx +11 -0
- package/src/components/TextInput/Adornment/utils.ts +39 -0
- package/src/components/TextInput/Label/InputLabel.tsx +216 -0
- package/src/components/TextInput/Label/LabelBackground.tsx +100 -0
- package/src/components/TextInput/TextInput.tsx +564 -0
- package/src/components/TextInput/TextInputDefault.tsx +187 -0
- package/src/components/TextInput/TextInputFlat.tsx +452 -0
- package/src/components/TextInput/constants.tsx +48 -0
- package/src/components/TextInput/helpers.tsx +546 -0
- package/src/components/TextInput/types.tsx +155 -0
- package/src/components/Toast/ToastProvider.tsx +69 -0
- package/src/components/Toast/index.tsx +239 -0
- package/src/components/Typography/AnimatedText.tsx +84 -0
- package/src/components/Typography/StyledText.tsx +53 -0
- package/src/components/Typography/Text.tsx +189 -0
- package/src/components/Typography/types.tsx +5 -0
- package/src/components/View/index.tsx +175 -0
- package/src/components/ViewVisibleAnimated/index.tsx +199 -0
- package/src/constants.tsx +16 -0
- package/src/core/theming.tsx +144 -0
- package/src/icons/IconArrowDown.tsx +14 -0
- package/src/icons/IconCheckbox.tsx +20 -0
- package/src/icons/IconCheckboxActive.tsx +18 -0
- package/src/icons/IconClearText.tsx +14 -0
- package/src/icons/IconRadio.tsx +11 -0
- package/src/icons/IconRadioActive.tsx +12 -0
- package/src/icons/IconRadioDisable.tsx +12 -0
- package/src/index.ts +51 -0
- package/src/index.tsx +50 -0
- package/src/styles/fonts.tsx +89 -0
- package/src/styles/overlay.tsx +69 -0
- package/src/styles/shadow.tsx +47 -0
- package/src/styles/themes/DarkTheme.tsx +157 -0
- package/src/styles/themes/LightTheme.tsx +160 -0
- package/src/styles/themes/index.ts +3 -0
- package/src/styles/themes/tokens.tsx +481 -0
- package/src/theme/blue.ts +25 -0
- package/src/theme/colors.ts +21 -0
- package/src/theme/container-styles.tsx +126 -0
- package/src/theme/dimensions.ts +44 -0
- package/src/theme/green.ts +27 -0
- package/src/theme/icon.ts +7 -0
- package/src/theme/ink.ts +18 -0
- package/src/theme/orange.ts +24 -0
- package/src/theme/purple.ts +8 -0
- package/src/theme/red.ts +26 -0
- package/src/theme/themes.tsx +287 -0
- package/src/theme/white.ts +16 -0
- package/src/theme/yellow.ts +26 -0
- package/src/types/index.ts +71 -0
- package/src/types/svg.d.ts +5 -0
- package/src/types.ts +259 -0
- package/src/types.tsx +284 -0
- package/src/utils/BackHandler/BackHandler.native.tsx +3 -0
- package/src/utils/BackHandler/BackHandler.tsx +11 -0
- package/src/utils/addEventListener.tsx +56 -0
- package/src/utils/forwardRef.tsx +23 -0
- package/src/utils/function-utils.tsx +108 -0
- package/src/utils/getContrastingColor.tsx +15 -0
- package/src/utils/hasTouchHandler.tsx +23 -0
- package/src/utils/roundLayoutSize.ts +2 -0
- package/src/utils/splitStyles.ts +60 -0
- package/src/utils/toast-manager.tsx +46 -0
- package/src/utils/useAnimatedValue.tsx +9 -0
- package/src/utils/useAnimatedValueArray.tsx +13 -0
- package/src/utils/useIsKeyboardShown.tsx +55 -0
- package/src/utils/useLayout.tsx +29 -0
- package/src/utils/useLazyRef.tsx +11 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
TextInput as NativeTextInput,
|
|
4
|
+
StyleSheet,
|
|
5
|
+
I18nManager,
|
|
6
|
+
Platform,
|
|
7
|
+
TextStyle,
|
|
8
|
+
TouchableOpacity,
|
|
9
|
+
} from "react-native";
|
|
10
|
+
import View from "../View";
|
|
11
|
+
import { MAXIMIZED_LABEL_FONT_SIZE } from "./constants";
|
|
12
|
+
import { getOutlinedInputColors } from "./helpers";
|
|
13
|
+
import type { RenderProps, ChildTextInputProps } from "./types";
|
|
14
|
+
import { CONSTANTS } from "../../styles/themes/tokens";
|
|
15
|
+
import Spacer from "../Spacer";
|
|
16
|
+
import Icon from "../Icon";
|
|
17
|
+
|
|
18
|
+
const TextInputDefault = ({
|
|
19
|
+
disabled = false,
|
|
20
|
+
editable = true,
|
|
21
|
+
label,
|
|
22
|
+
error = false,
|
|
23
|
+
selectionColor: customSelectionColor,
|
|
24
|
+
cursorColor,
|
|
25
|
+
outlineColor: customOutlineColor,
|
|
26
|
+
activeOutlineColor,
|
|
27
|
+
outlineStyle,
|
|
28
|
+
textColor,
|
|
29
|
+
dense,
|
|
30
|
+
style,
|
|
31
|
+
theme,
|
|
32
|
+
render = (props: RenderProps) => <NativeTextInput {...props} />,
|
|
33
|
+
multiline = false,
|
|
34
|
+
parentState,
|
|
35
|
+
innerRef,
|
|
36
|
+
onFocus,
|
|
37
|
+
forceFocus,
|
|
38
|
+
onBlur,
|
|
39
|
+
onChangeText,
|
|
40
|
+
onLayout,
|
|
41
|
+
left,
|
|
42
|
+
right,
|
|
43
|
+
placeholderTextColor,
|
|
44
|
+
clearButton = false,
|
|
45
|
+
contentStyle,
|
|
46
|
+
value,
|
|
47
|
+
...rest
|
|
48
|
+
}: ChildTextInputProps) => {
|
|
49
|
+
const { colors } = theme;
|
|
50
|
+
const font = theme.fonts.bodyLarge;
|
|
51
|
+
|
|
52
|
+
const {
|
|
53
|
+
fontSize: fontSizeStyle,
|
|
54
|
+
fontWeight,
|
|
55
|
+
lineHeight: lineHeightStyle,
|
|
56
|
+
height,
|
|
57
|
+
backgroundColor = colors?.backgroundPrimary,
|
|
58
|
+
textAlign,
|
|
59
|
+
...viewStyle
|
|
60
|
+
} = (StyleSheet.flatten(style) || {}) as TextStyle;
|
|
61
|
+
const fontSize = fontSizeStyle || MAXIMIZED_LABEL_FONT_SIZE;
|
|
62
|
+
const lineHeight =
|
|
63
|
+
lineHeightStyle || (Platform.OS === "web" ? fontSize * 1.2 : undefined);
|
|
64
|
+
|
|
65
|
+
const { inputTextColor, activeColor, outlineColor, selectionColor } =
|
|
66
|
+
getOutlinedInputColors({
|
|
67
|
+
activeOutlineColor,
|
|
68
|
+
customOutlineColor,
|
|
69
|
+
customSelectionColor,
|
|
70
|
+
textColor,
|
|
71
|
+
disabled,
|
|
72
|
+
error,
|
|
73
|
+
theme,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const [inputValue, setInputValue] = React.useState(value || "");
|
|
77
|
+
|
|
78
|
+
React.useEffect(() => {
|
|
79
|
+
setInputValue(value || "");
|
|
80
|
+
}, [value]);
|
|
81
|
+
|
|
82
|
+
const handleChangeText = (text: string) => {
|
|
83
|
+
setInputValue(text);
|
|
84
|
+
onChangeText?.(text);
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
const handleClear = () => {
|
|
88
|
+
setInputValue("");
|
|
89
|
+
onChangeText?.("");
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (height && typeof height !== "number") {
|
|
93
|
+
console.warn("Currently we support only numbers in height prop");
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const placeholderTextColorBasedOnState =
|
|
97
|
+
placeholderTextColor || colors.textSecondary;
|
|
98
|
+
|
|
99
|
+
const getBorderColor = () => {
|
|
100
|
+
if (disabled) {
|
|
101
|
+
return theme.colors.surfacePrimaryDisabled;
|
|
102
|
+
} else if (parentState.focused) {
|
|
103
|
+
return activeColor;
|
|
104
|
+
} else {
|
|
105
|
+
return theme.colors.borderPrimaryDefault;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
return (
|
|
110
|
+
<View style={viewStyle}>
|
|
111
|
+
<View
|
|
112
|
+
row
|
|
113
|
+
alignCenter
|
|
114
|
+
style={[
|
|
115
|
+
{
|
|
116
|
+
borderRadius: CONSTANTS.BORDER_RADIUS_6,
|
|
117
|
+
borderWidth: 1,
|
|
118
|
+
borderColor: getBorderColor(),
|
|
119
|
+
overflow: "hidden",
|
|
120
|
+
backgroundColor: disabled
|
|
121
|
+
? theme.colors.surfacePrimaryDisabled
|
|
122
|
+
: theme.colors.surfacePrimaryDefault,
|
|
123
|
+
},
|
|
124
|
+
]}
|
|
125
|
+
>
|
|
126
|
+
{<View paddingLeft={CONSTANTS.SPACE_12}>{left}</View>}
|
|
127
|
+
{left && <Spacer width={CONSTANTS.SPACE_8} />}
|
|
128
|
+
{render?.({
|
|
129
|
+
...rest,
|
|
130
|
+
ref: innerRef,
|
|
131
|
+
onChangeText: handleChangeText,
|
|
132
|
+
value: inputValue,
|
|
133
|
+
placeholder: rest.placeholder,
|
|
134
|
+
editable: !disabled && editable,
|
|
135
|
+
selectionColor,
|
|
136
|
+
cursorColor:
|
|
137
|
+
typeof cursorColor === "undefined" ? activeColor : cursorColor,
|
|
138
|
+
placeholderTextColor: placeholderTextColorBasedOnState,
|
|
139
|
+
onFocus,
|
|
140
|
+
onBlur,
|
|
141
|
+
underlineColorAndroid: "transparent",
|
|
142
|
+
multiline,
|
|
143
|
+
style: [
|
|
144
|
+
styles.input,
|
|
145
|
+
{
|
|
146
|
+
...font,
|
|
147
|
+
fontSize,
|
|
148
|
+
lineHeight,
|
|
149
|
+
fontWeight,
|
|
150
|
+
color: inputTextColor,
|
|
151
|
+
textAlignVertical: multiline ? "top" : "center",
|
|
152
|
+
textAlign: textAlign
|
|
153
|
+
? textAlign
|
|
154
|
+
: I18nManager.getConstants().isRTL
|
|
155
|
+
? "right"
|
|
156
|
+
: "left",
|
|
157
|
+
height: height ? height : 48,
|
|
158
|
+
},
|
|
159
|
+
contentStyle,
|
|
160
|
+
],
|
|
161
|
+
} as RenderProps)}
|
|
162
|
+
{!disabled && clearButton && inputValue ? (
|
|
163
|
+
<TouchableOpacity onPress={handleClear} style={styles.clearButton}>
|
|
164
|
+
<Icon name={"IconClearText"} type="Svg" size={24} />
|
|
165
|
+
</TouchableOpacity>
|
|
166
|
+
) : (
|
|
167
|
+
<Spacer width={CONSTANTS.SPACE_12} />
|
|
168
|
+
)}
|
|
169
|
+
{right && <Spacer width={CONSTANTS.SPACE_8} />}
|
|
170
|
+
{right && <View paddingRight={CONSTANTS.SPACE_12}>{right}</View>}
|
|
171
|
+
</View>
|
|
172
|
+
</View>
|
|
173
|
+
);
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
export default TextInputDefault;
|
|
177
|
+
|
|
178
|
+
const styles = StyleSheet.create({
|
|
179
|
+
input: {
|
|
180
|
+
margin: 0,
|
|
181
|
+
flex: 1,
|
|
182
|
+
height: 48,
|
|
183
|
+
},
|
|
184
|
+
clearButton: {
|
|
185
|
+
padding: CONSTANTS.SPACE_8,
|
|
186
|
+
},
|
|
187
|
+
});
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import {
|
|
3
|
+
I18nManager,
|
|
4
|
+
Platform,
|
|
5
|
+
StyleSheet,
|
|
6
|
+
TextInput as NativeTextInput,
|
|
7
|
+
TextStyle,
|
|
8
|
+
View,
|
|
9
|
+
Animated,
|
|
10
|
+
TouchableOpacity,
|
|
11
|
+
} from "react-native";
|
|
12
|
+
|
|
13
|
+
import { getAdornmentConfig } from "./Adornment/TextInputAdornment";
|
|
14
|
+
import {
|
|
15
|
+
LABEL_PADDING_TOP_DENSE,
|
|
16
|
+
LABEL_WIGGLE_X_OFFSET,
|
|
17
|
+
MAXIMIZED_LABEL_FONT_SIZE,
|
|
18
|
+
MINIMIZED_LABEL_FONT_SIZE,
|
|
19
|
+
MINIMIZED_LABEL_Y_OFFSET,
|
|
20
|
+
MIN_DENSE_HEIGHT,
|
|
21
|
+
MIN_DENSE_HEIGHT_WL,
|
|
22
|
+
} from "./constants";
|
|
23
|
+
import {
|
|
24
|
+
adjustPaddingFlat,
|
|
25
|
+
calculateFlatInputHorizontalPadding,
|
|
26
|
+
calculateInputHeight,
|
|
27
|
+
calculateLabelTopPosition,
|
|
28
|
+
calculatePadding,
|
|
29
|
+
getConstants,
|
|
30
|
+
getFlatInputColors,
|
|
31
|
+
Padding,
|
|
32
|
+
} from "./helpers";
|
|
33
|
+
import InputLabel from "./Label/InputLabel";
|
|
34
|
+
import type { ChildTextInputProps, RenderProps } from "./types";
|
|
35
|
+
import { Outline } from "./Addons/Outline";
|
|
36
|
+
import Spacer from "../Spacer";
|
|
37
|
+
import { CONSTANTS } from "../../styles/themes/tokens";
|
|
38
|
+
import Icon from "../Icon";
|
|
39
|
+
|
|
40
|
+
const TextInputFlat = ({
|
|
41
|
+
disabled = false,
|
|
42
|
+
editable = true,
|
|
43
|
+
label,
|
|
44
|
+
error = false,
|
|
45
|
+
selectionColor: customSelectionColor,
|
|
46
|
+
cursorColor,
|
|
47
|
+
underlineColor,
|
|
48
|
+
underlineStyle,
|
|
49
|
+
activeUnderlineColor,
|
|
50
|
+
textColor,
|
|
51
|
+
dense,
|
|
52
|
+
style,
|
|
53
|
+
theme,
|
|
54
|
+
render = (props: RenderProps) => <NativeTextInput {...props} />,
|
|
55
|
+
multiline = false,
|
|
56
|
+
parentState,
|
|
57
|
+
innerRef,
|
|
58
|
+
onFocus,
|
|
59
|
+
forceFocus,
|
|
60
|
+
onBlur,
|
|
61
|
+
onChangeText,
|
|
62
|
+
onLayoutAnimatedText,
|
|
63
|
+
onLabelTextLayout,
|
|
64
|
+
onLeftAffixLayoutChange,
|
|
65
|
+
onRightAffixLayoutChange,
|
|
66
|
+
onInputLayout,
|
|
67
|
+
left,
|
|
68
|
+
right,
|
|
69
|
+
placeholderTextColor,
|
|
70
|
+
clearButton,
|
|
71
|
+
contentStyle,
|
|
72
|
+
scaledLabel,
|
|
73
|
+
outlineStyle,
|
|
74
|
+
outlineColor,
|
|
75
|
+
value,
|
|
76
|
+
...rest
|
|
77
|
+
}: ChildTextInputProps) => {
|
|
78
|
+
const [inputValue, setInputValue] = React.useState(value || "");
|
|
79
|
+
|
|
80
|
+
React.useEffect(() => {
|
|
81
|
+
setInputValue(value || "");
|
|
82
|
+
}, [value]);
|
|
83
|
+
|
|
84
|
+
const handleChangeText = (text: string) => {
|
|
85
|
+
setInputValue(text);
|
|
86
|
+
onChangeText?.(text);
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const handleClear = () => {
|
|
90
|
+
setInputValue("");
|
|
91
|
+
onChangeText?.("");
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
const isAndroid = Platform.OS === "android";
|
|
95
|
+
const { roundness } = theme;
|
|
96
|
+
const font = theme.fonts.bodyLarge;
|
|
97
|
+
const hasActiveOutline = parentState.focused || error;
|
|
98
|
+
|
|
99
|
+
const { LABEL_PADDING_TOP, FLAT_INPUT_OFFSET, MIN_HEIGHT } = getConstants();
|
|
100
|
+
|
|
101
|
+
const {
|
|
102
|
+
fontSize: fontSizeStyle,
|
|
103
|
+
lineHeight: lineHeightStyle,
|
|
104
|
+
fontWeight,
|
|
105
|
+
height,
|
|
106
|
+
paddingHorizontal,
|
|
107
|
+
textAlign,
|
|
108
|
+
...viewStyle
|
|
109
|
+
} = (StyleSheet.flatten(style) || {}) as TextStyle;
|
|
110
|
+
const fontSize = fontSizeStyle || MAXIMIZED_LABEL_FONT_SIZE;
|
|
111
|
+
const lineHeight =
|
|
112
|
+
lineHeightStyle || (Platform.OS === "web" ? fontSize * 1.2 : undefined);
|
|
113
|
+
|
|
114
|
+
const isPaddingHorizontalPassed =
|
|
115
|
+
paddingHorizontal !== undefined && typeof paddingHorizontal === "number";
|
|
116
|
+
|
|
117
|
+
const adornmentConfig = getAdornmentConfig({
|
|
118
|
+
left,
|
|
119
|
+
right,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
let { paddingLeft, paddingRight } = calculateFlatInputHorizontalPadding({
|
|
123
|
+
adornmentConfig,
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
if (isPaddingHorizontalPassed) {
|
|
127
|
+
paddingLeft = paddingHorizontal as number;
|
|
128
|
+
paddingRight = paddingHorizontal as number;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const {
|
|
132
|
+
inputTextColor,
|
|
133
|
+
activeColor,
|
|
134
|
+
placeholderColor,
|
|
135
|
+
errorColor,
|
|
136
|
+
backgroundColor,
|
|
137
|
+
selectionColor,
|
|
138
|
+
} = getFlatInputColors({
|
|
139
|
+
underlineColor,
|
|
140
|
+
activeUnderlineColor,
|
|
141
|
+
customSelectionColor,
|
|
142
|
+
textColor,
|
|
143
|
+
disabled,
|
|
144
|
+
error,
|
|
145
|
+
theme,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const containerStyle = {
|
|
149
|
+
backgroundColor,
|
|
150
|
+
borderTopLeftRadius: theme.roundness,
|
|
151
|
+
borderTopRightRadius: theme.roundness,
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const labelScale = MINIMIZED_LABEL_FONT_SIZE / fontSize;
|
|
155
|
+
const fontScale = MAXIMIZED_LABEL_FONT_SIZE / fontSize;
|
|
156
|
+
|
|
157
|
+
const labelWidth = parentState.labelLayout.width;
|
|
158
|
+
const labelHeight = parentState.labelLayout.height;
|
|
159
|
+
const labelHalfWidth = labelWidth / 2;
|
|
160
|
+
const labelHalfHeight = labelHeight / 2;
|
|
161
|
+
|
|
162
|
+
const baseLabelTranslateX =
|
|
163
|
+
(I18nManager.getConstants().isRTL ? 1 : -1) *
|
|
164
|
+
(labelHalfWidth - (labelScale * labelWidth) / 2) +
|
|
165
|
+
(1 - labelScale) *
|
|
166
|
+
(I18nManager.getConstants().isRTL ? -1 : 1) *
|
|
167
|
+
paddingLeft;
|
|
168
|
+
|
|
169
|
+
const minInputHeight = dense
|
|
170
|
+
? (label ? MIN_DENSE_HEIGHT_WL : MIN_DENSE_HEIGHT) - LABEL_PADDING_TOP_DENSE
|
|
171
|
+
: MIN_HEIGHT - LABEL_PADDING_TOP;
|
|
172
|
+
|
|
173
|
+
const inputHeight = calculateInputHeight(labelHeight, height, minInputHeight);
|
|
174
|
+
|
|
175
|
+
const topPosition = calculateLabelTopPosition(
|
|
176
|
+
labelHeight,
|
|
177
|
+
inputHeight,
|
|
178
|
+
multiline && height ? 0 : !height ? minInputHeight / 2 : 0
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
if (height && typeof height !== "number") {
|
|
182
|
+
// eslint-disable-next-line
|
|
183
|
+
console.warn("Currently we support only numbers in height prop");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const paddingSettings = {
|
|
187
|
+
height: height ? +height : null,
|
|
188
|
+
labelHalfHeight,
|
|
189
|
+
offset: FLAT_INPUT_OFFSET,
|
|
190
|
+
multiline: multiline ? multiline : null,
|
|
191
|
+
dense: dense ? dense : null,
|
|
192
|
+
topPosition,
|
|
193
|
+
fontSize,
|
|
194
|
+
lineHeight,
|
|
195
|
+
label,
|
|
196
|
+
scale: fontScale,
|
|
197
|
+
isAndroid,
|
|
198
|
+
styles: StyleSheet.flatten(
|
|
199
|
+
dense ? styles.inputFlatDense : styles.inputFlat
|
|
200
|
+
) as Padding,
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
const pad = calculatePadding(paddingSettings);
|
|
204
|
+
|
|
205
|
+
const paddingFlat = adjustPaddingFlat({
|
|
206
|
+
...paddingSettings,
|
|
207
|
+
pad,
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
const baseLabelTranslateY =
|
|
211
|
+
-labelHalfHeight - (topPosition + MINIMIZED_LABEL_Y_OFFSET);
|
|
212
|
+
|
|
213
|
+
const { current: placeholderOpacityAnims } = React.useRef([
|
|
214
|
+
new Animated.Value(0),
|
|
215
|
+
new Animated.Value(1),
|
|
216
|
+
]);
|
|
217
|
+
|
|
218
|
+
const placeholderOpacity = hasActiveOutline
|
|
219
|
+
? parentState.labeled
|
|
220
|
+
: placeholderOpacityAnims[parentState.labelLayout.measured ? 1 : 0];
|
|
221
|
+
|
|
222
|
+
// We don't want to show placeholder if label is displayed, because they overlap.
|
|
223
|
+
// Before it was done by setting placeholder's value to " ", but inputs have the same props
|
|
224
|
+
// what causes broken styles due to: https://github.com/facebook/react-native/issues/48249
|
|
225
|
+
const placeholderTextColorBasedOnState = parentState.displayPlaceholder
|
|
226
|
+
? placeholderTextColor ?? placeholderColor
|
|
227
|
+
: "transparent";
|
|
228
|
+
|
|
229
|
+
const minHeight =
|
|
230
|
+
height ||
|
|
231
|
+
(dense ? (label ? MIN_DENSE_HEIGHT_WL : MIN_DENSE_HEIGHT) : MIN_HEIGHT);
|
|
232
|
+
|
|
233
|
+
const labelProps = {
|
|
234
|
+
label,
|
|
235
|
+
onLayoutAnimatedText,
|
|
236
|
+
onLabelTextLayout,
|
|
237
|
+
placeholderOpacity,
|
|
238
|
+
labelError: error,
|
|
239
|
+
placeholderStyle: styles.placeholder,
|
|
240
|
+
baseLabelTranslateY,
|
|
241
|
+
baseLabelTranslateX,
|
|
242
|
+
font,
|
|
243
|
+
fontSize,
|
|
244
|
+
lineHeight,
|
|
245
|
+
fontWeight,
|
|
246
|
+
labelScale,
|
|
247
|
+
wiggleOffsetX: LABEL_WIGGLE_X_OFFSET,
|
|
248
|
+
topPosition,
|
|
249
|
+
paddingLeft: isAndroid
|
|
250
|
+
? I18nManager.isRTL
|
|
251
|
+
? paddingRight
|
|
252
|
+
: paddingLeft
|
|
253
|
+
: paddingLeft,
|
|
254
|
+
paddingRight: isAndroid
|
|
255
|
+
? I18nManager.isRTL
|
|
256
|
+
? paddingLeft
|
|
257
|
+
: paddingRight
|
|
258
|
+
: paddingRight,
|
|
259
|
+
hasActiveOutline,
|
|
260
|
+
activeColor,
|
|
261
|
+
placeholderColor,
|
|
262
|
+
errorColor,
|
|
263
|
+
roundness,
|
|
264
|
+
maxFontSizeMultiplier: rest.maxFontSizeMultiplier,
|
|
265
|
+
contentStyle,
|
|
266
|
+
inputContainerLayout: parentState.inputContainerLayout,
|
|
267
|
+
labelTextLayout: parentState.labelTextLayout,
|
|
268
|
+
opacity:
|
|
269
|
+
parentState.value || parentState.focused
|
|
270
|
+
? parentState.labelLayout.measured
|
|
271
|
+
? 1
|
|
272
|
+
: 0
|
|
273
|
+
: 1,
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const getBorderColor = () => {
|
|
277
|
+
if (disabled) {
|
|
278
|
+
return theme.colors.surfacePrimaryDisabled;
|
|
279
|
+
} else if (parentState.focused) {
|
|
280
|
+
return activeColor;
|
|
281
|
+
} else {
|
|
282
|
+
return theme.colors.borderPrimaryDefault;
|
|
283
|
+
}
|
|
284
|
+
};
|
|
285
|
+
|
|
286
|
+
return (
|
|
287
|
+
<View
|
|
288
|
+
style={{
|
|
289
|
+
flexDirection: "row",
|
|
290
|
+
alignItems: "center",
|
|
291
|
+
borderRadius: CONSTANTS.BORDER_RADIUS_6,
|
|
292
|
+
borderWidth: 1,
|
|
293
|
+
borderColor: getBorderColor(),
|
|
294
|
+
height: 48,
|
|
295
|
+
overflow: "hidden",
|
|
296
|
+
backgroundColor: disabled
|
|
297
|
+
? theme.colors.surfacePrimaryDisabled
|
|
298
|
+
: theme.colors.surfacePrimaryDefault,
|
|
299
|
+
}}
|
|
300
|
+
>
|
|
301
|
+
<View style={{ flexDirection: "row" }}>
|
|
302
|
+
{left && (
|
|
303
|
+
<View style={{ paddingLeft: CONSTANTS.SPACE_12 }}>{left}</View>
|
|
304
|
+
)}
|
|
305
|
+
{left ? (
|
|
306
|
+
<Spacer width={CONSTANTS.SPACE_8} />
|
|
307
|
+
) : (
|
|
308
|
+
<Spacer width={CONSTANTS.SPACE_12} />
|
|
309
|
+
)}
|
|
310
|
+
</View>
|
|
311
|
+
<Outline
|
|
312
|
+
style={outlineStyle}
|
|
313
|
+
label={label}
|
|
314
|
+
roundness={roundness}
|
|
315
|
+
hasActiveOutline={hasActiveOutline}
|
|
316
|
+
focused={parentState.focused}
|
|
317
|
+
activeColor={activeColor}
|
|
318
|
+
outlineColor={outlineColor}
|
|
319
|
+
backgroundColor={backgroundColor}
|
|
320
|
+
/>
|
|
321
|
+
|
|
322
|
+
<View
|
|
323
|
+
onLayout={onInputLayout}
|
|
324
|
+
style={[
|
|
325
|
+
styles.labelContainer,
|
|
326
|
+
{
|
|
327
|
+
minHeight,
|
|
328
|
+
flex: 1,
|
|
329
|
+
},
|
|
330
|
+
]}
|
|
331
|
+
>
|
|
332
|
+
{!isAndroid && multiline && !!label && !disabled && (
|
|
333
|
+
<View
|
|
334
|
+
pointerEvents="none"
|
|
335
|
+
style={[
|
|
336
|
+
StyleSheet.absoluteFill,
|
|
337
|
+
dense ? styles.densePatchContainer : styles.patchContainer,
|
|
338
|
+
{
|
|
339
|
+
backgroundColor:
|
|
340
|
+
viewStyle.backgroundColor || containerStyle.backgroundColor,
|
|
341
|
+
left: paddingLeft,
|
|
342
|
+
right: paddingRight,
|
|
343
|
+
},
|
|
344
|
+
]}
|
|
345
|
+
/>
|
|
346
|
+
)}
|
|
347
|
+
{label ? (
|
|
348
|
+
<InputLabel
|
|
349
|
+
labeled={parentState.labeled}
|
|
350
|
+
error={parentState.error}
|
|
351
|
+
focused={parentState.focused}
|
|
352
|
+
scaledLabel={scaledLabel}
|
|
353
|
+
wiggle={Boolean(parentState.value && labelProps.labelError)}
|
|
354
|
+
labelLayoutMeasured={parentState.labelLayout.measured}
|
|
355
|
+
labelLayoutWidth={parentState.labelLayout.width}
|
|
356
|
+
labelLayoutHeight={parentState.labelLayout.height}
|
|
357
|
+
{...labelProps}
|
|
358
|
+
/>
|
|
359
|
+
) : null}
|
|
360
|
+
{render?.({
|
|
361
|
+
...rest,
|
|
362
|
+
ref: innerRef,
|
|
363
|
+
onChangeText: handleChangeText,
|
|
364
|
+
value: inputValue,
|
|
365
|
+
placeholder: rest.placeholder,
|
|
366
|
+
editable: !disabled && editable,
|
|
367
|
+
selectionColor,
|
|
368
|
+
cursorColor:
|
|
369
|
+
typeof cursorColor === "undefined" ? activeColor : cursorColor,
|
|
370
|
+
placeholderTextColor: placeholderTextColorBasedOnState,
|
|
371
|
+
onFocus,
|
|
372
|
+
onBlur,
|
|
373
|
+
underlineColorAndroid: "transparent",
|
|
374
|
+
multiline,
|
|
375
|
+
style: [
|
|
376
|
+
styles.input,
|
|
377
|
+
// paddingFlat,
|
|
378
|
+
{
|
|
379
|
+
paddingLeft,
|
|
380
|
+
paddingRight,
|
|
381
|
+
paddingTop: CONSTANTS.SPACE_12,
|
|
382
|
+
...font,
|
|
383
|
+
fontSize,
|
|
384
|
+
lineHeight,
|
|
385
|
+
fontWeight,
|
|
386
|
+
color: inputTextColor,
|
|
387
|
+
textAlignVertical: multiline ? "top" : "center",
|
|
388
|
+
textAlign: textAlign
|
|
389
|
+
? textAlign
|
|
390
|
+
: I18nManager.getConstants().isRTL
|
|
391
|
+
? "right"
|
|
392
|
+
: "left",
|
|
393
|
+
},
|
|
394
|
+
Platform.OS === "web" && { outline: "none" },
|
|
395
|
+
contentStyle,
|
|
396
|
+
],
|
|
397
|
+
} as RenderProps)}
|
|
398
|
+
</View>
|
|
399
|
+
{!disabled && clearButton && inputValue ? (
|
|
400
|
+
<TouchableOpacity onPress={handleClear} style={styles.clearButton}>
|
|
401
|
+
<Icon name="IconClearText" type="Svg" size={24} />
|
|
402
|
+
</TouchableOpacity>
|
|
403
|
+
) : (
|
|
404
|
+
<Spacer width={CONSTANTS.SPACE_12} />
|
|
405
|
+
)}
|
|
406
|
+
<View style={{ flexDirection: "row" }}>
|
|
407
|
+
{right && <Spacer width={CONSTANTS.SPACE_8} />}
|
|
408
|
+
{right && (
|
|
409
|
+
<View style={{ paddingRight: CONSTANTS.SPACE_12 }}>{right}</View>
|
|
410
|
+
)}
|
|
411
|
+
</View>
|
|
412
|
+
</View>
|
|
413
|
+
);
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
export default TextInputFlat;
|
|
417
|
+
|
|
418
|
+
const styles = StyleSheet.create({
|
|
419
|
+
placeholder: {
|
|
420
|
+
position: "absolute",
|
|
421
|
+
left: 0,
|
|
422
|
+
},
|
|
423
|
+
labelContainer: {
|
|
424
|
+
paddingTop: 0,
|
|
425
|
+
paddingBottom: 0,
|
|
426
|
+
// flex: 1,
|
|
427
|
+
},
|
|
428
|
+
input: {
|
|
429
|
+
// margin: 0,
|
|
430
|
+
flex: 1,
|
|
431
|
+
height: 48,
|
|
432
|
+
},
|
|
433
|
+
inputFlat: {
|
|
434
|
+
paddingTop: 24,
|
|
435
|
+
paddingBottom: 4,
|
|
436
|
+
},
|
|
437
|
+
inputFlatDense: {
|
|
438
|
+
paddingTop: 22,
|
|
439
|
+
paddingBottom: 2,
|
|
440
|
+
},
|
|
441
|
+
patchContainer: {
|
|
442
|
+
height: 24,
|
|
443
|
+
zIndex: 2,
|
|
444
|
+
},
|
|
445
|
+
densePatchContainer: {
|
|
446
|
+
height: 22,
|
|
447
|
+
zIndex: 2,
|
|
448
|
+
},
|
|
449
|
+
clearButton: {
|
|
450
|
+
padding: CONSTANTS.SPACE_8,
|
|
451
|
+
},
|
|
452
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export const MAXIMIZED_LABEL_FONT_SIZE = 14;
|
|
2
|
+
export const MINIMIZED_LABEL_FONT_SIZE = 12;
|
|
3
|
+
export const LABEL_WIGGLE_X_OFFSET = 4;
|
|
4
|
+
|
|
5
|
+
export const ADORNMENT_SIZE = 24;
|
|
6
|
+
export const MIN_WIDTH = 100;
|
|
7
|
+
|
|
8
|
+
//Text input affix offset
|
|
9
|
+
export const MD2_AFFIX_OFFSET = 12;
|
|
10
|
+
export const MD3_AFFIX_OFFSET = 16;
|
|
11
|
+
|
|
12
|
+
// Text input icon
|
|
13
|
+
export const ICON_SIZE = 24;
|
|
14
|
+
export const MD2_ICON_OFFSET = 12;
|
|
15
|
+
export const MD3_ICON_OFFSET = 16;
|
|
16
|
+
|
|
17
|
+
// Text input common
|
|
18
|
+
export const MD2_MIN_HEIGHT = 64;
|
|
19
|
+
export const MD3_MIN_HEIGHT = 56;
|
|
20
|
+
export const MD3_ADORNMENT_OFFSET = 16;
|
|
21
|
+
export const MD2_ADORNMENT_OFFSET = 12;
|
|
22
|
+
export const LABEL_PADDING_TOP_DENSE = 24;
|
|
23
|
+
export const LABEL_PADDING_TOP = 8;
|
|
24
|
+
|
|
25
|
+
// Text input flat
|
|
26
|
+
export const MD2_LABEL_PADDING_TOP = 30;
|
|
27
|
+
export const MD3_LABEL_PADDING_TOP = 26;
|
|
28
|
+
|
|
29
|
+
export const MD2_LABEL_PADDING_HORIZONTAL = 12;
|
|
30
|
+
export const MD3_LABEL_PADDING_HORIZONTAL = 16;
|
|
31
|
+
|
|
32
|
+
export const MD2_FLAT_INPUT_OFFSET = 8;
|
|
33
|
+
export const MD3_FLAT_INPUT_OFFSET = 16;
|
|
34
|
+
|
|
35
|
+
export const MINIMIZED_LABEL_Y_OFFSET = -18;
|
|
36
|
+
export const MIN_DENSE_HEIGHT_WL = 52;
|
|
37
|
+
export const MIN_DENSE_HEIGHT = 40;
|
|
38
|
+
|
|
39
|
+
// Text input outlined
|
|
40
|
+
export const MD2_INPUT_PADDING_HORIZONTAL = 14;
|
|
41
|
+
export const MD3_INPUT_PADDING_HORIZONTAL = 16;
|
|
42
|
+
|
|
43
|
+
// extra space to avoid overlapping input's text and icon
|
|
44
|
+
export const MD2_OUTLINED_INPUT_OFFSET = 8;
|
|
45
|
+
export const MD3_OUTLINED_INPUT_OFFSET = 16;
|
|
46
|
+
|
|
47
|
+
export const OUTLINE_MINIMIZED_LABEL_Y_OFFSET = -6;
|
|
48
|
+
export const MIN_DENSE_HEIGHT_OUTLINED = 48;
|