base_project

This commit is contained in:
2026-01-24 05:16:13 +00:00
commit 73ee588e7b
1349 changed files with 89007 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import '/widgets/custom_image_view.dart';
// ignore: must_be_immutable
class AppbarImage extends StatelessWidget {
AppbarImage(
{super.key, required this.height,
required this.width,
this.imagePath,
this.svgPath,
this.margin,
this.onTap});
double height;
double width;
String? imagePath;
String? svgPath;
EdgeInsetsGeometry? margin;
Function? onTap;
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {
onTap?.call();
},
child: Padding(
padding: margin ?? EdgeInsets.zero,
child: CustomImageView(
svgPath: svgPath,
imagePath: imagePath,
height: height,
width: width,
fit: BoxFit.contain,
),
),
);
}
}

View File

@@ -0,0 +1,36 @@
import 'package:flutter/material.dart';
import '../../core/app_export.dart';
import '../../utils/image_constant.dart';
import '../custom_icon_button.dart'; // ignore: must_be_immutable
// ignore_for_file: must_be_immutable
// ignore_for_file: must_be_immutable
class AppbarLeadingIconbutton extends StatelessWidget {
AppbarLeadingIconbutton({super.key, this.imagePath, this.margin, this.onTap});
String? imagePath;
EdgeInsetsGeometry? margin;
Function? onTap;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onTap?.call();
},
child: Padding(
padding: margin ?? EdgeInsets.zero,
child: CustomIconButton(
height: 32.adaptSize,
width: 32.adaptSize,
decoration: IconButtonStyleHelper.outlineIndigo,
child: CustomImageView(
imagePath: ImageConstant.imgArrowleft,
),
),
),
);
}
}

View File

@@ -0,0 +1,35 @@
import 'package:flutter/material.dart';
import '../../utils/color_constants.dart';
import '../../theme/app_style.dart';
// ignore: must_be_immutable
class AppbarTitle extends StatelessWidget {
AppbarTitle({super.key, required this.text, this.margin, this.onTap});
String text;
EdgeInsetsGeometry? margin;
Function? onTap;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () {
onTap?.call();
},
child: Padding(
padding: margin ?? EdgeInsets.zero,
child: Text(
text,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: AppStyle.txtGilroySemiBold24.copyWith(
color: ColorConstant.blueGray900,
),
),
),
);
}
}

View File

@@ -0,0 +1,56 @@
import 'package:flutter/material.dart';
import '../../utils/size_utils.dart';
// ignore: must_be_immutable
class CustomAppBar extends StatelessWidget implements PreferredSizeWidget {
CustomAppBar(
{super.key, required this.height,
this.leadingWidth,
this.leading,
this.title,
this.bottom,
this.flexibleSpace,
this.centerTitle,
this.actions});
double height;
double? leadingWidth;
Widget? leading;
Widget? title;
PreferredSize? flexibleSpace;
TabBar? bottom;
bool? centerTitle;
List<Widget>? actions;
@override
Widget build(BuildContext context) {
return AppBar(
elevation: 0,
toolbarHeight: height,
automaticallyImplyLeading: false,
backgroundColor: Colors.transparent,
leadingWidth: leadingWidth ?? 0,
leading: leading,
title: title,
bottom: bottom,
flexibleSpace: flexibleSpace,
titleSpacing: 0,
centerTitle: centerTitle ?? false,
actions: actions,
);
}
@override
Size get preferredSize => Size(
size.width,
height,
);
}

View File

@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
class BaseButton extends StatelessWidget {
const BaseButton(
{super.key,
required this.text,
this.onPressed,
this.buttonStyle,
this.buttonTextStyle,
this.isDisabled,
this.height,
this.width,
this.margin,
this.alignment});
final String text;
final VoidCallback? onPressed;
final ButtonStyle? buttonStyle;
final TextStyle? buttonTextStyle;
final bool? isDisabled;
final double? height;
final double? width;
final EdgeInsets? margin;
final Alignment? alignment;
@override
Widget build(BuildContext context) {
return const SizedBox.shrink();
}
}

View File

@@ -0,0 +1,92 @@
import 'package:flutter/material.dart';
import '../utils/size_utils.dart';
class customFloatingButton extends StatelessWidget {
const customFloatingButton({super.key,
this.shape,
this.variant,
this.alignment,
this.margin,
this.onTap,
this.width,
this.height,
this.child,
this.color,
});
final FloatingButtonShape? shape;
final FloatingButtonVariant? variant;
final Alignment? alignment;
final EdgeInsetsGeometry? margin;
final VoidCallback? onTap;
final double? width;
final double? height;
final Widget? child;
final Color? color;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildFabWidget(),
)
: _buildFabWidget();
}
Widget _buildFabWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: FloatingActionButton(
backgroundColor: _setColor(),
onPressed: onTap,
child: child,
),
);
}
BoxDecoration _buildDecoration() {
return BoxDecoration(
color: _setColor(),
borderRadius: _setBorderRadius(),
);
}
Color _setColor() {
if (color != null) {
return color!;
}
switch (variant) {
case FloatingButtonVariant.FillBlueA700:
return const Color(0xFF1976D2); // Example color for FillBlueA700
default:
return Colors.black;
}
}
BorderRadius _setBorderRadius() {
switch (shape) {
case FloatingButtonShape.RoundedBorder6:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
}
enum FloatingButtonShape {
RoundedBorder6,
}
enum FloatingButtonVariant {
FillBlueA700,
}

View File

@@ -0,0 +1,135 @@
import '/widgets/custom_image_view.dart';
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/image_constant.dart';
import '../utils/size_utils.dart';
class CustomBottomBar extends StatefulWidget {
CustomBottomBar({super.key, this.onChanged});
Function(BottomBarEnum)? onChanged;
@override
_CustomBottomBarState createState() => _CustomBottomBarState();
}
class _CustomBottomBarState extends State<CustomBottomBar> {
int selectedIndex = 0;
List<BottomMenuModel> bottomMenuList = [
BottomMenuModel(
icon: ImageConstant.imgFire,
type: BottomBarEnum.Fire,
),
BottomMenuModel(
icon: ImageConstant.imgSearchWhiteA70020x20,
type: BottomBarEnum.Searchwhitea70020x20,
),
BottomMenuModel(
icon: ImageConstant.imgMenu,
type: BottomBarEnum.Menu,
),
BottomMenuModel(
icon: ImageConstant.imgOverflowmenuWhiteA700,
type: BottomBarEnum.Overflowmenuwhitea700,
)
];
@override
Widget build(BuildContext context) {
return Container(
margin: getMargin(
left: 16,
right: 16,
),
decoration: BoxDecoration(
color: ColorConstant.blueA700,
borderRadius: BorderRadius.circular(
getHorizontalSize(
14,
),
),
),
child: BottomNavigationBar(
backgroundColor: Colors.transparent,
showSelectedLabels: false,
showUnselectedLabels: false,
elevation: 0,
currentIndex: selectedIndex,
type: BottomNavigationBarType.fixed,
items: List.generate(bottomMenuList.length, (index) {
return BottomNavigationBarItem(
icon: CustomImageView(
svgPath: bottomMenuList[index].icon,
height: getSize(
24,
),
width: getSize(
24,
),
color: ColorConstant.whiteA700,
),
activeIcon: CustomImageView(
svgPath: bottomMenuList[index].icon,
height: getSize(
24,
),
width: getSize(
24,
),
color: ColorConstant.whiteA700,
),
label: '',
);
}),
onTap: (index) {
selectedIndex = index;
widget.onChanged?.call(bottomMenuList[index].type);
setState(() {});
},
),
);
}
}
enum BottomBarEnum {
Fire,
Searchwhitea70020x20,
Menu,
Overflowmenuwhitea700,
}
class BottomMenuModel {
BottomMenuModel({required this.icon, required this.type});
String icon;
BottomBarEnum type;
}
class DefaultWidget extends StatelessWidget {
const DefaultWidget({super.key});
@override
Widget build(BuildContext context) {
return Container(
color: Colors.white,
padding: const EdgeInsets.all(10),
child: const Center(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Please replace the respective Widget here',
style: TextStyle(
fontSize: 18,
),
),
],
),
),
);
}
}

