diff --git a/CHANGELOG.md b/CHANGELOG.md index 46e6cd3..91e030e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 5.1.3 +* Added title spacer + ## 5.1.2 * Removed bottom padding from password text field diff --git a/lib/src/config/spacer_options.dart b/lib/src/config/spacer_options.dart index bef92d6..41de027 100644 --- a/lib/src/config/spacer_options.dart +++ b/lib/src/config/spacer_options.dart @@ -10,6 +10,7 @@ class LoginSpacerOptions { this.spacerAfterForm, this.spacerAfterButton, this.formFlexValue = 1, + this.titleSpacer = 1, }); /// Flex value for the spacer before the title. @@ -33,4 +34,6 @@ class LoginSpacerOptions { /// Flex value for the form. Defaults to 1. Use this when also using the /// other spacer options. final int formFlexValue; + + final int titleSpacer; } diff --git a/lib/src/widgets/email_password_login.dart b/lib/src/widgets/email_password_login.dart index 3af36de..3df2f91 100644 --- a/lib/src/widgets/email_password_login.dart +++ b/lib/src/widgets/email_password_login.dart @@ -74,57 +74,56 @@ class _EmailPasswordLoginFormState extends State { var theme = Theme.of(context); var options = widget.options; return CustomScrollView( - physics: MediaQuery.of(context).viewInsets.bottom == 0 - ? const NeverScrollableScrollPhysics() - : null, + physics: const ScrollPhysics(), slivers: [ SliverFillRemaining( - fillOverscroll: true, hasScrollBody: false, + fillOverscroll: true, child: Column( children: [ - if (options.spacers.spacerBeforeTitle != null) ...[ - Spacer(flex: options.spacers.spacerBeforeTitle!), - ], - if (options.title != null) ...[ - const SizedBox( - height: 60, + Expanded( + flex: options.spacers.titleSpacer, + child: Column( + children: [ + if (options.spacers.spacerBeforeTitle != null) ...[ + Spacer(flex: options.spacers.spacerBeforeTitle!), + ], + if (options.title != null) ...[ + Align( + alignment: Alignment.topCenter, + child: _wrapWithDefaultStyle( + options.title, + theme.textTheme.headlineSmall, + ), + ), + ], + if (options.spacers.spacerAfterTitle != null) ...[ + Spacer(flex: options.spacers.spacerAfterTitle!), + ], + if (options.subtitle != null) ...[ + Align( + alignment: Alignment.topCenter, + child: _wrapWithDefaultStyle( + options.subtitle, + theme.textTheme.titleSmall, + ), + ), + ], + if (options.spacers.spacerAfterSubtitle != null) ...[ + Spacer(flex: options.spacers.spacerAfterSubtitle!), + ], + if (options.image != null) ...[ + Padding( + padding: const EdgeInsets.all(16), + child: options.image, + ), + ], + if (options.spacers.spacerAfterImage != null) ...[ + Spacer(flex: options.spacers.spacerAfterImage!), + ], + ], ), - Align( - alignment: Alignment.topCenter, - child: _wrapWithDefaultStyle( - options.title, - theme.textTheme.headlineSmall, - ), - ), - ], - if (options.spacers.spacerAfterTitle != null) ...[ - Spacer(flex: options.spacers.spacerAfterTitle!), - ], - if (options.subtitle != null) ...[ - const SizedBox( - height: 10, - ), - Align( - alignment: Alignment.topCenter, - child: _wrapWithDefaultStyle( - options.subtitle, - theme.textTheme.titleSmall, - ), - ), - ], - if (options.spacers.spacerAfterSubtitle != null) ...[ - Spacer(flex: options.spacers.spacerAfterSubtitle!), - ], - if (options.image != null) ...[ - Padding( - padding: const EdgeInsets.all(16), - child: options.image, - ), - ], - if (options.spacers.spacerAfterImage != null) ...[ - Spacer(flex: options.spacers.spacerAfterImage!), - ], + ), Expanded( flex: options.spacers.formFlexValue, child: ConstrainedBox( @@ -133,101 +132,96 @@ class _EmailPasswordLoginFormState extends State { ), child: Form( key: _formKey, - child: Align( - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - options.emailInputContainerBuilder( - TextFormField( - onChanged: _updateCurrentEmail, - validator: - widget.options.validations.validateEmail, - initialValue: options.initialEmail, - keyboardType: TextInputType.emailAddress, - textInputAction: TextInputAction.next, - style: options.emailTextStyle, - decoration: options.emailDecoration, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + options.emailInputContainerBuilder( + TextFormField( + 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( + 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( + onPressed: () { + setState(() { + _obscurePassword = !_obscurePassword; + }); + }, + icon: Icon( + _obscurePassword + ? Icons.visibility + : Icons.visibility_off, + ), + ) + : null, ), ), - options.passwordInputContainerBuilder( - TextFormField( - 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( - onPressed: () { - setState(() { - _obscurePassword = - !_obscurePassword; - }); - }, - icon: Icon( - _obscurePassword - ? Icons.visibility - : Icons.visibility_off, - ), - ) - : null, - ), - ), - ), - if (widget.onForgotPassword != null) ...[ - Align( - alignment: Alignment.topRight, - child: options.forgotPasswordButtonBuilder( - context, - () { - widget.onForgotPassword?.call(_currentEmail); - }, - false, - () {}, - options, - ), - ), - ], - if (options.spacers.spacerAfterForm != null) ...[ - Spacer(flex: options.spacers.spacerAfterForm!), - ], - const SizedBox(height: 8), - AnimatedBuilder( - animation: _formValid, - builder: (context, _) => options.loginButtonBuilder( + ), + if (widget.onForgotPassword != null) ...[ + Align( + alignment: Alignment.topRight, + child: options.forgotPasswordButtonBuilder( context, - _handleLogin, - !_formValid.value, () { - _formKey.currentState?.validate(); - }, - options, - ), - ), - if (widget.onRegister != null) ...[ - options.registrationButtonBuilder( - context, - () async { - widget.onRegister?.call( - _currentEmail, - _currentPassword, - ); + widget.onForgotPassword?.call(_currentEmail); }, false, () {}, options, ), - ], - 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, + ); + }, + false, + () {}, + options, + ), + ], + if (options.spacers.spacerAfterButton != null) ...[ + Spacer(flex: options.spacers.spacerAfterButton!), + ], + ], ), ), ), diff --git a/pubspec.yaml b/pubspec.yaml index 3dcef5e..c28be95 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_login description: Flutter Login Component -version: 5.1.2 +version: 5.1.3 environment: sdk: ">=2.18.1 <3.0.0"