Init core module

This commit is contained in:
dab246
2021-07-27 12:50:45 +07:00
committed by Dat H. Pham
parent e26927790b
commit 5b0a8f6fb2
30 changed files with 1029 additions and 0 deletions
+124
View File
@@ -0,0 +1,124 @@
# Miscellaneous
*.class
*.lock
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# Visual Studio Code related
.classpath
.project
.settings/
.vscode/
# Flutter repo-specific
/bin/cache/
/bin/mingit/
/dev/benchmarks/mega_gallery/
/dev/bots/.recipe_deps
/dev/bots/android_tools/
/dev/devicelab/ABresults*.json
/dev/docs/doc/
/dev/docs/flutter.docs.zip
/dev/docs/lib/
/dev/docs/pubspec.yaml
/dev/integration_tests/**/xcuserdata
/dev/integration_tests/**/Pods
/packages/flutter/coverage/
version
analysis_benchmark.json
# packages file containing multi-root paths
.packages.generated
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
**/generated_plugin_registrant.dart
.packages
.pub-cache/
.pub/
build/
flutter_*.png
linked_*.ds
unlinked.ds
unlinked_spec.ds
# Android related
**/android/.gradle
**/android/captures/
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
**/android/key.properties
*.jks
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/.last_build_id
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# macOS
**/macos/Flutter/GeneratedPluginRegistrant.swift
**/macos/Flutter/Flutter-Debug.xcconfig
**/macos/Flutter/Flutter-Release.xcconfig
**/macos/Flutter/Flutter-Profile.xcconfig
# Coverage
coverage/
# Symbols
app.*.symbols
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
!/dev/ci/**/Gemfile.lock
#generated file
*.g.dart
messages_all.dart
messages_en.dart
messages_fr.dart
messages_messages.dart
messages_ru.dart
messages_vi.dart
+10
View File
@@ -0,0 +1,10 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: d79295af24c3ed621c33713ecda14ad196fd9c31
channel: stable
project_type: module
+3
View File
@@ -0,0 +1,3 @@
# core
Core Module
+40
View File
@@ -0,0 +1,40 @@
library core;
// Extensions
export 'presentation/extensions/color_extension.dart';
export 'presentation/extensions/url_extension.dart';
// Utils
export 'presentation/utils/theme_utils.dart';
export 'presentation/utils/responsive_utils.dart';
export 'presentation/utils/keyboard_utils.dart';
export 'presentation/utils/style_utils.dart';
export 'presentation/extensions/list_extensions.dart';
// Views
export 'presentation/views/text/slogan_builder.dart';
export 'presentation/views/text/text_field_builder.dart';
export 'presentation/views/text/input_decoration_builder.dart';
export 'presentation/views/text/text_builder.dart';
export 'presentation/views/responsive/responsive_widget.dart';
export 'presentation/views/list/tree_view.dart';
// Resources
export 'presentation/resources/assets_paths.dart';
export 'presentation/resources/image_paths.dart';
// Constants
export 'presentation/constants/constants_ui.dart';
export 'data/constants/constant.dart';
// Network
export 'data/network/config/authorization_interceptors.dart';
export 'data/network/config/dynamic_url_interceptors.dart';
export 'data/network/config/endpoint.dart';
export 'data/network/config/service_path.dart';
export 'data/network/dio_client.dart';
// State
export 'presentation/state/success.dart';
export 'presentation/state/failure.dart';
export 'presentation/state/app_state.dart';
+7
View File
@@ -0,0 +1,7 @@
class Constant {
static const userId = '_id';
static const firstName = 'firstname';
static const lastName = 'lastname';
static const acceptHeaderDefault = 'application/json';
static const contentTypeHeaderDefault = 'application/json';
}
@@ -0,0 +1,19 @@
import 'dart:convert';
import 'package:dio/dio.dart';
class AuthorizationInterceptors extends InterceptorsWrapper {
String? _authorization;
void changeAuthorization(String? userName, String? password) {
_authorization = base64Encode(utf8.encode('$userName:$password'));
}
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (_authorization != null) {
options.headers['Authorization'] = 'Basic $_authorization';
}
super.onRequest(options, handler);
}
}
@@ -0,0 +1,17 @@
import 'package:dio/dio.dart';
class DynamicUrlInterceptors extends InterceptorsWrapper {
String? _baseUrl;
void changeBaseUrl(String? url) {
_baseUrl = url;
}
@override
void onRequest(RequestOptions options, RequestInterceptorHandler handler) {
if (_baseUrl != null) {
options.baseUrl = _baseUrl!;
}
super.onRequest(options, handler);
}
}
@@ -0,0 +1,5 @@
import 'package:core/data/network/config/service_path.dart';
class Endpoint {
static final ServicePath authentication = ServicePath('/api/login');
}
@@ -0,0 +1,19 @@
class ServicePath {
final String path;
ServicePath(this.path);
}
extension ServicePathExtension on ServicePath {
String generateEndpointPath() {
return '$path';
}
String generateAuthenticationUrl(Uri? baseUrl) {
if (baseUrl == null) {
return generateEndpointPath();
} else {
return baseUrl.origin + generateEndpointPath();
}
}
}
+84
View File
@@ -0,0 +1,84 @@
import 'package:dio/dio.dart';
class DioClient {
final Dio _dio;
DioClient(this._dio);
Map<String, dynamic> getHeaders() => Map.from(_dio.options.headers);
Future<dynamic> get(
String path, {
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onReceiveProgress,
}) async {
return await _dio.get(
path,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
onReceiveProgress: onReceiveProgress)
.then((value) => value.data)
.catchError((error) => throw error);
}
Future<dynamic> post(
String path, {
data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress,
}) async {
return await _dio.post(path,
data: data,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress)
.then((value) => value.data)
.catchError((error) => throw error);
}
Future<dynamic> delete(
String path, {
data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
}) async {
return await _dio.delete(
path,
data: data,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken)
.then((value) => value.data)
.catchError((error) => throw(error));
}
Future<dynamic> put(
String path, {
data,
Map<String, dynamic>? queryParameters,
Options? options,
CancelToken? cancelToken,
ProgressCallback? onSendProgress,
ProgressCallback? onReceiveProgress
}) async {
return await _dio.put(
path,
data: data,
queryParameters: queryParameters,
options: options,
cancelToken: cancelToken,
onSendProgress: onSendProgress,
onReceiveProgress: onReceiveProgress)
.then((value) => value.data)
.catchError((error) => throw(error));
}
}
@@ -0,0 +1,3 @@
class ConstantsUI {
static const fontApp = 'CircularStd';
}
@@ -0,0 +1,36 @@
import 'dart:ui' show Color;
import 'package:flutter/material.dart';
extension AppColor on Color {
static const primaryColor = Color(0xFF837DFF);
static const primaryDarkColor = Color(0xFF1C1C1C);
static const primaryLightColor = Color(0xFFFFFFFF);
static const baseTextColor = Color(0xFF7E869B);
static const textFieldTextColor = Color(0xFF7E869B);
static const textFieldLabelColor = Color(0xFF7E869B);
static const textFieldHintColor = Color(0xFF757575);
static const textFieldBorderColor = Color(0xfff2f1fd);
static const textFieldFocusedBorderColor = Color(0xFF837DFF);
static const textFieldErrorBorderColor = Color(0xffFF5858);
static const buttonColor = Color(0xFF837DFF);
static const appColor = Color(0xFF3840F7);
static const nameUserColor = Color(0xFF182952);
static const emailUserColor = Color(0xFF7E869B);
static const userInformationBackgroundColor = Color(0xFFF5F5F7);
static const searchBorderColor = Color(0xFFEAEAEA);
static const searchHintTextColor = Color(0xFF7E869B);
static const mailboxSelectedBackgroundColor = Color(0xFFE6E5FF);
static const mailboxBackgroundColor = Color(0xFFFFFFFF);
static const mailboxSelectedTextColor = Color(0xFF3840F7);
static const mailboxTextColor = Color(0xFF182952);
static const mailboxSelectedTextNumberColor = Color(0xFF182952);
static const mailboxTextNumberColor = Color(0xFF837DFF);
static const mailboxSelectedIconColor = Color(0xFF3840F7);
static const mailboxIconColor = Color(0xFF7E869B);
static const storageBackgroundColor = Color(0xFFF5F5F7);
static const storageTitleColor = Color(0xFF7E869B);
static const storageMaxSizeColor = Color(0xFF101D43);
static const storageUseSizeColor = Color(0xFF2D0CFF);
static const myFolderTitleColor = Color(0xFF7E869B);
}
@@ -0,0 +1,19 @@
import 'package:built_collection/built_collection.dart';
import 'package:dartz/dartz.dart';
extension ListExtensions<T> on List<T> {
Tuple2<List<T>, List<T>> split(bool test(T element)) {
final validBuilder = ListBuilder<T>();
final invalidBuilder = ListBuilder<T>();
forEach((element) {
if (test(element)) {
validBuilder.add(element);
} else {
invalidBuilder.add(element);
}
});
return Tuple2(
validBuilder.build().toList(),
validBuilder.build().toList());
}
}
@@ -0,0 +1,16 @@
import 'package:flutter/foundation.dart';
extension URLExtension on String {
static final String prefixUrlHttps = 'https://';
static final String prefixUrlHttp = 'http://';
String formatURLValid() {
if (startsWith(prefixUrlHttps)) {
return this;
} else if (startsWith(prefixUrlHttp)) {
return kReleaseMode ? replaceAll(prefixUrlHttp, prefixUrlHttps) : this;
} else {
return '$prefixUrlHttps${this}';
}
}
}
@@ -0,0 +1,3 @@
class AssetsPaths {
static const images = 'assets/images/';
}
@@ -0,0 +1,23 @@
import 'package:core/presentation/resources/assets_paths.dart';
class ImagePaths {
String get icTMailLogo => _getImagePath('tmail_logo.svg');
String get icCloseMailbox => _getImagePath('ic_close.svg');
String get icSearch => _getImagePath('ic_search.svg');
String get icNextArrow => _getImagePath('ic_next_arrow.svg');
String get icMailboxInbox => _getImagePath('ic_mailbox_inbox.svg');
String get icMailboxTrash => _getImagePath('ic_mailbox_trash.svg');
String get icMailboxAllMail => _getImagePath('ic_mailbox_allmail.svg');
String get icMailboxDrafts => _getImagePath('ic_mailbox_draft.svg');
String get icMailboxSent => _getImagePath('ic_mailbox_sent.svg');
String get icMailboxSpam => _getImagePath('ic_mailbox_spam.svg');
String get icMailboxTemplate => _getImagePath('ic_mailbox_template.svg');
String get icMailboxFolder => _getImagePath('ic_mailbox_folder.svg');
String get icMailboxNewFolder => _getImagePath('ic_mailbox_new_folder.svg');
String get icFolderArrow => _getImagePath('ic_folder_arrow.svg');
String get icExpandFolder => _getImagePath('ic_expand_folder.svg');
String _getImagePath(String imageName) {
return AssetsPaths.images + imageName;
}
}
@@ -0,0 +1,14 @@
import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:meta/meta.dart';
import 'package:equatable/equatable.dart';
@immutable
abstract class AppState with EquatableMixin {
final Either<Failure, Success> viewState;
AppState(this.viewState);
@override
List<Object?> get props => [viewState];
}
+5
View File
@@ -0,0 +1,5 @@
import 'package:equatable/equatable.dart';
abstract class Failure extends Equatable {}
abstract class FeatureFailure extends Failure {}
+15
View File
@@ -0,0 +1,15 @@
import 'package:equatable/equatable.dart';
abstract class Success with EquatableMixin {}
abstract class ViewState extends Success {}
class UIState extends ViewState {
static final idle = UIState();
static final loading = UIState();
UIState() : super();
@override
List<Object?> get props => [];
}
@@ -0,0 +1,10 @@
import 'package:flutter/cupertino.dart';
class KeyboardUtils {
void hideKeyboard(BuildContext context) {
FocusScopeNode currentFocus = FocusScope.of(context);
if (!currentFocus.hasPrimaryFocus) {
currentFocus.unfocus();
}
}
}
@@ -0,0 +1,37 @@
import 'package:flutter/widgets.dart';
class ResponsiveUtils {
static const int _minLargeWidth = 950;
static const int _minMediumWidth = 600;
static const double _loginTextFieldWidthSmallScreen = 280.0;
static const double _loginTextFieldWidthLargeScreen = 320.0;
static const double _loginButtonWidth = 240.0;
double getSizeWidthScreen(BuildContext context) {
return MediaQuery.of(context).size.width;
}
double getSizeHeightScreen(BuildContext context) {
return MediaQuery.of(context).size.height;
}
bool isLargeScreen(BuildContext context) {
return getSizeWidthScreen(context) >= _minLargeWidth;
}
bool isSmallScreen(BuildContext context) {
return getSizeWidthScreen(context) < _minMediumWidth;
}
bool isMediumScreen(BuildContext context) {
return getSizeWidthScreen(context) >= _minMediumWidth && getSizeWidthScreen(context) < _minLargeWidth;
}
double getWidthLoginTextField(BuildContext context) => isSmallScreen(context)
? _loginTextFieldWidthSmallScreen
: _loginTextFieldWidthLargeScreen;
double getWidthLoginButton() => _loginButtonWidth;
}
@@ -0,0 +1,11 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
class CommonTextStyle {
static final textStyleNormal = TextStyle(
color: AppColor.primaryColor,
fontSize: 14,
fontStyle: FontStyle.normal,
fontWeight: FontWeight.normal,
);
}
@@ -0,0 +1,47 @@
import 'package:core/presentation/constants/constants_ui.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
ThemeData appTheme() {
return ThemeData(
scaffoldBackgroundColor: Colors.white,
fontFamily: ConstantsUI.fontApp,
appBarTheme: appBarTheme(),
textTheme: textTheme(),
visualDensity: VisualDensity.adaptivePlatformDensity,
);
}
InputDecorationTheme inputDecorationTheme() {
OutlineInputBorder outlineInputBorder = OutlineInputBorder(
borderRadius: BorderRadius.circular(28),
borderSide: BorderSide(color: AppColor.baseTextColor),
gapPadding: 10,
);
return InputDecorationTheme(
floatingLabelBehavior: FloatingLabelBehavior.always,
contentPadding: EdgeInsets.symmetric(horizontal: 42, vertical: 20),
enabledBorder: outlineInputBorder,
focusedBorder: outlineInputBorder,
border: outlineInputBorder,
);
}
TextTheme textTheme() {
return TextTheme(
bodyText1: TextStyle(color: AppColor.baseTextColor),
bodyText2: TextStyle(color: AppColor.baseTextColor),
);
}
AppBarTheme appBarTheme() {
return AppBarTheme(
color: Colors.white,
elevation: 0,
brightness: Brightness.light,
iconTheme: IconThemeData(color: Colors.black),
textTheme: TextTheme(
headline6: TextStyle(color: Color(0XFF8B8B8B), fontSize: 18),
),
);
}
@@ -0,0 +1,133 @@
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
class TreeView extends InheritedWidget {
final List<Widget> children;
final bool startExpanded;
TreeView({
Key? key,
required List<Widget> children,
bool startExpanded = false,
}) : this.children = children, this.startExpanded = startExpanded, super (
key: key,
child: _TreeViewData(
children: children,
),
);
static TreeView of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<TreeView>()!;
}
@override
bool updateShouldNotify(TreeView oldWidget) {
if (oldWidget.children == this.children &&
oldWidget.startExpanded == this.startExpanded) {
return false;
}
return true;
}
}
class _TreeViewData extends StatelessWidget {
final List<Widget> children;
const _TreeViewData({
required this.children,
});
@override
Widget build(BuildContext context) {
return ListView.builder(
shrinkWrap: true,
primary: false,
itemCount: children.length,
itemBuilder: (context, index) {
return children.elementAt(index);
},
);
}
}
class TreeViewChild extends StatefulWidget {
final bool? startExpanded;
final Widget parent;
final List<Widget> children;
final VoidCallback? onTap;
TreeViewChild({
required this.parent,
required this.children,
this.startExpanded,
this.onTap,
Key? key,
}) : super(key: key);
@override
TreeViewChildState createState() => TreeViewChildState();
TreeViewChild copyWith(
TreeViewChild source, {
bool? startExpanded,
Widget? parent,
List<Widget>? children,
VoidCallback? onTap,
}) {
return TreeViewChild(
parent: parent ?? source.parent,
children: children ?? source.children,
startExpanded: startExpanded ?? source.startExpanded,
onTap: onTap ?? source.onTap,
);
}
}
class TreeViewChildState extends State<TreeViewChild> {
bool? isExpanded;
@override
void initState() {
super.initState();
isExpanded = widget.startExpanded;
}
@override
void didChangeDependencies() {
isExpanded = widget.startExpanded ?? TreeView.of(context).startExpanded;
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
GestureDetector(
child: widget.parent,
onTap: () {
if (widget.onTap != null) {
widget.onTap!();
}
toggleExpanded();
},
),
AnimatedContainer(
duration: Duration(milliseconds: 400),
child: isExpanded!
? Column(
mainAxisSize: MainAxisSize.min,
children: widget.children,
)
: Offstage(),
),
],
);
}
void toggleExpanded() {
setState(() {
this.isExpanded = !this.isExpanded!;
});
}
}
@@ -0,0 +1,31 @@
import 'package:core/presentation/utils/responsive_utils.dart';
import 'package:flutter/material.dart';
class ResponsiveWidget extends StatelessWidget {
final Widget? largeScreen;
final Widget mediumScreen;
final Widget? smallScreen;
final ResponsiveUtils responsiveUtils;
const ResponsiveWidget({
Key? key,
this.largeScreen,
required this.mediumScreen,
this.smallScreen,
required this.responsiveUtils,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return LayoutBuilder(builder: (context, constraints) {
if (responsiveUtils.isLargeScreen(context)) {
return largeScreen ?? mediumScreen;
} else if (responsiveUtils.isMediumScreen(context)) {
return mediumScreen;
} else {
return smallScreen ?? mediumScreen;
}
});
}
}
@@ -0,0 +1,57 @@
import 'package:flutter/material.dart';
abstract class InputDecorationBuilder {
String? prefixText;
String? labelText;
TextStyle? labelStyle;
String? hintText;
TextStyle? hintStyle;
EdgeInsets? contentPadding;
OutlineInputBorder? enabledBorder;
InputDecorationBuilder setPrefixText(String newPrefixText) {
prefixText = newPrefixText;
return this;
}
InputDecorationBuilder setLabelText(String newLabelText) {
labelText = newLabelText;
return this;
}
InputDecorationBuilder setLabelStyle(TextStyle newLabelStyle) {
labelStyle = newLabelStyle;
return this;
}
InputDecorationBuilder setHintText(String newHintText) {
hintText = newHintText;
return this;
}
InputDecorationBuilder setHintStyle(TextStyle newHintStyle) {
hintStyle = newHintStyle;
return this;
}
InputDecorationBuilder setContentPadding(EdgeInsets newContentPadding) {
contentPadding = newContentPadding;
return this;
}
InputDecorationBuilder setEnabledBorder(OutlineInputBorder newEnabledBorder) {
enabledBorder = newEnabledBorder;
return this;
}
InputDecoration build() {
return InputDecoration(
prefixText: prefixText,
labelText: labelText,
labelStyle: labelStyle,
hintText: hintText,
hintStyle: hintStyle,
contentPadding: contentPadding,
enabledBorder: enabledBorder);
}
}
@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
/// A builder which builds a reusable slogan widget.
/// This contains the logo and the slogan text.
/// The elements are arranged in a column.
class SloganBuilder {
Key? _key;
String? _text;
TextStyle? _textStyle;
TextAlign? _textAlign;
String? _logo;
SloganBuilder key(Key key) {
_key = key;
return this;
}
SloganBuilder setSloganText(String text) {
_text = text;
return this;
}
SloganBuilder setSloganTextStyle(TextStyle textStyle) {
_textStyle = textStyle;
return this;
}
SloganBuilder setSloganTextAlign(TextAlign textAlign) {
_textAlign = textAlign;
return this;
}
SloganBuilder setLogo(String logo) {
_logo = logo;
return this;
}
Widget build() {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
_logo != null ? SvgPicture.asset(_logo!, width: 150, height: 150) : SizedBox.shrink(),
Padding(
padding: EdgeInsets.only(top: 16, left: 16, right: 16),
child: Text(_text ?? '', key: _key, style: _textStyle, textAlign: _textAlign),
),
],
);
}
}
@@ -0,0 +1,40 @@
import 'package:core/presentation/utils/style_utils.dart';
import 'package:flutter/material.dart';
class TextBuilder {
String? _text;
TextStyle? _textStyle;
TextAlign? _textAlign;
Key? _key;
TextBuilder key(Key key) {
_key = key;
return this;
}
TextBuilder text(String text) {
_text = text;
return this;
}
TextBuilder textStyle(TextStyle textStyle) {
_textStyle = textStyle;
return this;
}
TextBuilder textAlign(TextAlign textAlign) {
_textAlign = textAlign;
return this;
}
Text build() {
return Text(_text ?? '', key: _key ?? Key('TextBuilder'), style: _textStyle ?? CommonTextStyle.textStyleNormal, textAlign: _textAlign ?? TextAlign.center);
}
}
class CenterTextBuilder extends TextBuilder {
@override
Text build() {
return Text(_text ?? '', key: _key ?? Key('TextBuilder'), style: _textStyle, textAlign: TextAlign.center);
}
}
@@ -0,0 +1,53 @@
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/material.dart';
class TextFieldBuilder {
Key? _key;
ValueChanged<String>? _onTextChange;
TextStyle? _textStyle;
TextInputAction? _textInputAction;
InputDecoration? _inputDecoration;
bool? _obscureText;
TextFieldBuilder key(Key key) {
_key = key;
return this;
}
TextFieldBuilder onChange(ValueChanged<String> onChange) {
_onTextChange = onChange;
return this;
}
TextFieldBuilder textStyle(TextStyle style) {
_textStyle = style;
return this;
}
TextFieldBuilder textInputAction(TextInputAction inputAction) {
_textInputAction = inputAction;
return this;
}
TextFieldBuilder textDecoration(InputDecoration inputDecoration) {
_inputDecoration = inputDecoration;
return this;
}
TextFieldBuilder obscureText(bool obscureText) {
_obscureText = obscureText;
return this;
}
TextField build() {
return TextField(
key: _key ?? Key('TextFieldBuilder'),
onChanged: _onTextChange,
cursorColor: AppColor.primaryColor,
textInputAction: _textInputAction,
decoration: _inputDecoration,
style: _textStyle ?? TextStyle(color: AppColor.textFieldTextColor),
obscureText: _obscureText ?? false,
);
}
}
+97
View File
@@ -0,0 +1,97 @@
name: core
description: Core Module
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
#
# This version is used _only_ for the Runner app, which is used if you just do
# a `flutter run` or a `flutter make-host-app-editable`. It has no impact
# on any other native host app that you embed your Flutter project into.
version: 1.0.0+1
environment:
sdk: ">=2.12.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
# flutter_svg
flutter_svg: 0.22.0
# Http client
dio: 4.0.0
# dartz
dartz: 0.10.0-nullsafety.2
# equatable
equatable: 2.0.3
built_collection: 5.1.0
dev_dependencies:
flutter_test:
sdk: flutter
build_runner: 2.0.5
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add Flutter specific assets to your application, add an assets section,
# like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add Flutter specific custom fonts to your application, add a fonts
# section here, in this "flutter" section. Each entry in this list should
# have a "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
# This section identifies your Flutter project as a module meant for
# embedding in a native host app. These identifiers should _not_ ordinarily
# be changed after generation - they are used to ensure that the tooling can
# maintain consistency when adding or modifying assets and plugins.
# They also do not have any bearing on your native host application's
# identifiers, which may be completely independent or the same as these.