View File

@@ -0,0 +1,351 @@
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
class CustomButton extends StatelessWidget {
CustomButton(
{super.key, this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.margin,
this.onTap,
this.width,
this.height,
this.text,
this.prefixWidget,
this.suffixWidget});
ButtonShape? shape;
ButtonPadding? padding;
ButtonVariant? variant;
ButtonFontStyle? fontStyle;
Alignment? alignment;
EdgeInsetsGeometry? margin;
VoidCallback? onTap;
double? width;
double? height;
String? text;
Widget? prefixWidget;
Widget? suffixWidget;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment!,
child: _buildButtonWidget(),
)
: _buildButtonWidget();
}
_buildButtonWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: TextButton(
onPressed: onTap,
style: _buildTextButtonStyle(),
child: _buildButtonWithOrWithoutIcon(),
),
);
}
_buildButtonWithOrWithoutIcon() {
if (prefixWidget != null || suffixWidget != null) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
prefixWidget ?? const SizedBox(),
Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
),
suffixWidget ?? const SizedBox(),
],
);
} else {
return Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
);
}
}
_buildTextButtonStyle() {
return TextButton.styleFrom(
fixedSize: Size(
width ?? double.maxFinite,
height ?? getVerticalSize(40),
),
padding: _setPadding(),
backgroundColor: _setColor(),
side: _setTextButtonBorder(),
shape: RoundedRectangleBorder(
borderRadius: _setBorderRadius(),
),
);
}
_setPadding() {
switch (padding) {
case ButtonPadding.PaddingT14:
return getPadding(
top: 14,
right: 14,
bottom: 14,
);
case ButtonPadding.PaddingT7:
return getPadding(
top: 7,
right: 7,
bottom: 7,
);
case ButtonPadding.PaddingAll7:
return getPadding(
all: 7,
);
case ButtonPadding.PaddingAll3:
return getPadding(
all: 3,
);
default:
return getPadding(
all: 14,
);
}
}
_setColor() {
switch (variant) {
case ButtonVariant.FillBlue50:
return ColorConstant.blue50;
case ButtonVariant.FillDeeporangeA10033:
return ColorConstant.deepOrangeA10033;
case ButtonVariant.FillGray10001:
return ColorConstant.gray10001;
case ButtonVariant.FillLightblue100:
return ColorConstant.lightBlue100;
case ButtonVariant.FillRed200:
return ColorConstant.red200;
case ButtonVariant.FillGreenA100:
return ColorConstant.greenA100;
case ButtonVariant.FillBlueA200:
return ColorConstant.blueA200;
case ButtonVariant.FillBluegray50:
return ColorConstant.blueGray50;
case ButtonVariant.OutlineBlueA700:
return null;
default:
return ColorConstant.blueA700;
}
}
_setTextButtonBorder() {
switch (variant) {
case ButtonVariant.OutlineBlueA700:
return BorderSide(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1.00,
),
);
case ButtonVariant.FillBlueA700:
case ButtonVariant.FillBlue50:
case ButtonVariant.FillDeeporangeA10033:
case ButtonVariant.FillGray10001:
case ButtonVariant.FillLightblue100:
case ButtonVariant.FillRed200:
case ButtonVariant.FillGreenA100:
case ButtonVariant.FillBlueA200:
case ButtonVariant.FillBluegray50:
return null;
default:
return null;
}
}
_setBorderRadius() {
switch (shape) {
case ButtonShape.RoundedBorder2:
return BorderRadius.circular(
getHorizontalSize(
2.00,
),
);
case ButtonShape.RoundedBorder16:
return BorderRadius.circular(
getHorizontalSize(
16.00,
),
);
case ButtonShape.Square:
return BorderRadius.circular(0);
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setFontStyle() {
switch (fontStyle) {
case ButtonFontStyle.GilroyMedium14:
return TextStyle(
color: ColorConstant.blueA700,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium14WhiteA700:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium16Black900:
return TextStyle(
color: ColorConstant.black900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.SFUIDisplayBold12:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
12,
),
fontFamily: 'SF UI Display',
fontWeight: FontWeight.w700,
);
case ButtonFontStyle.GilroyMedium16BlueA700:
return TextStyle(
color: ColorConstant.blueA700,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium12:
return TextStyle(
color: ColorConstant.deepOrange400,
fontSize: getFontSize(
12,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.GilroyMedium12Red700:
return TextStyle(
color: ColorConstant.red700,
fontSize: getFontSize(
12,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.InterSemiBold10:
return TextStyle(
color: ColorConstant.black90001,
fontSize: getFontSize(
10,
),
fontFamily: 'Inter',
fontWeight: FontWeight.w600,
);
case ButtonFontStyle.RobotoMedium14:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
14,
),
fontFamily: 'Roboto',
fontWeight: FontWeight.w500,
);
case ButtonFontStyle.InterRegular14:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
14,
),
fontFamily: 'Inter',
fontWeight: FontWeight.w400,
);
default:
return TextStyle(
color: ColorConstant.whiteA700,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
}
enum ButtonShape {
Square,
RoundedBorder6,
RoundedBorder2,
RoundedBorder16,
}
enum ButtonPadding {
PaddingAll14,
PaddingT14,
PaddingT7,
PaddingAll7,
PaddingAll3,
}
enum ButtonVariant {
FillBlueA700,
OutlineBlueA700,
FillBlue50,
FillDeeporangeA10033,
FillGray10001,
FillLightblue100,
FillRed200,
FillGreenA100,
FillBlueA200,
FillBluegray50,
}
enum ButtonFontStyle {
GilroyMedium16,
GilroyMedium14,
GilroyMedium14WhiteA700,
GilroyMedium16Black900,
SFUIDisplayBold12,
GilroyMedium16BlueA700,
GilroyMedium12,
GilroyMedium12Red700,
InterSemiBold10,
RobotoMedium14,
InterRegular14,
}

View File

@@ -0,0 +1,147 @@
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
class CustomCheckbox extends StatelessWidget {
CustomCheckbox(
{super.key, this.fontStyle,
this.alignment,
this.isRightCheck = false,
this.iconSize,
this.value,
this.onChange,
this.text,
this.width,
this.margin});
CheckboxFontStyle? fontStyle;
Alignment? alignment;
bool? isRightCheck;
double? iconSize;
bool? value;
Function(bool)? onChange;
String? text;
double? width;
EdgeInsetsGeometry? margin;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildCheckboxWidget(),
)
: _buildCheckboxWidget();
}
_buildCheckboxWidget() {
return InkWell(
onTap: () {
value = !(value!);
onChange!(value!);
},
child: Container(
width: width,
margin: margin ?? EdgeInsets.zero,
child: isRightCheck! ? getRightSideCheckbox() : getLeftSideCheckbox(),
),
);
}
Widget getRightSideCheckbox() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
right: 8,
),
child: getTextWidget(),
),
getCheckboxWidget(),
],
);
}
Widget getLeftSideCheckbox() {
return Row(
children: [
getCheckboxWidget(),
Padding(
padding: const EdgeInsets.only(
left: 8,
),
child: getTextWidget(),
),
],
);
}
Widget getTextWidget() {
return Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
);
}
Widget getCheckboxWidget() {
return SizedBox(
height: iconSize,
width: iconSize,
child: Checkbox(
value: value ?? false,
onChanged: (value) {
onChange!(value!);
},
checkColor: ColorConstant.whiteA700,
visualDensity: const VisualDensity(
vertical: -4,
horizontal: -4,
),
),
);
}
_setFontStyle() {
switch (fontStyle) {
case CheckboxFontStyle.GilroyMedium16:
return TextStyle(
color: ColorConstant.blueGray900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case CheckboxFontStyle.GilroyMedium14:
return TextStyle(
color: ColorConstant.blueGray300,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
default:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
14,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400,
);
}
}
}
enum CheckboxFontStyle { GilroyRegular14, GilroyMedium16, GilroyMedium14 }

