Browse React Native
React NativeComponentsNo. 10 of 22
Input
A single-line text field in the theme: 44 px tall, a focus ring, and an error state from aria-invalid.
For the web: Input, with the same name and variants.
Preview
Loading the preview
The gallery's web build, through react-native-web. On a phone the same code draws native views.
Installation
npx shadcn@latest add @corsair-native/inputThe app's components.json needs the @corsair-native registry first; see Installation. The files land in your project as source: edit them like your own code.
- Also adds
- theme
API
Read from the source's own comments and types. Props marked * are required.
InputComponent
A single-line text field in the theme: 44 px tall, 16 px text, a ring while focused and a destructive border when aria-invalid. Name it for screen readers with accessibilityLabel (or aria-labelledby pointing at a label's nativeID), and give it the right keyboardType, autoComplete and textContentType so the keyboard and autofill help.
| Prop | Type | Default |
|---|---|---|
aria-invalidShows the error state. Pair it with a visible message that says what is wrong. | boolean | false |
ref | Ref<TextInput> | — |
editable | TextInputProps["editable"] | true |
Also takes every TextInputProps prop (React Native docs).
<Input
accessibilityLabel="Email"
placeholder="you@example.com"
keyboardType="email-address"
autoComplete="email"
autoCapitalize="none"
/>Compatibility
- Expo SDK
- 54 and 57, both checked in CI
- React Native
- 0.81 and 0.86, New Architecture
- Web
- Expo's web target, through react-native-web
Source
1 file, installed as source you own
input.tsxView on GitHubimport { useState, type Ref } from "react";
import { StyleSheet, TextInput, type TextInputProps } from "react-native";
import { useTheme, withAlpha } from "@/registry/native/lib/theme";
interface InputProps extends TextInputProps {
/** Shows the error state. Pair it with a visible message that says what is wrong. */
"aria-invalid"?: boolean;
ref?: Ref<TextInput>;
}
/**
* A single-line text field in the theme: 44 px tall, 16 px text, a ring while
* focused and a destructive border when `aria-invalid`. Name it for screen
* readers with `accessibilityLabel` (or `aria-labelledby` pointing at a label's
* `nativeID`), and give it the right `keyboardType`, `autoComplete` and
* `textContentType` so the keyboard and autofill help.
*
* @example
* <Input
* accessibilityLabel="Email"
* placeholder="you@example.com"
* keyboardType="email-address"
* autoComplete="email"
* autoCapitalize="none"
* />
*/
function Input({
"aria-invalid": invalid = false,
editable = true,
style,
onFocus,
onBlur,
...props
}: InputProps) {
const { colors, radius, text, font } = useTheme();
const [focused, setFocused] = useState(false);
const ring = invalid ? withAlpha(colors.destructive, 0.2) : withAlpha(colors.ring, 0.5);
return (
<TextInput
editable={editable}
aria-disabled={!editable || undefined}
placeholderTextColor={colors.mutedForeground}
selectionColor={colors.primary}
cursorColor={colors.foreground}
style={[
styles.input,
text.base,
font("regular"),
{
borderRadius: radius.md,
backgroundColor: colors.field,
color: colors.foreground,
borderColor: invalid ? colors.destructive : focused ? colors.ring : colors.input,
},
focused ? { boxShadow: `0 0 0 3px ${ring}` } : null,
editable ? null : styles.disabled,
style,
]}
onFocus={(event) => {
setFocused(true);
onFocus?.(event);
}}
onBlur={(event) => {
setFocused(false);
onBlur?.(event);
}}
{...props}
/>
);
}
const styles = StyleSheet.create({
input: {
minHeight: 44,
borderWidth: 1,
paddingHorizontal: 12,
paddingVertical: 10,
},
disabled: {
opacity: 0.5,
},
});
export { Input, type InputProps };