@tamagui/input 2.7.7 → 3.0.0-beta.1093.1

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 (169) hide show
  1. package/dist/cjs/Input.cjs +72 -163
  2. package/dist/cjs/Input.native.cjs +208 -0
  3. package/dist/cjs/Input.native.js +186 -283
  4. package/dist/cjs/Input.native.js.map +1 -1
  5. package/dist/cjs/InputNativeProps.cjs +9 -11
  6. package/dist/cjs/InputNativeProps.native.cjs +18 -0
  7. package/dist/cjs/InputNativeProps.native.js +9 -10
  8. package/dist/cjs/InputNativeProps.native.js.map +1 -1
  9. package/dist/cjs/TextArea.cjs +23 -39
  10. package/dist/cjs/TextArea.native.cjs +38 -0
  11. package/dist/cjs/TextArea.native.js +23 -38
  12. package/dist/cjs/TextArea.native.js.map +1 -1
  13. package/dist/cjs/index.cjs +15 -17
  14. package/dist/cjs/index.native.cjs +32 -0
  15. package/dist/cjs/index.native.js +15 -16
  16. package/dist/cjs/index.native.js.map +1 -1
  17. package/dist/cjs/shared.cjs +74 -124
  18. package/dist/cjs/shared.native.cjs +101 -0
  19. package/dist/cjs/shared.native.js +80 -129
  20. package/dist/cjs/shared.native.js.map +1 -1
  21. package/dist/cjs/types.cjs +9 -11
  22. package/dist/cjs/types.native.cjs +18 -0
  23. package/dist/cjs/types.native.js +9 -10
  24. package/dist/cjs/types.native.js.map +1 -1
  25. package/dist/esm/Input.mjs +59 -139
  26. package/dist/esm/Input.mjs.map +1 -1
  27. package/dist/esm/Input.native.js +174 -261
  28. package/dist/esm/Input.native.js.map +1 -1
  29. package/dist/esm/InputNativeProps.mjs +0 -2
  30. package/dist/esm/InputNativeProps.native.js +0 -2
  31. package/dist/esm/TextArea.mjs +12 -22
  32. package/dist/esm/TextArea.mjs.map +1 -1
  33. package/dist/esm/TextArea.native.js +12 -22
  34. package/dist/esm/TextArea.native.js.map +1 -1
  35. package/dist/esm/index.js +6 -4
  36. package/dist/esm/index.mjs +6 -4
  37. package/dist/esm/index.native.js +6 -4
  38. package/dist/esm/shared.mjs +59 -107
  39. package/dist/esm/shared.mjs.map +1 -1
  40. package/dist/esm/shared.native.js +64 -112
  41. package/dist/esm/shared.native.js.map +1 -1
  42. package/dist/esm/types.mjs +0 -2
  43. package/dist/esm/types.native.js +0 -2
  44. package/dist/jsx/Input.mjs +59 -139
  45. package/dist/jsx/Input.mjs.map +1 -1
  46. package/dist/jsx/Input.native.cjs +208 -0
  47. package/dist/jsx/Input.native.js +186 -283
  48. package/dist/jsx/Input.native.js.map +1 -1
  49. package/dist/jsx/InputNativeProps.mjs +0 -2
  50. package/dist/jsx/InputNativeProps.native.cjs +18 -0
  51. package/dist/jsx/InputNativeProps.native.js +9 -10
  52. package/dist/jsx/InputNativeProps.native.js.map +1 -1
  53. package/dist/jsx/TextArea.mjs +12 -22
  54. package/dist/jsx/TextArea.mjs.map +1 -1
  55. package/dist/jsx/TextArea.native.cjs +38 -0
  56. package/dist/jsx/TextArea.native.js +23 -38
  57. package/dist/jsx/TextArea.native.js.map +1 -1
  58. package/dist/jsx/index.js +6 -4
  59. package/dist/jsx/index.mjs +6 -4
  60. package/dist/jsx/index.native.cjs +32 -0
  61. package/dist/jsx/index.native.js +15 -16
  62. package/dist/jsx/index.native.js.map +1 -1
  63. package/dist/jsx/shared.mjs +59 -107
  64. package/dist/jsx/shared.mjs.map +1 -1
  65. package/dist/jsx/shared.native.cjs +101 -0
  66. package/dist/jsx/shared.native.js +80 -129
  67. package/dist/jsx/shared.native.js.map +1 -1
  68. package/dist/jsx/types.mjs +0 -2
  69. package/dist/jsx/types.native.cjs +18 -0
  70. package/dist/jsx/types.native.js +9 -10
  71. package/dist/jsx/types.native.js.map +1 -1
  72. package/package.json +17 -17
  73. package/src/Input.native.tsx +267 -242
  74. package/src/Input.tsx +150 -154
  75. package/src/TextArea.tsx +9 -18
  76. package/src/shared.tsx +56 -109
  77. package/src/types.ts +2 -2
  78. package/types/Input.d.ts +32 -50
  79. package/types/Input.d.ts.map +1 -1
  80. package/types/Input.native.d.ts +32 -50
  81. package/types/Input.native.d.ts.map +1 -1
  82. package/types/TextArea.d.ts +16 -34
  83. package/types/TextArea.d.ts.map +1 -1
  84. package/types/shared.d.ts +38 -109
  85. package/types/shared.d.ts.map +1 -1
  86. package/types/types.d.ts +2 -2
  87. package/types/types.d.ts.map +1 -1
  88. package/dist/cjs/inputTypes.test-d.cjs +0 -128
  89. package/dist/cjs/inputTypes.test-d.native.js +0 -131
  90. package/dist/cjs/inputTypes.test-d.native.js.map +0 -1
  91. package/dist/cjs/v1/Input.cjs +0 -200
  92. package/dist/cjs/v1/Input.native.js +0 -183
  93. package/dist/cjs/v1/Input.native.js.map +0 -1
  94. package/dist/cjs/v1/TextArea.cjs +0 -52
  95. package/dist/cjs/v1/TextArea.native.js +0 -55
  96. package/dist/cjs/v1/TextArea.native.js.map +0 -1
  97. package/dist/cjs/v1/index.cjs +0 -21
  98. package/dist/cjs/v1/index.native.js +0 -24
  99. package/dist/cjs/v1/index.native.js.map +0 -1
  100. package/dist/cjs/v1/types.cjs +0 -18
  101. package/dist/cjs/v1/types.native.js +0 -21
  102. package/dist/cjs/v1/types.native.js.map +0 -1
  103. package/dist/esm/InputNativeProps.mjs.map +0 -1
  104. package/dist/esm/InputNativeProps.native.js.map +0 -1
  105. package/dist/esm/index.js.map +0 -1
  106. package/dist/esm/index.mjs.map +0 -1
  107. package/dist/esm/index.native.js.map +0 -1
  108. package/dist/esm/inputTypes.test-d.mjs +0 -129
  109. package/dist/esm/inputTypes.test-d.mjs.map +0 -1
  110. package/dist/esm/inputTypes.test-d.native.js +0 -129
  111. package/dist/esm/inputTypes.test-d.native.js.map +0 -1
  112. package/dist/esm/types.mjs.map +0 -1
  113. package/dist/esm/types.native.js.map +0 -1
  114. package/dist/esm/v1/Input.mjs +0 -164
  115. package/dist/esm/v1/Input.mjs.map +0 -1
  116. package/dist/esm/v1/Input.native.js +0 -144
  117. package/dist/esm/v1/Input.native.js.map +0 -1
  118. package/dist/esm/v1/TextArea.mjs +0 -27
  119. package/dist/esm/v1/TextArea.mjs.map +0 -1
  120. package/dist/esm/v1/TextArea.native.js +0 -27
  121. package/dist/esm/v1/TextArea.native.js.map +0 -1
  122. package/dist/esm/v1/index.mjs +0 -3
  123. package/dist/esm/v1/index.mjs.map +0 -1
  124. package/dist/esm/v1/index.native.js +0 -3
  125. package/dist/esm/v1/index.native.js.map +0 -1
  126. package/dist/esm/v1/types.mjs +0 -2
  127. package/dist/esm/v1/types.mjs.map +0 -1
  128. package/dist/esm/v1/types.native.js +0 -2
  129. package/dist/esm/v1/types.native.js.map +0 -1
  130. package/dist/jsx/InputNativeProps.mjs.map +0 -1
  131. package/dist/jsx/index.js.map +0 -1
  132. package/dist/jsx/index.mjs.map +0 -1
  133. package/dist/jsx/inputTypes.test-d.mjs +0 -129
  134. package/dist/jsx/inputTypes.test-d.mjs.map +0 -1
  135. package/dist/jsx/inputTypes.test-d.native.js +0 -131
  136. package/dist/jsx/inputTypes.test-d.native.js.map +0 -1
  137. package/dist/jsx/types.mjs.map +0 -1
  138. package/dist/jsx/v1/Input.mjs +0 -164
  139. package/dist/jsx/v1/Input.mjs.map +0 -1
  140. package/dist/jsx/v1/Input.native.js +0 -183
  141. package/dist/jsx/v1/Input.native.js.map +0 -1
  142. package/dist/jsx/v1/TextArea.mjs +0 -27
  143. package/dist/jsx/v1/TextArea.mjs.map +0 -1
  144. package/dist/jsx/v1/TextArea.native.js +0 -55
  145. package/dist/jsx/v1/TextArea.native.js.map +0 -1
  146. package/dist/jsx/v1/index.mjs +0 -3
  147. package/dist/jsx/v1/index.mjs.map +0 -1
  148. package/dist/jsx/v1/index.native.js +0 -24
  149. package/dist/jsx/v1/index.native.js.map +0 -1
  150. package/dist/jsx/v1/types.mjs +0 -2
  151. package/dist/jsx/v1/types.mjs.map +0 -1
  152. package/dist/jsx/v1/types.native.js +0 -21
  153. package/dist/jsx/v1/types.native.js.map +0 -1
  154. package/src/inputTypes.test-d.ts +0 -245
  155. package/src/v1/Input.native.tsx +0 -153
  156. package/src/v1/Input.tsx +0 -190
  157. package/src/v1/TextArea.tsx +0 -35
  158. package/src/v1/index.ts +0 -3
  159. package/src/v1/types.ts +0 -65
  160. package/types/v1/Input.d.ts +0 -64
  161. package/types/v1/Input.d.ts.map +0 -1
  162. package/types/v1/Input.native.d.ts +0 -63
  163. package/types/v1/Input.native.d.ts.map +0 -1
  164. package/types/v1/TextArea.d.ts +0 -41
  165. package/types/v1/TextArea.d.ts.map +0 -1
  166. package/types/v1/index.d.ts +0 -4
  167. package/types/v1/index.d.ts.map +0 -1
  168. package/types/v1/types.d.ts +0 -39
  169. package/types/v1/types.d.ts.map +0 -1