View File

@@ -0,0 +1,199 @@
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
class CustomDropDown extends StatelessWidget {
CustomDropDown(
{super.key, this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.width,
this.margin,
this.focusNode,
this.icon,
this.hintText,
this.prefix,
this.prefixConstraints,
this.items,
this.onChanged,
this.validator});
DropDownShape? shape;
DropDownPadding? padding;
DropDownVariant? variant;
DropDownFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
FocusNode? focusNode;
Widget? icon;
String? hintText;
Widget? prefix;
BoxConstraints? prefixConstraints;
List<String>? items;
Function(String)? onChanged;
FormFieldValidator<String>? validator;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildDropDownWidget(),
)
: _buildDropDownWidget();
}
_buildDropDownWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: DropdownButtonFormField(
focusNode: focusNode,
icon: icon,
style: _setFontStyle(),
decoration: _buildDecoration(),
items: items?.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(
value,
overflow: TextOverflow.ellipsis,
),
);
}).toList(),
onChanged: (value) {
onChanged!(value.toString());
},
validator: validator,
),
);
}
_buildDecoration() {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: _setFontStyle(),
border: _setBorderStyle(),
enabledBorder: _setBorderStyle(),
focusedBorder: _setBorderStyle(),
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
fillColor: _setFillColor(),
filled: _setFilled(),
isDense: true,
contentPadding: _setPadding(),
);
}
_setFontStyle() {
switch (fontStyle) {
case DropDownFontStyle.GilroyRegular16:
return TextStyle(
color: ColorConstant.blueGray200,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400,
);
default:
return TextStyle(
color: ColorConstant.blueGray900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w600,
);
}
}
_setOutlineBorderRadius() {
switch (shape) {
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setBorderStyle() {
switch (variant) {
case DropDownVariant.None:
return InputBorder.none;
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
case DropDownVariant.None:
return false;
default:
return true;
}
}
_setPadding() {
switch (padding) {
default:
return getPadding(
left: 10,
top: 10,
bottom: 10,
);
}
}
}
enum DropDownShape {
RoundedBorder6,
}
enum DropDownPadding {
PaddingT10,
}
enum DropDownVariant {
None,
OutlineBluegray100,
}
enum DropDownFontStyle {
GilroySemiBold16,
GilroyRegular16,
}

View File

@@ -0,0 +1,161 @@
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
import 'custom_text_form_field.dart';
class CustomDropdownFormField extends StatelessWidget {
CustomDropdownFormField({super.key,
this.shape,
this.padding,
this.initialValue,
this.variant,
this.fontStyle,
this.alignment,
this.width,
this.margin,
this.items,
this.value,
this.hintText,
this.onChanged,
this.validator,
this.onSaved,
});
TextFormFieldShape? shape;
TextFormFieldPadding? padding;
String? initialValue;
TextFormFieldVariant? variant;
TextFormFieldFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
List<DropdownMenuItem<String>>? items;
String? value;
String? hintText;
void Function(String?)? onChanged;
FormFieldValidator<String>? validator;
void Function(String?)? onSaved;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildDropdownFormFieldWidget(),
)
: _buildDropdownFormFieldWidget();
}
_buildDropdownFormFieldWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: DropdownButtonFormField<String>(
value: value,
items: items,
onChanged: onChanged,
validator: validator,
onSaved: onSaved,
decoration: _buildDecoration(),
),
);
}
_buildDecoration() {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: _setFontStyle(),
border: _setBorderStyle(),
enabledBorder: _setBorderStyle(),
focusedBorder: _setBorderStyle(),
fillColor: _setFillColor(),
filled: _setFilled(),
isDense: true,
contentPadding: _setPadding(),
);
}
_setFontStyle() {
switch (fontStyle) {
// Add cases for different font styles if needed
default:
return TextStyle(
color: ColorConstant.blueGray200,
fontSize: getFontSize(16),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
_setOutlineBorderRadius() {
switch (shape) {
case TextFormFieldShape.CircleBorder16:
return BorderRadius.circular(getHorizontalSize(16.00));
default:
return BorderRadius.circular(getHorizontalSize(6.00));
}
}
_setBorderStyle() {
switch (variant) {
case TextFormFieldVariant.FillBlue50:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide.none,
);
// Add cases for different variants if needed
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
case TextFormFieldVariant.FillBlue50:
return ColorConstant.blue50;
// Add cases for different variants if needed
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
case TextFormFieldVariant.FillBlue50:
return true;
// Add cases for different variants if needed
default:
return true;
}
}
_setPadding() {
switch (padding) {
case TextFormFieldPadding.PaddingAll11:
return getPadding(all: 11);
// Add cases for different paddings if needed
default:
return getPadding(all: 11);
}
}
}

View File

@@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
class CustomDropdownField<T> extends StatelessWidget {
final String? hintText;
final List<DropdownMenuItem<T>> items;
final T? value;
final void Function(T?)? onChanged;
final void Function(T?)? onSaved;
final String? Function(T?)? validator;
const CustomDropdownField(
{super.key, this.hintText,
required this.items,
this.value,
this.onChanged,
this.onSaved,
this.validator});
@override
Widget build(BuildContext context) {
return FormField<T>(
builder: (FormFieldState<T> state) {
return InputDecorator(
decoration: InputDecoration(
enabledBorder: InputBorder.none,
hintStyle: TextStyle(color: Colors.black.withOpacity(.4)),
contentPadding: const EdgeInsets.only(left: 10, right: 10, bottom: 6),
errorText: state.errorText,
),
child: DropdownButtonFormField<T>(
value: value,
items: items,
onChanged: (T? newValue) {
state.didChange(newValue);
if (onChanged != null) {
onChanged!(newValue);
}
},
onSaved: onSaved,
hint: Text(hintText ?? ''),
style: TextStyle(color: Colors.black.withOpacity(.8)),
//isExpanded: true,
validator: validator),
);
},
);
}
}

View File

@@ -0,0 +1,58 @@
// import 'package:flutter/material.dart';
// import '../core/app_export.dart';
// import 'base_button.dart';
// class CustomElevatedButton extends BaseButton {
// const CustomElevatedButton(
// {super.key, Key? key,
// this.decoration,
// this.leftIcon,
// this.rightIcon,
// super.margin,
// super.onPressed,
// super.buttonStyle,
// super.alignment,
// super.buttonTextStyle,
// super.isDisabled,
// super.height,
// super.width,
// required super.text});
// final BoxDecoration? decoration;
// final Widget? leftIcon;
// final Widget? rightIcon;
// @override
// Widget build(BuildContext context) {
// return alignment != null
// ? Align(
// alignment: alignment ?? Alignment.center,
// child: buildElevatedButtonWidget)
// : buildElevatedButtonWidget;
// }
// Widget get buildElevatedButtonWidget => Container(
// height: height ?? 41.v,
// width: width ?? double.maxFinite,
// margin: margin,
// decoration: decoration,
// child: ElevatedButton(
// style: buttonStyle,
// onPressed: isDisabled ?? false ? null : onPressed ?? () {},
// child: Row(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// leftIcon ?? const SizedBox.shrink(),
// Text(
// text,
// style: buttonTextStyle ?? CustomTextStyles.titleMediumWhiteA700,
// ),
// rightIcon ?? const SizedBox.shrink()
// ],
// ),
// ),
// );
// }

View File

@@ -0,0 +1,91 @@
import 'package:flutter/material.dart';
import '../utils/size_utils.dart';
class CustomFloatingButton extends StatelessWidget {
CustomFloatingButton(
{super.key, this.shape,
this.variant,
this.alignment,
this.margin,
this.onTap,
this.width,
this.height,
this.child});
FloatingButtonShape? shape;
FloatingButtonVariant? variant;
Alignment? alignment;
EdgeInsetsGeometry? margin;
VoidCallback? onTap;
double? width;
double? height;
Widget? child;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildFabWidget(),
)
: _buildFabWidget();
}
_buildFabWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: FloatingActionButton(
backgroundColor: _setColor(),
onPressed: onTap,
child: Container(
alignment: Alignment.center,
width: getSize(width ?? 0),
height: getSize(height ?? 0),
decoration: _buildDecoration(),
child: child,
),
),
);
}
_buildDecoration() {
return BoxDecoration(
color: _setColor(),
borderRadius: _setBorderRadius(),
);
}
_setColor() {
switch (variant) {
default:
return const Color.fromRGBO(253, 202, 101, 1.0);
}
}
_setBorderRadius() {
switch (shape) {
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
}
enum FloatingButtonShape {
RoundedBorder6,
}
enum FloatingButtonVariant {
FillBlueA700,
}

View File

@@ -0,0 +1,152 @@
import 'package:flutter/material.dart';
import '../core/app_export.dart';
class CustomFloatingTextField extends StatelessWidget {
const CustomFloatingTextField(
{super.key,
this.alignment,
this.width,
this.scrollPadding,
this.controller,
this.focusNode,
this.autofocus = false,
this.textStyle,
this.obscureText = false,
this.textInputAction = TextInputAction.next,
this.textInputType = TextInputType.text,
this.maxLines,
this.hintText,
this.hintStyle,
this.labelText,
this.labelStyle,
this.prefix,
this.prefixConstraints,
this.suffix,
this.suffixConstraints,
this.contentPadding,
this.borderDecoration,
this.fillColor,
this.filled = true,
this.validator});
final Alignment? alignment;
final double? width;
final TextEditingController? scrollPadding;
final TextEditingController? controller;
final FocusNode? focusNode;
final bool? autofocus;
final TextStyle? textStyle;
final bool? obscureText;
final TextInputAction? textInputAction;
final TextInputType? textInputType;
final int? maxLines;
final String? hintText;
final TextStyle? hintStyle;
final String? labelText;
final TextStyle? labelStyle;
final Widget? prefix;
final BoxConstraints? prefixConstraints;
final Widget? suffix;
final BoxConstraints? suffixConstraints;
final EdgeInsets? contentPadding;
final InputBorder? borderDecoration;
final Color? fillColor;
final bool? filled;
final FormFieldValidator<String>? validator;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: floatingTextFieldWidget(context))
: floatingTextFieldWidget(context);
}
Widget floatingTextFieldWidget(BuildContext context) => SizedBox(
width: width ?? double.maxFinite,
child: TextFormField(
scrollPadding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
controller: controller,
focusNode: focusNode,
onTapOutside: (event) {
if (focusNode != null) {
focusNode?.unfocus();
} else {
FocusManager.instance.primaryFocus?.unfocus();
}
},
autofocus: autofocus!,
style: textStyle ?? theme.textTheme.bodyMedium,
obscureText: obscureText!,
textInputAction: textInputAction,
keyboardType: textInputType,
maxLines: maxLines ?? 1,
decoration: decoration,
validator: validator,
),
);
InputDecoration get decoration => InputDecoration(
hintText: hintText ?? "",
hintStyle: hintStyle ?? theme.textTheme.bodyMedium,
labelText: labelText ?? "",
labelStyle: labelStyle,
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
isDense: true,
contentPadding:
contentPadding ?? EdgeInsets.fromLTRB(8.h, 24.v, 8.h, 8.v),
fillColor: fillColor ?? appTheme.gray50,
filled: filled,
border: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: theme.colorScheme.errorContainer,
width: 1,
),
),
enabledBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: theme.colorScheme.errorContainer,
width: 1,
),
),
focusedBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: theme.colorScheme.errorContainer,
width: 1,
),
),
);
}

