expo-interface 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +227 -0
- package/package.json +78 -0
- package/src/accent.tsx +62 -0
- package/src/button/button.css +118 -0
- package/src/button/index.android.tsx +114 -0
- package/src/button/index.ios.tsx +78 -0
- package/src/button/index.tsx +75 -0
- package/src/button/shared.ts +42 -0
- package/src/button/types.ts +72 -0
- package/src/css.d.ts +2 -0
- package/src/date-time/index.android.tsx +108 -0
- package/src/date-time/index.ios.tsx +54 -0
- package/src/date-time/index.tsx +119 -0
- package/src/date-time/shared.ts +160 -0
- package/src/date-time/types.ts +41 -0
- package/src/field-group/field-group.css +18 -0
- package/src/field-group/index.android.tsx +193 -0
- package/src/field-group/index.tsx +8 -0
- package/src/field-group/index.web.tsx +24 -0
- package/src/fill/index.android.ts +4 -0
- package/src/fill/index.ios.ts +9 -0
- package/src/fill/index.ts +10 -0
- package/src/global.css +17 -0
- package/src/icons.ts +42 -0
- package/src/index.ts +59 -0
- package/src/link.ts +36 -0
- package/src/list-item/index.android.tsx +52 -0
- package/src/list-item/index.tsx +21 -0
- package/src/list-item/types.ts +21 -0
- package/src/picker/index.android.tsx +80 -0
- package/src/picker/index.ios.tsx +48 -0
- package/src/picker/index.tsx +145 -0
- package/src/picker/shared.ts +70 -0
- package/src/picker/types.ts +48 -0
- package/src/progress/index.android.tsx +24 -0
- package/src/progress/index.ios.tsx +20 -0
- package/src/progress/index.tsx +30 -0
- package/src/progress/progress.css +27 -0
- package/src/progress/types.ts +19 -0
- package/src/qr/index.tsx +26 -0
- package/src/router/external-link.tsx +26 -0
- package/src/screen/header.tsx +65 -0
- package/src/screen/host-accent.android.ts +8 -0
- package/src/screen/host-accent.ios.ts +9 -0
- package/src/screen/host-accent.ts +15 -0
- package/src/screen/index.tsx +79 -0
- package/src/sheet/index.android.tsx +25 -0
- package/src/sheet/index.ios.tsx +20 -0
- package/src/sheet/index.tsx +18 -0
- package/src/stack-header/index.tsx +3 -0
- package/src/stack-header/index.web.tsx +33 -0
- package/src/switch/index.android.tsx +60 -0
- package/src/switch/index.ios.tsx +33 -0
- package/src/switch/index.tsx +62 -0
- package/src/switch/types.ts +23 -0
- package/src/tab-stack/index.tsx +21 -0
- package/src/tabs/index.tsx +34 -0
- package/src/tabs/index.web.tsx +114 -0
- package/src/tabs/types.ts +64 -0
- package/src/text-field/index.android.tsx +123 -0
- package/src/text-field/index.ios.tsx +73 -0
- package/src/text-field/index.tsx +78 -0
- package/src/text-field/shared.ts +83 -0
- package/src/text-field/types.ts +64 -0
- package/src/theme.ts +528 -0
- package/src/typography/index.tsx +83 -0
- package/src/typography/index.web.tsx +80 -0
- package/src/typography/types.ts +45 -0
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import type {TextFieldKeyboard, TextFieldProps} from './types';
|
|
2
|
+
import type {TextFieldColors, TextFieldKeyboardType} from '@expo/ui/jetpack-compose';
|
|
3
|
+
|
|
4
|
+
import {TextField as ComposeTextField, Text, useMaterialColors, useNativeState} from '@expo/ui/jetpack-compose';
|
|
5
|
+
import {fillMaxWidth, offset, testID as testIDModifier} from '@expo/ui/jetpack-compose/modifiers';
|
|
6
|
+
import {useColor} from '../theme';
|
|
7
|
+
import {useSyncedState} from './shared';
|
|
8
|
+
|
|
9
|
+
const TRANSPARENT = 'transparent';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Material 3's filled `TextField` bakes a 16dp horizontal content padding into
|
|
13
|
+
* the field itself (`TextFieldDefaults.contentPaddingWithoutLabel`), which the
|
|
14
|
+
* published `@expo/ui` does not expose (`BasicTextField` is documented for
|
|
15
|
+
* v56 but not shipped yet). Inside a `FieldGroup` row that padding stacks on
|
|
16
|
+
* the row's own 16dp inset, pushing the text 16dp right of sibling rows — so
|
|
17
|
+
* the field is shifted back by the same amount to line up.
|
|
18
|
+
*/
|
|
19
|
+
const CONTENT_PADDING = 16;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Android's Material `TextField` ships with a filled background and a bottom
|
|
23
|
+
* indicator line that clash with the iOS `Form` look. Here those are stripped
|
|
24
|
+
* to transparent so the field reads as a plain borderless row — the placeholder
|
|
25
|
+
* doubles as the label — living natively inside the surrounding
|
|
26
|
+
* `Host`/`FieldGroup`.
|
|
27
|
+
*/
|
|
28
|
+
export function TextField({
|
|
29
|
+
placeholder,
|
|
30
|
+
value,
|
|
31
|
+
onChangeText,
|
|
32
|
+
onSubmit,
|
|
33
|
+
disabled,
|
|
34
|
+
secureTextEntry,
|
|
35
|
+
keyboardType,
|
|
36
|
+
autoCapitalize,
|
|
37
|
+
autoCorrect,
|
|
38
|
+
multiline,
|
|
39
|
+
autoFocus,
|
|
40
|
+
maxLength,
|
|
41
|
+
accentColor,
|
|
42
|
+
testID,
|
|
43
|
+
}: TextFieldProps) {
|
|
44
|
+
const colors = useMaterialColors();
|
|
45
|
+
const tint = useColor('tint');
|
|
46
|
+
// Placeholder uses the app palette's tertiaryLabel (like web and iOS's
|
|
47
|
+
// `placeholderText`) instead of Material's onSurfaceVariant, which reads
|
|
48
|
+
// too bright in dark mode next to the other platforms.
|
|
49
|
+
const placeholderColor = useColor('tertiaryLabel');
|
|
50
|
+
const text = useNativeState(value ?? '');
|
|
51
|
+
useSyncedState(text, value);
|
|
52
|
+
|
|
53
|
+
const fieldColors: TextFieldColors = {
|
|
54
|
+
focusedContainerColor: TRANSPARENT,
|
|
55
|
+
unfocusedContainerColor: TRANSPARENT,
|
|
56
|
+
disabledContainerColor: TRANSPARENT,
|
|
57
|
+
errorContainerColor: TRANSPARENT,
|
|
58
|
+
focusedIndicatorColor: TRANSPARENT,
|
|
59
|
+
unfocusedIndicatorColor: TRANSPARENT,
|
|
60
|
+
disabledIndicatorColor: TRANSPARENT,
|
|
61
|
+
focusedTextColor: colors.onSurface,
|
|
62
|
+
unfocusedTextColor: colors.onSurface,
|
|
63
|
+
disabledTextColor: colors.onSurfaceVariant,
|
|
64
|
+
// Live accent seed by default — matches the web cursor (`theme.tint`) and
|
|
65
|
+
// the iOS field tint, even inside sheets whose native host is unseeded.
|
|
66
|
+
cursorColor: accentColor ?? tint,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<ComposeTextField
|
|
71
|
+
value={text}
|
|
72
|
+
onValueChange={onChangeText}
|
|
73
|
+
enabled={disabled !== true}
|
|
74
|
+
singleLine={!multiline}
|
|
75
|
+
autoFocus={autoFocus}
|
|
76
|
+
maxLength={maxLength}
|
|
77
|
+
visualTransformation={secureTextEntry ? 'password' : 'none'}
|
|
78
|
+
keyboardOptions={{
|
|
79
|
+
keyboardType: keyboardTypeFor(keyboardType, secureTextEntry),
|
|
80
|
+
capitalization: autoCapitalize,
|
|
81
|
+
autoCorrectEnabled: autoCorrect,
|
|
82
|
+
imeAction: onSubmit ? 'done' : 'default',
|
|
83
|
+
}}
|
|
84
|
+
keyboardActions={onSubmit ? {onDone: onSubmit} : undefined}
|
|
85
|
+
colors={fieldColors}
|
|
86
|
+
textStyle={{fontSize: 16, color: colors.onSurface}}
|
|
87
|
+
modifiers={[
|
|
88
|
+
fillMaxWidth(),
|
|
89
|
+
offset(-CONTENT_PADDING, 0),
|
|
90
|
+
...(testID ? [testIDModifier(testID)] : []),
|
|
91
|
+
]}>
|
|
92
|
+
{placeholder != null ? (
|
|
93
|
+
<ComposeTextField.Placeholder>
|
|
94
|
+
<Text color={placeholderColor}>{placeholder}</Text>
|
|
95
|
+
</ComposeTextField.Placeholder>
|
|
96
|
+
) : null}
|
|
97
|
+
</ComposeTextField>
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function keyboardTypeFor(
|
|
102
|
+
type: TextFieldKeyboard | undefined,
|
|
103
|
+
secure: boolean | undefined,
|
|
104
|
+
): TextFieldKeyboardType {
|
|
105
|
+
if (secure) {
|
|
106
|
+
return type === 'number' ? 'numberPassword' : 'password';
|
|
107
|
+
}
|
|
108
|
+
switch (type) {
|
|
109
|
+
case 'email':
|
|
110
|
+
return 'email';
|
|
111
|
+
case 'number':
|
|
112
|
+
return 'number';
|
|
113
|
+
case 'phone':
|
|
114
|
+
return 'phone';
|
|
115
|
+
case 'decimal':
|
|
116
|
+
return 'decimal';
|
|
117
|
+
case 'url':
|
|
118
|
+
return 'uri';
|
|
119
|
+
case 'default':
|
|
120
|
+
default:
|
|
121
|
+
return 'text';
|
|
122
|
+
}
|
|
123
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type {TextFieldCapitalize, TextFieldProps} from './types';
|
|
2
|
+
import type {ViewModifier} from '@expo/ui/swift-ui/modifiers';
|
|
3
|
+
|
|
4
|
+
import {SecureField, TextField as SwiftUITextField, useNativeState} from '@expo/ui/swift-ui';
|
|
5
|
+
import {autocorrectionDisabled, disabled as disabledMod, keyboardType as keyboardTypeMod, onSubmit as onSubmitMod, textInputAutocapitalization, tint} from '@expo/ui/swift-ui/modifiers';
|
|
6
|
+
import {keyboardTypeFor, useSyncedState} from './shared';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* iOS renders the field inline using SwiftUI's `TextField` (or `SecureField`
|
|
10
|
+
* for masked input), which is exactly the borderless `Form` row look the other
|
|
11
|
+
* platforms emulate: a placeholder that doubles as the label and the value
|
|
12
|
+
* filling the row. Drop it straight into a `FieldGroup.Section`.
|
|
13
|
+
*/
|
|
14
|
+
export function TextField({
|
|
15
|
+
placeholder,
|
|
16
|
+
value,
|
|
17
|
+
onChangeText,
|
|
18
|
+
onSubmit,
|
|
19
|
+
disabled,
|
|
20
|
+
secureTextEntry,
|
|
21
|
+
keyboardType,
|
|
22
|
+
autoCapitalize,
|
|
23
|
+
autoCorrect,
|
|
24
|
+
multiline,
|
|
25
|
+
autoFocus,
|
|
26
|
+
maxLength,
|
|
27
|
+
accentColor,
|
|
28
|
+
testID,
|
|
29
|
+
}: TextFieldProps) {
|
|
30
|
+
const text = useNativeState(value ?? '');
|
|
31
|
+
useSyncedState(text, value);
|
|
32
|
+
|
|
33
|
+
const modifiers: ViewModifier[] = [];
|
|
34
|
+
if (accentColor) modifiers.push(tint(accentColor));
|
|
35
|
+
if (keyboardType) modifiers.push(keyboardTypeMod(keyboardTypeFor(keyboardType)));
|
|
36
|
+
if (autoCorrect === false) modifiers.push(autocorrectionDisabled(true));
|
|
37
|
+
if (autoCapitalize) modifiers.push(textInputAutocapitalization(autocapitalizationFor(autoCapitalize)));
|
|
38
|
+
if (onSubmit) modifiers.push(onSubmitMod(() => onSubmit(text.value)));
|
|
39
|
+
if (disabled) modifiers.push(disabledMod(true));
|
|
40
|
+
|
|
41
|
+
if (secureTextEntry) {
|
|
42
|
+
return (
|
|
43
|
+
<SecureField
|
|
44
|
+
text={text}
|
|
45
|
+
placeholder={placeholder}
|
|
46
|
+
autoFocus={autoFocus}
|
|
47
|
+
maxLength={maxLength}
|
|
48
|
+
onTextChange={onChangeText}
|
|
49
|
+
modifiers={modifiers}
|
|
50
|
+
testID={testID}
|
|
51
|
+
/>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<SwiftUITextField
|
|
57
|
+
text={text}
|
|
58
|
+
placeholder={placeholder}
|
|
59
|
+
autoFocus={autoFocus}
|
|
60
|
+
maxLength={maxLength}
|
|
61
|
+
axis={multiline ? 'vertical' : 'horizontal'}
|
|
62
|
+
onTextChange={onChangeText}
|
|
63
|
+
modifiers={modifiers}
|
|
64
|
+
testID={testID}
|
|
65
|
+
/>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function autocapitalizationFor(
|
|
70
|
+
value: TextFieldCapitalize,
|
|
71
|
+
): 'never' | 'words' | 'sentences' | 'characters' {
|
|
72
|
+
return value === 'none' ? 'never' : value;
|
|
73
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type {TextFieldProps} from './types';
|
|
2
|
+
import type {TextStyle} from 'react-native';
|
|
3
|
+
|
|
4
|
+
import {StyleSheet, TextInput} from 'react-native';
|
|
5
|
+
import {fonts, fontWeights, theme, variants} from '../theme';
|
|
6
|
+
import {keyboardTypeFor, useTextValue} from './shared';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* On web the field mirrors the native iOS/Android row: a borderless, full-width
|
|
10
|
+
* input whose placeholder doubles as the label, styled with the shared body
|
|
11
|
+
* typography so it sits flush inside a `FieldGroup.Section`. The browser focus
|
|
12
|
+
* outline is suppressed to match the chromeless iOS `Form` look.
|
|
13
|
+
*/
|
|
14
|
+
export function TextField({
|
|
15
|
+
placeholder,
|
|
16
|
+
value,
|
|
17
|
+
onChangeText,
|
|
18
|
+
onSubmit,
|
|
19
|
+
disabled,
|
|
20
|
+
secureTextEntry,
|
|
21
|
+
keyboardType,
|
|
22
|
+
autoCapitalize,
|
|
23
|
+
autoCorrect,
|
|
24
|
+
multiline,
|
|
25
|
+
autoFocus,
|
|
26
|
+
maxLength,
|
|
27
|
+
accentColor,
|
|
28
|
+
testID,
|
|
29
|
+
style,
|
|
30
|
+
}: TextFieldProps) {
|
|
31
|
+
const [current, setValue] = useTextValue(value, onChangeText);
|
|
32
|
+
const cursor = accentColor ?? (theme.tint as string);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<TextInput
|
|
36
|
+
value={current}
|
|
37
|
+
onChangeText={setValue}
|
|
38
|
+
placeholder={placeholder}
|
|
39
|
+
placeholderTextColor={theme.tertiaryLabel}
|
|
40
|
+
editable={!disabled}
|
|
41
|
+
secureTextEntry={secureTextEntry}
|
|
42
|
+
keyboardType={keyboardTypeFor(keyboardType)}
|
|
43
|
+
autoCapitalize={autoCapitalize}
|
|
44
|
+
autoCorrect={autoCorrect}
|
|
45
|
+
multiline={multiline}
|
|
46
|
+
autoFocus={autoFocus}
|
|
47
|
+
maxLength={maxLength}
|
|
48
|
+
cursorColor={cursor}
|
|
49
|
+
selectionColor={cursor}
|
|
50
|
+
onSubmitEditing={onSubmit ? event => onSubmit(event.nativeEvent.text) : undefined}
|
|
51
|
+
aria-label={placeholder}
|
|
52
|
+
testID={testID}
|
|
53
|
+
style={[styles.input, disabled && styles.disabled, style]}
|
|
54
|
+
/>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const styles = StyleSheet.create({
|
|
59
|
+
input: {
|
|
60
|
+
width: '100%',
|
|
61
|
+
margin: 0,
|
|
62
|
+
paddingVertical: 0,
|
|
63
|
+
// `label` (14px) matches the sibling rows in a `FieldGroup.Section`:
|
|
64
|
+
// `@expo/ui`'s universal `Text` renders at react-native-web's 14px
|
|
65
|
+
// default, and rows like `DateTimePicker` use the `label` variant.
|
|
66
|
+
fontSize: variants.label.fontSize,
|
|
67
|
+
lineHeight: variants.label.lineHeight,
|
|
68
|
+
fontFamily: fonts?.sans,
|
|
69
|
+
fontWeight: fontWeights.normal,
|
|
70
|
+
color: theme.label,
|
|
71
|
+
// Web-only: drop the default browser focus ring so the field stays flush
|
|
72
|
+
// with the surrounding card, matching the iOS Form row.
|
|
73
|
+
...({outlineStyle: 'none'} as unknown as TextStyle),
|
|
74
|
+
},
|
|
75
|
+
disabled: {
|
|
76
|
+
opacity: 0.4,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type {TextFieldKeyboard} from './types';
|
|
2
|
+
import type {ObservableState} from '@expo/ui';
|
|
3
|
+
import {useCallback, useEffect, useState} from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Keyboard variants understood by both React Native's `keyboardType` prop and
|
|
7
|
+
* SwiftUI's `keyboardType` modifier — the overlap the web and iOS fields share.
|
|
8
|
+
*/
|
|
9
|
+
type AppleKeyboardType =
|
|
10
|
+
| 'default'
|
|
11
|
+
| 'email-address'
|
|
12
|
+
| 'numeric'
|
|
13
|
+
| 'phone-pad'
|
|
14
|
+
| 'decimal-pad'
|
|
15
|
+
| 'url';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Bridges controlled and uncontrolled usage on web, mirroring `useDateValue`.
|
|
19
|
+
* When `value` is provided the component is controlled; otherwise it falls back
|
|
20
|
+
* to internal state seeded with an empty string.
|
|
21
|
+
* @param value - The current value of the field.
|
|
22
|
+
* @param onChangeText - The function to call when the text changes.
|
|
23
|
+
* @returns The current text and the function to call when the text changes.
|
|
24
|
+
*/
|
|
25
|
+
export function useTextValue(
|
|
26
|
+
value: string | undefined,
|
|
27
|
+
onChangeText: ((text: string) => void) | undefined,
|
|
28
|
+
): [string, (next: string) => void] {
|
|
29
|
+
const [internal, setInternal] = useState(value ?? '');
|
|
30
|
+
const current = value ?? internal;
|
|
31
|
+
|
|
32
|
+
const setValue = useCallback(
|
|
33
|
+
(next: string) => {
|
|
34
|
+
if (value === undefined) {
|
|
35
|
+
setInternal(next);
|
|
36
|
+
}
|
|
37
|
+
onChangeText?.(next);
|
|
38
|
+
},
|
|
39
|
+
[value, onChangeText],
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return [current, setValue];
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Pushes a controlled `value` prop into a native `useNativeState` observable so
|
|
47
|
+
* parent-driven updates reflect in the field. Uncontrolled fields (no `value`)
|
|
48
|
+
* are left to manage their own state. The native field writes user input back
|
|
49
|
+
* into the same observable, so this only fires for external changes.
|
|
50
|
+
* @param state - The observable bound to the native field's text.
|
|
51
|
+
* @param value - The controlled value, or `undefined` when uncontrolled.
|
|
52
|
+
*/
|
|
53
|
+
export function useSyncedState(state: ObservableState<string>, value: string | undefined): void {
|
|
54
|
+
useEffect(() => {
|
|
55
|
+
if (value !== undefined && state.value !== value) {
|
|
56
|
+
state.value = value;
|
|
57
|
+
}
|
|
58
|
+
}, [state, value]);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Maps the conformed keyboard variant to the React Native / SwiftUI keyboard
|
|
63
|
+
* type, shared by the web and iOS implementations.
|
|
64
|
+
* @param type - The cross-platform keyboard variant.
|
|
65
|
+
* @returns The matching `KeyboardTypeOptions` value.
|
|
66
|
+
*/
|
|
67
|
+
export function keyboardTypeFor(type: TextFieldKeyboard | undefined): AppleKeyboardType {
|
|
68
|
+
switch (type) {
|
|
69
|
+
case 'email':
|
|
70
|
+
return 'email-address';
|
|
71
|
+
case 'number':
|
|
72
|
+
return 'numeric';
|
|
73
|
+
case 'phone':
|
|
74
|
+
return 'phone-pad';
|
|
75
|
+
case 'decimal':
|
|
76
|
+
return 'decimal-pad';
|
|
77
|
+
case 'url':
|
|
78
|
+
return 'url';
|
|
79
|
+
case 'default':
|
|
80
|
+
default:
|
|
81
|
+
return 'default';
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type {StyleProp, TextStyle} from 'react-native';
|
|
2
|
+
|
|
3
|
+
/** Keyboard variant shown while editing, conformed across platforms. */
|
|
4
|
+
export type TextFieldKeyboard =
|
|
5
|
+
| 'default'
|
|
6
|
+
| 'email'
|
|
7
|
+
| 'number'
|
|
8
|
+
| 'phone'
|
|
9
|
+
| 'decimal'
|
|
10
|
+
| 'url';
|
|
11
|
+
|
|
12
|
+
/** Automatic capitalization behaviour while typing. */
|
|
13
|
+
export type TextFieldCapitalize = 'none' | 'sentences' | 'words' | 'characters';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Cross-platform single/multi-line text input with a conformed iOS-style
|
|
17
|
+
* appearance — a borderless field whose placeholder doubles as the row label,
|
|
18
|
+
* exactly the SwiftUI `Form` row look the other platforms emulate. Drop it
|
|
19
|
+
* straight into a `FieldGroup.Section` alongside other rows.
|
|
20
|
+
*
|
|
21
|
+
* The control may be used controlled (pass `value` + `onChangeText`) or
|
|
22
|
+
* uncontrolled (omit both and it manages its own state).
|
|
23
|
+
*/
|
|
24
|
+
export interface TextFieldProps {
|
|
25
|
+
/** Placeholder shown when the field is empty, doubling as the row's label. */
|
|
26
|
+
placeholder?: string;
|
|
27
|
+
/** Current text (controlled). When omitted the component keeps its own state. */
|
|
28
|
+
value?: string;
|
|
29
|
+
/** Called whenever the text changes. */
|
|
30
|
+
onChangeText?: (text: string) => void;
|
|
31
|
+
/** Called when the user presses the keyboard return key. Receives the text. */
|
|
32
|
+
onSubmit?: (text: string) => void;
|
|
33
|
+
/** Disables editing and dims the field. */
|
|
34
|
+
disabled?: boolean;
|
|
35
|
+
/** Masks the input for sensitive values such as passwords. */
|
|
36
|
+
secureTextEntry?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Keyboard variant to display.
|
|
39
|
+
* @default 'default'
|
|
40
|
+
*/
|
|
41
|
+
keyboardType?: TextFieldKeyboard;
|
|
42
|
+
/**
|
|
43
|
+
* Automatic capitalization behaviour.
|
|
44
|
+
* @default 'sentences'
|
|
45
|
+
*/
|
|
46
|
+
autoCapitalize?: TextFieldCapitalize;
|
|
47
|
+
/**
|
|
48
|
+
* Enables autocorrect / spellcheck suggestions.
|
|
49
|
+
* @default true
|
|
50
|
+
*/
|
|
51
|
+
autoCorrect?: boolean;
|
|
52
|
+
/** Allows multiple lines of input that grow vertically. */
|
|
53
|
+
multiline?: boolean;
|
|
54
|
+
/** Focuses the field automatically when mounted. */
|
|
55
|
+
autoFocus?: boolean;
|
|
56
|
+
/** Maximum number of characters allowed. Truncates natively as the user types. */
|
|
57
|
+
maxLength?: number;
|
|
58
|
+
/** Tint applied to the cursor/selection (web/android) and the field (iOS). */
|
|
59
|
+
accentColor?: string;
|
|
60
|
+
/** Identifier used to locate the component in end-to-end tests. */
|
|
61
|
+
testID?: string;
|
|
62
|
+
/** Style applied to the text content (web only). */
|
|
63
|
+
style?: StyleProp<TextStyle>;
|
|
64
|
+
}
|