@expo/ui 55.0.9 → 55.0.11

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 (79) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/android/build.gradle +2 -2
  3. package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +11 -7
  4. package/android/src/main/java/expo/modules/ui/TextFieldView.kt +326 -0
  5. package/build/jetpack-compose/SlotView.d.ts +7 -0
  6. package/build/jetpack-compose/SlotView.d.ts.map +1 -0
  7. package/build/jetpack-compose/TextField/index.d.ts +177 -0
  8. package/build/jetpack-compose/TextField/index.d.ts.map +1 -0
  9. package/build/jetpack-compose/index.d.ts +1 -1
  10. package/build/swift-ui/SecureField/index.d.ts +9 -20
  11. package/build/swift-ui/SecureField/index.d.ts.map +1 -1
  12. package/build/swift-ui/TextField/index.d.ts +17 -63
  13. package/build/swift-ui/TextField/index.d.ts.map +1 -1
  14. package/build/swift-ui/modifiers/index.d.ts +65 -4
  15. package/build/swift-ui/modifiers/index.d.ts.map +1 -1
  16. package/expo-module.config.json +1 -1
  17. package/ios/Modifiers/KeyboardTypeModifier.swift +68 -0
  18. package/ios/Modifiers/LineLimitModifier.swift +29 -0
  19. package/ios/Modifiers/OnSubmitModifier.swift +21 -0
  20. package/ios/Modifiers/ScrollTargetBehaviorModifier.swift +26 -0
  21. package/ios/Modifiers/ScrollTargetLayoutModifier.swift +14 -0
  22. package/ios/Modifiers/TextContentTypeModifier.swift +191 -0
  23. package/ios/Modifiers/TextInputAutocapitalizationModifier.swift +28 -0
  24. package/ios/Modifiers/ViewModifierRegistry.swift +28 -8
  25. package/ios/SecureFieldView.swift +5 -12
  26. package/ios/TextFieldView.swift +26 -94
  27. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.9/expo.modules.ui-55.0.9-sources.jar → 55.0.11/expo.modules.ui-55.0.11-sources.jar} +0 -0
  28. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.md5 +1 -0
  29. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.sha1 +1 -0
  30. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.sha256 +1 -0
  31. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.sha512 +1 -0
  32. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar +0 -0
  33. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.md5 +1 -0
  34. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.sha1 +1 -0
  35. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.sha256 +1 -0
  36. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.sha512 +1 -0
  37. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.9/expo.modules.ui-55.0.9.module → 55.0.11/expo.modules.ui-55.0.11.module} +22 -22
  38. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.md5 +1 -0
  39. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.sha1 +1 -0
  40. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.sha256 +1 -0
  41. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.sha512 +1 -0
  42. package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.9/expo.modules.ui-55.0.9.pom → 55.0.11/expo.modules.ui-55.0.11.pom} +1 -1
  43. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.md5 +1 -0
  44. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.sha1 +1 -0
  45. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.sha256 +1 -0
  46. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.sha512 +1 -0
  47. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
  48. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
  49. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
  50. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
  51. package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
  52. package/package.json +2 -2
  53. package/src/jetpack-compose/SlotView.tsx +15 -0
  54. package/src/jetpack-compose/TextField/index.tsx +276 -0
  55. package/src/jetpack-compose/index.ts +1 -1
  56. package/src/swift-ui/SecureField/index.tsx +18 -36
  57. package/src/swift-ui/TextField/index.tsx +30 -91
  58. package/src/swift-ui/modifiers/index.ts +151 -3
  59. package/android/src/main/java/expo/modules/ui/TextInputView.kt +0 -124
  60. package/build/jetpack-compose/TextInput/index.d.ts +0 -105
  61. package/build/jetpack-compose/TextInput/index.d.ts.map +0 -1
  62. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.md5 +0 -1
  63. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.sha1 +0 -1
  64. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.sha256 +0 -1
  65. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9-sources.jar.sha512 +0 -1
  66. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar +0 -0
  67. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.md5 +0 -1
  68. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.sha1 +0 -1
  69. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.sha256 +0 -1
  70. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.aar.sha512 +0 -1
  71. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.md5 +0 -1
  72. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.sha1 +0 -1
  73. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.sha256 +0 -1
  74. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.module.sha512 +0 -1
  75. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.md5 +0 -1
  76. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.sha1 +0 -1
  77. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.sha256 +0 -1
  78. package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.9/expo.modules.ui-55.0.9.pom.sha512 +0 -1
  79. package/src/jetpack-compose/TextInput/index.tsx +0 -157
