@expo/ui 55.0.10 → 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.
- package/CHANGELOG.md +7 -0
- package/android/build.gradle +2 -2
- package/android/src/main/java/expo/modules/ui/ExpoUIModule.kt +11 -7
- package/android/src/main/java/expo/modules/ui/TextFieldView.kt +326 -0
- package/build/jetpack-compose/SlotView.d.ts +7 -0
- package/build/jetpack-compose/SlotView.d.ts.map +1 -0
- package/build/jetpack-compose/TextField/index.d.ts +177 -0
- package/build/jetpack-compose/TextField/index.d.ts.map +1 -0
- package/build/jetpack-compose/index.d.ts +1 -1
- package/build/swift-ui/SecureField/index.d.ts +9 -20
- package/build/swift-ui/SecureField/index.d.ts.map +1 -1
- package/build/swift-ui/TextField/index.d.ts +17 -63
- package/build/swift-ui/TextField/index.d.ts.map +1 -1
- package/build/swift-ui/modifiers/index.d.ts +35 -4
- package/build/swift-ui/modifiers/index.d.ts.map +1 -1
- package/expo-module.config.json +1 -1
- package/ios/Modifiers/KeyboardTypeModifier.swift +68 -0
- package/ios/Modifiers/LineLimitModifier.swift +29 -0
- package/ios/Modifiers/OnSubmitModifier.swift +21 -0
- package/ios/Modifiers/ViewModifierRegistry.swift +12 -8
- package/ios/SecureFieldView.swift +5 -12
- package/ios/TextFieldView.swift +26 -94
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.10/expo.modules.ui-55.0.10-sources.jar → 55.0.11/expo.modules.ui-55.0.11-sources.jar} +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11-sources.jar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.aar.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.10/expo.modules.ui-55.0.10.module → 55.0.11/expo.modules.ui-55.0.11.module} +22 -22
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.module.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/{55.0.10/expo.modules.ui-55.0.10.pom → 55.0.11/expo.modules.ui-55.0.11.pom} +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.md5 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.sha1 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.sha256 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.11/expo.modules.ui-55.0.11.pom.sha512 +1 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml +4 -4
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.md5 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha1 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha256 +1 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/maven-metadata.xml.sha512 +1 -1
- package/package.json +2 -2
- package/src/jetpack-compose/SlotView.tsx +15 -0
- package/src/jetpack-compose/TextField/index.tsx +276 -0
- package/src/jetpack-compose/index.ts +1 -1
- package/src/swift-ui/SecureField/index.tsx +18 -36
- package/src/swift-ui/TextField/index.tsx +30 -91
- package/src/swift-ui/modifiers/index.ts +63 -3
- package/android/src/main/java/expo/modules/ui/TextInputView.kt +0 -124
- package/build/jetpack-compose/TextInput/index.d.ts +0 -105
- package/build/jetpack-compose/TextInput/index.d.ts.map +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10-sources.jar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10-sources.jar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10-sources.jar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10-sources.jar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.aar +0 -0
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.aar.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.aar.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.aar.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.aar.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.module.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.module.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.module.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.module.sha512 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.pom.md5 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.pom.sha1 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.pom.sha256 +0 -1
- package/local-maven-repo/expo/modules/ui/expo.modules.ui/55.0.10/expo.modules.ui-55.0.10.pom.sha512 +0 -1
- package/src/jetpack-compose/TextInput/index.tsx +0 -157
|
@@ -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 './
|
|
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
|
|
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
|
-
|
|
40
|
-
keyboardType?: TextFieldKeyboardType;
|
|
30
|
+
onValueChange?: (value: string) => void;
|
|
41
31
|
/**
|
|
42
|
-
*
|
|
43
|
-
* @default false
|
|
32
|
+
* A callback triggered when the field gains or loses focus.
|
|
44
33
|
*/
|
|
45
|
-
|
|
34
|
+
onFocusChange?: (focused: boolean) => void;
|
|
46
35
|
} & CommonViewModifierProps;
|
|
47
36
|
|
|
48
|
-
type NativeSecureFieldProps = Omit<SecureFieldProps, '
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
68
|
-
props.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
props.
|
|
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`
|
|
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
|
|
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
|
-
|
|
35
|
+
onValueChange?: (value: string) => void;
|
|
73
36
|
/**
|
|
74
|
-
* A callback triggered when
|
|
37
|
+
* A callback triggered when the field gains or loses focus.
|
|
75
38
|
*/
|
|
76
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
89
|
-
*
|
|
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
|
-
|
|
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
|
-
'
|
|
116
|
-
> &
|
|
117
|
-
ViewEvent<'
|
|
118
|
-
ViewEvent<'
|
|
119
|
-
ViewEvent<'
|
|
120
|
-
|
|
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
|
-
|
|
133
|
-
props.
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
props.
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
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
|
|
87
|
+
* Renders a SwiftUI `TextField`.
|
|
149
88
|
*/
|
|
150
89
|
export function TextField(props: TextFieldProps) {
|
|
151
90
|
return <TextFieldNativeView {...transformTextFieldProps(props)} />;
|
|
@@ -851,11 +851,31 @@ export const textSelection = (value: boolean) => createModifier('textSelection',
|
|
|
851
851
|
*/
|
|
852
852
|
export const lineSpacing = (value: number) => createModifier('lineSpacing', { value });
|
|
853
853
|
/**
|
|
854
|
-
* Sets the
|
|
855
|
-
*
|
|
854
|
+
* Sets the line limit for text in the view.
|
|
855
|
+
*
|
|
856
|
+
* Four variants matching SwiftUI:
|
|
857
|
+
* - `lineLimit()` — no line limit (unlimited lines)
|
|
858
|
+
* - `lineLimit(5)` — max 5 lines
|
|
859
|
+
* - `lineLimit(5, { reservesSpace: true })` — max 5 lines, reserves height even when empty (iOS 16+, tvOS 16+)
|
|
860
|
+
* - `lineLimit({ min: 3, max: 8 })` — range of 3 to 8 lines (iOS 16+, tvOS 16+)
|
|
861
|
+
*
|
|
856
862
|
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/linelimit(_:)).
|
|
857
863
|
*/
|
|
858
|
-
export
|
|
864
|
+
export function lineLimit(): ModifierConfig;
|
|
865
|
+
export function lineLimit(limit: number, options?: { reservesSpace?: boolean }): ModifierConfig;
|
|
866
|
+
export function lineLimit(range: { min: number; max: number }): ModifierConfig;
|
|
867
|
+
export function lineLimit(
|
|
868
|
+
limitOrRange?: number | { min: number; max: number },
|
|
869
|
+
options?: { reservesSpace?: boolean }
|
|
870
|
+
): ModifierConfig {
|
|
871
|
+
if (typeof limitOrRange === 'object' && limitOrRange !== null) {
|
|
872
|
+
return createModifier('lineLimit', { min: limitOrRange.min, max: limitOrRange.max });
|
|
873
|
+
}
|
|
874
|
+
return createModifier('lineLimit', {
|
|
875
|
+
limit: limitOrRange,
|
|
876
|
+
reservesSpace: options?.reservesSpace,
|
|
877
|
+
});
|
|
878
|
+
}
|
|
859
879
|
/**
|
|
860
880
|
* Sets the header prominence for this view.
|
|
861
881
|
* @param prominence - The prominence to apply.
|
|
@@ -1017,6 +1037,43 @@ export const submitLabel = (
|
|
|
1017
1037
|
submitLabel: 'continue' | 'done' | 'go' | 'join' | 'next' | 'return' | 'route' | 'search' | 'send'
|
|
1018
1038
|
) => createModifier('submitLabel', { submitLabel });
|
|
1019
1039
|
|
|
1040
|
+
/**
|
|
1041
|
+
* Sets the keyboard type for text input views.
|
|
1042
|
+
* @param keyboardType - The type of keyboard to display.
|
|
1043
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/keyboardtype(_:)).
|
|
1044
|
+
*/
|
|
1045
|
+
export const keyboardType = (
|
|
1046
|
+
keyboardType:
|
|
1047
|
+
| 'default'
|
|
1048
|
+
| 'email-address'
|
|
1049
|
+
| 'numeric'
|
|
1050
|
+
| 'phone-pad'
|
|
1051
|
+
| 'ascii-capable'
|
|
1052
|
+
| 'numbers-and-punctuation'
|
|
1053
|
+
| 'url'
|
|
1054
|
+
| 'name-phone-pad'
|
|
1055
|
+
| 'decimal-pad'
|
|
1056
|
+
| 'twitter'
|
|
1057
|
+
| 'web-search'
|
|
1058
|
+
| 'ascii-capable-number-pad'
|
|
1059
|
+
) => createModifier('keyboardType', { keyboardType });
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* Disables autocorrection for text input views.
|
|
1063
|
+
* @param disabled - Whether autocorrection is disabled. Defaults to `true`.
|
|
1064
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/autocorrectiondisabled(_:)).
|
|
1065
|
+
*/
|
|
1066
|
+
export const autocorrectionDisabled = (disabled: boolean = true) =>
|
|
1067
|
+
createModifier('autocorrectionDisabled', { disabled });
|
|
1068
|
+
|
|
1069
|
+
/**
|
|
1070
|
+
* Adds an action to perform when the user submits a value to this view (e.g. pressing return in a text field).
|
|
1071
|
+
* @param handler - Function to call on submit.
|
|
1072
|
+
* @see Official [SwiftUI documentation](https://developer.apple.com/documentation/swiftui/view/onsubmit(of:_:)).
|
|
1073
|
+
*/
|
|
1074
|
+
export const onSubmit = (handler: () => void) =>
|
|
1075
|
+
createModifierWithEventListener('onSubmit', handler);
|
|
1076
|
+
|
|
1020
1077
|
/**
|
|
1021
1078
|
* Sets how often the shift key in the keyboard is automatically enabled.
|
|
1022
1079
|
* @param autocapitalization - The autocapitalization behavior.
|
|
@@ -1242,6 +1299,9 @@ export type BuiltInModifier =
|
|
|
1242
1299
|
| ReturnType<typeof gridColumnAlignment>
|
|
1243
1300
|
| ReturnType<typeof gridCellAnchor>
|
|
1244
1301
|
| ReturnType<typeof submitLabel>
|
|
1302
|
+
| ReturnType<typeof keyboardType>
|
|
1303
|
+
| ReturnType<typeof autocorrectionDisabled>
|
|
1304
|
+
| ReturnType<typeof onSubmit>
|
|
1245
1305
|
| ReturnType<typeof textInputAutocapitalization>
|
|
1246
1306
|
| ReturnType<typeof textContentType>
|
|
1247
1307
|
| ReturnType<typeof datePickerStyle>
|