UI Designs: Login Screen
Like the Flutter track's design page, this one is different from the rest: instead of just reading about components, you're looking at a real login screen design — a mockup on the left rendered to look exactly like a real phone screen, and the real React Native/JSX code that produces it on the right. This is the first entry in a small, growing gallery of hands-on UI designs (a sign-up screen, a dashboard, a profile page are natural next additions).
The Design
Welcome Back
Sign in to continue to your account
jane.doe@example.com
••••••••••
Forgot Password?
LOG IN
OR CONTINUE WITH
Don't have an account? Sign Up
What's in this design
- An app icon/logo, a title, and a short subtitle for context
- Two bordered text inputs (email, password) — React Native's
TextInputhas no default border, so styling it is entirely up to you - A right-aligned "Forgot Password?" link
- A full-width, high-emphasis "Log In" button
- A visual divider for an "or continue with" alternative sign-in section
- A "Sign Up" prompt pinned toward the bottom of the screen
Note: The mockup above is an HTML/CSS recreation for illustration — this website doesn't run a real React Native build. The JSX code below it is correct, real React Native code that produces this exact screen.
The Full React Native Code
Here's the complete LoginScreen component that builds the design above, section by section.
1. Imports, State, and Refs
import React, { useState } from 'react';
import {
View, Text, TextInput, TouchableOpacity,
StyleSheet, SafeAreaView,
} from 'react-native';
export default function LoginScreen() {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
2. The Logo, Title, and Subtitle
const handleLogin = () => {
if (!email.includes('@')) {
setError('Enter a valid email');
return;
}
if (password.length < 6) {
setError('Password must be at least 6 characters');
return;
}
setError('');
// Both fields passed validation — proceed with login
};
return (
<SafeAreaView style={styles.container}>
<View style={styles.logo}>
<Text style={styles.logoText}>⚡</Text>
</View>
<Text style={styles.title}>Welcome Back</Text>
<Text style={styles.subtitle}>
Sign in to continue to your account
</Text>
Cross-reference: This screen leans on components covered in Core Components and styling from Styling with StyleSheet and Flexbox Layout.
3. The Email and Password Fields
<Text style={styles.label}>Email</Text>
<TextInput
style={styles.input}
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
/>
<Text style={styles.label}>Password</Text>
<TextInput
style={styles.input}
value={password}
onChangeText={setPassword}
secureTextEntry
/>
{!!error && <Text style={styles.errorText}>{error}</Text>}
Note:
secureTextEntry is exactly what turns the password field into dots on screen. The full validation pattern here is covered in depth in Forms & TextInput.4. The Forgot Password Link and Login Button
<TouchableOpacity style={styles.forgotWrap}>
<Text style={styles.forgotText}>Forgot Password?</Text>
</TouchableOpacity>
<TouchableOpacity style={styles.loginButton} onPress={handleLogin}>
<Text style={styles.loginButtonText}>LOG IN</Text>
</TouchableOpacity>
<View style={styles.dividerRow}>
<View style={styles.dividerLine} />
<Text style={styles.dividerText}>OR CONTINUE WITH</Text>
<View style={styles.dividerLine} />
</View>
5. The Sign-Up Prompt and Styles
<View style={styles.signupWrap}>
<Text style={styles.signupText}>
Don't have an account?{' '}
<Text style={styles.signupLink}>Sign Up</Text>
</Text>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: { flex: 1, paddingHorizontal: 24, paddingTop: 40 },
logo: {
width: 64, height: 64, borderRadius: 16,
backgroundColor: '#1a8cbf', alignSelf: 'center',
alignItems: 'center', justifyContent: 'center', marginBottom: 18,
},
logoText: { fontSize: 28, color: '#fff' },
title: { fontSize: 22, fontWeight: '700', textAlign: 'center' },
input: {
borderWidth: 1.5, borderColor: '#e2e4e8', borderRadius: 8,
padding: 12, marginBottom: 16,
},
loginButton: { backgroundColor: '#1a8cbf', borderRadius: 10, padding: 14 },
loginButtonText: { color: '#fff', textAlign: 'center', fontWeight: '700' },
});
Note: Every visual property comes from
StyleSheet.create() — React Native never uses CSS files, cross-reference Styling with StyleSheet.Design Choices Worth Noticing
| Choice | Why it's made this way |
|---|---|
| Explicitly bordered TextInputs | React Native's TextInput has NO default border or underline — unlike Flutter or web forms, every visual detail here is styled by hand |
| One high-emphasis button | Only ONE primary action (Log In) uses a solid-filled TouchableOpacity — "Forgot Password?" and "Sign Up" are plain text, correctly guiding the eye |
| Validation on submit, not on every keystroke | handleLogin only runs validation when the button is pressed, not on every onChangeText call — less naggy for the user |
Conditional error rendering with {!!error && ...} | A common React/JSX idiom — render a node only when a condition is true, foreshadowed in Components & Props |
More designs coming: this Login Screen is the first in a growing gallery — a Sign-Up screen, a Dashboard, and a Profile page are natural next additions. Continue to Debugging Tools for now.