From bb65426298db27820dd14c34b4a3403a8c61ad4b Mon Sep 17 00:00:00 2001 From: Tobias Leijs Date: Tue, 25 Jun 2024 15:09:04 +0200 Subject: [PATCH] feat: add AutoFillGroup to support native password managers --- lib/src/widgets/email_password_login.dart | 194 ++++++++++++---------- lib/src/widgets/forgot_password_form.dart | 33 ++-- 2 files changed, 120 insertions(+), 107 deletions(-) diff --git a/lib/src/widgets/email_password_login.dart b/lib/src/widgets/email_password_login.dart index 8fca6e5..eb0e43e 100644 --- a/lib/src/widgets/email_password_login.dart +++ b/lib/src/widgets/email_password_login.dart @@ -153,108 +153,118 @@ class _EmailPasswordLoginFormState extends State { ), child: Form( key: _formKey, - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - options.emailInputContainerBuilder( - TextFormField( - textAlign: - options.emailTextAlign ?? TextAlign.start, - onChanged: _updateCurrentEmail, - validator: - widget.options.validations.validateEmail, - initialValue: options.initialEmail, - keyboardType: TextInputType.emailAddress, - textInputAction: TextInputAction.next, - style: options.emailTextStyle, - decoration: options.emailDecoration, - ), - ), - options.passwordInputContainerBuilder( - TextFormField( - textAlign: - options.passwordTextAlign ?? TextAlign.start, - obscureText: _obscurePassword, - onChanged: _updateCurrentPassword, - validator: - widget.options.validations.validatePassword, - initialValue: options.initialPassword, - keyboardType: TextInputType.visiblePassword, - textInputAction: TextInputAction.done, - style: options.passwordTextStyle, - onFieldSubmitted: (_) async => _handleLogin(), - decoration: options.passwordDecoration.copyWith( - suffixIcon: options.showObscurePassword - ? IconButton( - padding: options.suffixIconPadding, - onPressed: () { - setState(() { - _obscurePassword = - !_obscurePassword; - }); - }, - icon: Icon( - _obscurePassword - ? Icons.visibility - : Icons.visibility_off, - size: options.suffixIconSize, - ), - ) - : null, + child: AutofillGroup( + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + options.emailInputContainerBuilder( + TextFormField( + autofillHints: const [ + AutofillHints.email, + AutofillHints.username, + ], + textAlign: + options.emailTextAlign ?? TextAlign.start, + onChanged: _updateCurrentEmail, + validator: + widget.options.validations.validateEmail, + initialValue: options.initialEmail, + keyboardType: TextInputType.emailAddress, + textInputAction: TextInputAction.next, + style: options.emailTextStyle, + decoration: options.emailDecoration, ), ), - ), - if (widget.onForgotPassword != null) ...[ - Align( - alignment: Alignment.topRight, - child: options.forgotPasswordButtonBuilder( + options.passwordInputContainerBuilder( + TextFormField( + autofillHints: const [ + AutofillHints.password, + ], + textAlign: options.passwordTextAlign ?? + TextAlign.start, + obscureText: _obscurePassword, + onChanged: _updateCurrentPassword, + validator: + widget.options.validations.validatePassword, + initialValue: options.initialPassword, + keyboardType: TextInputType.visiblePassword, + textInputAction: TextInputAction.done, + style: options.passwordTextStyle, + onFieldSubmitted: (_) async => _handleLogin(), + decoration: options.passwordDecoration.copyWith( + suffixIcon: options.showObscurePassword + ? IconButton( + padding: options.suffixIconPadding, + onPressed: () { + setState(() { + _obscurePassword = + !_obscurePassword; + }); + }, + icon: Icon( + _obscurePassword + ? Icons.visibility + : Icons.visibility_off, + size: options.suffixIconSize, + ), + ) + : null, + ), + ), + ), + if (widget.onForgotPassword != null) ...[ + Align( + alignment: Alignment.topRight, + child: options.forgotPasswordButtonBuilder( + context, + () { + widget.onForgotPassword + ?.call(_currentEmail, context); + }, + false, + () {}, + options, + ), + ), + ] else ...[ + const SizedBox(height: 16), + ], + if (options.spacers.spacerAfterForm != null) ...[ + Spacer(flex: options.spacers.spacerAfterForm!), + ], + AnimatedBuilder( + animation: _formValid, + builder: (context, _) => + options.loginButtonBuilder( context, + _handleLogin, + !_formValid.value, () { - widget.onForgotPassword - ?.call(_currentEmail, context); + _formKey.currentState?.validate(); + }, + options, + ), + ), + if (widget.onRegister != null) ...[ + options.registrationButtonBuilder( + context, + () async { + widget.onRegister?.call( + _currentEmail, + _currentPassword, + context, + ); }, false, () {}, options, ), - ), - ] else ...[ - const SizedBox(height: 16), + ], + if (options.spacers.spacerAfterButton != null) ...[ + Spacer(flex: options.spacers.spacerAfterButton!), + ], ], - if (options.spacers.spacerAfterForm != null) ...[ - Spacer(flex: options.spacers.spacerAfterForm!), - ], - AnimatedBuilder( - animation: _formValid, - builder: (context, _) => options.loginButtonBuilder( - context, - _handleLogin, - !_formValid.value, - () { - _formKey.currentState?.validate(); - }, - options, - ), - ), - if (widget.onRegister != null) ...[ - options.registrationButtonBuilder( - context, - () async { - widget.onRegister?.call( - _currentEmail, - _currentPassword, - context, - ); - }, - false, - () {}, - options, - ), - ], - if (options.spacers.spacerAfterButton != null) ...[ - Spacer(flex: options.spacers.spacerAfterButton!), - ], - ], + ), ), ), ), diff --git a/lib/src/widgets/forgot_password_form.dart b/lib/src/widgets/forgot_password_form.dart index b848594..3928fd5 100644 --- a/lib/src/widgets/forgot_password_form.dart +++ b/lib/src/widgets/forgot_password_form.dart @@ -129,21 +129,24 @@ class _ForgotPasswordFormState extends State { ), child: Form( key: _formKey, - child: Align( - alignment: Alignment.center, - child: options.emailInputContainerBuilder( - TextFormField( - textAlign: - options.emailTextAlign ?? TextAlign.start, - focusNode: _focusNode, - onChanged: _updateCurrentEmail, - validator: - widget.options.validations.validateEmail, - initialValue: options.initialEmail, - keyboardType: TextInputType.emailAddress, - textInputAction: TextInputAction.next, - style: options.emailTextStyle, - decoration: options.emailDecoration, + child: AutofillGroup( + child: Align( + alignment: Alignment.center, + child: options.emailInputContainerBuilder( + TextFormField( + autofillHints: const [AutofillHints.email], + textAlign: + options.emailTextAlign ?? TextAlign.start, + focusNode: _focusNode, + onChanged: _updateCurrentEmail, + validator: + widget.options.validations.validateEmail, + initialValue: options.initialEmail, + keyboardType: TextInputType.emailAddress, + textInputAction: TextInputAction.next, + style: options.emailTextStyle, + decoration: options.emailDecoration, + ), ), ), ),