Skip to main content

TextField

Text fields allow users to enter and edit text. TeamLock UI's TextField component provides a flexible and accessible input solution with multiple variants and customization options.

Import

import { TextField } from "teamlock-ui";

Basic Usage

import React, { useState } from "react";
import { TextField } from "teamlock-ui";

export function BasicTextFieldExample() {
const [value, setValue] = useState("");

return (
<TextField
label="Email"
placeholder="Enter your email"
value={value}
onChangeText={setValue}
/>
);
}

Variants

The TextField component supports three visual variants:

Filled (Default)

<TextField variant="filled" label="Filled TextField" placeholder="Enter text" />

Outlined

<TextField
variant="outline"
label="Outlined TextField"
placeholder="Enter text"
/>

Underline

<TextField
variant="underline"
label="Underline TextField"
placeholder="Enter text"
/>

Sizes

Text fields come in three different sizes:

<TextField size="sm" label="Small" placeholder="Small text field" />
<TextField size="md" label="Medium" placeholder="Medium text field" />
<TextField size="lg" label="Large" placeholder="Large text field" />

Colors

Customize text field colors using semantic color keys:

<TextField color="primary" label="Primary" />
<TextField color="secondary" label="Secondary" />
<TextField color="accent" label="Accent" />
<TextField color="success" label="Success" />
<TextField color="error" label="Error" />
<TextField color="warning" label="Warning" />
<TextField color="info" label="Info" />

States

Error State

<TextField
label="Email"
placeholder="Enter your email"
error
errorText="Please enter a valid email address"
/>

Disabled State

<TextField
label="Disabled Field"
placeholder="This field is disabled"
disabled
/>

Loading State

<TextField label="Loading Field" placeholder="Loading..." loading />

Required Field

<TextField
label="Required Field"
placeholder="This field is required"
required
/>

Helper Text

Provide additional context with helper text:

<TextField
label="Password"
placeholder="Enter your password"
secureTextEntry
helperText="Password must be at least 8 characters long"
/>

Icons

Add icons to enhance the user experience:

import { Ionicons } from '@expo/vector-icons';

// Start icon
<TextField
label="Search"
placeholder="Search..."
startIcon={<Ionicons name="search" />}
/>

// End icon
<TextField
label="Password"
placeholder="Enter password"
secureTextEntry
endIcon={<Ionicons name="eye-off" />}
/>

// Both icons
<TextField
label="Amount"
placeholder="0.00"
startIcon={<Ionicons name="card" />}
endIcon={<Ionicons name="calculator" />}
/>

Multiline Text

Create text areas for longer content:

<TextField
label="Description"
placeholder="Enter a description..."
multiline
numberOfLines={4}
/>

Input Types

Configure different input behaviors:

Email Input

<TextField
label="Email"
placeholder="user@example.com"
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
/>

Phone Number

<TextField
label="Phone"
placeholder="+1 (555) 123-4567"
keyboardType="phone-pad"
/>

Numeric Input

<TextField label="Age" placeholder="25" keyboardType="numeric" />

Password Input

<TextField
label="Password"
placeholder="Enter password"
secureTextEntry
autoCapitalize="none"
autoCorrect={false}
/>

Full Width

Make text fields span the full width of their container:

<TextField
label="Full Width Field"
placeholder="This field spans full width"
fullWidth
/>

Styling

Custom Styles

<TextField
label="Custom Styled"
placeholder="Custom styling"
style={{
borderRadius: 20,
backgroundColor: "#f0f0f0",
}}
containerStyle={{
marginVertical: 10,
}}
/>

Theme-Aware Styling

import { useTheme } from "teamlock-ui";

export function ThemedTextField() {
const { theme } = useTheme();

return (
<TextField
label="Themed Field"
placeholder="Theme-aware styling"
style={{
borderColor: theme.colors.accent,
backgroundColor: theme.colors.surface,
}}
/>
);
}

Event Handlers

Handle various text field events:

<TextField
label="Interactive Field"
placeholder="Type something..."
onChangeText={(text) => console.log("Text changed:", text)}
onFocus={() => console.log("Field focused")}
onBlur={() => console.log("Field blurred")}
onSubmitEditing={() => console.log("Submit pressed")}
/>

Complete Example

import React, { useState } from "react";
import { View, Alert } from "react-native";
import { TextField, Button } from "teamlock-ui";
import { Ionicons } from "@expo/vector-icons";