@@ -1,284 +1,309 @@
1
1
  import React from 'react'
2
2
  import { TextInput, type TextInputProps as RNTextInputProps } from 'react-native'
3
- import { styled } from '@tamagui/core'
3
+ import { createStyledHOC, type GetProps, styled } from '@tamagui/core'
4
4
  import { registerFocusable } from '@tamagui/focusable'
5
5
  import { useNativeInputRef } from '@tamagui/element'
6
- import { styledBody } from './shared'
6
+ import { resolveMultilineInputSize, styledBody } from './shared'
7
7
  import type { InputExtraProps } from './types'
8
8
 
9
- const StyledInput = styled(TextInput, styledBody[0], styledBody[1])
9
+ const StyledInput = styled(TextInput, styledBody[0], styledBody[1]).resolve(
10
+ resolveMultilineInputSize
11
+ )
10
12
 
11
13
  /**
12
14
  * A web-aligned input component for React Native.
13
15
  * @see — Docs https://tamagui.dev/ui/inputs#input
14
16
  */
15
- export const Input = StyledInput.styleable<InputExtraProps>((props, forwardedRef) => {
16
- const {
17
- // Web props we need to convert
18
- type,
19
- disabled,
20
- readOnly,
21
- id,
22
- rows,
23
- autoComplete,
24
- enterKeyHint,
17
+ export const Input = createStyledHOC(
18
+ StyledInput,
19
+ (
20
+ props: Omit<GetProps<typeof StyledInput>, keyof InputExtraProps> & InputExtraProps,
21
+ forwardedRef
22
+ ) => {
23
+ const {
24
+ // Web props we need to convert
25
+ type,
26
+ disabled,
27
+ readOnly,
28
+ id,
29
+ rows,
30
+ autoComplete,
31
+ enterKeyHint,
25
32
 
26
- // Callbacks
27
- onChange,
28
- onInput,
29
- onKeyDown,
30
- onChangeText,
31
- onSubmitEditing,
32
- onSelectionChange,
33
- onEndEditing,
34
- onContentSizeChange,
35
- onScroll,
36
- onKeyPress: onKeyPressProp,
37
- selection,
33
+ // Callbacks
34
+ onChange,
35
+ onInput,
36
+ onKeyDown,
37
+ onChangeText,
38
+ onSubmitEditing,
39
+ onSelectionChange,
40
+ onEndEditing,
41
+ onContentSizeChange,
42
+ onScroll,
43
+ onKeyPress: onKeyPressProp,
44
+ selection,
38
45
 
39
- // Native-only props (pass through directly)
40
- keyboardAppearance,
41
- returnKeyType: returnKeyTypeProp,
42
- submitBehavior,
43
- blurOnSubmit,
44
- caretHidden,
45
- contextMenuHidden,
46
- selectTextOnFocus,
47
- secureTextEntry: secureTextEntryProp,
48
- maxFontSizeMultiplier,
49
- allowFontScaling,
50
- multiline: multilineProp,
51
- keyboardType: keyboardTypeProp,
52
- inputMode: inputModeProp,
53
- autoCapitalize: autoCapitalizeProp,
54
- autoCorrect: autoCorrectProp,
55
- autoFocusNative,
56
- textContentType,
46
+ // Native-only props (pass through directly)
47
+ keyboardAppearance,
48
+ returnKeyType: returnKeyTypeProp,
49
+ submitBehavior,
50
+ blurOnSubmit,
51
+ caretHidden,
52
+ contextMenuHidden,
53
+ selectTextOnFocus,
54
+ secureTextEntry: secureTextEntryProp,
55
+ maxFontSizeMultiplier,
56
+ allowFontScaling,
57
+ multiline: multilineProp,
58
+ keyboardType: keyboardTypeProp,
59
+ inputMode: inputModeProp,
60
+ autoCapitalize: autoCapitalizeProp,
61
+ autoCorrect: autoCorrectProp,
62
+ autoFocusNative,
63
+ textContentType,
57
64
 
58
- // iOS-only props
59
- clearButtonMode,
60
- clearTextOnFocus,
61
- enablesReturnKeyAutomatically,
62
- dataDetectorTypes,
63
- scrollEnabled,
64
- passwordRules,
65
- rejectResponderTermination,
66
- spellCheck,
67
- lineBreakStrategyIOS,
68
- lineBreakModeIOS,
69
- smartInsertDelete,
70
- inputAccessoryViewID,
71
- inputAccessoryViewButtonLabel,
72
- disableKeyboardShortcuts,
65
+ // iOS-only props
66
+ clearButtonMode,
67
+ clearTextOnFocus,
68
+ enablesReturnKeyAutomatically,
69
+ dataDetectorTypes,
70
+ scrollEnabled,
71
+ passwordRules,
72
+ rejectResponderTermination,
73
+ spellCheck,
74
+ lineBreakStrategyIOS,
75
+ lineBreakModeIOS,
76
+ smartInsertDelete,
77
+ inputAccessoryViewID,
78
+ inputAccessoryViewButtonLabel,
79
+ disableKeyboardShortcuts,
73
80
 
74
- // Android-only props
75
- importantForAutofill,
76
- disableFullscreenUI,
77
- inlineImageLeft,
78
- inlineImagePadding,
79
- returnKeyLabel,
80
- textBreakStrategy,
81
- textAlignVertical,
82
- verticalAlign,
83
- showSoftInputOnFocus,
84
- numberOfLines: numberOfLinesProp,
81
+ // Android-only props
82
+ importantForAutofill,
83
+ disableFullscreenUI,
84
+ inlineImageLeft,
85
+ inlineImagePadding,
86
+ returnKeyLabel,
87
+ textBreakStrategy,
88
+ textAlignVertical,
89
+ verticalAlign,
90
+ showSoftInputOnFocus,
91
+ numberOfLines: numberOfLinesProp,
85
92
 
86
- // Web-only props to filter out
87
- // @ts-ignore
88
- dirname,
89
- min,
90
- max,
91
- minLength,
92
- multiple,
93
- name,
94
- pattern,
95
- required,
96
- step,
97
- render,
93
+ // Web-only props to filter out
94
+ // @ts-ignore
95
+ dirname,
96
+ min,
97
+ max,
98
+ minLength,
99
+ multiple,
100
+ name,
101
+ pattern,
102
+ required,
103
+ step,
104
+ render,
98
105
 
99
- ...rest
100
- } = props
106
+ // caretColor is web-only as a CSS prop; on native forward to
107
+ // cursorColor (Android) + selectionColor (iOS+Android caret) unless
108
+ // those are explicitly set.
109
+ // @ts-ignore - caretColor is typed as web-only in core
110
+ caretColor,
111
+ cursorColor: cursorColorProp,
112
+ selectionColor: selectionColorProp,
101
113
 
102
- const { ref, composedRef } = useNativeInputRef(forwardedRef)
114
+ ...rest
115
+ } = props
103
116
 
104
- // Convert web type to native props (if not explicitly overridden)
105
- let secureTextEntry = secureTextEntryProp ?? false
106
- let keyboardType: RNTextInputProps['keyboardType'] = keyboardTypeProp ?? 'default'
107
- let inputMode: RNTextInputProps['inputMode'] = inputModeProp
117
+ const { ref, composedRef } = useNativeInputRef(forwardedRef)
108
118
 
109
- // only derive from type if native props weren't explicitly set
110
- if (!secureTextEntryProp && !keyboardTypeProp && !inputModeProp) {
111
- switch (type) {
112
- case 'password':
113
- secureTextEntry = true
114
- break
115
- case 'email':
116
- keyboardType = 'email-address'
117
- inputMode = 'email'
118
- break
119
- case 'tel':
120
- keyboardType = 'phone-pad'
121
- inputMode = 'tel'
122
- break
123
- case 'number':
124
- keyboardType = 'numeric'
125
- inputMode = 'numeric'
126
- break
127
- case 'url':
128
- keyboardType = 'url'
129
- inputMode = 'url'
130
- break
131
- case 'search':
132
- inputMode = 'search'
133
- break
119
+ // Convert web type to native props (if not explicitly overridden)
120
+ let secureTextEntry = secureTextEntryProp ?? false
121
+ let keyboardType: RNTextInputProps['keyboardType'] = keyboardTypeProp ?? 'default'
122
+ let inputMode: RNTextInputProps['inputMode'] = inputModeProp
123
+
124
+ // only derive from type if native props weren't explicitly set
125
+ if (!secureTextEntryProp && !keyboardTypeProp && !inputModeProp) {
126
+ switch (type) {
127
+ case 'password':
128
+ secureTextEntry = true
129
+ break
130
+ case 'email':
131
+ keyboardType = 'email-address'
132
+ inputMode = 'email'
133
+ break
134
+ case 'tel':
135
+ keyboardType = 'phone-pad'
136
+ inputMode = 'tel'
137
+ break
138
+ case 'number':
139
+ keyboardType = 'numeric'
140
+ inputMode = 'numeric'
141
+ break
142
+ case 'url':
143
+ keyboardType = 'url'
144
+ inputMode = 'url'
145
+ break
146
+ case 'search':
147
+ inputMode = 'search'
148
+ break
149
+ }
134
150
  }
135
- }
136
151
 
137
- // Use explicit returnKeyType if provided, otherwise convert enterKeyHint
138
- let returnKeyType: RNTextInputProps['returnKeyType'] = returnKeyTypeProp
139
- if (!returnKeyType && enterKeyHint) {
140
- switch (enterKeyHint) {
141
- case 'done':
142
- returnKeyType = 'done'
143
- break
144
- case 'go':
145
- returnKeyType = 'go'
146
- break
147
- case 'next':
148
- returnKeyType = 'next'
149
- break
150
- case 'search':
151
- returnKeyType = 'search'
152
- break
153
- case 'send':
154
- returnKeyType = 'send'
155
- break
152
+ // Use explicit returnKeyType if provided, otherwise convert enterKeyHint
153
+ let returnKeyType: RNTextInputProps['returnKeyType'] = returnKeyTypeProp
154
+ if (!returnKeyType && enterKeyHint) {
155
+ switch (enterKeyHint) {
156
+ case 'done':
157
+ returnKeyType = 'done'
158
+ break
159
+ case 'go':
160
+ returnKeyType = 'go'
161
+ break
162
+ case 'next':
163
+ returnKeyType = 'next'
164
+ break
165
+ case 'search':
166
+ returnKeyType = 'search'
167
+ break
168
+ case 'send':
169
+ returnKeyType = 'send'
170
+ break
171
+ }
156
172
  }
157
- }
158
173
 
159
- // Determine multiline
160
- const multiline = multilineProp ?? (render === 'textarea' || (rows && rows > 1))
161
- const numberOfLines = numberOfLinesProp ?? rows
174
+ // Determine multiline
175
+ const multiline = multilineProp ?? (render === 'textarea' || (rows && rows > 1))
176
+ const numberOfLines = numberOfLinesProp ?? rows
162
177
 
163
- // convert web-style autoCorrect string to native boolean
164
- const autoCorrect =
165
- autoCorrectProp === 'on' ? true : autoCorrectProp === 'off' ? false : autoCorrectProp
178
+ // convert web-style autoCorrect string to native boolean
179
+ const autoCorrect =
180
+ autoCorrectProp === 'on'
181
+ ? true
182
+ : autoCorrectProp === 'off'
183
+ ? false
184
+ : autoCorrectProp
166
185
 
167
- // convert web-style autoCapitalize to native values
168
- const autoCapitalize =
169
- autoCapitalizeProp === 'on'
170
- ? 'sentences'
171
- : autoCapitalizeProp === 'off'
172
- ? 'none'
173
- : autoCapitalizeProp
186
+ // convert web-style autoCapitalize to native values
187
+ const autoCapitalize =
188
+ autoCapitalizeProp === 'on'
189
+ ? 'sentences'
190
+ : autoCapitalizeProp === 'off'
191
+ ? 'none'
192
+ : autoCapitalizeProp
174
193
 
175
- // Register focusable
176
- React.useEffect(() => {
177
- if (!id || disabled) return
178
- return registerFocusable(id, {
179
- focusAndSelect: () => ref.current?.focus(),
180
- focus: () => ref.current?.focus(),
181
- })
182
- }, [id, disabled])
194
+ // Register focusable
195
+ React.useEffect(() => {
196
+ if (!id || disabled) return
197
+ return registerFocusable(id, {
198
+ focusAndSelect: () => ref.current?.focus(),
199
+ focus: () => ref.current?.focus(),
200
+ })
201
+ }, [id, disabled])
183
202
 
184
- // Handle web onChange/onInput -> native onChangeText
185
- const handleChangeText = (text: string) => {
186
- onChangeText?.(text)
187
- if (onChange) {
188
- onChange({ target: { value: text }, type: 'change' } as any)
203
+ // Handle web onChange/onInput -> native onChangeText
204
+ const handleChangeText = (text: string) => {
205
+ onChangeText?.(text)
206
+ if (onChange) {
207
+ onChange({ target: { value: text }, type: 'change' } as any)
208
+ }
209
+ if (onInput) {
210
+ onInput({ target: { value: text }, type: 'input' } as any)
211
+ }
189
212
  }
190
- if (onInput) {
191
- onInput({ target: { value: text }, type: 'input' } as any)
213
+
214
+ // Handle onKeyDown via onKeyPress + onSubmitEditing
215
+ const handleKeyPress = (e: any) => {
216
+ // call user's onKeyPress first
217
+ onKeyPressProp?.(e)
218
+ // then handle web onKeyDown compat
219
+ if (onKeyDown) {
220
+ const { key } = e.nativeEvent
221
+ if (key === 'Backspace' || key === 'Enter' || key.length === 1) {
222
+ onKeyDown({ key, type: 'keydown' } as any)
223
+ }
224
+ }
192
225
  }
193
- }
194
226
 
195
- // Handle onKeyDown via onKeyPress + onSubmitEditing
196
- const handleKeyPress = (e: any) => {
197
- // call user's onKeyPress first
198
- onKeyPressProp?.(e)
199
- // then handle web onKeyDown compat
200
- if (onKeyDown) {
201
- const { key } = e.nativeEvent
202
- if (key === 'Backspace' || key === 'Enter' || key.length === 1) {
203
- onKeyDown({ key, type: 'keydown' } as any)
227
+ const handleSubmitEditing = (e: any) => {
228
+ if (onKeyDown) {
229
+ onKeyDown({ key: 'Enter', type: 'keydown' } as any)
204
230
  }
231
+ onSubmitEditing?.(e)
205
232
  }
206
- }
207
233
 
208
- const handleSubmitEditing = (e: any) => {
209
- if (onKeyDown) {
210
- onKeyDown({ key: 'Enter', type: 'keydown' } as any)
234
+ // Handle selection change
235
+ const handleSelectionChange = (e: any) => {
236
+ onSelectionChange?.(e)
211
237
  }
212
- onSubmitEditing?.(e)
213
- }
214
238
 
215
- // Handle selection change
216
- const handleSelectionChange = (e: any) => {
217
- onSelectionChange?.(e)
218
- }
239
+ const finalProps: any = {
240
+ ...rest,
241
+ editable: !disabled && !readOnly,
242
+ secureTextEntry,
243
+ keyboardType,
244
+ keyboardAppearance,
245
+ inputMode,
246
+ returnKeyType,
247
+ multiline,
248
+ numberOfLines,
249
+ selection,
250
+ autoComplete: autoComplete as any,
251
+ autoFocus: autoFocusNative,
219
252
 
220
- const finalProps: any = {
221
- ...rest,
222
- editable: !disabled && !readOnly,
223
- secureTextEntry,
224
- keyboardType,
225
- keyboardAppearance,
226
- inputMode,
227
- returnKeyType,
228
- multiline,
229
- numberOfLines,
230
- selection,
231
- autoComplete: autoComplete as any,
232
- autoFocus: autoFocusNative,
253
+ // callbacks
254
+ onChangeText: handleChangeText,
255
+ onKeyPress: onKeyPressProp || onKeyDown ? handleKeyPress : undefined,
256
+ onSubmitEditing: onKeyDown || onSubmitEditing ? handleSubmitEditing : undefined,
257
+ onSelectionChange: onSelectionChange ? handleSelectionChange : undefined,
258
+ onEndEditing,
259
+ onContentSizeChange,
260
+ onScroll,
233
261
 
234
- // callbacks
235
- onChangeText: handleChangeText,
236
- onKeyPress: onKeyPressProp || onKeyDown ? handleKeyPress : undefined,
237
- onSubmitEditing: onKeyDown || onSubmitEditing ? handleSubmitEditing : undefined,
238
- onSelectionChange: onSelectionChange ? handleSelectionChange : undefined,
239
- onEndEditing,
240
- onContentSizeChange,
241
- onScroll,
262
+ // cross-platform native props
263
+ submitBehavior,
264
+ blurOnSubmit,
265
+ caretHidden,
266
+ contextMenuHidden,
267
+ selectTextOnFocus,
268
+ maxFontSizeMultiplier,
269
+ allowFontScaling,
270
+ autoCapitalize,
271
+ autoCorrect,
272
+ textContentType,
242
273
 
243
- // cross-platform native props
244
- submitBehavior,
245
- blurOnSubmit,
246
- caretHidden,
247
- contextMenuHidden,
248
- selectTextOnFocus,
249
- maxFontSizeMultiplier,
250
- allowFontScaling,
251
- autoCapitalize,
252
- autoCorrect,
253
- textContentType,
274
+ // iOS-only props
275
+ clearButtonMode,
276
+ clearTextOnFocus,
277
+ enablesReturnKeyAutomatically,
278
+ dataDetectorTypes,
279
+ scrollEnabled,
280
+ passwordRules,
281
+ rejectResponderTermination,
282
+ spellCheck,
283
+ lineBreakStrategyIOS,
284
+ lineBreakModeIOS,
285
+ smartInsertDelete,
286
+ inputAccessoryViewID,
287
+ inputAccessoryViewButtonLabel,
288
+ disableKeyboardShortcuts,
254
289
 
255
- // iOS-only props
256
- clearButtonMode,
257
- clearTextOnFocus,
258
- enablesReturnKeyAutomatically,
259
- dataDetectorTypes,
260
- scrollEnabled,
261
- passwordRules,
262
- rejectResponderTermination,
263
- spellCheck,
264
- lineBreakStrategyIOS,
265
- lineBreakModeIOS,
266
- smartInsertDelete,
267
- inputAccessoryViewID,
268
- inputAccessoryViewButtonLabel,
269
- disableKeyboardShortcuts,
290
+ // Android-only props
291
+ importantForAutofill,
292
+ disableFullscreenUI,
293
+ inlineImageLeft,
294
+ inlineImagePadding,
295
+ returnKeyLabel,
296
+ textBreakStrategy,
297
+ textAlignVertical,
298
+ verticalAlign,
299
+ showSoftInputOnFocus,
270
300
 
271
- // Android-only props
272
- importantForAutofill,
273
- disableFullscreenUI,
274
- inlineImageLeft,
275
- inlineImagePadding,
276
- returnKeyLabel,
277
- textBreakStrategy,
278
- textAlignVertical,
279
- verticalAlign,
280
- showSoftInputOnFocus,
281
- }
301
+ // caretColor → cursorColor (Android) + selectionColor (iOS+Android),
302
+ // unless the caller passed those explicitly.
303
+ cursorColor: cursorColorProp ?? caretColor,
304
+ selectionColor: selectionColorProp ?? caretColor,
305
+ }
282
306
 
283
- return <StyledInput ref={composedRef} {...finalProps} />
284
- })
307
+ return <StyledInput ref={composedRef} {...finalProps} />
308
+ }
309
+ )