View File

@@ -0,0 +1,398 @@
// ignore_for_file: constant_identifier_names
import 'package:base_project/core/app_export.dart';
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
extension IconButtonStyleHelper on CustomIconButton {
static BoxDecoration get fillErrorContainer => BoxDecoration(
color: theme.colorScheme.errorContainer,
);
static BoxDecoration get fillDeepOrangeA => BoxDecoration(
color: appTheme.deepOrangeA400,
borderRadius: BorderRadius.circular(26.h),
);
static BoxDecoration get fillLightBlue => BoxDecoration(
color: appTheme.lightBlue900,
borderRadius: BorderRadius.circular(4.h),
);
static BoxDecoration get fillBlue => BoxDecoration(
color: appTheme.blue400,
borderRadius: BorderRadius.circular(25.h),
);
static BoxDecoration get outlineIndigoTL12 => BoxDecoration(
color: appTheme.lightGreenA200,
borderRadius: BorderRadius.circular(12.h),
border: Border.all(
color: appTheme.indigo50,
width: 1.h,
),
);
static BoxDecoration get fillPrimaryContainer => BoxDecoration(
color: theme.colorScheme.primaryContainer,
);
static BoxDecoration get fillPrimary => BoxDecoration(
color: theme.colorScheme.primary,
borderRadius: BorderRadius.circular(16.h),
);
static BoxDecoration get outlineIndigo => BoxDecoration(
color: appTheme.lightGreenA200,
borderRadius: BorderRadius.circular(12.h),
border: Border.all(
color: appTheme.indigo50,
width: 1.h,
),
);
static BoxDecoration get fillBlueA => BoxDecoration(
color: appTheme.blueA20002,
);
static BoxDecoration get gradientLightGreenAToLightGreenA => BoxDecoration(
borderRadius: BorderRadius.circular(32.h),
gradient: LinearGradient(
begin: const Alignment(0.5, 0),
end: const Alignment(0.5, 1),
colors: [appTheme.lightGreenA20001, appTheme.lightGreenA20000],
),
);
}
class CustomIconButton extends StatelessWidget {
final EdgeInsetsGeometry? padding;
CustomIconButton({super.key,
this.shape,
this.padding,
this.variant,
this.alignment,
this.margin,
this.width,
this.height,
this.child,
this.onTap,
this.decoration,
this.padding_f,
});
// file===green color for all boottom bar
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTap,
child: Container(
height: height,
width: width,
padding: padding ?? EdgeInsets.zero,
decoration: decoration ??
BoxDecoration(
color: const Color.fromRGBO(253, 202, 101, 1.0),
borderRadius: BorderRadius.circular(
// Set borderRadius to half of the smallest dimension
width! < height! ? width! / 2 : height! / 2,
), // Adjust as needed
),
child: Center(child: child), // Ensure child is centered
),
);
}
// @override
// Widget build(BuildContext context) {
// return GestureDetector(
// onTap: onTap,
// child: Container(
// height: height,
// width: width,
// padding: padding ?? EdgeInsets.zero,
// decoration: decoration ??
// BoxDecoration(
// color: Colors.blue,
// borderRadius: BorderRadius.circular(16), // Adjust as needed
// ),
// child: Center(child: child), // Ensure child is centered
// ),
// );
// }
IconButtonShape? shape;
// IconButtonPadding? padding;
IconButtonVariant? variant;
Alignment? alignment;
EdgeInsetsGeometry? margin;
double? width;
double? height;
Widget? child;
VoidCallback? onTap;
final BoxDecoration? decoration;
final EdgeInsetsGeometry? padding_f;
// @override
// Widget build(BuildContext context) {
// return alignment != null
// ? Align(
// alignment: alignment ?? Alignment.center,
// child: _buildIconButtonWidget(),
// )
// : _buildIconButtonWidget();
// }
Widget get iconButtonWidget => SizedBox(
height: height ?? 0,
width: width ?? 0,
child: IconButton(
padding: EdgeInsets.zero,
icon: Container(
height: height ?? 0,
width: width ?? 0,
padding: padding_f ?? EdgeInsets.zero,
decoration: decoration ??
BoxDecoration(
color: appTheme.lightGreenA200,
borderRadius: BorderRadius.circular(25.h),
),
child: child,
),
onPressed: onTap,
),
);
_buildIconButtonWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: IconButton(
visualDensity: const VisualDensity(
vertical: -4,
horizontal: -4,
),
iconSize: getSize(height ?? 0),
padding: const EdgeInsets.all(0),
icon: Container(
alignment: Alignment.center,
width: getSize(width ?? 0),
height: getSize(height ?? 0),
padding: _setPadding(),
decoration: _buildDecoration(),
child: child,
),
onPressed: onTap,
),
);
}
_buildDecoration() {
return BoxDecoration(
color: _setColor(),
border: _setBorder(),
borderRadius: _setBorderRadius(),
boxShadow: _setBoxShadow(),
);
}
EdgeInsets _setPadding() {
if (padding == IconButtonPadding.PaddingAll4) {
return const EdgeInsets.all(4);
} else if (padding == IconButtonPadding.PaddingAll16) {
return const EdgeInsets.all(16);
} else if (padding == IconButtonPadding.PaddingAll8) {
return const EdgeInsets.all(8);
} else {
return const EdgeInsets.all(11);
}
}
// _setPadding() {
// switch (padding) {
// case IconButtonPadding.PaddingAll4:
// return getPadding(
// all: 4,
// );
// case IconButtonPadding.PaddingAll16:
// return getPadding(
// all: 16,
// );
// case IconButtonPadding.PaddingAll8:
// return getPadding(
// all: 8,
// );
// default:
// return getPadding(
// all: 11,
// );
// }
// }
_setColor() {
switch (variant) {
case IconButtonVariant.FillBlueA700:
return ColorConstant.blueA700;
case IconButtonVariant.OutlineGray80049:
return ColorConstant.whiteA700;
case IconButtonVariant.FillGray300:
return ColorConstant.gray300;
case IconButtonVariant.FillGray100:
return ColorConstant.gray100;
case IconButtonVariant.FillBlack90001:
return ColorConstant.black90001;
case IconButtonVariant.OutlineBluegray400:
return ColorConstant.whiteA700;
case IconButtonVariant.FillBlueA200:
return ColorConstant.blueA200;
case IconButtonVariant.OutlineBlueA700:
case IconButtonVariant.OutlineBlue50:
return null;
default:
return ColorConstant.blue50;
}
}
_setBorder() {
switch (variant) {
case IconButtonVariant.OutlineBlueA700:
return Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.OutlineGray80049:
return Border.all(
color: ColorConstant.gray80049,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.OutlineBlue50:
return Border.all(
color: ColorConstant.blue50,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.OutlineBluegray400:
return Border.all(
color: ColorConstant.blueGray400,
width: getHorizontalSize(
1.00,
),
);
case IconButtonVariant.FillBlue50:
case IconButtonVariant.FillBlueA700:
case IconButtonVariant.FillGray300:
case IconButtonVariant.FillGray100:
case IconButtonVariant.FillBlack90001:
case IconButtonVariant.FillBlueA200:
return null;
default:
return null;
}
}
_setBorderRadius() {
switch (shape) {
case IconButtonShape.CircleBorder15:
return BorderRadius.circular(
getHorizontalSize(
15.00,
),
);
case IconButtonShape.RoundedBorder26:
return BorderRadius.circular(
getHorizontalSize(
26.00,
),
);
case IconButtonShape.CircleBorder10:
return BorderRadius.circular(
getHorizontalSize(
10.00,
),
);
case IconButtonShape.CircleBorder30:
return BorderRadius.circular(
getHorizontalSize(
30.00,
),
);
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setBoxShadow() {
switch (variant) {
case IconButtonVariant.OutlineBlueA700:
return [
BoxShadow(
color: ColorConstant.indigoA20033,
spreadRadius: getHorizontalSize(
2.00,
),
blurRadius: getHorizontalSize(
2.00,
),
offset: const Offset(
0,
4,
),
),
];
case IconButtonVariant.FillBlue50:
case IconButtonVariant.FillBlueA700:
case IconButtonVariant.OutlineGray80049:
case IconButtonVariant.FillGray300:
case IconButtonVariant.FillGray100:
case IconButtonVariant.FillBlack90001:
case IconButtonVariant.OutlineBlue50:
case IconButtonVariant.OutlineBluegray400:
case IconButtonVariant.FillBlueA200:
return null;
default:
return null;
}
}
}
enum IconButtonShape {
RoundedBorder6,
CircleBorder15,
RoundedBorder26,
CircleBorder10,
CircleBorder30,
}
enum IconButtonPadding {
PaddingAll4,
PaddingAll16,
PaddingAll8,
PaddingAll11,
}
enum IconButtonVariant {
FillBlue50,
FillBlueA700,
OutlineBlueA700,
OutlineGray80049,
FillGray300,
FillGray100,
FillBlack90001,
OutlineBlue50,
OutlineBluegray400,
FillBlueA200,
}

View File

@@ -0,0 +1,60 @@
import 'package:flutter/material.dart';
import '../core/app_export.dart';
class CustomIconButton_f extends StatelessWidget {
const CustomIconButton_f(
{super.key,
this.alignment,
this.height,
this.width,
this.padding,
this.decoration,
this.child,
this.onTap});
final Alignment? alignment;
final double? height;
final double? width;
final EdgeInsetsGeometry? padding;
final BoxDecoration? decoration;
final Widget? child;
final VoidCallback? onTap;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center, child: iconButtonWidget)
: iconButtonWidget;
}
Widget get iconButtonWidget => SizedBox(
height: height ?? 0,
width: width ?? 0,
child: IconButton(
padding: EdgeInsets.zero,
icon: Container(
height: height ?? 0,
width: width ?? 0,
padding: padding ?? EdgeInsets.zero,
decoration: decoration ??
BoxDecoration(
color: appTheme.whiteA700,
borderRadius: BorderRadius.circular(12.h),
border: Border.all(
color: theme.colorScheme.onPrimaryContainer,
width: 1.h,
),
),
child: child,
),
onPressed: onTap,
),
);
}

View File

@@ -0,0 +1,154 @@
// ignore_for_file: must_be_immutable
import 'dart:io';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CustomImageView extends StatelessWidget {
///[url] is required parameter for fetching network image
String? url;
///[imagePath] is required parameter for showing png,jpg,etc image
String? imagePath;
///[svgPath] is required parameter for showing svg image
String? svgPath;
///[file] is required parameter for fetching image file
File? file;
double? height;
double? width;
Color? color;
BoxFit? fit;
final String placeHolder;
Alignment? alignment;
VoidCallback? onTap;
EdgeInsetsGeometry? margin;
BorderRadius? radius;
BoxBorder? border;
///a [CustomImageView] it can be used for showing any type of images
/// it will shows the placeholder image if image is not found on network image
CustomImageView({
super.key,
this.url,
this.imagePath,
this.svgPath,
this.file,
this.height,
this.width,
this.color,
this.fit,
this.alignment,
this.onTap,
this.radius,
this.margin,
this.border,
this.placeHolder = 'assets/images/image_not_found.png',
});
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment!,
child: _buildWidget(),
)
: _buildWidget();
}
Widget _buildWidget() {
return Padding(
padding: margin ?? EdgeInsets.zero,
child: InkWell(
onTap: onTap,
child: _buildCircleImage(),
),
);
}
///build the image with border radius
_buildCircleImage() {
if (radius != null) {
return ClipRRect(
borderRadius: radius ?? BorderRadius.zero,
child: _buildImageWithBorder(),
);
} else {
return _buildImageWithBorder();
}
}
///build the image with border and border radius style
_buildImageWithBorder() {
if (border != null) {
return Container(
decoration: BoxDecoration(
border: border,
borderRadius: radius,
),
child: _buildImageView(),
);
} else {
return _buildImageView();
}
}
Widget _buildImageView() {
if (svgPath != null && svgPath!.isNotEmpty) {
return SizedBox(
height: height,
width: width,
child: SvgPicture.asset(
svgPath!,
height: height,
width: width,
fit: fit ?? BoxFit.contain,
color: color,
),
);
} else if (file != null && file!.path.isNotEmpty) {
return Image.file(
file!,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
color: color,
);
} else if (url != null && url!.isNotEmpty) {
return CachedNetworkImage(
height: height,
width: width,
fit: fit,
imageUrl: url!,
color: color,
placeholder: (context, url) => SizedBox(
height: 30,
width: 30,
child: LinearProgressIndicator(
color: Colors.grey.shade200,
backgroundColor: Colors.grey.shade100,
),
),
errorWidget: (context, url, error) => Image.asset(
placeHolder,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
),
);
} else if (imagePath != null && imagePath!.isNotEmpty) {
return Image.asset(
imagePath!,
height: height,
width: width,
fit: fit ?? BoxFit.cover,
color: color,
);
}
return const SizedBox();
}
}

