@@ -179,7 +179,7 @@ class SupaEmailAuth extends StatefulWidget {
179179 final String ? Function (String ? )? passwordValidator;
180180
181181 /// Callback for the user to complete a sign in.
182- final void Function (AuthResponse response) onSignInComplete;
182+ final void Function (AuthResponse response, String email ) onSignInComplete;
183183
184184 /// Callback for the user to complete a signUp.
185185 ///
@@ -217,12 +217,15 @@ class SupaEmailAuth extends StatefulWidget {
217217 final Widget ? prefixIconEmail;
218218 final Widget ? prefixIconPassword;
219219
220+ final String ? initialEmail;
221+
220222 /// Whether the confirm password field should be displayed
221223 final bool showConfirmPasswordField;
222224
223225 /// {@macro supa_email_auth}
224226 const SupaEmailAuth ({
225227 super .key,
228+ this .initialEmail = "" ,
226229 this .autofocus = true ,
227230 this .redirectTo,
228231 this .resetPasswordRedirectTo,
@@ -248,7 +251,7 @@ class SupaEmailAuth extends StatefulWidget {
248251
249252class _SupaEmailAuthState extends State <SupaEmailAuth > {
250253 final _formKey = GlobalKey <FormState >();
251- final _emailController = TextEditingController () ;
254+ late final TextEditingController _emailController ;
252255 final _passwordController = TextEditingController ();
253256 final _confirmPasswordController = TextEditingController ();
254257 late bool _isSigningIn;
@@ -261,10 +264,12 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
261264
262265 /// Focus node for email field
263266 final FocusNode _emailFocusNode = FocusNode ();
267+ final FocusNode _passwordFocusNode = FocusNode ();
264268
265269 @override
266270 void initState () {
267271 super .initState ();
272+ _emailController = TextEditingController (text: widget.initialEmail);
268273 _isSigningIn = widget.isInitiallySigningIn;
269274 _metadataControllers = Map .fromEntries ((widget.metadataFields ?? []).map (
270275 (metadataField) => MapEntry (
@@ -274,13 +279,33 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
274279 : TextEditingController (),
275280 ),
276281 ));
282+
283+ // Request focus on password field if email is pre-filled and not recovering password
284+ if (widget.initialEmail != null && widget.initialEmail! .isNotEmpty && ! _isRecoveringPassword) {
285+ // It's important to request focus after the first frame has been built.
286+ // WidgetsBinding.instance.addPostFrameCallback ensures that.
287+ WidgetsBinding .instance.addPostFrameCallback ((_) {
288+ if (mounted) {
289+ FocusScope .of (context).requestFocus (_passwordFocusNode);
290+ }
291+ });
292+ } else if (widget.autofocus && ! _isRecoveringPassword) {
293+ // Default autofocus behavior if no initial email or recovering password
294+ WidgetsBinding .instance.addPostFrameCallback ((_) {
295+ if (mounted) {
296+ FocusScope .of (context).requestFocus (_emailFocusNode);
297+ }
298+ });
299+ }
277300 }
278301
279302 @override
280303 void dispose () {
281304 _emailController.dispose ();
282305 _passwordController.dispose ();
283306 _confirmPasswordController.dispose ();
307+ _emailFocusNode.dispose ();
308+ _passwordFocusNode.dispose ();
284309 for (final controller in _metadataControllers.values) {
285310 if (controller is TextEditingController ) {
286311 controller.dispose ();
@@ -333,6 +358,7 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
333358 ? [AutofillHints .password]
334359 : [AutofillHints .newPassword],
335360 autovalidateMode: AutovalidateMode .onUserInteraction,
361+ focusNode: _passwordFocusNode,
336362 textInputAction: widget.metadataFields != null && ! _isSigningIn
337363 ? TextInputAction .next
338364 : TextInputAction .done,
@@ -468,7 +494,7 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
468494 height: 16 ,
469495 width: 16 ,
470496 child: CircularProgressIndicator (
471- color: Theme .of (context).colorScheme.onPrimary ,
497+ color: Theme .of (context).colorScheme.surface ,
472498 strokeWidth: 1.5 ,
473499 ),
474500 )
@@ -539,7 +565,7 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
539565 email: _emailController.text.trim (),
540566 password: _passwordController.text.trim (),
541567 );
542- widget.onSignInComplete.call (response);
568+ widget.onSignInComplete.call (response, _emailController.text. trim () );
543569 } else {
544570 final user = supabase.auth.currentUser;
545571 late final AuthResponse response;
@@ -607,9 +633,7 @@ class _SupaEmailAuthState extends State<SupaEmailAuth> {
607633 // FIX use_build_context_synchronously
608634 if (! mounted) return ;
609635 context.showSnackBar (widget.localization.passwordResetSent);
610- setState (() {
611- _isRecoveringPassword = false ;
612- });
636+
613637 } on AuthException catch (error) {
614638 widget.onError? .call (error);
615639 } catch (error) {
0 commit comments