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.
Files changed (215) hide show
  1. package/README.md +69 -0
  2. package/dist/assets/error.png +0 -0
  3. package/dist/assets/icon-checkbox-active.svg +4 -0
  4. package/dist/assets/icon-checkbox.svg +3 -0
  5. package/dist/assets/image_default.png +0 -0
  6. package/dist/assets/images/error.png +0 -0
  7. package/dist/assets/images/image_default.png +0 -0
  8. package/dist/assets/images/info.png +0 -0
  9. package/dist/assets/images/success.png +0 -0
  10. package/dist/assets/images/warning.png +0 -0
  11. package/dist/assets/info.png +0 -0
  12. package/dist/assets/success.png +0 -0
  13. package/dist/assets/svg/icon-checkbox-active.svg +4 -0
  14. package/dist/assets/svg/icon-checkbox.svg +3 -0
  15. package/dist/assets/warning.png +0 -0
  16. package/dist/components/ActivityIndicator.d.ts +28 -0
  17. package/dist/components/Avatar/index.d.ts +17 -0
  18. package/dist/components/Badge/index.d.ts +13 -0
  19. package/dist/components/Button/index.d.ts +23 -0
  20. package/dist/components/ButtonIcon/index.d.ts +18 -0
  21. package/dist/components/Checkbox/index.d.ts +14 -0
  22. package/dist/components/ChipBar/index.d.ts +16 -0
  23. package/dist/components/CountingDot/index.d.ts +13 -0
  24. package/dist/components/FloatingButton/index.d.ts +17 -0
  25. package/dist/components/Icon/index.d.ts +17 -0
  26. package/dist/components/IconSvg/index.d.ts +12 -0
  27. package/dist/components/Image/index.d.ts +14 -0
  28. package/dist/components/ProgressBar.d.ts +42 -0
  29. package/dist/components/RadioButton/index.d.ts +13 -0
  30. package/dist/components/ScaleButton/index.d.ts +4 -0
  31. package/dist/components/SelectionField/index.d.ts +24 -0
  32. package/dist/components/Spacer/index.d.ts +9 -0
  33. package/dist/components/Switch/Switch.d.ts +47 -0
  34. package/dist/components/Switch/utils.d.ts +14 -0
  35. package/dist/components/Text/index.d.ts +14 -0
  36. package/dist/components/TextInput/Addons/Outline.d.ts +15 -0
  37. package/dist/components/TextInput/Addons/Underline.d.ts +19 -0
  38. package/dist/components/TextInput/Adornment/TextInputAdornment.d.ts +43 -0
  39. package/dist/components/TextInput/Adornment/TextInputAffix.d.ts +72 -0
  40. package/dist/components/TextInput/Adornment/enums.d.ts +12 -0
  41. package/dist/components/TextInput/Adornment/types.d.ts +11 -0
  42. package/dist/components/TextInput/Adornment/utils.d.ts +11 -0
  43. package/dist/components/TextInput/Label/InputLabel.d.ts +4 -0
  44. package/dist/components/TextInput/Label/LabelBackground.d.ts +4 -0
  45. package/dist/components/TextInput/TextInput.d.ts +171 -0
  46. package/dist/components/TextInput/TextInputDefault.d.ts +4 -0
  47. package/dist/components/TextInput/TextInputFlat.d.ts +4 -0
  48. package/dist/components/TextInput/constants.d.ts +31 -0
  49. package/dist/components/TextInput/helpers.d.ts +95 -0
  50. package/dist/components/TextInput/types.d.ts +154 -0
  51. package/dist/components/Toast/ToastProvider.d.ts +21 -0
  52. package/dist/components/Toast/index.d.ts +3 -0
  53. package/dist/components/Typography/AnimatedText.d.ts +34 -0
  54. package/dist/components/Typography/StyledText.d.ts +12 -0
  55. package/dist/components/Typography/Text.d.ts +35 -0
  56. package/dist/components/Typography/types.d.ts +2 -0
  57. package/dist/components/View/index.d.ts +38 -0
  58. package/dist/components/ViewVisibleAnimated/index.d.ts +25 -0
  59. package/dist/constants.d.ts +1 -0
  60. package/dist/core/theming.d.ts +43 -0
  61. package/dist/icons/IconArrowDown.d.ts +4 -0
  62. package/dist/icons/IconCheckbox.d.ts +4 -0
  63. package/dist/icons/IconCheckboxActive.d.ts +4 -0
  64. package/dist/icons/IconClearText.d.ts +4 -0
  65. package/dist/icons/IconRadio.d.ts +4 -0
  66. package/dist/icons/IconRadioActive.d.ts +4 -0
  67. package/dist/icons/IconRadioDisable.d.ts +4 -0
  68. package/dist/index.d.ts +33 -0
  69. package/dist/index.esm.js +6758 -0
  70. package/dist/index.esm.js.map +1 -0
  71. package/dist/index.js +6823 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/styles/fonts.d.ts +78 -0
  74. package/dist/styles/overlay.d.ts +3 -0
  75. package/dist/styles/shadow.d.ts +18 -0
  76. package/dist/styles/themes/DarkTheme.d.ts +2 -0
  77. package/dist/styles/themes/LightTheme.d.ts +2 -0
  78. package/dist/styles/themes/index.d.ts +2 -0
  79. package/dist/styles/themes/tokens.d.ts +830 -0
  80. package/dist/theme/blue.d.ts +14 -0
  81. package/dist/theme/colors.d.ts +99 -0
  82. package/dist/theme/container-styles.d.ts +124 -0
  83. package/dist/theme/dimensions.d.ts +36 -0
  84. package/dist/theme/green.d.ts +15 -0
  85. package/dist/theme/icon.d.ts +5 -0
  86. package/dist/theme/ink.d.ts +11 -0
  87. package/dist/theme/orange.d.ts +14 -0
  88. package/dist/theme/purple.d.ts +6 -0
  89. package/dist/theme/red.d.ts +15 -0
  90. package/dist/theme/themes.d.ts +277 -0
  91. package/dist/theme/white.d.ts +10 -0
  92. package/dist/theme/yellow.d.ts +15 -0
  93. package/dist/types/index.d.ts +65 -0
  94. package/dist/types.d.ts +220 -0
  95. package/dist/utils/BackHandler/BackHandler.d.ts +9 -0
  96. package/dist/utils/BackHandler/BackHandler.native.d.ts +2 -0
  97. package/dist/utils/addEventListener.d.ts +12 -0
  98. package/dist/utils/forwardRef.d.ts +11 -0
  99. package/dist/utils/function-utils.d.ts +12 -0
  100. package/dist/utils/getContrastingColor.d.ts +2 -0
  101. package/dist/utils/hasTouchHandler.d.ts +5 -0
  102. package/dist/utils/roundLayoutSize.d.ts +1 -0
  103. package/dist/utils/splitStyles.d.ts +19 -0
  104. package/dist/utils/toast-manager.d.ts +21 -0
  105. package/dist/utils/useAnimatedValue.d.ts +2 -0
  106. package/dist/utils/useAnimatedValueArray.d.ts +2 -0
  107. package/dist/utils/useIsKeyboardShown.d.ts +6 -0
  108. package/dist/utils/useLayout.d.ts +6 -0
  109. package/dist/utils/useLazyRef.d.ts +2 -0
  110. package/package.json +104 -0
  111. package/src/.DS_Store +0 -0
  112. package/src/assets/images/error.png +0 -0
  113. package/src/assets/images/image_default.png +0 -0
  114. package/src/assets/images/info.png +0 -0
  115. package/src/assets/images/success.png +0 -0
  116. package/src/assets/images/warning.png +0 -0
  117. package/src/assets/svg/icon-checkbox-active.svg +4 -0
  118. package/src/assets/svg/icon-checkbox.svg +3 -0
  119. package/src/babel/.eslintrc +7 -0
  120. package/src/babel/index.js +63 -0
  121. package/src/components/.DS_Store +0 -0
  122. package/src/components/ActivityIndicator.tsx +238 -0
  123. package/src/components/Avatar/index.tsx +102 -0
  124. package/src/components/Badge/index.tsx +55 -0
  125. package/src/components/Button/index.tsx +162 -0
  126. package/src/components/ButtonIcon/index.tsx +98 -0
  127. package/src/components/Checkbox/index.tsx +107 -0
  128. package/src/components/ChipBar/index.tsx +112 -0
  129. package/src/components/CountingDot/index.tsx +63 -0
  130. package/src/components/FloatingButton/index.tsx +99 -0
  131. package/src/components/Icon/index.tsx +135 -0
  132. package/src/components/IconSvg/index.tsx +42 -0
  133. package/src/components/Image/index.tsx +127 -0
  134. package/src/components/ProgressBar.tsx +272 -0
  135. package/src/components/RadioButton/index.tsx +105 -0
  136. package/src/components/ScaleButton/index.tsx +17 -0
  137. package/src/components/SelectionField/index.tsx +166 -0
  138. package/src/components/Spacer/index.tsx +19 -0
  139. package/src/components/Switch/Switch.tsx +110 -0
  140. package/src/components/Switch/utils.ts +96 -0
  141. package/src/components/Text/index.tsx +69 -0
  142. package/src/components/TextInput/.DS_Store +0 -0
  143. package/src/components/TextInput/Addons/Outline.tsx +62 -0
  144. package/src/components/TextInput/Addons/Underline.tsx +71 -0
  145. package/src/components/TextInput/Adornment/TextInputAdornment.tsx +191 -0
  146. package/src/components/TextInput/Adornment/TextInputAffix.tsx +212 -0
  147. package/src/components/TextInput/Adornment/enums.tsx +12 -0
  148. package/src/components/TextInput/Adornment/types.tsx +11 -0
  149. package/src/components/TextInput/Adornment/utils.ts +39 -0
  150. package/src/components/TextInput/Label/InputLabel.tsx +216 -0
  151. package/src/components/TextInput/Label/LabelBackground.tsx +100 -0
  152. package/src/components/TextInput/TextInput.tsx +564 -0
  153. package/src/components/TextInput/TextInputDefault.tsx +187 -0
  154. package/src/components/TextInput/TextInputFlat.tsx +452 -0
  155. package/src/components/TextInput/constants.tsx +48 -0
  156. package/src/components/TextInput/helpers.tsx +546 -0
  157. package/src/components/TextInput/types.tsx +155 -0
  158. package/src/components/Toast/ToastProvider.tsx +69 -0
  159. package/src/components/Toast/index.tsx +239 -0
  160. package/src/components/Typography/AnimatedText.tsx +84 -0
  161. package/src/components/Typography/StyledText.tsx +53 -0
  162. package/src/components/Typography/Text.tsx +189 -0
  163. package/src/components/Typography/types.tsx +5 -0
  164. package/src/components/View/index.tsx +175 -0
  165. package/src/components/ViewVisibleAnimated/index.tsx +199 -0
  166. package/src/constants.tsx +16 -0
  167. package/src/core/theming.tsx +144 -0
  168. package/src/icons/IconArrowDown.tsx +14 -0
  169. package/src/icons/IconCheckbox.tsx +20 -0
  170. package/src/icons/IconCheckboxActive.tsx +18 -0
  171. package/src/icons/IconClearText.tsx +14 -0
  172. package/src/icons/IconRadio.tsx +11 -0
  173. package/src/icons/IconRadioActive.tsx +12 -0
  174. package/src/icons/IconRadioDisable.tsx +12 -0
  175. package/src/index.ts +51 -0
  176. package/src/index.tsx +50 -0
  177. package/src/styles/fonts.tsx +89 -0
  178. package/src/styles/overlay.tsx +69 -0
  179. package/src/styles/shadow.tsx +47 -0
  180. package/src/styles/themes/DarkTheme.tsx +157 -0
  181. package/src/styles/themes/LightTheme.tsx +160 -0
  182. package/src/styles/themes/index.ts +3 -0
  183. package/src/styles/themes/tokens.tsx +481 -0
  184. package/src/theme/blue.ts +25 -0
  185. package/src/theme/colors.ts +21 -0
  186. package/src/theme/container-styles.tsx +126 -0
  187. package/src/theme/dimensions.ts +44 -0
  188. package/src/theme/green.ts +27 -0
  189. package/src/theme/icon.ts +7 -0
  190. package/src/theme/ink.ts +18 -0
  191. package/src/theme/orange.ts +24 -0
  192. package/src/theme/purple.ts +8 -0
  193. package/src/theme/red.ts +26 -0
  194. package/src/theme/themes.tsx +287 -0
  195. package/src/theme/white.ts +16 -0
  196. package/src/theme/yellow.ts +26 -0
  197. package/src/types/index.ts +71 -0
  198. package/src/types/svg.d.ts +5 -0
  199. package/src/types.ts +259 -0
  200. package/src/types.tsx +284 -0
  201. package/src/utils/BackHandler/BackHandler.native.tsx +3 -0
  202. package/src/utils/BackHandler/BackHandler.tsx +11 -0
  203. package/src/utils/addEventListener.tsx +56 -0
  204. package/src/utils/forwardRef.tsx +23 -0
  205. package/src/utils/function-utils.tsx +108 -0
  206. package/src/utils/getContrastingColor.tsx +15 -0
  207. package/src/utils/hasTouchHandler.tsx +23 -0
  208. package/src/utils/roundLayoutSize.ts +2 -0
  209. package/src/utils/splitStyles.ts +60 -0
  210. package/src/utils/toast-manager.tsx +46 -0
  211. package/src/utils/useAnimatedValue.tsx +9 -0
  212. package/src/utils/useAnimatedValueArray.tsx +13 -0
  213. package/src/utils/useIsKeyboardShown.tsx +55 -0
  214. package/src/utils/useLayout.tsx +29 -0
  215. 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;