export function ContactForm() {
const [formData, setFormData] = useState({
name: "",
email: "",
phone: "",
message: "",
});
const [errors, setErrors] = useState({});
const [loading, setLoading] = useState(false);

const validateForm = () => {
const newErrors = {};

if (!formData.name.trim()) {
newErrors.name = "Name is required";
}

if (!formData.email.trim()) {
newErrors.email = "Email is required";
} else if (!/\S+@\S+\.\S+/.test(formData.email)) {
newErrors.email = "Please enter a valid email";
}

setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};

const handleSubmit = async () => {
if (!validateForm()) return;

setLoading(true);

// Simulate API call
setTimeout(() => {
setLoading(false);
Alert.alert("Success", "Form submitted successfully!");
}, 2000);
};

return (
<View style={{ padding: 20, gap: 16 }}>
<TextField
label="Full Name"
placeholder="Enter your full name"
value={formData.name}
onChangeText={(text) => setFormData({ ...formData, name: text })}
error={!!errors.name}
errorText={errors.name}
required
startIcon={<Ionicons name="person" />}
fullWidth
/>

<TextField
label="Email Address"
placeholder="user@example.com"
value={formData.email}
onChangeText={(text) => setFormData({ ...formData, email: text })}
error={!!errors.email}
errorText={errors.email}
required
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
startIcon={<Ionicons name="mail" />}
fullWidth
/>

<TextField
label="Phone Number"
placeholder="+1 (555) 123-4567"
value={formData.phone}
onChangeText={(text) => setFormData({ ...formData, phone: text })}
keyboardType="phone-pad"
startIcon={<Ionicons name="call" />}
fullWidth
/>

<TextField
label="Message"
placeholder="Enter your message..."
value={formData.message}
onChangeText={(text) => setFormData({ ...formData, message: text })}
multiline
numberOfLines={4}
helperText="Optional: Tell us more about your inquiry"
fullWidth
/>

<Button
variant="primary"
size="lg"
fullWidth
loading={loading}
onPress={handleSubmit}
>
Submit Form
</Button>
</View>
);
}

Props

PropTypeDefaultDescription
labelstring-Field label text
placeholderstring-Placeholder text
valuestring-Current input value
onChangeText(text: string) => void-Text change handler
variantTextFieldVariant"filled"Visual style variant
sizeTextFieldSize"md"Field size
colorTextFieldColorKey"primary"Color theme key
fullWidthbooleanfalseWhether field takes full width
disabledbooleanfalseDisable field interaction
errorbooleanfalseShow error state
loadingbooleanfalseShow loading indicator
requiredbooleanfalseMark field as required
helperTextstring-Helper text below field
errorTextstring-Error message text
startIconReact.ReactNode-Icon at start of field
endIconReact.ReactNode-Icon at end of field
multilinebooleanfalseEnable multiline input
numberOfLinesnumber1Number of lines for multiline
secureTextEntrybooleanfalseHide text input (passwords)
keyboardTypeKeyboardTypeOptions"default"Keyboard type
autoCapitalizeAutoCapitalize"sentences"Auto-capitalization behavior
autoCorrectbooleantrueEnable auto-correction
returnKeyTypeReturnKeyTypeOptions"done"Return key type
styleStyleProp<TextStyle>-Input style overrides
containerStyleStyleProp<ViewStyle>-Container style overrides
onFocus() => void-Focus event handler
onBlur() => void-Blur event handler
onSubmitEditing() => void-Submit event handler

Types

TextFieldVariant

type TextFieldVariant = "filled" | "outline" | "underline";

TextFieldSize

type TextFieldSize = "sm" | "md" | "lg";

TextFieldColorKey

type TextFieldColorKey =
| "primary"
| "secondary"
| "accent"
| "success"
| "error"
| "warning"
| "info";

Accessibility

The TextField component includes built-in accessibility features:

  • Proper accessibilityRole is set to "text"
  • Labels are properly associated with inputs
  • Error states are announced to screen readers
  • Supports accessibilityLabel and accessibilityHint
  • Required fields are properly indicated
<TextField
label="Email"
placeholder="Enter email"
accessibilityLabel="Email address input"
accessibilityHint="Enter your email address for account access"
required
/>

Best Practices

  1. Always provide labels for better accessibility:

    // ✅ Good
    <TextField label="Email" placeholder="user@example.com" />

    // ❌ Avoid
    <TextField placeholder="Email" />
  2. Use appropriate keyboard types:

    <TextField keyboardType="email-address" />
    <TextField keyboardType="phone-pad" />
    <TextField keyboardType="numeric" />
  3. Provide helpful error messages:

    <TextField
    error={!!emailError}
    errorText="Please enter a valid email address"
    />
  4. Use helper text for guidance:

    <TextField helperText="Password must be at least 8 characters" />
  5. Disable auto-features for sensitive inputs:

    <TextField secureTextEntry autoCapitalize="none" autoCorrect={false} />

Text fields are essential for user input. Design them thoughtfully to create great user experiences!