Screens / auth
Sign up
Lets people create an account with name, email and a password whose rules are checked while typing, accept the terms, or use a provider; email taken and offline included.
Import
Sign up 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-upAlso installs: core, alert, auth-form, auth-header, button, checkbox, field, icons, link-button, page, social-sign-in, text-field
Examples
Minimal
A shorter sign-up: no name field (ask for it later, on the profile), your logo above the title, and the providers first, one per line. title and subtitle replace the screen's texts when you pass them.
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_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
class SignUpMinimalExample extends StatelessWidget {
const SignUpMinimalExample({super.key});
@override
Widget build(BuildContext context) {
return SignUpScreen.standalone(
service: const SampleSignUpService(latency: Duration(milliseconds: 600)),
initial: const SignUpReady(),
mark: FlIcon(FlIcons.starFill),
showName: false,
providersLayout: FlSocialSignInLayout.column,
providersFirst: true,
providers: [
for (final provider in sampleSignUpProviders) (provider: provider, icon: _Monogram(provider.name)),
],
onSignIn: () {},
onTerms: () {},
onPrivacy: () {},
);
}
}
/// 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-up form, with a button per provider above it and the links to the terms and privacy policy below.
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
class SignUpReadyExample extends StatelessWidget {
const SignUpReadyExample({super.key});
@override
Widget build(BuildContext context) {
return SignUpScreen.standalone(
service: const SampleSignUpService(latency: Duration(milliseconds: 600)),
initial: const SignUpReady(),
providers: [
for (final provider in sampleSignUpProviders) (provider: provider, icon: _Monogram(provider.name)),
],
onSignIn: () {},
onTerms: () {},
onPrivacy: () {},
);
}
}
/// 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 account is created, the button shows its spinner.
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
class SignUpSendingExample extends StatelessWidget {
const SignUpSendingExample({super.key});
@override
Widget build(BuildContext context) {
return SignUpScreen.standalone(
service: const SampleSignUpService(latency: Duration(milliseconds: 600)),
initial: const SignUpSending(),
providers: [
for (final provider in sampleSignUpProviders) (provider: provider, icon: _Monogram(provider.name)),
],
onSignIn: () {},
onTerms: () {},
onPrivacy: () {},
);
}
}
/// 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,
),
),
),
),
),
);
}
}Email taken
The email already has an account: the screen offers to sign in with it instead.
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
class SignUpEmailTakenExample extends StatelessWidget {
const SignUpEmailTakenExample({super.key});
@override
Widget build(BuildContext context) {
return SignUpScreen.standalone(
service: const SampleSignUpService(latency: Duration(milliseconds: 600)),
initial: const SignUpEmailInUse('[email protected]'),
providers: [
for (final provider in sampleSignUpProviders) (provider: provider, icon: _Monogram(provider.name)),
],
onSignIn: () {},
onTerms: () {},
onPrivacy: () {},
);
}
}
/// 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, an alert asks to reconnect and keeps what was typed.
import 'package:your_app/ui/fliin/core/fliin.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
class SignUpOfflineExample extends StatelessWidget {
const SignUpOfflineExample({super.key});
@override
Widget build(BuildContext context) {
return SignUpScreen.standalone(
service: const SampleSignUpService(latency: Duration(milliseconds: 600)),
initial: const SignUpReady(problem: SignUpProblem.offline),
providers: [
for (final provider in sampleSignUpProviders) (provider: provider, icon: _Monogram(provider.name)),
],
onSignIn: () {},
onTerms: () {},
onPrivacy: () {},
);
}
}
/// 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-up 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_up_route.dart, next to sign_up_page.dart.
import 'package:your_app/ui/fliin/screens/verify_code/verify_code_data.dart';
import 'package:go_router/go_router.dart';
import 'sign_up_page.dart';
/// Add signUpRoute to the routes of your GoRouter.
final signUpRoute = GoRoute(
path: '/sign-up',
builder: (context, state) => SignUpPage(
// '/': your app's home, when the account comes from a provider.
onSignedUp: (email) => email == null ? context.go('/') : context.push('/verify-code', extra: VerifyCodeEmail(email)),
// Goes back to the sign-in that opened sign-up, or else opens it.
onSignIn: () => context.canPop() ? context.pop() : context.pushReplacement('/sign-in'),
),
);navigator
// lib/sign_up_route.dart, next to sign_up_page.dart.
import 'package:your_app/ui/fliin/screens/verify_code/verify_code_data.dart';
import 'package:flutter/material.dart';
import 'sign_in_route.dart';
import 'sign_up_page.dart';
import 'verify_code_route.dart';
/// Opens “Sign up”: `Navigator.of(context).push(signUpRoute(homePage: …))`.
/// [homePage] builds your app's home.
Route<void> signUpRoute({required WidgetBuilder homePage}) => MaterialPageRoute<void>(
builder: (context) => SignUpPage(
onSignedUp: (email) => email == null
? Navigator.of(context).pushAndRemoveUntil(MaterialPageRoute<void>(builder: homePage), (_) => false)
: Navigator.of(context).push(verifyCodeRoute(destination: VerifyCodeEmail(email), homePage: homePage)),
onSignIn: () => Navigator.of(context).canPop() ? Navigator.of(context).pop() : Navigator.of(context).pushReplacement(signInRoute(homePage: homePage)),
),
);State
The controller is a ChangeNotifier from widgets.dart, with no package. fliin add sign-up 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_up_page.dart
// Your backend: implement SignUpService (sign_up_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
class SignUpPage extends StatelessWidget {
const SignUpPage({
super.key,
required this.onSignedUp,
required this.onSignIn,
});
final ValueChanged<String?> onSignedUp;
final VoidCallback onSignIn;
@override
Widget build(BuildContext context) => SignUpScreen.standalone(
service: const SampleSignUpService(),
onSignedUp: onSignedUp,
onSignIn: onSignIn,
);
}provider
// lib/sign_up_page.dart
// Your backend: implement SignUpService (sign_up_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:provider/provider.dart';
class SignUpPage extends StatelessWidget {
const SignUpPage({
super.key,
required this.onSignedUp,
required this.onSignIn,
});
final ValueChanged<String?> onSignedUp;
final VoidCallback onSignIn;
@override
Widget build(BuildContext context) => ChangeNotifierProvider(
create: (_) => SignUpController(service: const SampleSignUpService()),
child: Builder(
builder: (context) => SignUpScreen(
controller: context.read<SignUpController>(),
onSignedUp: onSignedUp,
onSignIn: onSignIn,
),
),
);
}riverpod
// lib/sign_up_page.dart
// Your backend: implement SignUpService (sign_up_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_screen.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
final signUpControllerProvider = Provider.autoDispose<SignUpController>((ref) {
final controller = SignUpController(service: const SampleSignUpService());
ref.onDispose(controller.dispose);
return controller;
});
class SignUpPage extends ConsumerWidget {
const SignUpPage({
super.key,
required this.onSignedUp,
required this.onSignIn,
});
final ValueChanged<String?> onSignedUp;
final VoidCallback onSignIn;
@override
Widget build(BuildContext context, WidgetRef ref) => SignUpScreen(
controller: ref.watch(signUpControllerProvider),
onSignedUp: onSignedUp,
onSignIn: onSignIn,
);
}bloc
// lib/sign_up_page.dart
// Your backend: implement SignUpService (sign_up_data.dart) and pass it instead of the sample service.
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_controller.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_data.dart';
import 'package:your_app/ui/fliin/screens/sign_up/sign_up_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 SignUpCubit extends Cubit<({SignUpState state, int version})> {
SignUpCubit(this.controller) : super((state: controller.state, version: 0)) {
controller.addListener(_changed);
}
final SignUpController controller;
void _changed() => emit((state: controller.state, version: state.version + 1));
@override
Future<void> close() {
controller
..removeListener(_changed)
..dispose();
return super.close();
}
}
class SignUpPage extends StatelessWidget {
const SignUpPage({
super.key,
required this.onSignedUp,
required this.onSignIn,
});
final ValueChanged<String?> onSignedUp;
final VoidCallback onSignIn;
@override
Widget build(BuildContext context) => BlocProvider(
create: (_) => SignUpCubit(SignUpController(service: const SampleSignUpService())),
child: Builder(
builder: (context) => SignUpScreen(
controller: context.read<SignUpCubit>().controller,
onSignedUp: onSignedUp,
onSignIn: onSignIn,
),
),
);
}The snippets lead to verify-code, sign-in: install these screens too and paste their snippets.
API
SignUpScreen: class extends StatefulWidget
SignUpScreen.new: const new({super.key, required SignUpController controller, List<({SignUpProvider provider, Widget icon})> providers, Widget? mark, String? title, String? subtitle, bool showName, FlSocialSignInLayout providersLayout, bool providersFirst, ValueChanged<String?>? onSignedUp, VoidCallback? onSignIn, VoidCallback? onTerms, VoidCallback? onPrivacy})
SignUpScreen.standalone: const new({super.key, required SignUpService service, SignUpState? initial, List<({SignUpProvider provider, Widget icon})> providers, Widget? mark, String? title, String? subtitle, bool showName, FlSocialSignInLayout providersLayout, bool providersFirst, ValueChanged<String?>? onSignedUp, VoidCallback? onSignIn, VoidCallback? onTerms, VoidCallback? onPrivacy})
SignUpScreen.controller: get SignUpController?
SignUpScreen.service: get SignUpService?
SignUpScreen.initial: get SignUpState?
SignUpScreen.providers: get List<({SignUpProvider provider, Widget icon})>
SignUpScreen.mark: get Widget?
SignUpScreen.title: get String?
SignUpScreen.subtitle: get String?
SignUpScreen.showName: get bool
SignUpScreen.providersLayout: get FlSocialSignInLayout
SignUpScreen.providersFirst: get bool
SignUpScreen.onSignedUp: get ValueChanged<String?>?
SignUpScreen.onSignIn: get VoidCallback?
SignUpScreen.onTerms: get VoidCallback?
SignUpScreen.onPrivacy: get VoidCallback?
SignUpScreen.createState: State<SignUpScreen>()
SignUpProblem: enum {offline, failed}
SignUpProblem.offline: static final SignUpProblem
SignUpProblem.failed: static final SignUpProblem
SignUpState: sealed class permits {SignUpDone, SignUpEmailInUse, SignUpReady, SignUpSending}
SignUpState.new: const new()
SignUpReady: final class extends SignUpState
SignUpReady.new: const new({SignUpProblem? problem})
SignUpReady.problem: get SignUpProblem?
SignUpEmailInUse: final class extends SignUpState
SignUpEmailInUse.new: const new(String email)
SignUpEmailInUse.email: get String
SignUpSending: final class extends SignUpState
SignUpSending.new: const new({SignUpProvider? provider})
SignUpSending.provider: get SignUpProvider?
SignUpDone: final class extends SignUpState
SignUpDone.new: const new()
SignUpController: class extends ChangeNotifier
SignUpController.new: new({required SignUpService service, SignUpState initial})
SignUpController.service: get SignUpService
SignUpController.state: get SignUpState
SignUpController.signUp: Future<bool>(SignUpRequest request)
SignUpController.signUpWith: Future<bool>(SignUpProvider provider)
SignUpController.dispose: void()
SignUpProvider: final class
SignUpProvider.new: const new({required String id, required String name})
SignUpProvider.id: get String
SignUpProvider.name: get String
SignUpProvider.toString: String()
SignUpRequest: final class
SignUpRequest.new: const new({required String name, required String email, required String password})
SignUpRequest.name: get String
SignUpRequest.email: get String
SignUpRequest.password: get String
SignUpRequest.toString: String()
SignUpEmailIssue: enum {missing, malformed}
SignUpEmailIssue.missing: static final SignUpEmailIssue
SignUpEmailIssue.malformed: static final SignUpEmailIssue
signUpEmailIssue: SignUpEmailIssue?(String email)
SignUpPasswordRule: enum {length, letter, digit}
SignUpPasswordRule.length: static final SignUpPasswordRule
SignUpPasswordRule.letter: static final SignUpPasswordRule
SignUpPasswordRule.digit: static final SignUpPasswordRule
SignUpPasswordRule.acceptedBy: bool(String password)
SignUpPasswordRule.all: static bool(String password)
SignUpEmailTaken: final class implements Exception
SignUpEmailTaken.new: const new()
SignUpNoNetwork: final class implements Exception
SignUpNoNetwork.new: const new()
SignUpService: abstract interface class
SignUpService.new: new()
SignUpService.signUp: abstract Future<void>(SignUpRequest request)
SignUpService.signUpWith: abstract Future<void>(SignUpProvider provider)
sampleSignUpProviders: const dynamic
SampleSignUpService: final class implements SignUpService
SampleSignUpService.new: const new({Duration latency})
SampleSignUpService.latency: get Duration
SampleSignUpService.signUp: Future<void>(SignUpRequest request)
SampleSignUpService.signUpWith: Future<void>(SignUpProvider provider)
signUpL10n: const Map<String, Map<String, String>>
SignUpStrings: final class
SignUpStrings.new: const new(String language)
SignUpStrings.of: factory new(BuildContext context)
SignUpStrings.language: get String
SignUpStrings.title: get String
SignUpStrings.subtitle: get String
SignUpStrings.name: get String
SignUpStrings.email: get String
SignUpStrings.emailPlaceholder: get String
SignUpStrings.password: get String
SignUpStrings.showPassword: get String
SignUpStrings.hidePassword: get String
SignUpStrings.showPasswordLabel: get String
SignUpStrings.hidePasswordLabel: get String
SignUpStrings.rule: String(SignUpPasswordRule rule)
SignUpStrings.ruleStatus: String(SignUpPasswordRule rule, {required bool met})
SignUpStrings.rulesMet: get String
SignUpStrings.acceptTerms: get String
SignUpStrings.acceptTermsLinks: get String
SignUpStrings.terms: get String
SignUpStrings.privacy: get String
SignUpStrings.submit: get String
SignUpStrings.or: get String
SignUpStrings.continueWith: String(String provider)
SignUpStrings.haveAccount: get String
SignUpStrings.signIn: get String
SignUpStrings.nameMissing: get String
SignUpStrings.emailMissing: get String
SignUpStrings.emailMalformed: get String
SignUpStrings.emailTaken: get String
SignUpStrings.passwordWeak: get String
SignUpStrings.termsMissing: get String
SignUpStrings.offlineTitle: get String
SignUpStrings.offlineMessage: get String
SignUpStrings.failedTitle: get String
SignUpStrings.failedMessage: get StringStrings
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.
| Key | en | fr | ar |
|---|---|---|---|
signUpTitle | Create your account | Créer votre compte | أنشئ حسابك |
signUpSubtitle | It takes less than a minute. | Cela prend moins d’une minute. | لن يستغرق ذلك أكثر من دقيقة. |
signUpName | Full name | Nom complet | الاسم الكامل |
signUpEmail | Adresse e-mail | البريد الإلكتروني | |
signUpEmailPlaceholder | [email protected] | [email protected] | [email protected] |
signUpPassword | Password | Mot de passe | كلمة المرور |
signUpShowPassword | Show | Afficher | إظهار |
signUpHidePassword | Hide | Masquer | إخفاء |
signUpShowPasswordLabel | Show password | Afficher le mot de passe | إظهار كلمة المرور |
signUpHidePasswordLabel | Hide password | Masquer le mot de passe | إخفاء كلمة المرور |
signUpRuleLength | At least 8 characters | 8 caractères au moins | 8 أحرف على الأقل |
signUpRuleLetter | At least one letter | Une lettre au moins | حرف واحد على الأقل |
signUpRuleDigit | At least one number | Un chiffre au moins | رقم واحد على الأقل |
signUpRuleMet | {rule}: done | {rule} : fait | {rule}: تم |
signUpRuleUnmet | {rule}: not yet | {rule} : pas encore | {rule}: ليس بعد |
signUpRulesMet | The password meets every rule. | Le mot de passe respecte toutes les règles. | كلمة المرور تستوفي كل الشروط. |
signUpAcceptTerms | I agree to the Terms of Use and the Privacy Policy. | J’accepte les conditions d’utilisation et la politique de confidentialité. | أوافق على شروط الاستخدام وسياسة الخصوصية. |
signUpAcceptTermsLinks | I agree to the {terms} and the {privacy}. | J’accepte les {terms} et la {privacy}. | أوافق على {terms} و{privacy}. |
signUpTerms | Terms of Use | conditions d’utilisation | شروط الاستخدام |
signUpPrivacy | Privacy Policy | politique de confidentialité | سياسة الخصوصية |
signUpSubmit | Create account | Créer le compte | إنشاء الحساب |
signUpOr | or | ou | أو |
signUpContinueWith | Continue with {provider} | Continuer avec {provider} | المتابعة باستخدام {provider} |
signUpHaveAccount | Already have an account? | Déjà un compte ? | لديك حساب بالفعل؟ |
signUpSignIn | Sign in | Se connecter | تسجيل الدخول |
signUpNameMissing | Enter your name. | Saisissez votre nom. | أدخل اسمك. |
signUpEmailMissing | Enter your email. | Saisissez votre adresse e-mail. | أدخل بريدك الإلكتروني. |
signUpEmailMalformed | Enter an email such as [email protected]. | Saisissez une adresse comme [email protected]. | أدخل بريدًا مثل [email protected]. |
signUpEmailTaken | This email already has an account. Sign in instead. | Cette adresse a déjà un compte. Connectez-vous plutôt. | لهذا البريد حساب بالفعل. سجّل الدخول بدلًا من ذلك. |
signUpPasswordWeak | Choose a password that meets the rules below. | Choisissez un mot de passe qui respecte les règles ci-dessous. | اختر كلمة مرور تستوفي الشروط أدناه. |
signUpTermsMissing | Accept the terms to continue. | Acceptez les conditions pour continuer. | وافق على الشروط للمتابعة. |
signUpOfflineTitle | You are offline | Vous êtes hors ligne | أنت غير متصل |
signUpOfflineMessage | Check your connection, then try again. | Vérifiez votre connexion, puis réessayez. | تحقق من اتصالك ثم أعد المحاولة. |
signUpFailedTitle | Your account could not be created | Impossible de créer le compte | تعذّر إنشاء حسابك |
signUpFailedMessage | Something went wrong on our side. Try again in a moment. | Un problème est survenu de notre côté. Réessayez dans 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-up compares your copy to them.
















Use it to
- create an account with name, email and password
- show password rules checked off while typing
- keep the active field and the button above the keyboard while signing up
- show that an email address already has an account
- offer sign up with Apple or Google
- open a registration page with a strong password check
- Not for
- a box to accept the terms before sending: use a checkbox (checkbox)
- signing in to an existing account: use the sign-in screen (sign-in)
- confirming the address with a received code: use the verification code screen (verify-code)
- an access form in an existing screen: use the access form block (auth-form)
- States