View File

@@ -0,0 +1,96 @@
import 'package:base_project/utils/image_constant.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class ShowSnackAlert {
static SnackBar CustomMessenger(
BuildContext context, Color color1, Color color2, String text) {
return SnackBar(
elevation: 0,
behavior: SnackBarBehavior.floating,
content: Stack(
clipBehavior: Clip.none,
children: [
Container(
padding: const EdgeInsets.all(16),
height: 100,
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(20)),
color: color1),
child: Row(
children: [
const SizedBox(
width: 48,
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (color1 == Colors.red.shade400)
const Text(
'Oh Snap!',
style: TextStyle(fontSize: 18, color: Colors.white),
),
if (color1 == Colors.orange.shade400)
const Text('Alert',
style:
TextStyle(fontSize: 18, color: Colors.white)),
if (color1 == Colors.green.shade600)
const Text('Success',
style:
TextStyle(fontSize: 18, color: Colors.white)),
Text(
text,
style: const TextStyle(
fontSize: 12, color: Colors.white),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
],
),
),
],
)),
Positioned(
bottom: 0,
child: ClipRRect(
borderRadius:
const BorderRadius.only(bottomLeft: Radius.circular(20)),
child: SvgPicture.asset(ImageConstant.bubbles,
// 'assets/icon/bubbles.svg',
height: 48,
width: 40,
colorFilter: ColorFilter.mode(color2, BlendMode.srcIn)),
),
),
Positioned(
top: -20,
left: 0,
child: Stack(
alignment: Alignment.center,
children: [
SvgPicture.asset(
ImageConstant.fail,
// 'assets/icon/fail.svg',
height: 40,
),
Positioned(
top: 10,
child: InkWell(
onTap: () {
ScaffoldMessenger.of(context).clearSnackBars();
},
child: SvgPicture.asset(ImageConstant.close,
// 'assets/icon/close.svg',
height: 16)))
],
),
)
],
),
backgroundColor: Colors.transparent,
);
}
}

