Last updated:
0 purchases
extrawest ui kit
Extrawest UI Kit #
Flutter package that provides Extrawest UI Kit based on Material 3 UI components
DEMO #
Features #
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
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:
Using ready Layouts with specifying needed parameters(or use default ones)
Using components separately to your own goals.
Available Customizable Components: #
EWBaseButton
// FilledButton - factory constructor approach
EWBaseButton.filled(
onPressed: () {},
title: 'Sign In'
),
// OutlinedButton - passing parameter approach
EWBaseButton(
buttonType: Filled(),
onPressed: () {},
title : 'Sign In'
),
copied to clipboard
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'),
),
copied to clipboard
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;
},
),
copied to clipboard
Social Auth Provider buttons: Google, Apple, Facebook, X
// Use Social button
AppleButton(
showTitle: false,
onTap: () {
// add tap handler here
},
),
copied to clipboard
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),
),
copied to clipboard
You can also specify other default TextStyle parameters
Text(
'Sign In',
style: context.textStyle(
TextScale.titleLarge,
fontStyle: FontStyle.italic,
color: Colors.black,
),
),
copied to clipboard
Logo
Logo(
title: title,
asset: 'path/to/asset',
),
copied to clipboard
Available customizable layouts #
SignIn
CreateAccount
PasswordRecovery
EmailSent
CreateNewPassword
OTPEnterPhoneNumber
OTPVerification
TwoFactorAuth
SplashScreen
ErrorPage
NoInternetConnection
ContactUs
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'),
),
);
},
),
],
);
}
}
copied to clipboard
OTPEnterPhoneNumber
OTPEnterPhoneNumber(
controller: TextEditingController(),
logo: Image.asset('path/to/asset'),
onSendPressed: () {
// add logic here
},
);
copied to clipboard
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
},
);
copied to clipboard
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: () {},
);
copied to clipboard
Contact Us page
DateInput(
labelText: 'Date of Birth',
hintText: 'Date of Birth',
onDatePicked: (date) {
// log('Date picked: $date');
},
),
copied to clipboard
EWGenderCheckboxList(
genderBlockTitle: 'Gender',
onGenderChanged: (gender) {
setState(() {
selectedGender = gender;
});
},
genderList: const ['Male', 'Female', 'Other', 'Prefer not to say'],
selectedGender: selectedGender,
isEnabled: true,
),
copied to clipboard
EWAvatarWidget(
onImagePicked: (List<XFile>? files) {},
pickImageCameraText: 'Use Camera',
pickImageGalleryText: 'Use Gallery',
),
copied to clipboard
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,
),
copied to clipboard
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: '[email protected]',
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',
),
],
);
copied to clipboard
Feedback #
Please file Extrawest UI Kit specific issues, bugs, or feature requests in
our issue tracker.
Contributing #
Fork it!
Create your feature branch: git checkout -b new-cool-tip
Commit your changes: git commit -am 'Added new tip'
Push to the branch: git push origin new-cool-tip
Submit a pull request.
LICENSE #
BSD-3-Clause
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.