Extrawest UI Kit

Maintenance Maintaner Ask Me Anything ! License GitHub release Supported Platforms View DEMO

Flutter package that provides Extrawest UI Kit based on Material 3 UI components

DEMO

ui_kit_demo

Features

  1. Extawest UI Components based on Material 3
    • Buttons (Elevated, Filled, Text, Outlined, Icon)
    • Text Fields (Email, Password, Custom)
    • Texts widgets with different Material 3 styles
  2. Ready to use Layouts with ability to change components dynamically.
    • Sign In layout with components: Email, Password inputs, Password recovery section, etc.
    • Create Account layout with textfields validation
    • Password recovery: Send link to email, Open email, Create new password
    • OTP verification: Enter phone number, Enter OTP code
    • 2FA app
    • Splash screen with components: logo, title, background
    • Error page with components: logo, title, content, retry and back buttons
    • Contact Us sent page with components: logo, title, content, back button
    • No Internet connection page with components: logo, title, content, retry button
    • Terms of Conditions page with components: logo, title, content, back button

The advantage of these layouts is that they come with built-in components having default parameters, which also can be customized to fit the application's requirements.

Usage

There are 2 approaches you can use package's components:

  1. Using ready Layouts with specifying needed parameters(or use default ones)
  2. Using components separately to your own goals.

Available Customizable Components:

  1. EWBaseButton
// FilledButton - factory constructor approach
EWBaseButton.filled(
   onPressed: () {}, 
   title: 'Sign In'
),

// OutlinedButton - passing parameter approach
EWBaseButton(
   buttonType: Filled(),
    onPressed: () {},
   title : 'Sign In'
),

  1. EWBaseTextFormField
// Use base textfield with custom configuration
EWTextField(
  controller: controller,
  autoValidateMode: AutovalidateMode.always,
  keyboardType: TextInputType.phone,
  prefixIcon: const Icon(Icons.add),
  errorText: 'Error',
  cursorColor: Colors.red,
  suffixIcon: const Text('Clear'),
),
  1. Inputs based on EWBaseTextFormField: EmailInput, PasswordInput
// Inputs
EmailInput(
    controller: emailController,
    hintText: 'Email Address'
    validator: (value) {
        if (value == null && value.isEmpty)
            return 'Invalid email';
        }
        return null;
    },
),
  1. Social Auth Provider buttons: Google, Apple, Facebook, X
// Use Social button
AppleButton(
   showTitle: false,
   onTap: () {
   // add tap handler here
   },
),
  1. Text widgets with various Material 3 scales (titleLarge, labelMedium, labelSmall etc) Access TextStyle from BuildContext context and pass TextScale as a positional argument
Text(
   'Sign In',
   style: context.textStyle(TextScale.titleLarge),
),

You can also specify other default TextStyle parameters

Text(
'Sign In',
   style: context.textStyle(
   TextScale.titleLarge,
   fontStyle: FontStyle.italic,
   color: Colors.black,
   ),
),
  1. Logo
Logo(
   title: title,
   asset: 'path/to/asset',
),

Available customizable layouts

  1. SignIn
  2. CreateAccount
  3. PasswordRecovery
  4. EmailSent
  5. CreateNewPassword
  6. OTPEnterPhoneNumber
  7. OTPVerification
  8. TwoFactorAuth
  9. SplashScreen
  10. ErrorPage
  11. NoInternetConnection
  12. ContactUs
  13. TermsOfConditions

Layout usage

SignIn

import 'package:extrawest_ui_kit/extrawest_ui_kit.dart';
import 'package:extrawest_ui_kit_app/common/screens/sign_up.dart';
import 'package:flutter/material.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({Key? key}) : super(key: key);

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  @override
  void dispose() {
    _emailController.dispose();
    _passwordController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SignIn(
      emailController: _emailController,
      passwordController: _passwordController,
      useSafeArea: true,
      authType: AuthType.emailPassword,
      title: 'Test',
      isSignUpEnabled: true,
      isResetPasswordEnabled: true,
      isGuestEnabled: true,
      onCreateAccountTap: () =>
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) => const SignUpScreen(),
            ),
          ),
      onSignInTap: () =>
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              duration: Duration(seconds: 2),
              content: Text('Sign In Attempt'),
            ),
          ),
      onSignInAsGuestTap: () =>
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              duration: Duration(seconds: 2),
              content: Text('Sign In as Guest Tap'),
            ),
          ),
      onPasswordRecoveryTap: () =>
          ScaffoldMessenger.of(context).showSnackBar(
            const SnackBar(
              duration: Duration(seconds: 2),
              content: Text('Password recovery'),
            ),
          ),
      socialAuthProviders: [
        SocialAuthProviderElement(
          socialAuthProvider: SocialAuthProvider.facebook,
          onTap: () {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                content: Text('Facebook login'),
              ),
            );
          },
        ),
        SocialAuthProviderElement(
          socialAuthProvider: SocialAuthProvider.google,
          onTap: () {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                content: Text('Google login'),
              ),
            );
          },
        ),
        SocialAuthProviderElement(
          socialAuthProvider: SocialAuthProvider.x,
          onTap: () {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                content: Text('X login'),
              ),
            );
          },
        ),
        SocialAuthProviderElement(
          socialAuthProvider: SocialAuthProvider.appleId,
          onTap: () {
            ScaffoldMessenger.of(context).showSnackBar(
              const SnackBar(
                content: Text('Apple login'),
              ),
            );
          },
        ),
      ],
    );
  }
}