View File

@@ -0,0 +1,61 @@
// import 'package:flutter/material.dart';
// import '../core/app_export.dart';
// import 'base_button.dart';
// class CustomOutlinedButton extends BaseButton {
// const CustomOutlinedButton(
// {super.key, Key? key,
// this.decoration,
// this.leftIcon,
// this.rightIcon,
// this.label,
// super.onPressed,
// super.buttonStyle,
// super.buttonTextStyle,
// super.isDisabled,
// super.alignment,
// super.height,
// super.width,
// super.margin,
// required super.text});
// final BoxDecoration? decoration;
// final Widget? leftIcon;
// final Widget? rightIcon;
// final Widget? label;
// @override
// Widget build(BuildContext context) {
// return alignment != null
// ? Align(
// alignment: alignment ?? Alignment.center,
// child: buildOutlinedButtonWidget)
// : buildOutlinedButtonWidget;
// }
// Widget get buildOutlinedButtonWidget => Container(
// height: height ?? 56.v,
// width: width ?? double.maxFinite,
// margin: margin,
// decoration: decoration,
// child: OutlinedButton(
// style: buttonStyle,
// onPressed: isDisabled ?? false ? null : onPressed ?? () {},
// child: Row(
// mainAxisAlignment: MainAxisAlignment.center,
// crossAxisAlignment: CrossAxisAlignment.center,
// children: [
// leftIcon ?? const SizedBox.shrink(),
// Text(
// text,
// style: buttonTextStyle ?? theme.textTheme.headlineLarge,
// ),
// rightIcon ?? const SizedBox.shrink()
// ],
// ),
// ),
// );
// }

View File

@@ -0,0 +1,258 @@
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
class CustomRadioButton extends StatelessWidget {
CustomRadioButton(
{super.key, this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.onChange,
this.isRightCheck = false,
this.iconSize,
this.value,
this.groupValue,
this.text,
this.width,
this.margin});
RadioShape? shape;
RadioPadding? padding;
RadioVariant? variant;
RadioFontStyle? fontStyle;
Alignment? alignment;
Function(String)? onChange;
bool? isRightCheck;
double? iconSize;
String? value;
String? groupValue;
String? text;
double? width;
EdgeInsetsGeometry? margin;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildRadioButtonWidget(),
)
: _buildRadioButtonWidget();
}
_buildRadioButtonWidget() {
return InkWell(
onTap: () {
onChange!(value!);
},
child: Container(
width: width,
margin: margin ?? EdgeInsets.zero,
padding: _setPadding(),
decoration: _buildDecoration(),
child: isRightCheck! ? getRightSideRadio() : getLeftSideRadio(),
),
);
}
_buildDecoration() {
return BoxDecoration(
color: _setColor(),
border: _setBorder(),
borderRadius: _setBorderRadius(),
);
}
Widget getRightSideRadio() {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Padding(
padding: const EdgeInsets.only(
right: 8,
),
child: getTextWidget(),
),
getRadioWidget(),
],
);
}
Widget getLeftSideRadio() {
return Row(
children: [
getRadioWidget(),
Padding(
padding: const EdgeInsets.only(
left: 8,
),
child: getTextWidget(),
),
],
);
}
Widget getTextWidget() {
return Text(
text ?? "",
textAlign: TextAlign.center,
style: _setFontStyle(),
);
}
Widget getRadioWidget() {
return SizedBox(
height: iconSize,
width: iconSize,
child: Radio<String>(
value: value ?? "",
groupValue: groupValue,
activeColor: ColorConstant.whiteA700,
onChanged: (value) {
onChange!(value!);
},
visualDensity: const VisualDensity(
vertical: -4,
horizontal: -4,
),
),
);
}
_setFontStyle() {
switch (fontStyle) {
case RadioFontStyle.GilroyMedium16:
return TextStyle(
color: ColorConstant.blueA700,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case RadioFontStyle.GilroyMedium18:
return TextStyle(
color: ColorConstant.blueGray300,
fontSize: getFontSize(
18,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
case RadioFontStyle.GilroyRegular16:
return TextStyle(
color: ColorConstant.blueGray900,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w400,
);
default:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
_setPadding() {
switch (padding) {
case RadioPadding.PaddingAll11:
return getPadding(
all: 11,
);
case RadioPadding.PaddingT1:
return getPadding(
top: 1,
bottom: 1,
);
default:
return null;
}
}
_setColor() {
switch (variant) {
case RadioVariant.OutlineBluegray400:
return ColorConstant.whiteA700;
case RadioVariant.OutlineBlueA700:
return ColorConstant.whiteA700;
default:
return null;
}
}
_setBorder() {
switch (variant) {
case RadioVariant.OutlineBluegray400:
return Border.all(
color: ColorConstant.blueGray400,
width: getHorizontalSize(
1.00,
),
);
case RadioVariant.OutlineBlueA700:
return Border.all(
color: ColorConstant.blueA700,
width: getHorizontalSize(
1.00,
),
);
default:
return null;
}
}
_setBorderRadius() {
switch (shape) {
case RadioShape.RoundedBorder6:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
default:
return null;
}
}
}
enum RadioShape {
RoundedBorder6,
}
enum RadioPadding {
PaddingAll11,
PaddingT1,
}
enum RadioVariant {
OutlineBluegray400,
OutlineBlueA700,
}
enum RadioFontStyle {
GilroyMedium16Bluegray400,
GilroyMedium16,
GilroyMedium18,
GilroyRegular16,
}

View File

@@ -0,0 +1,202 @@
import 'package:flutter/material.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
class CustomSearchView extends StatelessWidget {
CustomSearchView(
{super.key, this.shape,
this.padding,
this.variant,
this.fontStyle,
this.alignment,
this.width,
this.margin,
this.controller,
this.focusNode,
this.hintText,
this.prefix,
this.prefixConstraints,
this.suffix,
this.suffixConstraints});
SearchViewShape? shape;
SearchViewPadding? padding;
SearchViewVariant? variant;
SearchViewFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
TextEditingController? controller;
FocusNode? focusNode;
String? hintText;
Widget? prefix;
BoxConstraints? prefixConstraints;
Widget? suffix;
BoxConstraints? suffixConstraints;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildSearchViewWidget(),
)
: _buildSearchViewWidget();
}
_buildSearchViewWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: TextFormField(
controller: controller,
focusNode: focusNode,
style: _setFontStyle(),
decoration: _buildDecoration(),
),
);
}
_buildDecoration() {
return InputDecoration(
hintText: hintText ?? "",
hintStyle: _setFontStyle(),
border: _setBorderStyle(),
enabledBorder: _setBorderStyle(),
focusedBorder: _setBorderStyle(),
disabledBorder: _setBorderStyle(),
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
fillColor: _setFillColor(),
filled: _setFilled(),
isDense: true,
contentPadding: _setPadding(),
);
}
_setFontStyle() {
switch (fontStyle) {
case SearchViewFontStyle.GilroyMedium16Bluegray400:
return TextStyle(
color: ColorConstant.blueGray400,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
default:
return TextStyle(
color: ColorConstant.blueGray200,
fontSize: getFontSize(
16,
),
fontFamily: 'Gilroy',
fontWeight: FontWeight.w500,
);
}
}
_setOutlineBorderRadius() {
switch (shape) {
default:
return BorderRadius.circular(
getHorizontalSize(
6.00,
),
);
}
}
_setBorderStyle() {
switch (variant) {
case SearchViewVariant.OutlineBluegray200:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray200,
width: 1,
),
);
case SearchViewVariant.None:
return InputBorder.none;
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
case SearchViewVariant.OutlineBluegray200:
return ColorConstant.whiteA700;
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
case SearchViewVariant.None:
return false;
default:
return true;
}
}
_setPadding() {
switch (padding) {
case SearchViewPadding.PaddingT11:
return getPadding(
top: 11,
right: 11,
bottom: 11,
);
default:
return getPadding(
top: 12,
bottom: 12,
);
}
}
}
enum SearchViewShape {
RoundedBorder6,
}
enum SearchViewPadding {
PaddingT11,
PaddingT12,
}
enum SearchViewVariant {
None,
OutlineBluegray100,
OutlineBluegray200,
}
enum SearchViewFontStyle {
GilroyMedium16,
GilroyMedium16Bluegray400,
}

