Fliin
On this page

Screens / auth

Sign in

Lets people sign in with email and password or an identity provider, with forgotten password, rejected credentials, offline and the wait after too many attempts.

16 of 16 variants pass
Sign in, brand state
Platform
Brightness
Text scale
Direction

Import

Sign in is part of Fliin Pro. With a license key, sign in once with fliin login, then add it in a Flutter app where fliin init has run:

fliin login
fliin add sign-in

Also installs: core, alert, auth-form, auth-header, button, link-button, page, social-sign-in, text-field, icons

Examples

Brand

Your brand on the screen: your logo above the title, and the providers first, their logos side by side, for an app whose users mostly sign in through one. title and subtitle replace the screen's texts when you pass them.

Sign in, brand state
import 'package:your_app/ui/fliin/components/social_sign_in/fl_social_sign_in.dart';
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/icons/fl_icons.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';

class SignInBrandExample extends StatelessWidget {
  const SignInBrandExample({super.key});

  @override
  Widget build(BuildContext context) {
    return SignInScreen.standalone(
      service: const SampleSignInService(latency: Duration(milliseconds: 600)),
      initial: const SignInReady(),
      mark: FlIcon(FlIcons.starFill),
      providersLayout: FlSocialSignInLayout.row,
      providersFirst: true,
      providers: [
        for (final provider in sampleSignInProviders) (provider: provider, icon: _Monogram(provider.name)),
      ],
      onForgotPassword: () {},
      onSignUp: () {},
    );
  }
}

/// Stands in for a provider's logo until the app puts in the official one:
/// its initial in a square, at the size and color of the icon.
class _Monogram extends StatelessWidget {
  const _Monogram(this.name);

  final String name;