OTPEnterPhoneNumber

  OTPEnterPhoneNumber(
      controller: TextEditingController(),
      logo: Image.asset('path/to/asset'),
      onSendPressed: () {
        // add logic here
      },
    );

ErrorPage

  ErrorPage(
      logo: Image.asset('path/to/asset'),
      title: 'Title',
      contentText: 'Enter content text here', // If not provided, default content will be used
      onRetryPressed: () {
      // add Retry button press handler here
      },
      onBackPressed: () {
      // add Retry button press handler here
      },
   );

No Internet Connection page

  NoInternetConnection(
      appBar: EWAppBar.medium(
        title: 'No Internet Connection',
        isTitleCentered: false,
        actions: [
          IconButton(
            icon: const Icon(Icons.search),
            onPressed: () {},
          ),
        ],
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        titleStyle: Theme.of(context).textTheme.headlineSmall,
      ),
      useSafeArea: true,
      logo: Image.asset(errorImg, package: 'extrawest_ui_kit'),
      contentText: 'Check your internet connection and try again',
      onBackPressed: () {},
      onRetryPressed: () {},
    );

Contact Us page

  ContactUs(
      appBar: EWAppBar.medium(
        title: 'Support',
        isTitleCentered: false,
        actions: [
          IconButton(
            icon: const Icon(Icons.search),
            onPressed: () {
              Navigator.pop(context);
            },
          ),
        ],
        leading: IconButton(
          icon: const Icon(Icons.arrow_back),
          onPressed: () {},
        ),
        titleStyle: Theme.of(context).textTheme.headlineSmall,
      ),
      showMissingMessengerError: true,
      sendMessageButtonText: 'Send message',
      chooseMessengerTitle: 'Choose your preferred messenger',
      changeMessengerButtonText: 'Change preferred messenger',
      onContactTypeChanged: (MessengerType messengerType) {},
      onContactItemTap: (ContactActionableSchema contactActionableSchema) {},
      sendMessageScreenAppbarTitle: 'Send us a message',
      sendMessageHintText: 'Your message',
      actionableContactListItems: [
        ContactActionableSchema(
          schemaType: SchemaType.tel,
          value: '00000000000',
          description: 'For calls in Ukraine (free)',
          iconData: Icons.phone,
        ),
        ContactActionableSchema(
          schemaType: SchemaType.email,
          value: 'some_mail@mail.com',
          description: 'For calls in Ukraine (free)',
          iconData: Icons.phone,
        ),
        ContactActionableSchema(
          schemaType: SchemaType.website,
          value: 'https://flutter.dev',
          description: 'For calls from other countries',
          iconData: Icons.phone,
        ),
      ],
      messengerProviders: const [
        MessengerTypeElement(
          recipient: 'Telegram_user_id',
          title: 'Telegram',
          messengerType: MessengerType.telegram,
        ),
        MessengerTypeElement(
          title: 'Viber',
          messengerType: MessengerType.viber,
        ),
        MessengerTypeElement(
          title: 'Facebook',
          messengerType: MessengerType.facebook,
          recipient: 'Facebook_id',
        ),
      ],
    );

Feedback

Please file Extrawest UI Kit specific issues, bugs, or feature requests in our issue tracker.

Contributing

  1. Fork it!
  2. Create your feature branch: git checkout -b new-cool-tip
  3. Commit your changes: git commit -am 'Added new tip'
  4. Push to the branch: git push origin new-cool-tip
  5. Submit a pull request.

LICENSE

BSD-3-Clause

Libraries

assets
components/messengers/contact_item_schema
components/messengers/ew_messenger_widget
components/messengers/messenger_element
components/sign_in/auth_type
components/sign_in/widgets/email_input
components/sign_in/widgets/password_input
components/sign_in/widgets/social_auth/apple_button
components/sign_in/widgets/social_auth/facebook_button
components/sign_in/widgets/social_auth/google_button
components/sign_in/widgets/social_auth/social_auth_button
components/sign_in/widgets/social_auth/social_auth_provider
components/sign_in/widgets/social_auth/social_button_body
components/sign_in/widgets/social_auth/x_button
components/sign_in/widgets/username_input
components/widgets/app_bars/ew_appbar
components/widgets/ew_base_button
components/widgets/ew_list_tile
components/widgets/ew_no_internet_widget
components/widgets/ew_snack_bar
components/widgets/ew_text_field
components/widgets/text_widgets/text_scales
components/widgets/tos_accepted_widget
consts
extrawest_ui_kit
layouts/contact_us/contact_us
layouts/contact_us/send_message_screen
layouts/create_account
layouts/enter_code
layouts/error_page
layouts/ew_terms_and_conditions
layouts/layout_wrapper
layouts/no_internet_connection
layouts/otp_verification/otp_enter_phone
layouts/otp_verification/otp_verification
layouts/password_recovery/create_new_password
layouts/password_recovery/email_sent
layouts/password_recovery/password_recovery
layouts/sign_in
layouts/splash_screen
layouts/two_factor_auth
theme
utils/conditional_import/webview/webview
utils/conditional_import/webview/webview_mobile
utils/conditional_import/webview/webview_web
utils/form_validation/create_account_form_state
utils/form_validation/email_validation
utils/form_validation/password_validation
utils/messanger_utils/open_messanger
utils/messanger_utils/utils