View File

@@ -0,0 +1,49 @@
// import 'package:flutter/material.dart';
// import 'package:flutter_switch/flutter_switch.dart';
// import '../Utils/color_constants.dart';
// import '../Utils/size_utils.dart';
// class CustomSwitch extends StatelessWidget {
// CustomSwitch({this.alignment, this.margin, this.value, this.onChanged});
// Alignment? alignment;
// EdgeInsetsGeometry? margin;
// bool? value;
// Function(bool)? onChanged;
// @override
// Widget build(BuildContext context) {
// return alignment != null
// ? Align(
// alignment: alignment ?? Alignment.center,
// child: _buildSwitchWidget(),
// )
// : _buildSwitchWidget();
// }
// _buildSwitchWidget() {
// return Padding(
// padding: margin ?? EdgeInsets.zero,
// child: FlutterSwitch(
// value: value ?? false,
// height: getHorizontalSize(25),
// width: getHorizontalSize(45),
// toggleSize: 25,
// borderRadius: getHorizontalSize(
// 12.00,
// ),
// activeColor: ColorConstant.blueA700,
// activeToggleColor: ColorConstant.gray50,
// inactiveColor: ColorConstant.blueGray50,
// inactiveToggleColor: ColorConstant.gray50,
// onToggle: (value) {
// onChanged!(value);
// },
// ),
// );
// }
// }

View File

@@ -0,0 +1,287 @@
import 'package:base_project/core/app_export.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../utils/color_constants.dart';
import '../utils/size_utils.dart';
extension TextFormFieldStyleHelper on CustomTextFormField {
static OutlineInputBorder get outlineLightGreenA => OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: appTheme.lightGreenA20001,
width: 1,
),
);
static OutlineInputBorder get outlineLimeA => OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: appTheme.limeA200,
width: 1,
),
);
static OutlineInputBorder get outlineYellow => OutlineInputBorder(
borderRadius: BorderRadius.circular(5.h),
);
static OutlineInputBorder get outlineLightGreenATL8 => OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: appTheme.lightGreenA20001,
width: 1,
),
);
static OutlineInputBorder get outlineCyan => OutlineInputBorder(
borderRadius: BorderRadius.circular(9.h),
borderSide: BorderSide(
color: appTheme.cyan900,
width: 1,
),
);
static OutlineInputBorder get outlineOnPrimaryContainer => OutlineInputBorder(
borderRadius: BorderRadius.circular(20.h),
borderSide: BorderSide(
color: theme.colorScheme.onPrimaryContainer,
width: 1,
),
);
static OutlineInputBorder get outlineOnPrimaryContainerTL8 =>
OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: theme.colorScheme.onPrimaryContainer,
width: 1,
),
);
}
class CustomTextFormField extends StatelessWidget {
TextFormFieldShape? shape;
TextFormFieldPadding? padding;
void Function(String?)? onsaved;
void Function(String)? onChanged;
void Function()? onTap;
String? initialValue;
bool? readOnly;
List<TextInputFormatter>? inputFormatters;
TextFormFieldVariant? variant;
TextFormFieldFontStyle? fontStyle;
Alignment? alignment;
double? width;
EdgeInsetsGeometry? margin;
TextEditingController? controller;
FocusNode? focusNode;
String? errorText;
bool? isObscureText;
TextInputAction? textInputAction;
TextInputType? textInputType;
int? maxLines;
int? maxLength; // Added this line
String? hintText;
Widget? prefix;
BoxConstraints? prefixConstraints;
Widget? suffix;
BoxConstraints? suffixConstraints;
FormFieldValidator<String>? validator;
TextInputType? keyboardType; // Add this line
final InputBorder? borderDecoration;
final TextStyle? hintStyle;
final EdgeInsets? contentPadding;
final Color? fillColor;
final bool? filled;
CustomTextFormField({super.key,
this.shape,
this.padding,
this.initialValue,
this.variant,
this.fontStyle,
this.readOnly,
this.alignment,
this.onChanged,
this.onTap,
this.width,
this.margin,
this.controller,
this.inputFormatters,
this.focusNode,
this.isObscureText = false,
this.textInputAction = TextInputAction.next,
this.textInputType,
this.maxLines,
this.maxLength, // Added this line
this.hintText,
this.prefix,
this.errorText,
this.onsaved,
this.prefixConstraints,
this.suffix,
this.suffixConstraints,
this.validator,
this.keyboardType, // Add this line
this.borderDecoration,
this.hintStyle,
this.contentPadding,
this.fillColor,
this.filled = true,
});
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: _buildTextFormFieldWidget(),
)
: _buildTextFormFieldWidget();
}
_buildTextFormFieldWidget() {
return Container(
width: width ?? double.maxFinite,
margin: margin,
child: TextFormField(
readOnly: readOnly ?? false,
onSaved: onsaved,
onChanged: onChanged,
controller: controller,
onTap: onTap,
focusNode: focusNode,
// style: _setFontStyle(),
obscureText: isObscureText!,
textInputAction: textInputAction,
keyboardType: textInputType,
maxLines: maxLines ?? 1,
maxLength: maxLength, // Added this line
decoration: _buildDecoration(),
validator: validator,
initialValue: initialValue,
inputFormatters: inputFormatters,
),
);
}
_buildDecoration() {
return InputDecoration(
labelText: hintText,
border: const OutlineInputBorder(),
);
}
// _buildDecoration() {
// return InputDecoration(
// hintText: hintText ?? "",
// hintStyle: _setFontStyle(),
// // border: _setBorderStyle(),
// enabledBorder: _setBorderStyle(),
// focusedBorder: _setBorderStyle(),
// disabledBorder: _setBorderStyle(),
// prefixIcon: prefix,
// errorText: errorText,
// prefixIconConstraints: prefixConstraints,
// suffixIcon: suffix,
// suffixIconConstraints: suffixConstraints,
// fillColor: _setFillColor(),
// filled: _setFilled(),
// isDense: true,
// contentPadding: _setPadding(),
// border: OutlineInputBorder(),
// );
// }
// _setFontStyle() {
// switch (fontStyle) {
// // Existing cases...
// case TextFormFieldFontStyle.RobotoMedium18:
// return TextStyle(
// color: ColorConstant.whiteA700,
// fontSize: getFontSize(18),
// fontFamily: 'Roboto',
// fontWeight: FontWeight.w500,
// );
// default:
// return TextStyle(
// color: ColorConstant.blueGray200,
// fontSize: getFontSize(16),
// fontFamily: 'Gilroy',
// fontWeight: FontWeight.w500,
// );
// }
// }
_setOutlineBorderRadius() {
switch (shape) {
// Existing cases...
default:
return BorderRadius.circular(getHorizontalSize(6.00));
}
}
_setBorderStyle() {
switch (variant) {
// Existing cases...
default:
return OutlineInputBorder(
borderRadius: _setOutlineBorderRadius(),
borderSide: BorderSide(
color: ColorConstant.blueGray100,
width: 1,
),
);
}
}
_setFillColor() {
switch (variant) {
// Existing cases...
default:
return ColorConstant.whiteA700;
}
}
_setFilled() {
switch (variant) {
// Existing cases...
default:
return true;
}
}
_setPadding() {
switch (padding) {
// Existing cases...
default:
return getPadding(all: 11);
}
}
}
enum TextFormFieldShape {
RoundedBorder6,
CircleBorder16,
}
enum TextFormFieldPadding {
PaddingAll11,
PaddingT12,
PaddingT16,
PaddingT20,
PaddingAll8,
PaddingT6,
PaddingT25,
}
enum TextFormFieldVariant {
None,
OutlineBluegray100,
FillBlue50,
OutlineBluegray400,
OutlineBlack9003f,
FillBlueA200,
}
enum TextFormFieldFontStyle {
GilroyMedium16,
GilroyMedium16BlueA700,
GilroyMedium16Bluegray400,
GilroySemiBold14,
RobotoMedium18,
}

