Skip to content

Extrawest UI Kit is a set of reusable UI components, styles, and other assets you can use to construct the UI of your Flutter apps

License

Notifications You must be signed in to change notification settings

extrawest/extrawest_ui_kit_mobile

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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

 DateInput(
    labelText: 'Date of Birth',
    hintText: 'Date of Birth',
    onDatePicked: (date) {
      // log('Date picked: $date');
    },
  ),
   EWGenderCheckboxList(
      genderBlockTitle: 'Gender',
      onGenderChanged: (gender) {
        setState(() {
          selectedGender = gender;
        });
      },
      genderList: const ['Male', 'Female', 'Other', 'Prefer not to say'],
      selectedGender: selectedGender,
      isEnabled: true,
    ),
   EWAvatarWidget(
       onImagePicked: (List<XFile>? files) {},
       pickImageCameraText: 'Use Camera',
       pickImageGalleryText: 'Use Gallery',
   ),
EWAddressPicker.fiveLines(
   appBar: EWAppBar.medium(
     title: 'User Profile',
     isTitleCentered: false,
     leading: IconButton(
       icon: const Icon(Icons.arrow_back),
       onPressed: () {
         Navigator.pop(context);
       },
     ),
     titleStyle: Theme.of(context).textTheme.headlineSmall,
   ),
   controllerAddressLine1: address1Controller,
   hintTextAddressLine1: 'Address Line 1',
   labelTextAddressLine1: 'Address Line 1',
   prefixIconAddressLine1: const Icon(Icons.location_on),
   controllerAddressLine2: address2Controller,
   hintTextAddressLine2: 'Address Line 2',
   labelTextAddressLine2: 'Address Line 2',
   prefixIconAddressLine2: const Icon(Icons.location_on),
   controllerZipCode: zipCodeController,
   hintTextZipCode: 'Zip Code',
   labelTextZipCode: 'Zip Code',
   prefixIconZipCode: const Icon(Icons.local_post_office_sharp),
   controllerState: stateController,
   hintTextState: 'State ',
   labelTextState: 'State ',
   hintTextCountry: 'Country',
   labelTextCountry: 'Country',
   prefixIconCountry: const Icon(Icons.location_city_outlined),
   prefixIconState: const Icon(Icons.house_outlined),
   controllerCountry: countryController,
   addressLine1FocusNode: FocusNode(),
   addressLine2FocusNode: FocusNode(),
   zipCodeFocusNode: FocusNode(),
   stateFocusNode: FocusNode(),
   countryFocusNode: FocusNode(),
   isEnabled: true,
   readOnly: true,
 ),
  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

About

Extrawest UI Kit is a set of reusable UI components, styles, and other assets you can use to construct the UI of your Flutter apps

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published