@@ -1 +1 @@
1
- 512c30401c335ddaa5c8a143422f5f3f
1
+ 673a16d18408687f0dc012731a1c3ae0
@@ -1 +1 @@
1
- bffac0e03358cb495aff9195a3bf93ad3d004c4b
1
+ 2743de4bd2449b97b2797ec00d23338e4716d8a8
@@ -1 +1 @@
1
- 7ce3b849501b2897111d27627b715a85b21f39a0a9c3f3005d4429af92279f60
1
+ bd5001b4d32986f25d3bd0d3a733d0d14d4e57b979a31557f9bafd0bc24f645b
@@ -1 +1 @@
1
- 3e96702666bb6d88dfbed286974dd194a9ea50aa55de5f9a2ec267383b0c3ef556e5984ac83c5d83ca951f35f07ecc19382fdd0eefe110f8d94a64b5a62f7264
1
+ 900435ec3391079a90e9d457986cc48ca094a86b0681c36c1d25e14e83364087eaee9d702352dbbb662888ecaaf5c820f3f713588702319ad6f20cae75057933
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@expo/ui",
3
- "version": "55.0.9",
3
+ "version": "55.0.11",
4
4
  "description": "A collection of UI components",
5
5
  "sideEffects": [
6
6
  "*.fx.js"
@@ -67,5 +67,5 @@
67
67
  "react": "*",
68
68
  "react-native": "*"
69
69
  },
70
- "gitHead": "9cfae0185951ef0eb335e1c1270c7682ff761f69"
70
+ "gitHead": "b0ada30fd6a819c5f98a23d99b1b89a2ed68743d"
71
71
  }