View File

@@ -0,0 +1,165 @@
import 'package:flutter/material.dart';
import '../core/app_export.dart';
extension TextFormFieldStyleHelper on custom_text_form_field_f {
static OutlineInputBorder get outlineOnPrimaryContainer => OutlineInputBorder(
borderRadius: BorderRadius.circular(20.h),
borderSide: BorderSide(
color: theme.colorScheme.onPrimaryContainer,
width: 1,
),
);
static OutlineInputBorder get outlineOnPrimaryContainerTL8 =>
OutlineInputBorder(
borderRadius: BorderRadius.circular(8.h),
borderSide: BorderSide(
color: theme.colorScheme.onPrimaryContainer,
width: 1,
),
);
}
class custom_text_form_field_f extends StatelessWidget {
const custom_text_form_field_f(
{super.key,
this.alignment,
this.width,
this.scrollPadding,
this.controller,
this.focusNode,
this.autofocus = false,
this.textStyle,
this.obscureText = false,
this.textInputAction = TextInputAction.next,
this.textInputType = TextInputType.text,
this.maxLines,
this.hintText,
this.hintStyle,
this.prefix,
this.prefixConstraints,
this.suffix,
this.suffixConstraints,
this.contentPadding,
this.borderDecoration,
this.fillColor,
this.filled = true,
this.validator});
final Alignment? alignment;
final double? width;
final TextEditingController? scrollPadding;
final TextEditingController? controller;
final FocusNode? focusNode;
final bool? autofocus;
final TextStyle? textStyle;
final bool? obscureText;
final TextInputAction? textInputAction;
final TextInputType? textInputType;
final int? maxLines;
final String? hintText;
final TextStyle? hintStyle;
final Widget? prefix;
final BoxConstraints? prefixConstraints;
final Widget? suffix;
final BoxConstraints? suffixConstraints;
final EdgeInsets? contentPadding;
final InputBorder? borderDecoration;
final Color? fillColor;
final bool? filled;
final FormFieldValidator<String>? validator;
@override
Widget build(BuildContext context) {
return alignment != null
? Align(
alignment: alignment ?? Alignment.center,
child: textFormFieldWidget(context))
: textFormFieldWidget(context);
}
Widget textFormFieldWidget(BuildContext context) => SizedBox(
width: width ?? double.maxFinite,
child: TextFormField(
scrollPadding:
EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom),
controller: controller,
focusNode: focusNode,
onTapOutside: (event) {
if (focusNode != null) {
focusNode?.unfocus();
} else {
FocusManager.instance.primaryFocus?.unfocus();
}
},
autofocus: autofocus!,
style: textStyle ?? theme.textTheme.titleSmall,
obscureText: obscureText!,
textInputAction: textInputAction,
keyboardType: textInputType,
maxLines: maxLines ?? 1,
decoration: decoration,
validator: validator,
),
);
InputDecoration get decoration => InputDecoration(
hintText: hintText ?? "",
hintStyle: hintStyle ?? theme.textTheme.titleSmall,
prefixIcon: prefix,
prefixIconConstraints: prefixConstraints,
suffixIcon: suffix,
suffixIconConstraints: suffixConstraints,
isDense: true,
contentPadding: contentPadding ??
EdgeInsets.symmetric(
horizontal: 18.h,
vertical: 19.v,
),
fillColor: fillColor ?? appTheme.gray100,
filled: filled,
border: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(20.h),
borderSide: BorderSide(
color: theme.colorScheme.onPrimaryContainer,
width: 1,
),
),
enabledBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(20.h),
borderSide: BorderSide(
color: theme.colorScheme.onPrimaryContainer,
width: 1,
),
),
focusedBorder: borderDecoration ??
OutlineInputBorder(
borderRadius: BorderRadius.circular(20.h),
borderSide: BorderSide(
color: theme.colorScheme.onPrimaryContainer,
width: 1,
),
),
);
}

View File

@@ -0,0 +1,68 @@
import 'package:flutter/material.dart';
class CustomTextField extends StatefulWidget {
final String hintText;
final Function(String)? onSaved;
final String? Function(String?)? validator;
final Function()? onTap;
final TextInputType? textInputType;
final IconButton? suffixIcon;
final Function(String)? onChanged;
final bool? isObscureText;
FocusNode? focusNode;
String? initialValue ;
TextEditingController? controller;
CustomTextField(
{super.key, required this.hintText,
this.controller,
this.onChanged,
this.focusNode,
this.isObscureText,
this.initialValue,
this.suffixIcon,
this.onSaved,
this.validator,
this.onTap,
this.textInputType});
@override
_CustomTextFieldState createState() => _CustomTextFieldState();
}
class _CustomTextFieldState extends State<CustomTextField> {
final TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return TextFormField(
maxLines: 1,
initialValue: widget.initialValue ,
obscureText: widget.isObscureText ?? false,
onChanged: widget.onChanged,
onTap: widget.onTap,
focusNode: widget.focusNode,
controller: _controller,
decoration: InputDecoration(
suffixIcon: widget.suffixIcon,
hintStyle: TextStyle(color: Colors.black.withOpacity(.4)),
hintText: widget.hintText,
border: const UnderlineInputBorder(),
),
validator: widget.validator,
onSaved: (String? value) {
if (widget.onSaved != null) {
widget.onSaved!(_controller.text);
}
},
);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
}