flutter_login_widget/lib/src/config/login_options.dart

313 lines
9.3 KiB
Dart
Raw Normal View History

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_login/src/config/forgot_password_spacer_options.dart';
2023-05-08 18:09:19 +02:00
import 'package:flutter_login/src/config/spacer_options.dart';
2022-10-27 15:57:54 +02:00
import 'package:flutter_login/src/service/login_validation.dart';
2022-09-29 17:22:26 +02:00
import 'package:flutter_login/src/service/validation.dart';
2023-05-08 18:09:19 +02:00
@immutable
class LoginOptions {
const LoginOptions({
this.image,
2023-05-08 18:09:19 +02:00
this.maxFormWidth,
2023-02-13 14:33:37 +01:00
this.emailTextStyle,
this.passwordTextStyle,
this.emailTextAlign,
this.passwordTextAlign,
2024-04-19 10:10:09 +02:00
this.emailDecoration = const InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 8),
labelText: 'Email address',
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff71C6D1),
),
),
labelStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 16,
),
),
this.passwordDecoration = const InputDecoration(
contentPadding: EdgeInsets.symmetric(horizontal: 8),
labelText: 'Password',
border: OutlineInputBorder(),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Color(0xff71C6D1),
),
),
labelStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w400,
fontSize: 16,
),
),
this.initialEmail = '',
this.initialPassword = '',
2024-04-19 10:10:09 +02:00
this.spacers = const LoginSpacerOptions(
spacerBeforeTitle: 8,
spacerAfterTitle: 2,
formFlexValue: 2,
),
this.translations = const LoginTranslations(),
2022-09-29 17:22:26 +02:00
this.validationService,
this.loginButtonBuilder = _createLoginButton,
this.forgotPasswordButtonBuilder = _createForgotPasswordButton,
2022-09-29 17:22:26 +02:00
this.requestForgotPasswordButtonBuilder =
_createRequestForgotPasswordButton,
this.registrationButtonBuilder = _createRegisterButton,
this.emailInputContainerBuilder = _createEmailInputContainer,
this.passwordInputContainerBuilder = _createPasswordInputContainer,
this.showObscurePassword = true,
2024-04-19 10:10:09 +02:00
this.forgotPasswordSpacerOptions = const ForgotPasswordSpacerOptions(
2024-08-08 09:44:01 +02:00
spacerAfterButton: 4,
2024-04-19 10:10:09 +02:00
spacerBeforeTitle: 1,
),
this.loginBackgroundColor = const Color(0xffFAF9F6),
this.forgotPasswordBackgroundColor = const Color(0xffFAF9F6),
this.forgotPasswordScreenPadding = const Padding(
padding: EdgeInsets.symmetric(horizontal: 60),
),
this.forgotPasswordCustomAppBar,
this.suffixIconSize,
this.suffixIconPadding,
});
2024-02-19 16:03:18 +01:00
/// Builds the login button.
final ButtonBuilder loginButtonBuilder;
2024-02-19 16:03:18 +01:00
/// Builds the registration button.
final ButtonBuilder registrationButtonBuilder;
2024-02-19 16:03:18 +01:00
/// Builds the forgot password button.
final ButtonBuilder forgotPasswordButtonBuilder;
2024-02-19 16:03:18 +01:00
/// Builds the request forgot password button.
2022-09-29 17:22:26 +02:00
final ButtonBuilder requestForgotPasswordButtonBuilder;
2024-02-19 16:03:18 +01:00
/// Builds the email input container.
final InputContainerBuilder emailInputContainerBuilder;
2024-02-19 16:03:18 +01:00
/// Builds the password input container.
final InputContainerBuilder passwordInputContainerBuilder;
2024-02-19 16:03:18 +01:00
/// The image to display on the login screen.
final Widget? image;
2024-02-19 16:03:18 +01:00
2024-02-06 16:05:46 +01:00
/// Option to modify the spacing between the title, subtitle, image, form,
/// and button.
2023-05-08 18:09:19 +02:00
final LoginSpacerOptions spacers;
/// Option to modify the spacing between the items on the forgotPasswordForm.
final ForgotPasswordSpacerOptions forgotPasswordSpacerOptions;
2023-05-08 18:09:19 +02:00
/// Maximum width of the form. Defaults to 400.
final double? maxFormWidth;
2024-02-19 16:03:18 +01:00
/// Decoration for the email input field.
final InputDecoration emailDecoration;
2024-02-19 16:03:18 +01:00
/// Decoration for the password input field.
final InputDecoration passwordDecoration;
2024-02-19 16:03:18 +01:00
/// The initial email value for the email input field.
final String initialEmail;
2024-02-19 16:03:18 +01:00
/// The initial password value for the password input field.
final String initialPassword;
2024-02-19 16:03:18 +01:00
/// The text style for the email input field.
2023-02-13 14:33:37 +01:00
final TextStyle? emailTextStyle;
2024-02-19 16:03:18 +01:00
/// The text style for the password input field.
2023-02-13 14:33:37 +01:00
final TextStyle? passwordTextStyle;
2024-02-19 16:03:18 +01:00
/// The text alignment for the email input field.
final TextAlign? emailTextAlign;
/// The text alignment for the password input field.
final TextAlign? passwordTextAlign;
2024-02-19 16:03:18 +01:00
/// Translations for various texts on the login screen.
final LoginTranslations translations;
2024-02-19 16:03:18 +01:00
/// The validation service used for validating email and password inputs.
2022-09-29 17:22:26 +02:00
final ValidationService? validationService;
2024-02-19 16:03:18 +01:00
/// Determines whether the password field should be obscured.
final bool showObscurePassword;
final double? suffixIconSize;
final EdgeInsets? suffixIconPadding;
2022-09-29 17:22:26 +02:00
2024-02-19 16:03:18 +01:00
/// Get validations.
2022-09-29 17:22:26 +02:00
ValidationService get validations =>
validationService ?? LoginValidationService(this);
2024-04-19 10:10:09 +02:00
/// The background color for the login screen.
final Color loginBackgroundColor;
/// The background color for the forgot password screen.
final Color forgotPasswordBackgroundColor;
/// The padding for the forgot password screen.
final Padding forgotPasswordScreenPadding;
/// forgot password custom AppBar
final AppBar? forgotPasswordCustomAppBar;
}
class LoginTranslations {
const LoginTranslations({
this.emailEmpty = 'Email is required',
this.passwordEmpty = 'Password is required',
this.emailInvalid = 'Enter a valid email address',
2024-08-08 09:44:01 +02:00
this.loginButton = 'Log in',
2022-11-04 09:23:48 +01:00
this.forgotPasswordButton = 'Forgot password?',
2024-04-19 10:10:09 +02:00
this.requestForgotPasswordButton = 'Send link',
2024-08-08 09:44:01 +02:00
this.registrationButton = 'Create account',
});
final String emailInvalid;
final String emailEmpty;
final String passwordEmpty;
2022-11-04 09:23:48 +01:00
final String loginButton;
final String forgotPasswordButton;
final String requestForgotPasswordButton;
final String registrationButton;
}
Widget _createEmailInputContainer(Widget child) => Padding(
padding: const EdgeInsets.only(bottom: 15),
child: child,
);
Widget _createPasswordInputContainer(Widget child) => child;
Widget _createLoginButton(
BuildContext context,
OptionalAsyncCallback onPressed,
bool disabled,
OptionalAsyncCallback onDisabledPress,
LoginOptions options,
2024-02-06 16:05:46 +01:00
) =>
Opacity(
opacity: disabled ? 0.5 : 1.0,
2024-08-08 09:44:01 +02:00
child: Row(
children: [
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: FilledButton(
onPressed: () async =>
!disabled ? await onPressed() : await onDisabledPress(),
child: Padding(
padding: const EdgeInsets.all(8),
child: Text(
options.translations.loginButton,
style: Theme.of(context).textTheme.displayLarge,
),
),
2024-04-19 10:10:09 +02:00
),
),
),
2024-08-08 09:44:01 +02:00
],
2024-02-06 16:05:46 +01:00
),
);
Widget _createForgotPasswordButton(
BuildContext context,
OptionalAsyncCallback onPressed,
bool disabled,
OptionalAsyncCallback onDisabledPress,
LoginOptions options,
2024-02-06 16:05:46 +01:00
) =>
Opacity(
opacity: disabled ? 0.5 : 1.0,
2024-04-19 10:10:09 +02:00
child: TextButton(
2024-02-06 16:05:46 +01:00
onPressed: !disabled ? onPressed : onDisabledPress,
2024-04-19 10:10:09 +02:00
child: Text(
options.translations.forgotPasswordButton,
style: const TextStyle(
decoration: TextDecoration.underline,
decorationColor: Color(0xff8D8D8D),
fontSize: 12,
fontWeight: FontWeight.w500,
color: Color(0xff8D8D8D),
),
),
2024-02-06 16:05:46 +01:00
),
);
2022-09-29 17:22:26 +02:00
Widget _createRequestForgotPasswordButton(
BuildContext context,
OptionalAsyncCallback onPressed,
bool disabled,
OptionalAsyncCallback onDisabledPress,
LoginOptions options,
2024-02-06 16:05:46 +01:00
) =>
Opacity(
opacity: disabled ? 0.5 : 1.0,
child: Padding(
padding: const EdgeInsets.only(top: 8),
child: InkWell(
onTap: !disabled ? onPressed : onDisabledPress,
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(20),
color: const Color(0xff71C6D1),
),
height: 44,
width: 254,
child: Center(
child: Text(
options.translations.requestForgotPasswordButton,
style: const TextStyle(
fontWeight: FontWeight.w800,
fontSize: 20,
color: Colors.white,
),
2024-04-19 10:10:09 +02:00
),
),
),
),
2024-02-06 16:05:46 +01:00
),
);
2022-09-29 17:22:26 +02:00
Widget _createRegisterButton(
BuildContext context,
OptionalAsyncCallback onPressed,
bool disabled,
OptionalAsyncCallback onDisabledPress,
LoginOptions options,
2024-02-06 16:05:46 +01:00
) =>
Opacity(
opacity: disabled ? 0.5 : 1.0,
2024-04-19 10:10:09 +02:00
child: TextButton(
2024-02-06 16:05:46 +01:00
onPressed: !disabled ? onPressed : onDisabledPress,
2024-04-19 10:10:09 +02:00
child: Text(
options.translations.registrationButton,
2024-08-08 09:44:01 +02:00
style: Theme.of(context).textTheme.displayMedium!.copyWith(
decoration: TextDecoration.underline,
),
2024-04-19 10:10:09 +02:00
),
2024-02-06 16:05:46 +01:00
),
);
typedef ButtonBuilder = Widget Function(
BuildContext context,
OptionalAsyncCallback onPressed,
2024-02-06 16:05:46 +01:00
// ignore: avoid_positional_boolean_parameters
bool isDisabled,
OptionalAsyncCallback onDisabledPress,
LoginOptions options,
);
typedef InputContainerBuilder = Widget Function(
Widget child,
);
typedef OptionalAsyncCallback = FutureOr<void> Function();