@@ -0,0 +1,15 @@
1
+ import { requireNativeView } from 'expo';
2
+
3
+ type SlotNativeViewProps = {
4
+ slotName: string;
5
+ children: React.ReactNode;
6
+ };
7
+
8
+ const SlotNativeView: React.ComponentType<SlotNativeViewProps> = requireNativeView(
9
+ 'ExpoUI',
10
+ 'SlotView'
11
+ );
12
+
13
+ export function Slot({ slotName, children }: SlotNativeViewProps) {
14
+ return <SlotNativeView slotName={slotName}>{children}</SlotNativeView>;
15
+ }
@@ -0,0 +1,276 @@
1
+ import { requireNativeView } from 'expo';
2
+ import { Ref } from 'react';
3
+ import { ColorValue } from 'react-native';
4
+
5
+ import { ModifierConfig, ViewEvent } from '../../types';
6
+ import { Slot } from '../SlotView';
7
+ import { createViewModifierEventListener } from '../modifiers/utils';
8
+
9
+ // region Types
10
+
11
+ /**
12
+ * Can be used for imperatively setting text and focus on the `TextField` component.
13
+ */
14
+ export type TextFieldRef = {
15
+ setText: (newText: string) => Promise<void>;
16
+ focus: () => Promise<void>;
17
+ blur: () => Promise<void>;
18
+ };
19
+
20
+ export type TextFieldCapitalization = 'none' | 'characters' | 'words' | 'sentences';
21
+
22
+ export type TextFieldKeyboardType =
23
+ | 'text'
24
+ | 'number'
25
+ | 'email'
26
+ | 'phone'
27
+ | 'decimal'
28
+ | 'password'
29
+ | 'ascii'
30
+ | 'uri'
31
+ | 'numberPassword';
32
+
33
+ export type TextFieldImeAction =
34
+ | 'default'
35
+ | 'none'
36
+ | 'go'
37
+ | 'search'
38
+ | 'send'
39
+ | 'previous'
40
+ | 'next'
41
+ | 'done';
42
+
43
+ /**
44
+ * Keyboard options matching Compose `KeyboardOptions`.
45
+ */
46
+ export type TextFieldKeyboardOptions = {
47
+ /** @default 'none' */
48
+ capitalization?: TextFieldCapitalization;
49
+ /** @default true */
50
+ autoCorrectEnabled?: boolean;
51
+ /** @default 'text' */
52
+ keyboardType?: TextFieldKeyboardType;
53
+ /** @default 'default' */
54
+ imeAction?: TextFieldImeAction;
55
+ };
56
+
57
+ /**
58
+ * Keyboard actions matching Compose `KeyboardActions`.
59
+ * The triggered callback depends on the `imeAction` in `keyboardOptions`.
60
+ */
61
+ export type TextFieldKeyboardActions = {
62
+ onDone?: (value: string) => void;
63
+ onGo?: (value: string) => void;
64
+ onNext?: (value: string) => void;
65
+ onPrevious?: (value: string) => void;
66
+ onSearch?: (value: string) => void;
67
+ onSend?: (value: string) => void;
68
+ };
69
+
70
+ /**
71
+ * Colors for `TextField` and `OutlinedTextField`.
72
+ * Maps to `TextFieldColors` in Compose, shared by both variants.
73
+ */
74
+ export type TextFieldColors = {
75
+ focusedTextColor?: ColorValue;
76
+ unfocusedTextColor?: ColorValue;
77
+ disabledTextColor?: ColorValue;
78
+ errorTextColor?: ColorValue;
79
+ focusedContainerColor?: ColorValue;
80
+ unfocusedContainerColor?: ColorValue;
81
+ disabledContainerColor?: ColorValue;
82
+ errorContainerColor?: ColorValue;
83
+ cursorColor?: ColorValue;
84
+ errorCursorColor?: ColorValue;
85
+ focusedIndicatorColor?: ColorValue;
86
+ unfocusedIndicatorColor?: ColorValue;
87
+ disabledIndicatorColor?: ColorValue;
88
+ errorIndicatorColor?: ColorValue;
89
+ focusedLeadingIconColor?: ColorValue;
90
+ unfocusedLeadingIconColor?: ColorValue;
91
+ disabledLeadingIconColor?: ColorValue;
92
+ errorLeadingIconColor?: ColorValue;
93
+ focusedTrailingIconColor?: ColorValue;
94
+ unfocusedTrailingIconColor?: ColorValue;
95
+ disabledTrailingIconColor?: ColorValue;
96
+ errorTrailingIconColor?: ColorValue;
97
+ focusedLabelColor?: ColorValue;
98
+ unfocusedLabelColor?: ColorValue;
99
+ disabledLabelColor?: ColorValue;
100
+ errorLabelColor?: ColorValue;
101
+ focusedPlaceholderColor?: ColorValue;
102
+ unfocusedPlaceholderColor?: ColorValue;
103
+ disabledPlaceholderColor?: ColorValue;
104
+ errorPlaceholderColor?: ColorValue;
105
+ focusedSupportingTextColor?: ColorValue;
106
+ unfocusedSupportingTextColor?: ColorValue;
107
+ disabledSupportingTextColor?: ColorValue;
108
+ errorSupportingTextColor?: ColorValue;
109
+ focusedPrefixColor?: ColorValue;
110
+ unfocusedPrefixColor?: ColorValue;
111
+ disabledPrefixColor?: ColorValue;
112
+ errorPrefixColor?: ColorValue;
113
+ focusedSuffixColor?: ColorValue;
114
+ unfocusedSuffixColor?: ColorValue;
115
+ disabledSuffixColor?: ColorValue;
116
+ errorSuffixColor?: ColorValue;
117
+ };
118
+
119
+ /** Shared props between `TextField` and `OutlinedTextField`. */
120
+ type BaseTextFieldProps = {
121
+ ref?: Ref<TextFieldRef>;
122
+ /** Initial value displayed when mounted. Uncontrolled — change `key` to reset. */
123
+ defaultValue?: string;
124
+ /** If true, the text field will be focused automatically when mounted. @default false */
125
+ autoFocus?: boolean;
126
+ /** @default true */
127
+ enabled?: boolean;
128
+ /** @default false */
129
+ readOnly?: boolean;
130
+ /** @default false */
131
+ isError?: boolean;
132
+ /** @default false */
133
+ singleLine?: boolean;
134
+ maxLines?: number;
135
+ minLines?: number;
136
+ keyboardOptions?: TextFieldKeyboardOptions;
137
+ keyboardActions?: TextFieldKeyboardActions;
138
+ /** A callback triggered when user types text. */
139
+ onValueChange?: (value: string) => void;
140
+ /** A callback triggered when the field gains or loses focus. */
141
+ onFocusChanged?: (focused: boolean) => void;
142
+ shape?: object;
143
+ modifiers?: ModifierConfig[];
144
+ /** Slot children (e.g. `TextField.Label`, `TextField.Placeholder`). */
145
+ children?: React.ReactNode;
146
+ };
147
+
148
+ export type TextFieldProps = BaseTextFieldProps & {
149
+ colors?: TextFieldColors;
150
+ };
151
+
152
+ export type OutlinedTextFieldProps = BaseTextFieldProps & {
153
+ colors?: TextFieldColors;
154
+ };
155
+
156
+ // endregion Types
157
+
158
+ // region Native
159
+
160
+ type NativeTextFieldProps = Omit<
161
+ BaseTextFieldProps,
162
+ 'onValueChange' | 'onFocusChanged' | 'keyboardActions' | 'children' | 'shape'
163
+ > & {
164
+ variant: 'filled' | 'outlined';
165
+ colors?: TextFieldColors;
166
+ shape?: object;
167
+ children?: React.ReactNode;
168
+ } & ViewEvent<'onValueChange', { value: string }> &
169
+ ViewEvent<'onFocusChanged', { value: boolean }> &
170
+ ViewEvent<'onKeyboardAction', { action: string; value: string }>;
171
+
172
+ const TextFieldNativeView: React.ComponentType<NativeTextFieldProps> = requireNativeView(
173
+ 'ExpoUI',
174
+ 'TextFieldView'
175
+ );
176
+
177
+ function transformProps(
178
+ props: TextFieldProps | OutlinedTextFieldProps,
179
+ variant: 'filled' | 'outlined'
180
+ ): NativeTextFieldProps {
181
+ const { modifiers, children, keyboardActions, onValueChange, onFocusChanged, ...restProps } =
182
+ props;
183
+ return {
184
+ modifiers,
185
+ ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
186
+ ...restProps,
187
+ variant,
188
+ children,
189
+ onValueChange: onValueChange ? (event) => onValueChange(event.nativeEvent.value) : undefined,
190
+ onFocusChanged: onFocusChanged ? (event) => onFocusChanged(event.nativeEvent.value) : undefined,
191
+ onKeyboardAction: keyboardActions
192
+ ? (event) => {
193
+ const { action, value } = event.nativeEvent;
194
+ const actionMap: Record<string, ((v: string) => void) | undefined> = {
195
+ done: keyboardActions.onDone,
196
+ go: keyboardActions.onGo,
197
+ next: keyboardActions.onNext,
198
+ previous: keyboardActions.onPrevious,
199
+ search: keyboardActions.onSearch,
200
+ send: keyboardActions.onSend,
201
+ };
202
+ actionMap[action]?.(value);
203
+ }
204
+ : undefined,
205
+ };
206
+ }
207
+
208
+ // endregion Native
209
+
210
+ // region Slot components
211
+
212
+ function Label(props: { children: React.ReactNode }) {
213
+ return <Slot slotName="label">{props.children}</Slot>;
214
+ }
215
+
216
+ function Placeholder(props: { children: React.ReactNode }) {
217
+ return <Slot slotName="placeholder">{props.children}</Slot>;
218
+ }
219
+
220
+ function LeadingIcon(props: { children: React.ReactNode }) {
221
+ return <Slot slotName="leadingIcon">{props.children}</Slot>;
222
+ }
223
+
224
+ function TrailingIcon(props: { children: React.ReactNode }) {
225
+ return <Slot slotName="trailingIcon">{props.children}</Slot>;
226
+ }
227
+
228
+ function Prefix(props: { children: React.ReactNode }) {
229
+ return <Slot slotName="prefix">{props.children}</Slot>;
230
+ }
231
+
232
+ function Suffix(props: { children: React.ReactNode }) {
233
+ return <Slot slotName="suffix">{props.children}</Slot>;
234
+ }
235
+
236
+ function SupportingText(props: { children: React.ReactNode }) {
237
+ return <Slot slotName="supportingText">{props.children}</Slot>;
238
+ }
239
+
240
+ // endregion Slot components
241
+
242
+ // region Components
243
+
244
+ /**
245
+ * A Material3 `TextField`.
246
+ */
247
+ function TextFieldComponent(props: TextFieldProps) {
248
+ return <TextFieldNativeView {...transformProps(props, 'filled')} />;
249
+ }
250
+
251
+ TextFieldComponent.Label = Label;
252
+ TextFieldComponent.Placeholder = Placeholder;
253
+ TextFieldComponent.LeadingIcon = LeadingIcon;
254
+ TextFieldComponent.TrailingIcon = TrailingIcon;
255
+ TextFieldComponent.Prefix = Prefix;
256
+ TextFieldComponent.Suffix = Suffix;
257
+ TextFieldComponent.SupportingText = SupportingText;
258
+
259
+ /**
260
+ * A Material3 `OutlinedTextField` with a transparent background and border outline.
261
+ */
262
+ function OutlinedTextFieldComponent(props: OutlinedTextFieldProps) {
263
+ return <TextFieldNativeView {...transformProps(props, 'outlined')} />;
264
+ }
265
+
266
+ OutlinedTextFieldComponent.Label = Label;
267
+ OutlinedTextFieldComponent.Placeholder = Placeholder;
268
+ OutlinedTextFieldComponent.LeadingIcon = LeadingIcon;
269
+ OutlinedTextFieldComponent.TrailingIcon = TrailingIcon;
270
+ OutlinedTextFieldComponent.Prefix = Prefix;
271
+ OutlinedTextFieldComponent.Suffix = Suffix;
272
+ OutlinedTextFieldComponent.SupportingText = SupportingText;
273
+
274
+ // endregion Components
275
+
276
+ export { TextFieldComponent as TextField, OutlinedTextFieldComponent as OutlinedTextField };
@@ -22,7 +22,7 @@ export * from './Progress';
22
22
  export * from './Slider';