  @override
  Widget build(BuildContext context) {
    final icon = IconTheme.of(context);
    final theme = FlScope.of(context);
    final size = icon.size!;
    return ExcludeSemantics(
      child: SizedBox.square(
        dimension: size,
        child: DecoratedBox(
          decoration: ShapeDecoration(
            shape: FlContinuousBorder(
              radius: theme.shape.radiusXs,
              side: BorderSide(color: icon.color!, width: theme.size.border),
            ),
          ),
          child: Center(
            child: Text(
              name[0].toUpperCase(),
              textScaler: TextScaler.noScaling,
              style: TextStyle(
                color: icon.color,
                fontSize: size * 0.6,
                height: 1,
                fontWeight: theme.tokens.typography.weight.semibold,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Ready

The sign-in form, with a button per provider above it. standalone holds its own controller over the service you pass; implement SignInService to reach your backend.

Sign in, ready state
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';

class SignInReadyExample extends StatelessWidget {
  const SignInReadyExample({super.key});

  @override
  Widget build(BuildContext context) {
    return SignInScreen.standalone(
      service: const SampleSignInService(latency: Duration(milliseconds: 600)),
      initial: const SignInReady(),
      providers: [
        for (final provider in sampleSignInProviders) (provider: provider, icon: _Monogram(provider.name)),
      ],
      onForgotPassword: () {},
      onSignUp: () {},
    );
  }
}

/// Stands in for a provider's logo until the app puts in the official one:
/// its initial in a square, at the size and color of the icon.
class _Monogram extends StatelessWidget {
  const _Monogram(this.name);

  final String name;

  @override
  Widget build(BuildContext context) {
    final icon = IconTheme.of(context);
    final theme = FlScope.of(context);
    final size = icon.size!;
    return ExcludeSemantics(
      child: SizedBox.square(
        dimension: size,
        child: DecoratedBox(
          decoration: ShapeDecoration(
            shape: FlContinuousBorder(
              radius: theme.shape.radiusXs,
              side: BorderSide(color: icon.color!, width: theme.size.border),
            ),
          ),
          child: Center(
            child: Text(
              name[0].toUpperCase(),
              textScaler: TextScaler.noScaling,
              style: TextStyle(
                color: icon.color,
                fontSize: size * 0.6,
                height: 1,
                fontWeight: theme.tokens.typography.weight.semibold,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Sending

While the service checks the credentials, the button shows its spinner and the fields stay put.

Sign in, sending state
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';

class SignInSendingExample extends StatelessWidget {
  const SignInSendingExample({super.key});

  @override
  Widget build(BuildContext context) {
    return SignInScreen.standalone(
      service: const SampleSignInService(latency: Duration(milliseconds: 600)),
      initial: const SignInSending(),
      providers: [
        for (final provider in sampleSignInProviders) (provider: provider, icon: _Monogram(provider.name)),
      ],
      onForgotPassword: () {},
      onSignUp: () {},
    );
  }
}

/// Stands in for a provider's logo until the app puts in the official one:
/// its initial in a square, at the size and color of the icon.
class _Monogram extends StatelessWidget {
  const _Monogram(this.name);

  final String name;

  @override
  Widget build(BuildContext context) {
    final icon = IconTheme.of(context);
    final theme = FlScope.of(context);
    final size = icon.size!;
    return ExcludeSemantics(
      child: SizedBox.square(
        dimension: size,
        child: DecoratedBox(
          decoration: ShapeDecoration(
            shape: FlContinuousBorder(
              radius: theme.shape.radiusXs,
              side: BorderSide(color: icon.color!, width: theme.size.border),
            ),
          ),
          child: Center(
            child: Text(
              name[0].toUpperCase(),
              textScaler: TextScaler.noScaling,
              style: TextStyle(
                color: icon.color,
                fontSize: size * 0.6,
                height: 1,
                fontWeight: theme.tokens.typography.weight.semibold,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Rejected

Wrong credentials: an alert above the form says so, without saying which of the two was wrong.

Sign in, rejected state
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';

class SignInRejectedExample extends StatelessWidget {
  const SignInRejectedExample({super.key});

  @override
  Widget build(BuildContext context) {
    return SignInScreen.standalone(
      service: const SampleSignInService(latency: Duration(milliseconds: 600)),
      initial: const SignInReady(problem: SignInProblem.rejected),
      providers: [
        for (final provider in sampleSignInProviders) (provider: provider, icon: _Monogram(provider.name)),
      ],
      onForgotPassword: () {},
      onSignUp: () {},
    );
  }
}

/// Stands in for a provider's logo until the app puts in the official one:
/// its initial in a square, at the size and color of the icon.
class _Monogram extends StatelessWidget {
  const _Monogram(this.name);

  final String name;

  @override
  Widget build(BuildContext context) {
    final icon = IconTheme.of(context);
    final theme = FlScope.of(context);
    final size = icon.size!;
    return ExcludeSemantics(
      child: SizedBox.square(
        dimension: size,
        child: DecoratedBox(
          decoration: ShapeDecoration(
            shape: FlContinuousBorder(
              radius: theme.shape.radiusXs,
              side: BorderSide(color: icon.color!, width: theme.size.border),
            ),
          ),
          child: Center(
            child: Text(
              name[0].toUpperCase(),
              textScaler: TextScaler.noScaling,
              style: TextStyle(
                color: icon.color,
                fontSize: size * 0.6,
                height: 1,
                fontWeight: theme.tokens.typography.weight.semibold,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Offline

Without a connection, the alert asks to reconnect and the form stays filled in.

Sign in, offline state
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';

class SignInOfflineExample extends StatelessWidget {
  const SignInOfflineExample({super.key});

  @override
  Widget build(BuildContext context) {
    return SignInScreen.standalone(
      service: const SampleSignInService(latency: Duration(milliseconds: 600)),
      initial: const SignInReady(problem: SignInProblem.offline),
      providers: [
        for (final provider in sampleSignInProviders) (provider: provider, icon: _Monogram(provider.name)),
      ],
      onForgotPassword: () {},
      onSignUp: () {},
    );
  }
}

/// Stands in for a provider's logo until the app puts in the official one:
/// its initial in a square, at the size and color of the icon.
class _Monogram extends StatelessWidget {
  const _Monogram(this.name);

  final String name;

  @override
  Widget build(BuildContext context) {
    final icon = IconTheme.of(context);
    final theme = FlScope.of(context);
    final size = icon.size!;
    return ExcludeSemantics(
      child: SizedBox.square(
        dimension: size,
        child: DecoratedBox(
          decoration: ShapeDecoration(
            shape: FlContinuousBorder(
              radius: theme.shape.radiusXs,
              side: BorderSide(color: icon.color!, width: theme.size.border),
            ),
          ),
          child: Center(
            child: Text(
              name[0].toUpperCase(),
              textScaler: TextScaler.noScaling,
              style: TextStyle(
                color: icon.color,
                fontSize: size * 0.6,
                height: 1,
                fontWeight: theme.tokens.typography.weight.semibold,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Throttled

After too many attempts, the form waits: the alert counts down until the time the service gave.

Sign in, throttled state
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';

class SignInThrottledExample extends StatelessWidget {
  const SignInThrottledExample({super.key});

  @override
  Widget build(BuildContext context) {
    return SignInScreen.standalone(
      service: const SampleSignInService(latency: Duration(milliseconds: 600)),
      initial: SignInThrottled(DateTime.now().add(const Duration(seconds: 45))),
      providers: [
        for (final provider in sampleSignInProviders) (provider: provider, icon: _Monogram(provider.name)),
      ],
      onForgotPassword: () {},
      onSignUp: () {},
    );
  }
}

/// Stands in for a provider's logo until the app puts in the official one:
/// its initial in a square, at the size and color of the icon.
class _Monogram extends StatelessWidget {
  const _Monogram(this.name);

  final String name;

  @override
  Widget build(BuildContext context) {
    final icon = IconTheme.of(context);
    final theme = FlScope.of(context);
    final size = icon.size!;
    return ExcludeSemantics(
      child: SizedBox.square(
        dimension: size,
        child: DecoratedBox(
          decoration: ShapeDecoration(
            shape: FlContinuousBorder(
              radius: theme.shape.radiusXs,
              side: BorderSide(color: icon.color!, width: theme.size.border),
            ),
          ),
          child: Center(
            child: Text(
              name[0].toUpperCase(),
              textScaler: TextScaler.noScaling,
              style: TextStyle(
                color: icon.color,
                fontSize: size * 0.6,
                height: 1,
                fontWeight: theme.tokens.typography.weight.semibold,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

Routing

fliin add sign-in prints the route for the router it finds in your pubspec, a file next to the page that wires its navigation. Each of them:

go_router

// lib/sign_in_route.dart, next to sign_in_page.dart.
import 'package:go_router/go_router.dart';

import 'sign_in_page.dart';

/// Add signInRoute to the routes of your GoRouter.
final signInRoute = GoRoute(
  path: '/sign-in',
  builder: (context, state) => SignInPage(
    // '/': your app's home.
    onSignedIn: () => context.go('/'),
    onForgotPassword: () => context.push('/forgot-password'),
    onSignUp: () => context.push('/sign-up'),
  ),
);

navigator

// lib/sign_in_route.dart, next to sign_in_page.dart.
import 'package:flutter/material.dart';

import 'forgot_password_route.dart';
import 'sign_in_page.dart';
import 'sign_up_route.dart';

/// Opens “Sign in”: `Navigator.of(context).push(signInRoute(homePage: …))`.
/// [homePage] builds your app's home.
Route<void> signInRoute({required WidgetBuilder homePage}) => MaterialPageRoute<void>(
  builder: (context) => SignInPage(
    onSignedIn: () => Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute<void>(builder: homePage), (_) => false),
    onForgotPassword: () => Navigator.of(context).push(forgotPasswordRoute()),
    onSignUp: () => Navigator.of(context).push(signUpRoute(homePage: homePage)),
  ),
);

State

The controller is a ChangeNotifier from widgets.dart, with no package. fliin add sign-in prints the page that holds it with the state management it finds, its imports written for your package; below they read your_app. Your backend implements the Service interface of the screen's _data.dart file:

none

// lib/sign_in_page.dart
// Your backend: implement SignInService (sign_in_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';

class SignInPage extends StatelessWidget {
  const SignInPage({
    super.key,
    required this.onSignedIn,
    required this.onForgotPassword,
    required this.onSignUp,
  });

  final VoidCallback onSignedIn;
  final VoidCallback onForgotPassword;
  final VoidCallback onSignUp;

  @override
  Widget build(BuildContext context) => SignInScreen.standalone(
    service: const SampleSignInService(),
    onSignedIn: onSignedIn,
    onForgotPassword: onForgotPassword,
    onSignUp: onSignUp,
  );
}

provider

// lib/sign_in_page.dart
// Your backend: implement SignInService (sign_in_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';

class SignInPage extends StatelessWidget {
  const SignInPage({
    super.key,
    required this.onSignedIn,
    required this.onForgotPassword,
    required this.onSignUp,
  });

  final VoidCallback onSignedIn;
  final VoidCallback onForgotPassword;
  final VoidCallback onSignUp;

  @override
  Widget build(BuildContext context) => ChangeNotifierProvider(
    create: (_) => SignInController(service: const SampleSignInService()),
    child: Builder(
      builder: (context) => SignInScreen(
        controller: context.read<SignInController>(),
        onSignedIn: onSignedIn,
        onForgotPassword: onForgotPassword,
        onSignUp: onSignUp,
      ),
    ),
  );
}

riverpod

// lib/sign_in_page.dart
// Your backend: implement SignInService (sign_in_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

final signInControllerProvider = Provider.autoDispose<SignInController>((ref) {
  final controller = SignInController(service: const SampleSignInService());
  ref.onDispose(controller.dispose);
  return controller;
});

class SignInPage extends ConsumerWidget {
  const SignInPage({
    super.key,
    required this.onSignedIn,
    required this.onForgotPassword,
    required this.onSignUp,
  });

  final VoidCallback onSignedIn;
  final VoidCallback onForgotPassword;
  final VoidCallback onSignUp;

  @override
  Widget build(BuildContext context, WidgetRef ref) => SignInScreen(
    controller: ref.watch(signInControllerProvider),
    onSignedIn: onSignedIn,
    onForgotPassword: onForgotPassword,
    onSignUp: onSignUp,
  );
}

bloc

// lib/sign_in_page.dart
// Your backend: implement SignInService (sign_in_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_data.dart';
import 'package:your_app/ui/fliin/screens/sign_in/sign_in_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

/// The screen's controller as a bloc, for your BlocListener and BlocBuilder:
/// one emission per controller notification. `version` tells them apart
/// when `state` does not change (mode, filters, text…, read them on
/// `controller`). The screen listens to the controller itself.
class SignInCubit extends Cubit<({SignInState state, int version})> {
  SignInCubit(this.controller) : super((state: controller.state, version: 0)) {
    controller.addListener(_changed);
  }

  final SignInController controller;

  void _changed() => emit((state: controller.state, version: state.version + 1));

  @override
  Future<void> close() {
    controller
      ..removeListener(_changed)
      ..dispose();
    return super.close();
  }
}

class SignInPage extends StatelessWidget {
  const SignInPage({
    super.key,
    required this.onSignedIn,
    required this.onForgotPassword,
    required this.onSignUp,
  });

  final VoidCallback onSignedIn;
  final VoidCallback onForgotPassword;
  final VoidCallback onSignUp;

  @override
  Widget build(BuildContext context) => BlocProvider(
    create: (_) => SignInCubit(SignInController(service: const SampleSignInService())),
    child: Builder(
      builder: (context) => SignInScreen(
        controller: context.read<SignInCubit>().controller,
        onSignedIn: onSignedIn,
        onForgotPassword: onForgotPassword,
        onSignUp: onSignUp,
      ),
    ),
  );
}

The snippets lead to forgot-password, sign-up: install these screens too and paste their snippets.

API

SignInScreen: class extends StatefulWidget
SignInScreen.new: const new({super.key, required SignInController controller, List<({SignInProvider provider, Widget icon})> providers, Widget? mark, String? title, String? subtitle, FlSocialSignInLayout providersLayout, bool providersFirst, VoidCallback? onSignedIn, VoidCallback? onForgotPassword, VoidCallback? onSignUp})
SignInScreen.standalone: const new({super.key, required SignInService service, SignInState? initial, DateTime Function()? now, List<({SignInProvider provider, Widget icon})> providers, Widget? mark, String? title, String? subtitle, FlSocialSignInLayout providersLayout, bool providersFirst, VoidCallback? onSignedIn, VoidCallback? onForgotPassword, VoidCallback? onSignUp})
SignInScreen.controller: get SignInController?
SignInScreen.service: get SignInService?
SignInScreen.initial: get SignInState?
SignInScreen.now: get DateTime Function()?
SignInScreen.providers: get List<({SignInProvider provider, Widget icon})>
SignInScreen.mark: get Widget?
SignInScreen.title: get String?
SignInScreen.subtitle: get String?
SignInScreen.providersLayout: get FlSocialSignInLayout
SignInScreen.providersFirst: get bool
SignInScreen.onSignedIn: get VoidCallback?
SignInScreen.onForgotPassword: get VoidCallback?
SignInScreen.onSignUp: get VoidCallback?
SignInScreen.createState: State<SignInScreen>()
SignInProblem: enum {rejected, offline, failed}
SignInProblem.rejected: static final SignInProblem
SignInProblem.offline: static final SignInProblem
SignInProblem.failed: static final SignInProblem
SignInState: sealed class permits {SignInDone, SignInReady, SignInSending, SignInThrottled}
SignInState.new: const new()
SignInReady: final class extends SignInState
SignInReady.new: const new({SignInProblem? problem})
SignInReady.problem: get SignInProblem?
SignInSending: final class extends SignInState
SignInSending.new: const new({SignInProvider? provider})
SignInSending.provider: get SignInProvider?
SignInThrottled: final class extends SignInState
SignInThrottled.new: const new(DateTime until)
SignInThrottled.until: get DateTime
SignInDone: final class extends SignInState
SignInDone.new: const new()
SignInController: class extends ChangeNotifier
SignInController.new: new({required SignInService service, SignInState initial, DateTime Function()? now})
SignInController.service: get SignInService
SignInController.state: get SignInState
SignInController.wait: get Duration?
SignInController.tick: void()
SignInController.signIn: Future<bool>(SignInCredentials credentials)
SignInController.signInWith: Future<bool>(SignInProvider provider)
SignInController.dispose: void()
SignInProvider: final class
SignInProvider.new: const new({required String id, required String name})
SignInProvider.id: get String
SignInProvider.name: get String
SignInProvider.toString: String()
SignInCredentials: final class
SignInCredentials.new: const new({required String email, required String password})
SignInCredentials.email: get String
SignInCredentials.password: get String
SignInCredentials.toString: String()
SignInEmailIssue: enum {missing, malformed}
SignInEmailIssue.missing: static final SignInEmailIssue
SignInEmailIssue.malformed: static final SignInEmailIssue
signInEmailIssue: SignInEmailIssue?(String email)
SignInRejected: final class implements Exception
SignInRejected.new: const new()
SignInNoNetwork: final class implements Exception
SignInNoNetwork.new: const new()
SignInTooManyAttempts: final class implements Exception
SignInTooManyAttempts.new: const new(Duration retryAfter)
SignInTooManyAttempts.retryAfter: get Duration
SignInService: abstract interface class
SignInService.new: new()
SignInService.signIn: abstract Future<void>(SignInCredentials credentials)
SignInService.signInWith: abstract Future<void>(SignInProvider provider)
sampleSignInProviders: const dynamic
SampleSignInService: final class implements SignInService
SampleSignInService.new: const new({Duration latency})
SampleSignInService.latency: get Duration
SampleSignInService.signIn: Future<void>(SignInCredentials credentials)
SampleSignInService.signInWith: Future<void>(SignInProvider provider)
signInL10n: const Map<String, Map<String, String>>
SignInStrings: final class
SignInStrings.new: const new(String language)
SignInStrings.of: factory new(BuildContext context)
SignInStrings.language: get String
SignInStrings.title: get String
SignInStrings.subtitle: get String
SignInStrings.email: get String
SignInStrings.emailPlaceholder: get String
SignInStrings.password: get String
SignInStrings.showPassword: get String
SignInStrings.hidePassword: get String
SignInStrings.showPasswordLabel: get String
SignInStrings.hidePasswordLabel: get String
SignInStrings.forgot: get String
SignInStrings.submit: get String
SignInStrings.retryIn: String(Duration wait)
SignInStrings.or: get String
SignInStrings.continueWith: String(String provider)
SignInStrings.noAccount: get String
SignInStrings.signUp: get String
SignInStrings.emailMissing: get String
SignInStrings.emailMalformed: get String
SignInStrings.passwordMissing: get String
SignInStrings.rejectedTitle: get String
SignInStrings.rejectedMessage: get String
SignInStrings.offlineTitle: get String
SignInStrings.offlineMessage: get String
SignInStrings.failedTitle: get String
SignInStrings.failedMessage: get String
SignInStrings.throttledTitle: get String
SignInStrings.throttledMessage: get String

Strings

Every label in English, French and Arabic. The screen follows the closest Localizations; the same table is in the manifest, ready for your ARB files.

Keyenfrar
signInTitleSign inConnexionتسجيل الدخول
signInSubtitleWelcome back. Enter your details to continue.Bon retour. Entrez vos identifiants pour continuer.مرحبًا بعودتك. أدخل بياناتك للمتابعة.
signInEmailEmailAdresse e-mailالبريد الإلكتروني
signInEmailPlaceholder[email protected][email protected][email protected]
signInPasswordPasswordMot de passeكلمة المرور
signInShowPasswordShowAfficherإظهار
signInHidePasswordHideMasquerإخفاء
signInShowPasswordLabelShow passwordAfficher le mot de passeإظهار كلمة المرور
signInHidePasswordLabelHide passwordMasquer le mot de passeإخفاء كلمة المرور
signInForgotForgot password?Mot de passe oublié ?هل نسيت كلمة المرور؟
signInSubmitSign inSe connecterتسجيل الدخول
signInRetryInTry again in {time}Réessayer dans {time}أعد المحاولة بعد {time}
signInOrorouأو
signInContinueWithContinue with {provider}Continuer avec {provider}المتابعة باستخدام {provider}
signInNoAccountNo account yet?Pas encore de compte ?ليس لديك حساب؟
signInSignUpCreate oneCréer un compteأنشئ حسابًا
signInEmailMissingEnter your email.Saisissez votre adresse e-mail.أدخل بريدك الإلكتروني.
signInEmailMalformedEnter an email such as [email protected].Saisissez une adresse comme [email protected].أدخل بريدًا مثل [email protected].
signInPasswordMissingEnter your password.Saisissez votre mot de passe.أدخل كلمة المرور.
signInRejectedTitleEmail or password is incorrectAdresse ou mot de passe incorrectالبريد الإلكتروني أو كلمة المرور غير صحيحة
signInRejectedMessageCheck them and try again, or reset your password.Vérifiez-les et réessayez, ou réinitialisez votre mot de passe.تحقق منهما وأعد المحاولة، أو أعد تعيين كلمة المرور.
signInOfflineTitleYou are offlineVous êtes hors ligneأنت غير متصل
signInOfflineMessageCheck your connection, then try again.Vérifiez votre connexion, puis réessayez.تحقق من اتصالك ثم أعد المحاولة.
signInFailedTitleSign-in failedLa connexion a échouéتعذّر تسجيل الدخول
signInFailedMessageSomething went wrong on our side. Try again in a moment.Un problème est survenu de notre côté. Réessayez dans un instant.حدثت مشكلة من جهتنا. أعد المحاولة بعد قليل.
signInThrottledTitleToo many attemptsTrop d’essaisمحاولات كثيرة جدًا
signInThrottledMessageFor your security, sign-in is paused for a moment.Par sécurité, la connexion est suspendue un instant.حفاظًا على أمانك، أُوقف تسجيل الدخول مؤقتًا.

Reference renders

The 16 images published with version 0.2.4, rendered by the shared harness on macOS with Flutter 3.47.7. Each shows every state side by side, at the size of an iPhone (390 × 844) or of an Android phone (412 × 915). fliin verify sign-in compares your copy to them.

iOS · Light
Sign in, iOS, Light, text 1.0×, Left to right
Text 1.0× · Left to right
Sign in, iOS, Light, text 1.0×, Right to left
Text 1.0× · Right to left
Sign in, iOS, Light, text 2.0×, Left to right
Text 2.0× · Left to right
Sign in, iOS, Light, text 2.0×, Right to left
Text 2.0× · Right to left
iOS · Dark
Sign in, iOS, Dark, text 1.0×, Left to right
Text 1.0× · Left to right
Sign in, iOS, Dark, text 1.0×, Right to left
Text 1.0× · Right to left
Sign in, iOS, Dark, text 2.0×, Left to right
Text 2.0× · Left to right
Sign in, iOS, Dark, text 2.0×, Right to left
Text 2.0× · Right to left
Android · Light
Sign in, Android, Light, text 1.0×, Left to right
Text 1.0× · Left to right
Sign in, Android, Light, text 1.0×, Right to left
Text 1.0× · Right to left
Sign in, Android, Light, text 2.0×, Left to right
Text 2.0× · Left to right
Sign in, Android, Light, text 2.0×, Right to left
Text 2.0× · Right to left
Android · Dark
Sign in, Android, Dark, text 1.0×, Left to right
Text 1.0× · Left to right
Sign in, Android, Dark, text 1.0×, Right to left
Text 1.0× · Right to left
Sign in, Android, Dark, text 2.0×, Left to right
Text 2.0× · Left to right
Sign in, Android, Dark, text 2.0×, Right to left
Text 2.0× · Right to left

Use it to

  • let users sign in with their email and password
  • offer sign in with Apple or Google next to the form
  • show that the email or password was rejected at sign in
  • make users wait after too many sign in attempts, with a countdown
  • let the password manager autofill the sign in form
  • present a login page with email, password and a Google button
Not for
  • creating an account: use the sign-up screen (sign-up)
  • resetting a forgotten password: use the forgot password screen (forgot-password)
  • an access form in an existing screen: use the access form block (auth-form)
States
  • Ready
  • Sending
  • Rejected
  • Offline
  • Throttled

Arrows to move, Enter to open, Escape to close.