Skip to content

Commit 97d40e3

Browse files
authored
Merge pull request #46 from BU-Spark/fix/keyboard_in_signin_stuck
fix: improve keyboard UX on sign-in/sign-up screens
2 parents cb97469 + 5912b4a commit 97d40e3

2 files changed

Lines changed: 178 additions & 156 deletions

File tree

mobile/app/(auth)/sign-in.tsx

Lines changed: 64 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import {
66
Platform,
77
View,
88
Pressable,
9+
Keyboard,
10+
TouchableWithoutFeedback,
911
} from 'react-native';
12+
import { useSafeAreaInsets } from 'react-native-safe-area-context';
1013
import CustomInput from '../../src/components/CustomInput';
1114
import CustomButton from '../../src/components/CustomButton';
1215
import { Link, router } from 'expo-router';
@@ -19,6 +22,10 @@ import { isClerkAPIResponseError, useSignIn } from '@clerk/clerk-expo';
1922
import SignInWith from '../../src/components/SignInWith';
2023
import { colors, typography, spacing } from '../../src/lib/theme';
2124

25+
// Adjust this value to control how much the screen moves up when keyboard appears
26+
// Negative values reduce upward movement (more negative = less movement)
27+
const KEYBOARD_OFFSET = -100;
28+
2229
const signInSchema = z.object({
2330
email: z
2431
.string({ message: 'Email is required' })
@@ -45,6 +52,7 @@ const mapClerkErrorToFormField = (error: any) => {
4552
};
4653

4754
export default function SignInScreen() {
55+
const insets = useSafeAreaInsets();
4856
const {
4957
control,
5058
handleSubmit,
@@ -88,60 +96,63 @@ export default function SignInScreen() {
8896
};
8997

9098
return (
91-
<KeyboardAvoidingView
92-
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
93-
style={styles.container}
94-
>
95-
{/* Back Button */}
96-
<Pressable
97-
style={styles.backButton}
98-
onPress={() => router.push('/welcome')}
99+
<TouchableWithoutFeedback onPress={Keyboard.dismiss}>
100+
<KeyboardAvoidingView
101+
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
102+
keyboardVerticalOffset={Platform.OS === 'ios' ? KEYBOARD_OFFSET - insets.top : KEYBOARD_OFFSET}
103+
style={styles.container}
99104
>
100-
<Text style={styles.backButtonText}>← Back</Text>
101-
</Pressable>
102-
103-
<Text style={styles.title}>Sign in</Text>
104-
<Text style={styles.subtitle}>Sign in with your @bu.edu email</Text>
105-
106-
<View style={styles.form}>
107-
<CustomInput
108-
control={control}
109-
name="email"
110-
placeholder="Email"
111-
autoFocus
112-
autoCapitalize="none"
113-
keyboardType="email-address"
114-
autoComplete="email"
115-
/>
116-
117-
<CustomInput
118-
control={control}
119-
name="password"
120-
placeholder="Password"
121-
secureTextEntry
122-
/>
123-
124-
{errors.root && (
125-
<Text style={styles.errorText}>{errors.root.message}</Text>
126-
)}
127-
</View>
128-
129-
<CustomButton text="Sign in" onPress={handleSubmit(onSignIn)} />
130-
131-
<Link href="/sign-up" style={styles.link}>
132-
{"Don't have an account? Sign up"}
133-
</Link>
134-
135-
<View style={styles.divider}>
136-
<View style={styles.dividerLine} />
137-
<Text style={styles.dividerText}>OR</Text>
138-
<View style={styles.dividerLine} />
139-
</View>
140-
141-
<View style={styles.socialContainer}>
142-
<SignInWith strategy="oauth_google" />
143-
</View>
144-
</KeyboardAvoidingView>
105+
{/* Back Button */}
106+
<Pressable
107+
style={styles.backButton}
108+
onPress={() => router.push('/welcome')}
109+
>
110+
<Text style={styles.backButtonText}>← Back</Text>
111+
</Pressable>
112+
113+
<Text style={styles.title}>Sign in</Text>
114+
<Text style={styles.subtitle}>Sign in with your @bu.edu email</Text>
115+
116+
<View style={styles.form}>
117+
<CustomInput
118+
control={control}
119+
name="email"
120+
placeholder="Email"
121+
autoFocus
122+
autoCapitalize="none"
123+
keyboardType="email-address"
124+
autoComplete="email"
125+
/>
126+
127+
<CustomInput
128+
control={control}
129+
name="password"
130+
placeholder="Password"
131+
secureTextEntry
132+
/>
133+
134+
{errors.root && (
135+
<Text style={styles.errorText}>{errors.root.message}</Text>
136+
)}
137+
</View>
138+
139+
<CustomButton text="Sign in" onPress={handleSubmit(onSignIn)} />
140+
141+
<Link href="/sign-up" style={styles.link}>
142+
{"Don't have an account? Sign up"}
143+
</Link>
144+
145+
<View style={styles.divider}>
146+
<View style={styles.dividerLine} />
147+
<Text style={styles.dividerText}>OR</Text>
148+
<View style={styles.dividerLine} />
149+
</View>
150+
151+
<View style={styles.socialContainer}>
152+
<SignInWith strategy="oauth_google" />
153+
</View>
154+
</KeyboardAvoidingView>
155+
</TouchableWithoutFeedback>
145156
);
146157
}
147158

0 commit comments

Comments
 (0)