23
23
  export * from './Spacer';
24
24
  export * from './Switch';
25
- export * from './TextInput';
25
+ export * from './TextField';
26
26
  export * from './ToggleButton';
27
27
  export * from './Shape';
28
28
  export * from './ModalBottomSheet';
@@ -2,12 +2,11 @@ import { requireNativeView } from 'expo';
2
2
  import { Ref } from 'react';
3
3
 
4
4
  import { type ViewEvent } from '../../types';
5
- import { TextFieldKeyboardType } from '../TextField';
6
5
  import { createViewModifierEventListener } from '../modifiers/utils';
7
6
  import { type CommonViewModifierProps } from '../types';
8
7
 
9
8
  /**
10
- * Can be used for imperatively setting text on the SecureField component.
9
+ * Can be used for imperatively setting text and focus on the `SecureField` component.
11
10
  */
12
11
  export type SecureFieldRef = {
13
12
  setText: (newText: string) => Promise<void>;
@@ -17,42 +16,28 @@ export type SecureFieldRef = {
17
16
 
18
17
  export type SecureFieldProps = {
19
18
  ref?: Ref<SecureFieldRef>;
20
- /**
21
- * Initial value that the SecureField displays when being mounted. As the SecureField is an uncontrolled component, change the key prop if you need to change the text value.
22
- */
19
+ /** Initial value displayed when mounted. Uncontrolled — change `key` to reset. */
23
20
  defaultValue?: string;
21
+ /** If true, the field will be focused automatically when mounted. @default false */
22
+ autoFocus?: boolean;
24
23
  /**
25
24
  * A text that is displayed when the field is empty.
26
25
  */
27
26
  placeholder?: string;
28
27
  /**
29
- * A callback triggered when user types in text into the SecureField.
30
- */
31
- onChangeText?: (value: string) => void;
32
- /**
33
- * A callback triggered when user submits the TextField by pressing the return key.
34
- */
35
- onSubmit?: (value: string) => void;
36
- /**
37
- * A callback triggered when user focuses or blurs the SecureField.
28
+ * A callback triggered when the text value changes.
38
29
  */
39
- onChangeFocus?: (focused: boolean) => void;
40
- keyboardType?: TextFieldKeyboardType;
30
+ onValueChange?: (value: string) => void;
41
31
  /**
42
- * If true, the text input will be focused automatically when the component is mounted.
43
- * @default false
32
+ * A callback triggered when the field gains or loses focus.
44
33
  */
45
- autoFocus?: boolean;
34
+ onFocusChange?: (focused: boolean) => void;
46
35
  } & CommonViewModifierProps;
47
36
 
48
- type NativeSecureFieldProps = Omit<SecureFieldProps, 'onChangeText' | 'onSubmit'> & {} & ViewEvent<
49
- 'onValueChanged',
50
- { value: string }
51
- > &
52
- ViewEvent<'onFocusChanged', { value: boolean }> &
53
- ViewEvent<'onSubmit', { value: string }>;
37
+ type NativeSecureFieldProps = Omit<SecureFieldProps, 'onValueChange' | 'onFocusChange'> &
38
+ ViewEvent<'onValueChange', { value: string }> &
39
+ ViewEvent<'onFocusChange', { value: boolean }>;
54
40
 
55
- // We have to work around the `role` and `onPress` props being reserved by React Native.
56
41
  const SecureFieldNativeView: React.ComponentType<NativeSecureFieldProps> = requireNativeView(
57
42
  'ExpoUI',
58
43
  'SecureFieldView'
@@ -64,20 +49,17 @@ function transformSecureFieldProps(props: SecureFieldProps): NativeSecureFieldPr
64
49
  modifiers,
65
50
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
66
51
  ...restProps,
67
- onValueChanged: (event) => {
68
- props.onChangeText?.(event.nativeEvent.value);
69
- },
70
- onFocusChanged: (event) => {
71
- props.onChangeFocus?.(event.nativeEvent.value);
72
- },
73
- onSubmit: (event) => {
74
- props.onSubmit?.(event.nativeEvent.value);
75
- },
52
+ onValueChange: props.onValueChange
53
+ ? (event) => props.onValueChange?.(event.nativeEvent.value)
54
+ : undefined,
55
+ onFocusChange: props.onFocusChange
56
+ ? (event) => props.onFocusChange?.(event.nativeEvent.value)
57
+ : undefined,
76
58
  };
77
59
  }
78
60
 
79
61
  /**
80
- * Renders a `SecureField` component. Should mostly be used for embedding text inputs inside of SwiftUI lists and sections. Is an uncontrolled component.
62
+ * Renders a SwiftUI `SecureField` for password input.
81
63
  */
82
64
  export function SecureField(props: SecureFieldProps) {
83
65
  return <SecureFieldNativeView {...transformSecureFieldProps(props)} />;
@@ -5,39 +5,6 @@ import { type ViewEvent } from '../../types';
5
5
  import { createViewModifierEventListener } from '../modifiers/utils';
6
6
  import { type CommonViewModifierProps } from '../types';
7
7
 
8
- /**
9
- * Determines which keyboard to open. For example, `'numeric'`.
10
- *
11
- * Available options:
12
- * - default
13
- * - numeric
14
- * - email-address
15
- * - phone-pad
16
- * - decimal-pad
17
- * - ascii-capable
18
- * - url
19
- * - numbers-and-punctuation
20
- * - name-phone-pad
21
- * - twitter
22
- * - web-search
23
- * - ascii-capable-number-pad
24
- *
25
- * @default default
26
- */
27
- export type TextFieldKeyboardType =
28
- | 'default'
29
- | 'email-address'
30
- | 'numeric'
31
- | 'phone-pad'
32
- | 'ascii-capable'
33
- | 'numbers-and-punctuation'
34
- | 'url'
35
- | 'name-phone-pad'
36
- | 'decimal-pad'
37
- | 'twitter'
38
- | 'web-search'
39
- | 'ascii-capable-number-pad';
40
-
41
8
  /**
42
9
  * Can be used for imperatively setting text and focus on the `TextField` component.
43
10
  */
@@ -54,70 +21,44 @@ export type TextFieldRef = {
54
21
 
55
22
  export type TextFieldProps = {
56
23
  ref?: Ref<TextFieldRef>;
57
- /**
58
- * Initial value that the `TextField` displays when being mounted. As the `TextField` is an uncontrolled component, change the key prop if you need to change the text value.
59
- */
24
+ /** Initial value displayed when mounted. Uncontrolled — change `key` to reset. */
60
25
  defaultValue?: string;
26
+ /** If true, the text field will be focused automatically when mounted. @default false */
27
+ autoFocus?: boolean;
61
28
  /**
62
29
  * A text that is displayed when the field is empty.
63
30
  */
64
31
  placeholder?: string;
65
32
  /**
66
- * A callback triggered when user types in text into the `TextField`.
67
- */
68
- onChangeText?: (value: string) => void;
69
- /**
70
- * A callback triggered when user focuses or blurs the `TextField`.
33
+ * A callback triggered when the text value changes.
71
34
  */
72
- onChangeFocus?: (focused: boolean) => void;
35
+ onValueChange?: (value: string) => void;
73
36
  /**
74
- * A callback triggered when user submits the `TextField` by pressing the return key.
37
+ * A callback triggered when the field gains or loses focus.
75
38
  */
76
- onSubmit?: (value: string) => void;
39
+ onFocusChange?: (focused: boolean) => void;
77
40
  /**
78
41
  * A callback triggered when user selects text in the TextField.
79
42
  * @platform ios 18.0+ tvos 18.0+
80
43
  */
81
- onChangeSelection?: ({ start, end }: { start: number; end: number }) => void;
82
- /**
83
- * If true, the text input can be multiple lines.
84
- * While the content will wrap, there's no keyboard button to insert a new line.
85
- */
86
- multiline?: boolean;
44
+ onSelectionChange?: ({ start, end }: { start: number; end: number }) => void;
87
45
  /**
88
- * If true, the text input will add new lines when the user presses the return key.
89
- * @default true
46
+ * The axis along which the text field grows when content exceeds a single line.
47
+ * - `'horizontal'` — single line (default).
48
+ * - `'vertical'` — expands vertically for multiline content. Use `lineLimit` modifier to cap visible lines.
49
+ * @default 'horizontal'
90
50
  */
91
- allowNewlines?: boolean;
92
- /**
93
- * The number of lines to display when `multiline` is set to true.
94
- * If the number of lines in the view is above this number, the view scrolls.
95
- * @default undefined, which means unlimited lines.
96
- */
97
- numberOfLines?: number;
98
-
99
- keyboardType?: TextFieldKeyboardType;
100
- /**
101
- * If true, autocorrection is enabled.
102
- * @default true
103
- */
104
- autocorrection?: boolean;
105
-
106
- /**
107
- * If true, the text input will be focused automatically when the component is mounted.
108
- * @default false
109
- */
110
- autoFocus?: boolean;
51
+ axis?: 'horizontal' | 'vertical';
111
52
  } & CommonViewModifierProps;
112
53
 
113
54
  export type NativeTextFieldProps = Omit<
114
55
  TextFieldProps,
115
- 'onChangeText' | 'onSubmit'
116
- > & {} & ViewEvent<'onValueChanged', { value: string }> &
117
- ViewEvent<'onFocusChanged', { value: boolean }> &
118
- ViewEvent<'onSelectionChanged', { start: number; end: number }> &
119
- ViewEvent<'onSubmit', { value: string }>;
120
- // We have to work around the `role` and `onPress` props being reserved by React Native.
56
+ 'onValueChange' | 'onFocusChange' | 'onSelectionChange'
57
+ > &
58
+ ViewEvent<'onValueChange', { value: string }> &
59
+ ViewEvent<'onFocusChange', { value: boolean }> &
60
+ ViewEvent<'onSelectionChange', { start: number; end: number }>;
61
+
121
62
  const TextFieldNativeView: React.ComponentType<NativeTextFieldProps> = requireNativeView(
122
63
  'ExpoUI',
123
64
  'TextFieldView'
@@ -129,23 +70,21 @@ function transformTextFieldProps(props: TextFieldProps): NativeTextFieldProps {
129
70
  modifiers,
130
71
  ...(modifiers ? createViewModifierEventListener(modifiers) : undefined),
131
72
  ...restProps,
132
- onValueChanged: (event) => {
133
- props.onChangeText?.(event.nativeEvent.value);
134
- },
135
- onFocusChanged: (event) => {
136
- props.onChangeFocus?.(event.nativeEvent.value);
137
- },
138
- onSelectionChanged: (event) => {
139
- props.onChangeSelection?.({ start: event.nativeEvent.start, end: event.nativeEvent.end });
140
- },
141
- onSubmit: (event) => {
142
- props.onSubmit?.(event.nativeEvent.value);
143
- },
73
+ onValueChange: props.onValueChange
74
+ ? (event) => props.onValueChange?.(event.nativeEvent.value)
75
+ : undefined,
76
+ onFocusChange: props.onFocusChange
77
+ ? (event) => props.onFocusChange?.(event.nativeEvent.value)
78
+ : undefined,
79
+ onSelectionChange: props.onSelectionChange
80
+ ? (event) =>
81
+ props.onSelectionChange?.({ start: event.nativeEvent.start, end: event.nativeEvent.end })
82
+ : undefined,
144
83
  };
145
84
  }
146
85
 
147
86
  /**
148
- * Renders a `TextField` component. Should mostly be used for embedding text inputs inside of SwiftUI lists and sections. Is an uncontrolled component.
87
+ * Renders a SwiftUI `TextField`.
149
88
  */
150
89
  export function TextField(props: TextFieldProps) {
151
90
  return <TextFieldNativeView {...transformTextFieldProps(props)} />;