diff --git a/assets/icons/add.svg b/assets/icons/add.svg
new file mode 100644
index 0000000..2d74577
--- /dev/null
+++ b/assets/icons/add.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/icons/arrow_left.svg b/assets/icons/arrow_left.svg
new file mode 100644
index 0000000..2db56f6
--- /dev/null
+++ b/assets/icons/arrow_left.svg
@@ -0,0 +1,7 @@
+
diff --git a/assets/icons/arrow_right.svg b/assets/icons/arrow_right.svg
new file mode 100644
index 0000000..dfc8100
--- /dev/null
+++ b/assets/icons/arrow_right.svg
@@ -0,0 +1,7 @@
+
diff --git a/assets/icons/download.svg b/assets/icons/download.svg
new file mode 100644
index 0000000..0e8dd4d
--- /dev/null
+++ b/assets/icons/download.svg
@@ -0,0 +1,10 @@
+
diff --git a/assets/icons/edit.svg b/assets/icons/edit.svg
new file mode 100644
index 0000000..632a118
--- /dev/null
+++ b/assets/icons/edit.svg
@@ -0,0 +1,9 @@
+
diff --git a/assets/icons/filter.svg b/assets/icons/filter.svg
new file mode 100644
index 0000000..52500e7
--- /dev/null
+++ b/assets/icons/filter.svg
@@ -0,0 +1,8 @@
+
diff --git a/assets/icons/scan.svg b/assets/icons/scan.svg
new file mode 100644
index 0000000..071b59b
--- /dev/null
+++ b/assets/icons/scan.svg
@@ -0,0 +1,14 @@
+
diff --git a/assets/icons/trash.svg b/assets/icons/trash.svg
new file mode 100644
index 0000000..6c9b5a1
--- /dev/null
+++ b/assets/icons/trash.svg
@@ -0,0 +1,11 @@
+
diff --git a/assets/vec/add.svg.vec b/assets/vec/add.svg.vec
new file mode 100644
index 0000000..0e0727a
Binary files /dev/null and b/assets/vec/add.svg.vec differ
diff --git a/assets/vec/arrow_left.svg.vec b/assets/vec/arrow_left.svg.vec
new file mode 100644
index 0000000..010f8fd
Binary files /dev/null and b/assets/vec/arrow_left.svg.vec differ
diff --git a/assets/vec/arrow_right.svg.vec b/assets/vec/arrow_right.svg.vec
new file mode 100644
index 0000000..432f905
Binary files /dev/null and b/assets/vec/arrow_right.svg.vec differ
diff --git a/assets/vec/download.svg.vec b/assets/vec/download.svg.vec
new file mode 100644
index 0000000..cf531fa
Binary files /dev/null and b/assets/vec/download.svg.vec differ
diff --git a/assets/vec/edit.svg.vec b/assets/vec/edit.svg.vec
new file mode 100644
index 0000000..e22f172
Binary files /dev/null and b/assets/vec/edit.svg.vec differ
diff --git a/assets/vec/filter.svg.vec b/assets/vec/filter.svg.vec
new file mode 100644
index 0000000..6c190a3
Binary files /dev/null and b/assets/vec/filter.svg.vec differ
diff --git a/assets/vec/scan.svg.vec b/assets/vec/scan.svg.vec
new file mode 100644
index 0000000..e8a6953
Binary files /dev/null and b/assets/vec/scan.svg.vec differ
diff --git a/assets/vec/trash.svg.vec b/assets/vec/trash.svg.vec
new file mode 100644
index 0000000..7d8c954
Binary files /dev/null and b/assets/vec/trash.svg.vec differ
diff --git a/fonts/iranyekanregularfanum.ttf b/fonts/iranyekanregularfanum.ttf
new file mode 100644
index 0000000..72d5808
Binary files /dev/null and b/fonts/iranyekanregularfanum.ttf differ
diff --git a/lib/main.dart b/lib/main.dart
index 616f2cc..787cc7e 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,7 +1,20 @@
import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/app_fonts.dart';
+import 'package:rasadyar_app/presentation/utils/color_utils.dart';
+import 'package:rasadyar_app/presentation/widget/buttons/elevated.dart';
+import 'package:rasadyar_app/presentation/widget/buttons/fab_outlined.dart';
+import 'package:rasadyar_app/presentation/widget/buttons/outline_elevated.dart';
+import 'package:rasadyar_app/presentation/widget/buttons/text_button.dart';
+import 'package:rasadyar_app/presentation/widget/inputs/r_input.dart';
+import 'package:rasadyar_app/presentation/widget/pagination/pagination_from_until.dart';
+import 'package:rasadyar_app/presentation/widget/pagination/show_more.dart';
+import 'package:rasadyar_app/presentation/widget/tabs/tab.dart';
+
+import 'presentation/widget/buttons/fab.dart';
void main() {
- runApp(const MyApp());
+ runApp(MyApp());
}
class MyApp extends StatelessWidget {
@@ -14,7 +27,259 @@ class MyApp extends StatelessWidget {
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
),
+ home: Home(),
);
}
}
+class Home extends StatefulWidget {
+ const Home({super.key});
+
+ @override
+ State createState() => _HomeState();
+}
+
+class _HomeState extends State {
+ List _isOpen = [false, false, false, false, false, false];
+
+ void _handleAdd() {
+ print("Add FAB pressed");
+ }
+
+ void _handleEdit() {
+ print("Edit FAB pressed");
+ }
+
+ void _handleDelete() {
+ print("Delete FAB pressed");
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(title: Text("System design"), centerTitle: true),
+ body: SingleChildScrollView(
+ child: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: ExpansionPanelList(
+ expansionCallback: (panelIndex, isExpanded) {
+ setState(() {
+ _isOpen[panelIndex] = isExpanded;
+ });
+ },
+ children: [
+ buttonWidget(),
+ fabWidget(),
+ outlinedFabWidget(),
+ paginationWidget(),
+ tabWidget(),
+ inputsWidget(),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+
+ ExpansionPanel inputsWidget() {
+ return ExpansionPanel(
+ isExpanded: _isOpen[5],
+ headerBuilder: (context, isExpanded) {
+ return ListTile(
+ title: Text(
+ "inputs",
+ style: AppFonts.yekan20Regular.copyWith(color: Colors.red),
+ ),
+ );
+ },
+ body: Padding(
+ padding: const EdgeInsets.all(8.0),
+ child: Column(
+ spacing: 14,
+ children: [
+ RTextField(
+ hintText: 'حجم کشتار را در روز به قطعه وارد کنید',
+ hintStyle: AppFonts.yekan13Regular,
+ ),
+ RTextField(
+ label: 'تلفن مرغداری',
+ labelStyle: AppFonts.yekan10Regular,
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ ExpansionPanel tabWidget() {
+ return ExpansionPanel(
+ isExpanded: _isOpen[4],
+ headerBuilder: (context, isExpanded) {
+ return ListTile(
+ title: Text(
+ "tab",
+ style: AppFonts.yekan20Regular.copyWith(color: Colors.red),
+ ),
+ );
+ },
+ body: Column(
+ spacing: 14,
+ children: [
+ CupertinoSegmentedControlDemo(),
+ CupertinoSegmentedControlDemo2(),
+ ],
+ ),
+ );
+ }
+
+ ExpansionPanel paginationWidget() {
+ return ExpansionPanel(
+ isExpanded: _isOpen[3],
+ headerBuilder: (context, isExpanded) {
+ return ListTile(
+ title: Text(
+ "پیجینیشن",
+ style: AppFonts.yekan20Regular.copyWith(color: Colors.red),
+ ),
+ );
+ },
+ body: Column(spacing: 14, children: [RShowMore(), PaginationFromUntil()]),
+ );
+ }
+
+ ExpansionPanel outlinedFabWidget() {
+ return ExpansionPanel(
+ isExpanded: _isOpen[2],
+ headerBuilder: (context, isExpanded) {
+ return ListTile(
+ title: Text(
+ "Outlined Fab ",
+ style: AppFonts.yekan20Regular.copyWith(color: Colors.green),
+ ),
+ );
+ },
+ body: Column(
+ spacing: 14,
+ children: [
+ Row(),
+
+ RFabOutlined.smallAdd(onPressed: () {}),
+ RFabOutlined.smallAdd(onPressed: null),
+
+ RFabOutlined.smallAddNoBorder(onPressed: () {}),
+ RFabOutlined.smallAddNoBorder(onPressed: null),
+
+ RFabOutlined.add(onPressed: () {}),
+ RFabOutlined.add(onPressed: null),
+
+ RFabOutlined.addNoBorder(onPressed: () {}),
+ RFabOutlined.addNoBorder(onPressed: null),
+ ],
+ ),
+ );
+ }
+
+ ExpansionPanel fabWidget() {
+ return ExpansionPanel(
+ isExpanded: _isOpen[1],
+ headerBuilder: (context, isExpanded) {
+ return ListTile(
+ title: Text(
+ "Fab",
+ style: AppFonts.yekan20Regular.copyWith(color: Colors.green),
+ ),
+ );
+ },
+ body: Column(
+ spacing: 14,
+ children: [
+ Row(),
+
+ RFab.smallAdd(onPressed: () {}),
+ RFab.smallAdd(onPressed: null),
+
+ RFab.add(onPressed: () {}),
+ RFab.add(onPressed: null),
+
+ RFab.smallEdit(onPressed: null),
+ RFab.smallEdit(onPressed: () {}),
+
+ RFab.edit(onPressed: () {}),
+ RFab.edit(onPressed: null),
+
+ RFab.smallDelete(onPressed: () {}),
+ RFab.smallDelete(onPressed: null),
+
+ RFab.delete(onPressed: () {}),
+ RFab.delete(onPressed: null),
+
+ RFab.smallAction(onPressed: () {}),
+ RFab.smallAction(onPressed: null),
+
+ RFab.action(onPressed: () {}),
+ RFab.action(onPressed: null),
+
+ RFab.smallFilter(onPressed: () {}),
+ RFab.smallFilter(onPressed: null),
+
+ RFab.filter(onPressed: () {}),
+ RFab.filter(onPressed: null),
+
+ RFab.smallDownload(onPressed: () {}),
+ RFab.smallDownload(onPressed: null),
+
+ RFab.download(onPressed: () {}),
+ RFab.download(onPressed: null),
+
+ RFab.smallExcel(onPressed: () {}),
+ RFab.smallExcel(onPressed: null),
+
+ RFab.excel(onPressed: () {}),
+ RFab.excel(onPressed: null),
+
+ RFab.smallBack(onPressed: () {}),
+ RFab.smallBack(onPressed: null),
+
+ RFab.back(onPressed: () {}),
+ RFab.back(onPressed: null),
+ ],
+ ),
+ );
+ }
+
+ ExpansionPanel buttonWidget() {
+ return ExpansionPanel(
+ isExpanded: _isOpen[0],
+ headerBuilder: (context, isExpanded) {
+ return ListTile(
+ title: Text(
+ "دکمه ها",
+ style: AppFonts.yekan20Regular.copyWith(color: Colors.green),
+ ),
+ );
+ },
+ body: Column(
+ spacing: 14,
+ children: [
+ Row(),
+
+ RElevated(text: 'ثبت', onPressed: () {}),
+
+ RElevated(text: 'ثبت', onPressed: null),
+
+ ROutlinedElevated(text: 'ثبت', onPressed: () {}),
+ ROutlinedElevated(
+ text: 'ثبتwwww',
+ onPressed: () {},
+ backgroundColor: AppColor.blueNormal.disabledColor,
+ pressedBackgroundColor: AppColor.blueNormal,
+ ),
+ ROutlinedElevated(text: 'ثبت', onPressed: null),
+
+ RTextButton(text: 'ثبت', onPressed: () {}),
+ RTextButton(text: 'ثبت', onPressed: null),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/common/app_fonts.dart b/lib/presentation/common/app_fonts.dart
new file mode 100644
index 0000000..70b06fe
--- /dev/null
+++ b/lib/presentation/common/app_fonts.dart
@@ -0,0 +1,155 @@
+import 'package:flutter/material.dart';
+
+class AppFonts {
+ AppFonts._(); // Private constructor to prevent instantiation
+
+ // --- Font Families ---
+ static const String yekan = 'yekan';
+
+ // --- Font Weights ---
+ static const FontWeight regular = FontWeight.w400;
+ static const FontWeight bold = FontWeight.w600;
+ static const double _height = 1.20;
+
+ static const TextStyle yekan61Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 61,
+ height: _height,
+ );
+
+ static const TextStyle yekan49Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 48,
+ height: _height,
+ );
+
+ static const TextStyle yekan39Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 39,
+ height: _height,
+ );
+
+ static const TextStyle yekan31Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 31,
+ height: _height,
+ );
+
+ static const TextStyle yekan25Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 25,
+ height: _height,
+ );
+
+ static const TextStyle yekan24Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 24,
+ height: _height,
+ );
+
+ static const TextStyle yekan20Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 20,
+ height: _height,
+ );
+
+ static const TextStyle yekan16Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 16,
+ height: _height,
+ );
+
+ static const TextStyle yekan13Regular = TextStyle(
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 13,
+ height: _height,
+ );
+
+ static const TextStyle yekan10Regular = TextStyle(
+ // Rounded from 10.24
+ fontFamily: yekan,
+ fontWeight: regular,
+ fontSize: 10,
+ height: _height,
+ );
+
+ static const TextStyle yekan61Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 61,
+ height: _height,
+ );
+
+ static const TextStyle yekan49Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 48,
+ height: _height,
+ );
+
+ static const TextStyle yekan39Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 39,
+ height: _height,
+ );
+
+ static const TextStyle yekan31Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 31,
+ height: _height,
+ );
+
+ static const TextStyle yekan25Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 25,
+ height: _height,
+ );
+
+ static const TextStyle yekan24Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 24,
+ height: _height,
+ );
+
+ static const TextStyle yekan20Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 20,
+ height: _height,
+ );
+
+ static const TextStyle yekan16Bold = TextStyle(
+ // Base size bold
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 16,
+ height: _height,
+ );
+
+ static const TextStyle yekan13Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 13,
+ height: _height,
+ );
+
+ static const TextStyle yekan10Bold = TextStyle(
+ fontFamily: yekan,
+ fontWeight: bold, // Use bold weight
+ fontSize: 10,
+ height: _height,
+ );
+}
diff --git a/lib/presentation/common/assets.dart b/lib/presentation/common/assets.dart
new file mode 100644
index 0000000..185d647
--- /dev/null
+++ b/lib/presentation/common/assets.dart
@@ -0,0 +1,24 @@
+///This file is automatically generated. DO NOT EDIT, all your changes would be lost.
+class Assets {
+ Assets._();
+
+ static const String iconsAdd = 'assets/icons/add.svg';
+ static const String iconsArrowLeft = 'assets/icons/arrow_left.svg';
+ static const String iconsArrowRight = 'assets/icons/arrow_right.svg';
+ static const String iconsDownload = 'assets/icons/download.svg';
+ static const String iconsEdit = 'assets/icons/edit.svg';
+ static const String iconsFilter = 'assets/icons/filter.svg';
+ static const String iconsScan = 'assets/icons/scan.svg';
+ static const String iconsTrash = 'assets/icons/trash.svg';
+ static const String imagesInnerSplash = 'assets/images/inner_splash.webp';
+ static const String imagesOutterSplash = 'assets/images/outter_splash.webp';
+ static const String vecAddSvg = 'assets/vec/add.svg.vec';
+ static const String vecArrowLeftSvg = 'assets/vec/arrow_left.svg.vec';
+ static const String vecArrowRightSvg = 'assets/vec/arrow_right.svg.vec';
+ static const String vecDownloadSvg = 'assets/vec/download.svg.vec';
+ static const String vecEditSvg = 'assets/vec/edit.svg.vec';
+ static const String vecFilterSvg = 'assets/vec/filter.svg.vec';
+ static const String vecScanSvg = 'assets/vec/scan.svg.vec';
+ static const String vecTrashSvg = 'assets/vec/trash.svg.vec';
+
+}
diff --git a/lib/presentation/utils/color_utils.dart b/lib/presentation/utils/color_utils.dart
new file mode 100644
index 0000000..46f9bb8
--- /dev/null
+++ b/lib/presentation/utils/color_utils.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+
+extension ColorUtils on Color {
+ Color _darken([double amount = 0.1]) {
+ assert(amount >= 0 && amount <= 1, 'مقدار تیرگی باید بین 0 و 1 باشد');
+ final hslColor = HSLColor.fromColor(this);
+ final newLightness = (hslColor.lightness - amount).clamp(0.0, 1.0);
+ final hslDarkerColor = hslColor.withLightness(newLightness);
+ return hslDarkerColor.toColor();
+ }
+
+ get disabledColor{
+ return withAlpha(38);
+ }
+
+ get hoverColor{
+ return _darken(0.5);
+ }
+
+ get pressedColor{
+ return _darken(0.10);
+ }
+
+}
diff --git a/lib/presentation/widget/buttons/elevated.dart b/lib/presentation/widget/buttons/elevated.dart
new file mode 100644
index 0000000..c03bc2e
--- /dev/null
+++ b/lib/presentation/widget/buttons/elevated.dart
@@ -0,0 +1,58 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/app_fonts.dart';
+
+class RElevated extends StatefulWidget {
+ RElevated({
+ super.key,
+ required this.text,
+ required this.onPressed,
+ foregroundColor,
+ backgroundColor,
+ disabledBackgroundColor,
+ disabledForegroundColor,
+ radius,
+ textStyle,
+ this.width = 150.0,
+ this.height = 56.0,
+ });
+
+ final String text;
+ final VoidCallback? onPressed;
+ final double width;
+ final double height;
+ Color? foregroundColor;
+ Color? backgroundColor;
+ Color? disabledForegroundColor;
+ Color? disabledBackgroundColor;
+ double? radius;
+ TextStyle? textStyle;
+
+ @override
+ State createState() => _RElevatedState();
+}
+
+class _RElevatedState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return ElevatedButton(
+ onPressed: () {
+ setState(() {});
+ },
+ style: ElevatedButton.styleFrom(
+ backgroundColor: widget.backgroundColor ?? AppColor.blueNormal,
+ foregroundColor: widget.foregroundColor ?? Colors.white,
+ disabledBackgroundColor:
+ widget.disabledBackgroundColor ?? AppColor.blueNormal.withAlpha(38),
+ disabledForegroundColor: widget.disabledForegroundColor ?? Colors.white,
+ shape: RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(widget.radius ?? 8),
+ ),
+ fixedSize: Size(widget.width, widget.height),
+ padding: EdgeInsets.zero,
+ textStyle: widget.textStyle ?? AppFonts.yekan24Regular,
+ ),
+ child: Text(widget.text),
+ );
+ }
+}
diff --git a/lib/presentation/widget/buttons/fab.dart b/lib/presentation/widget/buttons/fab.dart
new file mode 100644
index 0000000..84a4e8b
--- /dev/null
+++ b/lib/presentation/widget/buttons/fab.dart
@@ -0,0 +1,232 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/assets.dart';
+import 'package:rasadyar_app/presentation/utils/color_utils.dart';
+import 'package:rasadyar_app/presentation/widget/vec_widget.dart';
+
+class RFab extends StatefulWidget {
+
+
+ final VoidCallback? onPressed;
+ Color? foregroundColor;
+ Color? backgroundColor;
+ Color? disabledForegroundColor;
+ Color? disabledBackgroundColor;
+ double? radius;
+ ShapeBorder? shapeBorder;
+ Widget? icon;
+
+ @override
+ State createState() => _RFabState();
+
+ //region Add
+ RFab.smallAdd({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecAddSvg),
+ backgroundColor: AppColor.greenNormal,
+ key: key,
+ );
+
+ RFab.add({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecAddSvg),
+ backgroundColor: AppColor.greenNormal,
+ key: key,
+ );
+
+ //endregion
+
+ //region Edit
+ RFab.smallEdit({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecEditSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ RFab.edit({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecEditSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ //endregion
+
+ //region delete
+ RFab.smallDelete({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecTrashSvg),
+ backgroundColor: AppColor.redNormal,
+ key: key,
+ );
+
+ RFab.delete({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecTrashSvg),
+ backgroundColor: AppColor.redNormal,
+ key: key,
+ );
+
+ //endregion
+
+ //region action
+ RFab.smallAction({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecScanSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ RFab.action({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecScanSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ //endregion
+
+ //region filter
+ RFab.smallFilter({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecFilterSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ RFab.filter({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecFilterSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ //endregion
+
+ //region download
+ RFab.smallDownload({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecDownloadSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ RFab.download({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecDownloadSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ //endregion
+
+ //region Excel
+ RFab.smallExcel({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecDownloadSvg),
+ backgroundColor: AppColor.greenDark,
+ key: key,
+ );
+
+ RFab.excel({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecDownloadSvg),
+ backgroundColor: AppColor.greenDark,
+ key: key,
+ );
+
+ //endregion
+
+ //region Back
+ RFab.smallBack({required VoidCallback? onPressed, Key? key})
+ : this.small(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecArrowLeftSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ RFab.back({required VoidCallback? onPressed, Key? key})
+ : this(
+ onPressed: onPressed,
+ icon: vecWidget(Assets.vecArrowLeftSvg),
+ backgroundColor: AppColor.blueNormal,
+ key: key,
+ );
+
+ //endregion
+
+ //region General
+ RFab.small({
+ required this.onPressed,
+ required this.icon,
+ required this.backgroundColor,
+ super.key,
+ }) : radius = 40.0,
+ foregroundColor = Colors.white;
+
+ RFab({
+ required this.onPressed,
+ required this.icon,
+ required this.backgroundColor,
+ super.key,
+ }) : radius = 56.0,
+ foregroundColor = Colors.white;
+
+ //endregion
+}
+
+class _RFabState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return ElevatedButton(
+ onPressed: widget.onPressed,
+ style: ButtonStyle(
+ side: WidgetStateProperty.all(BorderSide.none),
+ backgroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return widget.backgroundColor?.pressedColor ??
+ AppColor.blueNormalActive;
+ } else if (states.contains(WidgetState.hovered)) {
+ return widget.backgroundColor?.hoverColor ??
+ AppColor.blueNormalHover;
+ } else if (states.contains(WidgetState.disabled)) {
+ return widget.backgroundColor?.disabledColor ??
+ AppColor.blueNormal.disabledColor;
+ }
+ return widget.backgroundColor ?? AppColor.blueNormal;
+ }),
+ foregroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.disabled)) {
+ return widget.foregroundColor?.disabledColor;
+ }
+ return widget.foregroundColor;
+ }),
+
+ shape: WidgetStatePropertyAll(
+ CircleBorder(side: BorderSide(width: 1, color: Colors.transparent)),
+ ),
+ fixedSize: WidgetStatePropertyAll(
+ Size(widget.radius ?? 56, widget.radius ?? 56),
+ ),
+ padding: WidgetStatePropertyAll(EdgeInsets.zero),
+ ),
+ child: widget.icon,
+ );
+ }
+}
diff --git a/lib/presentation/widget/buttons/fab_outlined.dart b/lib/presentation/widget/buttons/fab_outlined.dart
new file mode 100644
index 0000000..ecd9ea1
--- /dev/null
+++ b/lib/presentation/widget/buttons/fab_outlined.dart
@@ -0,0 +1,605 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/assets.dart';
+import 'package:rasadyar_app/presentation/utils/color_utils.dart';
+import 'package:rasadyar_app/presentation/widget/vec_widget.dart';
+
+class RFabOutlined extends StatefulWidget {
+ final Widget icon;
+ VoidCallback? onPressed;
+ final Color backgroundColor;
+ final Color? borderColor;
+ final double? radius;
+ OutlinedBorder? shapeBorder;
+
+ @override
+ State createState() => _RFabOutlinedState();
+
+ //region General
+ RFabOutlined({
+ required this.icon,
+ required this.onPressed,
+ required this.backgroundColor,
+ required this.borderColor,
+ this.radius = 56.0,
+ super.key,
+ }) : shapeBorder = CircleBorder(
+ side: BorderSide(color: borderColor ?? Colors.transparent),
+ );
+
+ RFabOutlined.noBorder({
+ required this.icon,
+ required this.onPressed,
+ required this.backgroundColor,
+ super.key,
+ }) : borderColor = Colors.transparent,
+ radius = 56.0,
+ shapeBorder = CircleBorder(
+ side: BorderSide(color: Colors.transparent, width: 1),
+ );
+
+ RFabOutlined.small({
+ required this.icon,
+ required this.onPressed,
+ required this.backgroundColor,
+ required this.borderColor,
+ super.key,
+ }) : radius = 40.0,
+ shapeBorder = CircleBorder(
+ side: BorderSide(color: borderColor ?? Colors.transparent, width: 1),
+ );
+
+ RFabOutlined.smallNoBorder({
+ required this.icon,
+ required this.onPressed,
+ required this.backgroundColor,
+ super.key,
+ }) : borderColor = Colors.transparent,
+ radius = 40.0,
+ shapeBorder = CircleBorder(
+ side: BorderSide(color: Colors.transparent, width: 1),
+ );
+
+ //endregion
+
+ //region Add
+ RFabOutlined.smallAdd({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenNormal,
+ borderColor: AppColor.greenNormal,
+ icon: vecWidget2(
+ Assets.vecAddSvg,
+
+ color: AppColor.greenNormal,
+ ),
+ );
+
+ RFabOutlined.smallAddNoBorder({VoidCallback? onPressed, Key? key})
+ : this.smallNoBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenNormal,
+ icon: vecWidget(
+ Assets.vecAddSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenNormal
+ : AppColor.greenNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.add({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenNormal,
+ borderColor: AppColor.greenNormal,
+ icon: vecWidget(
+ Assets.vecAddSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenNormal
+ : AppColor.greenNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.addNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenNormal,
+ icon: vecWidget(
+ Assets.vecAddSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenNormal
+ : AppColor.greenNormal.disabledColor,
+ ),
+ );
+
+ //endregion
+
+ //region Edit
+ RFabOutlined.smallEdit({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecEditSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.smallEditNoBorder({VoidCallback? onPressed, Key? key})
+ : this.smallNoBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecEditSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.edit({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecEditSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.editNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecEditSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ //endregion
+
+ //region Delete
+ RFabOutlined.smallDelete({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.redNormal,
+ borderColor: AppColor.redNormal,
+ icon: vecWidget(
+ Assets.vecTrashSvg,
+ color:
+ onPressed != null
+ ? AppColor.redNormal
+ : AppColor.redNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.smallDeleteNoBorder({VoidCallback? onPressed, Key? key})
+ : this.smallNoBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.redNormal,
+ icon: vecWidget(
+ Assets.vecTrashSvg,
+ color:
+ onPressed != null
+ ? AppColor.redNormal
+ : AppColor.redNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.delete({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.redNormal,
+ borderColor: AppColor.redNormal,
+ icon: vecWidget(
+ Assets.vecTrashSvg,
+ color:
+ onPressed != null
+ ? AppColor.redNormal
+ : AppColor.redNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.deleteNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.redNormal,
+ icon: vecWidget(
+ Assets.vecTrashSvg,
+ color:
+ onPressed != null
+ ? AppColor.redNormal
+ : AppColor.redNormal.disabledColor,
+ ),
+ );
+
+ //endregion
+
+ //region Action
+ RFabOutlined.smallAction({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecScanSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.smallActionNoBorder({VoidCallback? onPressed, Key? key})
+ : this.smallNoBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecScanSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.action({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecScanSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.actionNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecScanSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ //endregion
+
+ //region Filter
+ RFabOutlined.smallFilter({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecFilterSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.smallFilterNoBorder({VoidCallback? onPressed, Key? key})
+ : this.smallNoBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecFilterSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.filter({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecFilterSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.filterNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecFilterSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ //endregion
+
+ //region Download
+ RFabOutlined.smallDownload({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ RFabOutlined.smallDownloadNoBorder({VoidCallback? onPressed, Key? key})
+ : this.smallNoBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ RFabOutlined.download({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ RFabOutlined.downloadNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ //endregion
+
+ //region Excel
+ RFabOutlined.smallExcel({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenDark,
+ borderColor: AppColor.greenDark,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ RFabOutlined.smallExcelNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenDark,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ RFabOutlined.excel({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenDark,
+ borderColor: AppColor.greenDark,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ RFabOutlined.excelNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.greenDark,
+ icon: vecWidget(
+ Assets.vecDownloadSvg,
+ color:
+ onPressed != null
+ ? AppColor.greenDark
+ : AppColor.greenDark.disabledColor,
+ ),
+ );
+
+ //endregion
+
+ //region Back
+ RFabOutlined.smallBack({VoidCallback? onPressed, Key? key})
+ : this.small(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecArrowLeftSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.smallBackNoBorder({VoidCallback? onPressed, Key? key})
+ : this.smallNoBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecArrowLeftSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.back({VoidCallback? onPressed, Key? key})
+ : this(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ borderColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecArrowLeftSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ RFabOutlined.backNoBorder({VoidCallback? onPressed, Key? key})
+ : this.noBorder(
+ key: key,
+ onPressed: onPressed,
+ backgroundColor: AppColor.blueNormal,
+ icon: vecWidget(
+ Assets.vecArrowLeftSvg,
+ color:
+ onPressed != null
+ ? AppColor.blueNormal
+ : AppColor.blueNormal.disabledColor,
+ ),
+ );
+
+ //endregion
+}
+
+class _RFabOutlinedState extends State {
+ bool isOnPressed =false;
+ @override
+ Widget build(BuildContext context) {
+ return OutlinedButton(
+ onPressed:widget.onPressed ,
+ style: ButtonStyle(
+ side: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.disabled)) {
+ return BorderSide(
+ color:
+ widget.borderColor?.disabledColor ??
+ AppColor.blueNormal.disabledColor,
+ width: 2,
+ );
+ }
+ return BorderSide(
+ color: widget.borderColor ?? AppColor.blueNormal,
+ width: 2,
+ );
+ }),
+ backgroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return widget.backgroundColor;
+ } else if (states.contains(WidgetState.hovered)) {
+ return widget.backgroundColor.hoverColor ??
+ AppColor.blueNormal.hoverColor;
+ } else if (states.contains(WidgetState.disabled)) {
+ return widget.backgroundColor.disabledColor ??
+ AppColor.blueNormal.disabledColor;
+ }
+ return Colors.transparent;
+ }),
+ foregroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return Colors.white;
+ } else if (states.contains(WidgetState.disabled)) {
+ return widget.backgroundColor.disabledColor ??
+ AppColor.blueNormal.disabledColor;
+ }
+ return widget.backgroundColor;
+ }),
+
+ shape: WidgetStatePropertyAll(widget.shapeBorder),
+ fixedSize: WidgetStatePropertyAll(
+ Size(widget.radius ?? 56, widget.radius ?? 56),
+ ),
+ padding: WidgetStatePropertyAll(EdgeInsets.zero),
+ ),
+ child: widget.icon
+ );
+ }
+}
+
diff --git a/lib/presentation/widget/buttons/outline_elevated.dart b/lib/presentation/widget/buttons/outline_elevated.dart
new file mode 100644
index 0000000..23272bf
--- /dev/null
+++ b/lib/presentation/widget/buttons/outline_elevated.dart
@@ -0,0 +1,101 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/app_fonts.dart';
+import 'package:rasadyar_app/presentation/utils/color_utils.dart';
+
+class ROutlinedElevated extends StatefulWidget {
+ ROutlinedElevated({
+ super.key,
+ required this.text,
+ required this.onPressed,
+ this.foregroundColor,
+ this.backgroundColor,
+ this.borderColor,
+ this.disabledBackgroundColor,
+ this.pressedBackgroundColor,
+ this.radius,
+ this.textStyle,
+ this.width = 150.0,
+ this.height = 56.0,
+ });
+
+ final String text;
+ final VoidCallback? onPressed;
+ final double width;
+ final double height;
+ Color? foregroundColor;
+ Color? backgroundColor;
+
+ Color? borderColor;
+
+ Color? disabledBackgroundColor;
+ Color? pressedBackgroundColor;
+ double? radius;
+ TextStyle? textStyle;
+
+ @override
+ State createState() => _ROutlinedElevatedState();
+}
+
+class _ROutlinedElevatedState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return OutlinedButton(
+ onPressed: widget.onPressed,
+ style: ButtonStyle(
+ side: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return BorderSide(
+ color: widget.borderColor ?? AppColor.blueNormal,
+ width: 2,
+ );
+ } else if (states.contains(WidgetState.disabled)) {
+ return BorderSide(
+ color: widget.borderColor ?? AppColor.blueNormal.withAlpha(38),
+ width: 2,
+ );
+ }
+ return BorderSide(
+ color: widget.borderColor ?? AppColor.blueNormal,
+ width: 2,
+ );
+ }),
+ backgroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ if (widget.pressedBackgroundColor != null) {
+ return widget.pressedBackgroundColor;
+ }
+ return widget.backgroundColor?.pressedColor ?? AppColor.blueNormal;
+ } else if (states.contains(WidgetState.hovered)) {
+ return widget.backgroundColor?.hoverColor ??
+ AppColor.blueNormal.hoverColor;
+ } else if (states.contains(WidgetState.disabled)) {
+ return widget.backgroundColor?.disabledColor ?? Colors.transparent;
+ }
+ return widget.backgroundColor;
+ }),
+ foregroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return Colors.white;
+ } else if (states.contains(WidgetState.disabled)) {
+ return AppColor.blueNormal.withAlpha(38);
+ }
+ return AppColor.blueNormal;
+ }),
+
+ shape: WidgetStatePropertyAll(
+ RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(widget.radius ?? 8),
+ ),
+ ),
+ fixedSize: WidgetStatePropertyAll(Size(widget.width, widget.height)),
+ padding: WidgetStatePropertyAll(EdgeInsets.zero),
+ textStyle: WidgetStatePropertyAll(
+ widget.textStyle ??
+ AppFonts.yekan24Regular.copyWith(color: AppColor.blueNormal),
+ ),
+ ),
+ child: Text(widget.text),
+ );
+ }
+}
diff --git a/lib/presentation/widget/buttons/text_button.dart b/lib/presentation/widget/buttons/text_button.dart
new file mode 100644
index 0000000..40fb3a4
--- /dev/null
+++ b/lib/presentation/widget/buttons/text_button.dart
@@ -0,0 +1,77 @@
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/app_fonts.dart';
+
+class RTextButton extends StatefulWidget {
+ RTextButton({
+ super.key,
+ required this.text,
+ required this.onPressed,
+ foregroundColor,
+ backgroundColor,
+ borderColor,
+ disabledBackgroundColor,
+ radius,
+ textStyle,
+ this.width = 150.0,
+ this.height = 56.0,
+ });
+
+ final String text;
+ final VoidCallback? onPressed;
+ final double width;
+ final double height;
+ Color? foregroundColor;
+ Color? backgroundColor;
+ Color? borderColor;
+
+ Color? disabledBackgroundColor;
+ double? radius;
+ TextStyle? textStyle;
+
+ @override
+ State createState() => _RTextButtonState();
+}
+
+class _RTextButtonState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return TextButton(
+ style: ButtonStyle(
+ side: WidgetStatePropertyAll(BorderSide.none),
+ backgroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return widget.backgroundColor ?? AppColor.blueNormal;
+ } else if (states.contains(WidgetState.hovered)) {
+ return widget.backgroundColor?.withAlpha(38) ?? AppColor.blueNormal.withAlpha(38);
+ } else if (states.contains(WidgetState.disabled)) {
+ return widget.disabledBackgroundColor ?? Colors.transparent;
+ }
+ return Colors.transparent;
+ }),
+ foregroundColor: WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return Colors.white;
+ } else if (states.contains(WidgetState.disabled)) {
+ return AppColor.blueNormal.withAlpha(38);
+ }
+ return AppColor.blueNormal;
+ }),
+
+ shape: WidgetStatePropertyAll(
+ RoundedRectangleBorder(
+ borderRadius: BorderRadius.circular(widget.radius ?? 8),
+ ),
+ ),
+ fixedSize: WidgetStatePropertyAll(Size(widget.width, widget.height)),
+ padding: WidgetStatePropertyAll(EdgeInsets.zero),
+ textStyle: WidgetStatePropertyAll(
+ widget.textStyle ??
+ AppFonts.yekan24Regular.copyWith(color: AppColor.blueNormal),
+ ),
+ ),
+ onPressed:widget.onPressed,
+ child: Text(widget.text),
+ );
+ }
+}
diff --git a/lib/presentation/widget/inputs/r_input.dart b/lib/presentation/widget/inputs/r_input.dart
new file mode 100644
index 0000000..07edc2b
--- /dev/null
+++ b/lib/presentation/widget/inputs/r_input.dart
@@ -0,0 +1,216 @@
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+@immutable
+class RTextField extends StatefulWidget {
+ RTextField(
+ {super.key,
+ this.maxLines,
+ this.maxLength,
+ this.hintText,
+ this.padding,
+ this.onChanged,
+ this.onSubmitted,
+ this.keyboardType,
+ this.showCounter = false,
+ this.isDense,
+ this.initText,
+ this.isForNumber = false,
+ this.style,
+ this.hintStyle,
+ this.suffixIcon,
+ this.prefixIcon,
+ this.validator,
+ this.readonly = false,
+ this.boxConstraints,
+ this.minLines,
+ this.radius,
+ this.filled,
+ this.enabled,
+ this.errorStyle,
+ this.labelStyle,
+ this.label}) {
+ filled = filled ?? false;
+ obscure = false;
+ _inputBorder = OutlineInputBorder(
+ borderSide: BorderSide(color: Colors.grey.shade300),
+ borderRadius: BorderRadius.circular(radius ?? 16));
+ }
+
+ RTextField.noBorder(
+ {super.key,
+ this.maxLines,
+ this.maxLength,
+ this.hintText,
+ this.padding,
+ this.onChanged,
+ this.onSubmitted,
+ this.keyboardType,
+ this.showCounter = false,
+ this.isDense,
+ this.initText,
+ this.style,
+ this.hintStyle,
+ this.suffixIcon,
+ this.radius,
+ this.validator,
+ this.boxConstraints,
+ this.minLines,
+ this.isForNumber = false,
+ this.readonly = false,
+ this.label,
+ this.filled,
+ this.errorStyle,
+ this.labelStyle,
+ this.enabled}) {
+ _inputBorder = OutlineInputBorder(
+ borderSide: BorderSide.none,
+ borderRadius: BorderRadius.circular(radius ?? 16));
+ obscure = false;
+ filled = filled ?? true;
+ }
+
+ RTextField.password(
+ {super.key,
+ this.maxLines = 1,
+ this.maxLength,
+ this.hintText,
+ this.padding,
+ this.onChanged,
+ this.onSubmitted,
+ this.keyboardType,
+ this.showCounter = false,
+ this.isDense,
+ this.initText,
+ this.style,
+ this.hintStyle,
+ this.suffixIcon,
+ this.prefixIcon,
+ this.radius,
+ this.validator,
+ this.boxConstraints,
+ this.minLines,
+ this.isForNumber = false,
+ this.readonly = false,
+ this.label,
+ this.filled,
+ this.errorStyle,
+ this.labelStyle,
+ this.enabled}) {
+ _inputBorder = OutlineInputBorder(
+ borderSide: BorderSide.none,
+ borderRadius: BorderRadius.circular(radius ?? 16));
+ filled = filled ?? true;
+ obscure = true;
+ _isPassword = true;
+ prefixIcon = prefixIcon ?? const Icon(CupertinoIcons.person);
+ }
+
+ final int? maxLines;
+ final int? minLines;
+ final int? maxLength;
+ final String? hintText;
+ final String? label;
+ final EdgeInsets? padding;
+ final TextStyle? style;
+ final TextStyle? errorStyle;
+ final TextStyle? hintStyle;
+ final TextStyle? labelStyle;
+ final bool showCounter;
+ final bool? isDense;
+ final bool? isForNumber;
+ final bool readonly;
+ bool? obscure;
+ final bool? enabled;
+ final double? radius;
+ final TextInputType? keyboardType;
+ final Function(String)? onChanged;
+ final Function(String)? onSubmitted;
+ final FormFieldValidator? validator;
+ final String? initText;
+ Widget? suffixIcon;
+ Widget? prefixIcon;
+ bool? filled;
+ bool _isPassword = false;
+
+ final BoxConstraints? boxConstraints;
+ late final InputBorder? _inputBorder;
+
+ @override
+ State createState() => _RTextFieldState();
+}
+
+class _RTextFieldState extends State {
+ final TextEditingController _controller = TextEditingController();
+ bool? obscure;
+
+ @override
+ void initState() {
+ super.initState();
+ if (widget.initText != null) {
+ _controller.text = widget.initText!;
+ }
+ obscure = widget.obscure;
+ }
+
+ @override
+ void didUpdateWidget(covariant RTextField oldWidget) {
+ super.didUpdateWidget(oldWidget);
+ if (widget.initText != oldWidget.initText) {
+ _controller.text = widget.initText ?? '';
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Padding(
+ padding: widget.padding ?? const EdgeInsets.symmetric(vertical: 6.0),
+ child: TextFormField(
+ controller: _controller,
+ readOnly: widget.readonly,
+ minLines: widget.minLines,
+ maxLines: widget.maxLines,
+ onChanged: widget.onChanged,
+ validator: widget.validator,
+ enabled: widget.enabled,
+ obscureText: obscure ?? false,
+ onTapOutside: (event) {
+ FocusScope.of(context).unfocus();
+ },
+ onFieldSubmitted: widget.onSubmitted,
+ maxLength: widget.maxLength,
+ textDirection: TextDirection.rtl,
+ style: widget.style ,
+ keyboardType: widget.keyboardType,
+ decoration: InputDecoration(
+ errorStyle: widget.errorStyle,
+ errorMaxLines: 1,
+ isDense: widget.isDense,
+ suffixIcon: widget.suffixIcon ??
+ (widget._isPassword
+ ? IconButton(
+ onPressed: () {
+ setState(() {
+ obscure = !obscure!;
+ });
+ },
+ icon: Icon(!obscure!
+ ? CupertinoIcons.eye_slash
+ : CupertinoIcons.eye))
+ : null),
+ suffixIconConstraints: widget.boxConstraints,
+ prefixIcon: widget.prefixIcon,
+ prefixIconConstraints: widget.boxConstraints,
+ hintText: widget.hintText,
+ labelText: widget.label,
+ labelStyle: widget.labelStyle,
+ filled: widget.filled,
+ counter: widget.showCounter ? null : const SizedBox(),
+ hintStyle: widget.hintStyle,
+ enabledBorder: widget._inputBorder,
+ focusedBorder: widget._inputBorder,
+ border: widget._inputBorder),
+ ));
+ }
+}
\ No newline at end of file
diff --git a/lib/presentation/widget/pagination/pagination_from_until.dart b/lib/presentation/widget/pagination/pagination_from_until.dart
new file mode 100644
index 0000000..53f1203
--- /dev/null
+++ b/lib/presentation/widget/pagination/pagination_from_until.dart
@@ -0,0 +1,255 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/app_fonts.dart';
+
+class PaginationFromUntil extends StatefulWidget {
+ const PaginationFromUntil({super.key});
+
+ @override
+ State createState() => _PaginationFromUntilState();
+}
+
+class _PaginationFromUntilState extends State {
+ int current = 1;
+ int total = 10;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: 164,
+ height: 47,
+ clipBehavior: Clip.antiAlias,
+ decoration: ShapeDecoration(
+ color: const Color(0xFFEAEFFF),
+ shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(50)),
+ ),
+ child: Row(
+ children: [
+ FloatingActionButton.small(
+ onPressed: () {
+ if(current>1){
+ setState(() {
+ current--;
+ });
+ }
+
+ },
+ shape: CircleBorder(),
+ elevation: 0,
+ backgroundColor: Colors.white,
+ child: Icon(CupertinoIcons.arrow_left, color: AppColor.blueNormal),
+ ),
+ Expanded(
+ child: Text(
+ '$current از $total',
+ textAlign: TextAlign.center,
+ textDirection: TextDirection.rtl,
+ style: AppFonts.yekan16Regular.copyWith(
+ color: AppColor.blueNormal,
+ ),
+ ),
+ ),
+ FloatingActionButton.small(
+
+ onPressed:() {
+ if (current < total) {
+ setState(() {
+ current++;
+ });
+ }
+ },
+ shape: CircleBorder(),
+ elevation: 0,
+ backgroundColor: AppColor.blueNormal,
+ child: Icon(CupertinoIcons.arrow_right, color: Colors.white),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Stack buildStack() {
+ return Stack(
+ children: [
+ Positioned(
+ left: 4,
+ top: 4,
+ child: Container(
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 40,
+ top: 40,
+ child: Container(
+ transform:
+ Matrix4.identity()
+ ..translate(0.0, 0.0)
+ ..rotateZ(-3.14),
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 0,
+ top: 0,
+ child: Container(
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 0,
+ top: 0,
+ child: Container(
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 0,
+ top: 0,
+ child: Container(
+ width: 40,
+ height: 40,
+ clipBehavior: Clip.antiAlias,
+ decoration: ShapeDecoration(
+ color:
+ Colors.white /* Secondary */,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ width: 1,
+ color:
+ Colors
+ .white /* Secondary */,
+ ),
+ borderRadius:
+ BorderRadius.circular(50),
+ ),
+ ),
+ child: Stack(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ Positioned(
+ left: 8,
+ top: 8,
+ child: Container(width: 24, height: 24, child: Stack()),
+ ),
+ ],
+ ),
+ ),
+ ),
+ Positioned(
+ left: 120,
+ top: 3,
+ child: Container(
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 40,
+ top: 40,
+ child: Container(
+ transform:
+ Matrix4.identity()
+ ..translate(0.0, 0.0)
+ ..rotateZ(-3.14),
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 0,
+ top: 0,
+ child: Container(
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 0,
+ top: 0,
+ child: Container(
+ width: 40,
+ height: 40,
+ child: Stack(
+ children: [
+ Positioned(
+ left: 0,
+ top: 0,
+ child: Container(
+ width: 40,
+ height: 40,
+ clipBehavior: Clip.antiAlias,
+ decoration: ShapeDecoration(
+ color: const Color(
+ 0xFF2D5FFF,
+ ) /* Primary */,
+ shape: RoundedRectangleBorder(
+ side: BorderSide(
+ width: 1,
+ color: const Color(
+ 0xFF2D5FFF,
+ ) /* Primary */,
+ ),
+ borderRadius:
+ BorderRadius.circular(50),
+ ),
+ ),
+ child: Stack(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ Positioned(
+ left: 8,
+ top: 8,
+ child: Container(width: 24, height: 24, child: Stack()),
+ ),
+ ],
+ ),
+ ),
+ ),
+ Positioned(
+ left: 63,
+ top: 9,
+ child: Text(
+ '1 از 17',
+ style: TextStyle(
+ color: const Color(0xFF2D5FFF) /* Primary */,
+ fontSize: 16,
+ fontFamily: 'IRANYekanFN',
+ fontWeight: FontWeight.w400,
+ height: 1.75,
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/presentation/widget/pagination/show_more.dart b/lib/presentation/widget/pagination/show_more.dart
new file mode 100644
index 0000000..36fb207
--- /dev/null
+++ b/lib/presentation/widget/pagination/show_more.dart
@@ -0,0 +1,78 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/app_fonts.dart';
+
+class RShowMore extends StatefulWidget {
+ const RShowMore({super.key});
+
+ @override
+ State createState() => _RShowMoreState();
+}
+
+class _RShowMoreState extends State
+ with SingleTickerProviderStateMixin {
+ bool _toggled = false;
+ late final AnimationController _controller;
+ late final Animation _iconRotation;
+
+ @override
+ void initState() {
+ super.initState();
+
+ _controller = AnimationController(
+ vsync: this,
+ duration: const Duration(milliseconds: 500),
+ );
+ _iconRotation = Tween(
+ begin: 0,
+ end: 0.50,
+ ) // 90 degrees (quarter turn)
+ .animate(CurvedAnimation(parent: _controller, curve: Curves.easeInOut));
+ }
+
+ void _toggle() {
+ setState(() => _toggled = !_toggled);
+ _toggled ? _controller.forward() : _controller.reverse();
+ }
+
+ @override
+ void dispose() {
+ _controller.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: _toggle,
+ behavior: HitTestBehavior.opaque,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ spacing: 8,
+ children: [
+ RotationTransition(
+ turns: _iconRotation,
+ child: const Icon(CupertinoIcons.chevron_down, size: 12,color:AppColor.blueNormal ,),
+ ),
+
+ AnimatedSwitcher(
+ duration: const Duration(milliseconds: 500),
+ transitionBuilder:
+ (child, animation) =>
+ FadeTransition(opacity: animation, child: child),
+ child: Text(
+ _toggled ? 'کمتر' : 'مشاهده بیشتر',
+ key: ValueKey(_toggled),
+ style: AppFonts.yekan10Regular.copyWith(color: AppColor.blueNormal),
+ ),
+ ),
+ SizedBox(height: 50,)
+ ],
+
+
+
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/widget/tabs/new_tab.dart b/lib/presentation/widget/tabs/new_tab.dart
new file mode 100644
index 0000000..c6e73c4
--- /dev/null
+++ b/lib/presentation/widget/tabs/new_tab.dart
@@ -0,0 +1,784 @@
+// Copyright 2014 The Flutter Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+/// @docImport 'switch.dart';
+library;
+
+import 'dart:collection';
+import 'dart:math' as math;
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/rendering.dart';
+
+// Minimum padding from edges of the segmented control to edges of
+// encompassing widget.
+const EdgeInsetsGeometry _kHorizontalItemPadding = EdgeInsets.symmetric(
+ horizontal: 16.0,
+);
+
+// Minimum height of the segmented control.
+const double _kMinSegmentedControlHeight = 28.0;
+
+// The default color used for the text of the disabled segment.
+const Color _kDisableTextColor = Color.fromARGB(115, 122, 122, 122);
+
+// The duration of the fade animation used to transition when a new widget
+// is selected.
+const Duration _kFadeDuration = Duration(milliseconds: 165);
+
+class NewCupertinoSegmentedControl extends StatefulWidget {
+ /// Creates an iOS-style segmented control bar.
+ ///
+ /// The [children] argument must be an ordered [Map] such as a
+ /// [LinkedHashMap]. Further, the length of the [children] list must be
+ /// greater than one.
+ ///
+ /// Each widget value in the map of [children] must have an associated key
+ /// that uniquely identifies this widget. This key is what will be returned
+ /// in the [onValueChanged] callback when a new value from the [children] map
+ /// is selected.
+ ///
+ /// The [groupValue] is the currently selected value for the segmented control.
+ /// If no [groupValue] is provided, or the [groupValue] is null, no widget will
+ /// appear as selected. The [groupValue] must be either null or one of the keys
+ /// in the [children] map.
+ NewCupertinoSegmentedControl({
+ super.key,
+ required this.children,
+ required this.onValueChanged,
+ this.groupValue,
+ this.unselectedColor,
+ this.selectedColor,
+ this.borderColor,
+ this.pressedColor,
+ this.disabledColor,
+ this.disabledTextColor,
+ this.padding,
+ this.disabledChildren = const {},
+ }) : assert(children.length >= 2),
+ assert(
+ groupValue == null ||
+ children.keys.any((T child) => child == groupValue),
+ 'The groupValue must be either null or one of the keys in the children map.',
+ );
+
+ /// The identifying keys and corresponding widget values in the
+ /// segmented control.
+ ///
+ /// The map must have more than one entry.
+ /// This attribute must be an ordered [Map] such as a [LinkedHashMap].
+ final Map children;
+
+ /// The identifier of the widget that is currently selected.
+ ///
+ /// This must be one of the keys in the [Map] of [children].
+ /// If this attribute is null, no widget will be initially selected.
+ final T? groupValue;
+
+ /// The callback that is called when a new option is tapped.
+ ///
+ /// The segmented control passes the newly selected widget's associated key
+ /// to the callback but does not actually change state until the parent
+ /// widget rebuilds the segmented control with the new [groupValue].
+ final ValueChanged onValueChanged;
+
+ /// The color used to fill the backgrounds of unselected widgets and as the
+ /// text color of the selected widget.
+ ///
+ /// Defaults to [CupertinoTheme]'s `primaryContrastingColor` if null.
+ final Color? unselectedColor;
+
+ /// The color used to fill the background of the selected widget and as the text
+ /// color of unselected widgets.
+ ///
+ /// Defaults to [CupertinoTheme]'s `primaryColor` if null.
+ final Color? selectedColor;
+
+ /// The color used as the border around each widget.
+ ///
+ /// Defaults to [CupertinoTheme]'s `primaryColor` if null.
+ final Color? borderColor;
+
+ /// The color used to fill the background of the widget the user is
+ /// temporarily interacting with through a long press or drag.
+ ///
+ /// Defaults to the selectedColor at 20% opacity if null.
+ final Color? pressedColor;
+
+ /// The color used to fill the background of the segment when it is disabled.
+ ///
+ /// If null, this color will be 50% opacity of the [selectedColor] when
+ /// the segment is selected. If the segment is unselected, this color will be
+ /// set to [unselectedColor].
+ final Color? disabledColor;
+
+ /// The color used for the text of the segment when it is disabled.
+ final Color? disabledTextColor;
+
+ /// The CupertinoSegmentedControl will be placed inside this padding.
+ ///
+ /// Defaults to EdgeInsets.symmetric(horizontal: 16.0)
+ final EdgeInsetsGeometry? padding;
+
+ /// The set of identifying keys that correspond to the segments that should be disabled.
+ ///
+ /// All segments are enabled by default.
+ final Set disabledChildren;
+
+ @override
+ State> createState() =>
+ _SegmentedControlState();
+}
+
+class _SegmentedControlState
+ extends State>
+ with TickerProviderStateMixin> {
+ T? _pressedKey;
+
+ final List _selectionControllers =
+ [];
+ final List _childTweens = [];
+
+ late ColorTween _forwardBackgroundColorTween;
+ late ColorTween _reverseBackgroundColorTween;
+ late ColorTween _textColorTween;
+
+ Color? _selectedColor;
+ Color? _unselectedColor;
+ Color? _borderColor;
+ Color? _pressedColor;
+ Color? _selectedDisabledColor;
+ Color? _unselectedDisabledColor;
+ Color? _disabledTextColor;
+
+ AnimationController createAnimationController() {
+ return AnimationController(duration: _kFadeDuration, vsync: this)
+ ..addListener(() {
+ setState(() {
+ // State of background/text colors has changed
+ });
+ });
+ }
+
+ bool _updateColors() {
+ assert(mounted, 'This should only be called after didUpdateDependencies');
+ bool changed = false;
+ final Color disabledTextColor =
+ widget.disabledTextColor ?? _kDisableTextColor;
+ if (_disabledTextColor != disabledTextColor) {
+ changed = true;
+ _disabledTextColor = disabledTextColor;
+ }
+ final Color selectedColor =
+ widget.selectedColor ?? CupertinoTheme.of(context).primaryColor;
+ if (_selectedColor != selectedColor) {
+ changed = true;
+ _selectedColor = selectedColor;
+ }
+ final Color unselectedColor =
+ widget.unselectedColor ??
+ CupertinoTheme.of(context).primaryContrastingColor;
+ if (_unselectedColor != unselectedColor) {
+ changed = true;
+ _unselectedColor = unselectedColor;
+ }
+ final Color selectedDisabledColor =
+ widget.disabledColor ?? selectedColor.withOpacity(0.5);
+ final Color unselectedDisabledColor =
+ widget.disabledColor ?? unselectedColor;
+ if (_selectedDisabledColor != selectedDisabledColor ||
+ _unselectedDisabledColor != unselectedDisabledColor) {
+ changed = true;
+ _selectedDisabledColor = selectedDisabledColor;
+ _unselectedDisabledColor = unselectedDisabledColor;
+ }
+ final Color borderColor =
+ widget.borderColor ?? CupertinoTheme.of(context).primaryColor;
+ if (_borderColor != borderColor) {
+ changed = true;
+ _borderColor = borderColor;
+ }
+ final Color pressedColor =
+ widget.pressedColor ??
+ CupertinoTheme.of(context).primaryColor.withOpacity(0.2);
+ if (_pressedColor != pressedColor) {
+ changed = true;
+ _pressedColor = pressedColor;
+ }
+
+ _forwardBackgroundColorTween = ColorTween(
+ begin: _pressedColor,
+ end: _selectedColor,
+ );
+ _reverseBackgroundColorTween = ColorTween(
+ begin: _unselectedColor,
+ end: _selectedColor,
+ );
+ _textColorTween = ColorTween(begin: _selectedColor, end: _unselectedColor);
+ return changed;
+ }
+
+ void _updateAnimationControllers() {
+ assert(mounted, 'This should only be called after didUpdateDependencies');
+ for (final AnimationController controller in _selectionControllers) {
+ controller.dispose();
+ }
+ _selectionControllers.clear();
+ _childTweens.clear();
+
+ for (final T key in widget.children.keys) {
+ final AnimationController animationController =
+ createAnimationController();
+ if (widget.groupValue == key) {
+ _childTweens.add(_reverseBackgroundColorTween);
+ animationController.value = 1.0;
+ } else {
+ _childTweens.add(_forwardBackgroundColorTween);
+ }
+ _selectionControllers.add(animationController);
+ }
+ }
+
+ @override
+ void didChangeDependencies() {
+ super.didChangeDependencies();
+
+ if (_updateColors()) {
+ _updateAnimationControllers();
+ }
+ }
+
+ @override
+ void didUpdateWidget(NewCupertinoSegmentedControl oldWidget) {
+ super.didUpdateWidget(oldWidget);
+
+ if (_updateColors() ||
+ oldWidget.children.length != widget.children.length) {
+ _updateAnimationControllers();
+ }
+
+ if (oldWidget.groupValue != widget.groupValue) {
+ int index = 0;
+ for (final T key in widget.children.keys) {
+ if (widget.groupValue == key) {
+ _childTweens[index] = _forwardBackgroundColorTween;
+ _selectionControllers[index].forward();
+ } else {
+ _childTweens[index] = _reverseBackgroundColorTween;
+ _selectionControllers[index].reverse();
+ }
+ index += 1;
+ }
+ }
+ }
+
+ @override
+ void dispose() {
+ for (final AnimationController animationController
+ in _selectionControllers) {
+ animationController.dispose();
+ }
+ super.dispose();
+ }
+
+ void _onTapDown(T currentKey) {
+ if (_pressedKey == null && currentKey != widget.groupValue) {
+ setState(() {
+ _pressedKey = currentKey;
+ });
+ }
+ }
+
+ void _onTapCancel() {
+ setState(() {
+ _pressedKey = null;
+ });
+ }
+
+ void _onTap(T currentKey) {
+ if (currentKey != _pressedKey) {
+ return;
+ }
+ if (!widget.disabledChildren.contains(currentKey)) {
+ if (currentKey != widget.groupValue) {
+ widget.onValueChanged(currentKey);
+ }
+ }
+ _pressedKey = null;
+ }
+
+ Color? getTextColor(int index, T currentKey) {
+ if (widget.disabledChildren.contains(currentKey)) {
+ return _disabledTextColor;
+ }
+ if (_selectionControllers[index].isAnimating) {
+ return _textColorTween.evaluate(_selectionControllers[index]);
+ }
+ if (widget.groupValue == currentKey) {
+ return _unselectedColor;
+ }
+ return _selectedColor;
+ }
+
+ Color? getBackgroundColor(int index, T currentKey) {
+ if (widget.disabledChildren.contains(currentKey)) {
+ return widget.groupValue == currentKey
+ ? _selectedDisabledColor
+ : _unselectedDisabledColor;
+ }
+ if (_selectionControllers[index].isAnimating) {
+ return _childTweens[index].evaluate(_selectionControllers[index]);
+ }
+ if (widget.groupValue == currentKey) {
+ return _selectedColor;
+ }
+ if (_pressedKey == currentKey) {
+ return _pressedColor;
+ }
+ return _unselectedColor;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final List gestureChildren = [];
+ final List backgroundColors = [];
+ int index = 0;
+ int? selectedIndex;
+ int? pressedIndex;
+ for (final T currentKey in widget.children.keys) {
+ selectedIndex = (widget.groupValue == currentKey) ? index : selectedIndex;
+ pressedIndex = (_pressedKey == currentKey) ? index : pressedIndex;
+
+ final TextStyle textStyle = DefaultTextStyle.of(
+ context,
+ ).style.copyWith(color: getTextColor(index, currentKey));
+ final IconThemeData iconTheme = IconThemeData(
+ color: getTextColor(index, currentKey),
+ );
+
+ Widget child = Center(child: widget.children[currentKey]);
+
+ child = MouseRegion(
+ cursor: kIsWeb ? SystemMouseCursors.click : MouseCursor.defer,
+ child: GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTapDown:
+ widget.disabledChildren.contains(currentKey)
+ ? null
+ : (TapDownDetails event) {
+ _onTapDown(currentKey);
+ },
+ onTapCancel:
+ widget.disabledChildren.contains(currentKey)
+ ? null
+ : _onTapCancel,
+ onTap: () {
+ _onTap(currentKey);
+ },
+ child: IconTheme(
+ data: iconTheme,
+ child: DefaultTextStyle(
+ style: textStyle,
+ child: Semantics(
+ button: true,
+ inMutuallyExclusiveGroup: true,
+ selected: widget.groupValue == currentKey,
+ child: child,
+ ),
+ ),
+ ),
+ ),
+ );
+
+ backgroundColors.add(getBackgroundColor(index, currentKey)!);
+ gestureChildren.add(child);
+ index += 1;
+ }
+
+ final Widget box = _SegmentedControlRenderWidget(
+ selectedIndex: selectedIndex,
+ pressedIndex: pressedIndex,
+ backgroundColors: backgroundColors,
+ borderColor: _borderColor!,
+ children: gestureChildren,
+ );
+
+ return Padding(
+ padding: widget.padding ?? _kHorizontalItemPadding,
+ child: UnconstrainedBox(constrainedAxis: Axis.horizontal, child: box),
+ );
+ }
+}
+
+class _SegmentedControlRenderWidget extends MultiChildRenderObjectWidget {
+ const _SegmentedControlRenderWidget({
+ super.key,
+ super.children,
+ required this.selectedIndex,
+ required this.pressedIndex,
+ required this.backgroundColors,
+ required this.borderColor,
+ });
+
+ final int? selectedIndex;
+ final int? pressedIndex;
+ final List backgroundColors;
+ final Color borderColor;
+
+ @override
+ RenderObject createRenderObject(BuildContext context) {
+ return _RenderSegmentedControl(
+ textDirection: Directionality.of(context),
+ selectedIndex: selectedIndex,
+ pressedIndex: pressedIndex,
+ backgroundColors: backgroundColors,
+ borderColor: borderColor,
+ );
+ }
+
+ @override
+ void updateRenderObject(
+ BuildContext context,
+ _RenderSegmentedControl renderObject,
+ ) {
+ renderObject
+ ..textDirection = Directionality.of(context)
+ ..selectedIndex = selectedIndex
+ ..pressedIndex = pressedIndex
+ ..backgroundColors = backgroundColors
+ ..borderColor = borderColor;
+ }
+}
+
+class _SegmentedControlContainerBoxParentData
+ extends ContainerBoxParentData {
+ RRect? surroundingRect;
+}
+
+typedef _NextChild = RenderBox? Function(RenderBox child);
+
+class _RenderSegmentedControl extends RenderBox
+ with
+ ContainerRenderObjectMixin<
+ RenderBox,
+ ContainerBoxParentData
+ >,
+ RenderBoxContainerDefaultsMixin<
+ RenderBox,
+ ContainerBoxParentData
+ > {
+ _RenderSegmentedControl({
+ required int? selectedIndex,
+ required int? pressedIndex,
+ required TextDirection textDirection,
+ required List backgroundColors,
+ required Color borderColor,
+ }) : _textDirection = textDirection,
+ _selectedIndex = selectedIndex,
+ _pressedIndex = pressedIndex,
+ _backgroundColors = backgroundColors,
+ _borderColor = borderColor;
+
+ int? get selectedIndex => _selectedIndex;
+ int? _selectedIndex;
+
+ set selectedIndex(int? value) {
+ if (_selectedIndex == value) {
+ return;
+ }
+ _selectedIndex = value;
+ markNeedsPaint();
+ }
+
+ int? get pressedIndex => _pressedIndex;
+ int? _pressedIndex;
+
+ set pressedIndex(int? value) {
+ if (_pressedIndex == value) {
+ return;
+ }
+ _pressedIndex = value;
+ markNeedsPaint();
+ }
+
+ TextDirection get textDirection => _textDirection;
+ TextDirection _textDirection;
+
+ set textDirection(TextDirection value) {
+ if (_textDirection == value) {
+ return;
+ }
+ _textDirection = value;
+ markNeedsLayout();
+ }
+
+ List get backgroundColors => _backgroundColors;
+ List _backgroundColors;
+
+ set backgroundColors(List value) {
+ if (_backgroundColors == value) {
+ return;
+ }
+ _backgroundColors = value;
+ markNeedsPaint();
+ }
+
+ Color get borderColor => _borderColor;
+ Color _borderColor;
+
+ set borderColor(Color value) {
+ if (_borderColor == value) {
+ return;
+ }
+ _borderColor = value;
+ markNeedsPaint();
+ }
+
+ @override
+ double computeMinIntrinsicWidth(double height) {
+ RenderBox? child = firstChild;
+ double minWidth = 0.0;
+ while (child != null) {
+ final _SegmentedControlContainerBoxParentData childParentData =
+ child.parentData! as _SegmentedControlContainerBoxParentData;
+ final double childWidth = child.getMinIntrinsicWidth(height);
+ minWidth = math.max(minWidth, childWidth);
+ child = childParentData.nextSibling;
+ }
+ return minWidth * childCount;
+ }
+
+ @override
+ double computeMaxIntrinsicWidth(double height) {
+ RenderBox? child = firstChild;
+ double maxWidth = 0.0;
+ while (child != null) {
+ final _SegmentedControlContainerBoxParentData childParentData =
+ child.parentData! as _SegmentedControlContainerBoxParentData;
+ final double childWidth = child.getMaxIntrinsicWidth(height);
+ maxWidth = math.max(maxWidth, childWidth);
+ child = childParentData.nextSibling;
+ }
+ return maxWidth * childCount;
+ }
+
+ @override
+ double computeMinIntrinsicHeight(double width) {
+ RenderBox? child = firstChild;
+ double minHeight = 0.0;
+ while (child != null) {
+ final _SegmentedControlContainerBoxParentData childParentData =
+ child.parentData! as _SegmentedControlContainerBoxParentData;
+ final double childHeight = child.getMinIntrinsicHeight(width);
+ minHeight = math.max(minHeight, childHeight);
+ child = childParentData.nextSibling;
+ }
+ return minHeight;
+ }
+
+ @override
+ double computeMaxIntrinsicHeight(double width) {
+ RenderBox? child = firstChild;
+ double maxHeight = 0.0;
+ while (child != null) {
+ final _SegmentedControlContainerBoxParentData childParentData =
+ child.parentData! as _SegmentedControlContainerBoxParentData;
+ final double childHeight = child.getMaxIntrinsicHeight(width);
+ maxHeight = math.max(maxHeight, childHeight);
+ child = childParentData.nextSibling;
+ }
+ return maxHeight;
+ }
+
+ @override
+ double? computeDistanceToActualBaseline(TextBaseline baseline) {
+ return defaultComputeDistanceToHighestActualBaseline(baseline);
+ }
+
+ @override
+ void setupParentData(RenderBox child) {
+ if (child.parentData is! _SegmentedControlContainerBoxParentData) {
+ child.parentData = _SegmentedControlContainerBoxParentData();
+ }
+ }
+
+ void _layoutRects(
+ _NextChild nextChild,
+ RenderBox? leftChild,
+ RenderBox? rightChild,
+ ) {
+ RenderBox? child = leftChild;
+ double start = 0.0;
+ while (child != null) {
+ final _SegmentedControlContainerBoxParentData childParentData =
+ child.parentData! as _SegmentedControlContainerBoxParentData;
+ final Offset childOffset = Offset(start, 0.0);
+ childParentData.offset = childOffset;
+ final Rect childRect = Rect.fromLTWH(
+ start,
+ 0.0,
+ child.size.width,
+ child.size.height,
+ );
+ final RRect rChildRect;
+ if (child == leftChild) {
+ rChildRect = RRect.fromRectAndCorners(
+ childRect,
+ topLeft: const Radius.circular(10.0),
+ bottomLeft: const Radius.circular(10.0),
+ );
+ } else if (child == rightChild) {
+ rChildRect = RRect.fromRectAndCorners(
+ childRect,
+ topRight: const Radius.circular(10.0),
+ bottomRight: const Radius.circular(10.0),
+ );
+ } else {
+ rChildRect = RRect.fromRectAndCorners(childRect);
+ }
+ childParentData.surroundingRect = rChildRect;
+ start += child.size.width;
+ child = nextChild(child);
+ }
+ }
+
+ Size _calculateChildSize(BoxConstraints constraints) {
+ double maxHeight = _kMinSegmentedControlHeight;
+ double childWidth = constraints.minWidth / childCount;
+ RenderBox? child = firstChild;
+ while (child != null) {
+ childWidth = math.max(
+ childWidth,
+ child.getMaxIntrinsicWidth(double.infinity),
+ );
+ child = childAfter(child);
+ }
+ childWidth = math.min(childWidth, constraints.maxWidth / childCount);
+ child = firstChild;
+ while (child != null) {
+ final double boxHeight = child.getMaxIntrinsicHeight(childWidth);
+ maxHeight = math.max(maxHeight, boxHeight);
+ child = childAfter(child);
+ }
+ return Size(childWidth, maxHeight);
+ }
+
+ Size _computeOverallSizeFromChildSize(Size childSize) {
+ return constraints.constrain(
+ Size(childSize.width * childCount, childSize.height),
+ );
+ }
+
+ @override
+ double? computeDryBaseline(
+ covariant BoxConstraints constraints,
+ TextBaseline baseline,
+ ) {
+ final Size childSize = _calculateChildSize(constraints);
+ final BoxConstraints childConstraints = BoxConstraints.tight(childSize);
+
+ BaselineOffset baselineOffset = BaselineOffset.noBaseline;
+ for (
+ RenderBox? child = firstChild;
+ child != null;
+ child = childAfter(child)
+ ) {
+ baselineOffset = baselineOffset.minOf(
+ BaselineOffset(child.getDryBaseline(childConstraints, baseline)),
+ );
+ }
+ return baselineOffset.offset;
+ }
+
+ @override
+ Size computeDryLayout(BoxConstraints constraints) {
+ final Size childSize = _calculateChildSize(constraints);
+ return _computeOverallSizeFromChildSize(childSize);
+ }
+
+ @override
+ void performLayout() {
+ final BoxConstraints constraints = this.constraints;
+ final Size childSize = _calculateChildSize(constraints);
+
+ final BoxConstraints childConstraints = BoxConstraints.tightFor(
+ width: childSize.width,
+ height: childSize.height,
+ );
+
+ RenderBox? child = firstChild;
+ while (child != null) {
+ child.layout(childConstraints, parentUsesSize: true);
+ child = childAfter(child);
+ }
+
+ switch (textDirection) {
+ case TextDirection.rtl:
+ _layoutRects(childBefore, lastChild, firstChild);
+ case TextDirection.ltr:
+ _layoutRects(childAfter, firstChild, lastChild);
+ }
+
+ size = _computeOverallSizeFromChildSize(childSize);
+ }
+
+ @override
+ void paint(PaintingContext context, Offset offset) {
+ RenderBox? child = firstChild;
+ int index = 0;
+ while (child != null) {
+ _paintChild(context, offset, child, index);
+ child = childAfter(child);
+ index += 1;
+ }
+ }
+
+ void _paintChild(
+ PaintingContext context,
+ Offset offset,
+ RenderBox child,
+ int childIndex,
+ ) {
+ final _SegmentedControlContainerBoxParentData childParentData =
+ child.parentData! as _SegmentedControlContainerBoxParentData;
+
+ context.canvas.drawRRect(
+ childParentData.surroundingRect!.shift(offset),
+ Paint()
+ ..color = backgroundColors[childIndex]
+ ..style = PaintingStyle.fill,
+ );
+ context.canvas.drawRRect(
+ childParentData.surroundingRect!.shift(offset),
+ Paint()
+ ..color = borderColor
+ ..strokeWidth = 1.0
+ ..style = PaintingStyle.stroke,
+ );
+
+ context.paintChild(child, childParentData.offset + offset);
+ }
+
+ @override
+ bool hitTestChildren(BoxHitTestResult result, {required Offset position}) {
+ RenderBox? child = lastChild;
+ while (child != null) {
+ final _SegmentedControlContainerBoxParentData childParentData =
+ child.parentData! as _SegmentedControlContainerBoxParentData;
+ if (childParentData.surroundingRect!.contains(position)) {
+ return result.addWithPaintOffset(
+ offset: childParentData.offset,
+ position: position,
+ hitTest: (BoxHitTestResult result, Offset localOffset) {
+ assert(localOffset == position - childParentData.offset);
+ return child!.hitTest(result, position: localOffset);
+ },
+ );
+ }
+ child = childParentData.previousSibling;
+ }
+ return false;
+ }
+}
diff --git a/lib/presentation/widget/tabs/tab.dart b/lib/presentation/widget/tabs/tab.dart
new file mode 100644
index 0000000..ac2f735
--- /dev/null
+++ b/lib/presentation/widget/tabs/tab.dart
@@ -0,0 +1,115 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:rasadyar_app/presentation/common/app_color.dart';
+import 'package:rasadyar_app/presentation/common/app_fonts.dart';
+
+import 'new_tab.dart';
+
+class CupertinoSegmentedControlDemo extends StatefulWidget {
+ const CupertinoSegmentedControlDemo({super.key});
+
+ @override
+ State createState() =>
+ _CupertinoSegmentedControlDemoState();
+}
+
+class _CupertinoSegmentedControlDemoState
+ extends State {
+ int _selectedSegment = 0;
+
+ // The data for the segments
+ final Map _segments = const {
+ 0: Text('Segment 1'),
+ 1: Text('Segment 2'),
+ 2: Text('Segment 3'),
+ };
+
+ @override
+ Widget build(BuildContext context) {
+ return SafeArea(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ CupertinoSlidingSegmentedControl(
+ children: _segments,
+ groupValue: _selectedSegment,
+
+ onValueChanged: (int? value) {
+ setState(() {
+ _selectedSegment = value!;
+ });
+ },
+ ),
+ const SizedBox(height: 20),
+ Text(
+ 'Selected Segment: ${_selectedSegment + 1}',
+ style: const TextStyle(fontSize: 24),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
+class CupertinoSegmentedControlDemo2 extends StatefulWidget {
+ const CupertinoSegmentedControlDemo2({super.key});
+
+ @override
+ State createState() =>
+ _CupertinoSegmentedControlDemoState2();
+}
+
+class _CupertinoSegmentedControlDemoState2
+ extends State {
+ int _selectedSegment = 0;
+
+ // The data for the segments
+ final Map _segments = {
+ 0:Container(
+ padding: EdgeInsets.all(10),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(50)
+ ),
+ child: Text('لاشه', style: AppFonts.yekan13Regular),
+ ),
+ 1: Container(
+ padding: EdgeInsets.all(10),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(50)
+ ),
+ child: Text('زنده', style: AppFonts.yekan13Regular),
+ ),
+ };
+
+ @override
+ Widget build(BuildContext context) {
+ return SafeArea(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ NewCupertinoSegmentedControl(
+ padding: EdgeInsetsDirectional.symmetric(
+ horizontal: 20,
+ vertical: 10,
+ ),
+ children: _segments,
+ groupValue: _selectedSegment,
+ selectedColor: AppColor.blueNormal,
+ unselectedColor: Colors.white,
+ borderColor: Colors.grey.shade300,
+ onValueChanged: (int value) {
+ setState(() {
+ _selectedSegment = value;
+ });
+ },
+ ),
+ const SizedBox(height: 20),
+ Text(
+ 'Selected Segment: ${_selectedSegment + 1}',
+ style: const TextStyle(fontSize: 24),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/presentation/widget/vec_widget.dart b/lib/presentation/widget/vec_widget.dart
new file mode 100644
index 0000000..8f76b40
--- /dev/null
+++ b/lib/presentation/widget/vec_widget.dart
@@ -0,0 +1,47 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:vector_graphics/vector_graphics.dart';
+
+SvgPicture vecWidget(
+ String assets, {
+ double? width,
+ double? height,
+ BoxFit? fit,
+ Color? color,
+}) {
+ return SvgPicture(
+ AssetBytesLoader(assets),
+ width: width,
+ height: height,
+ fit: fit ?? BoxFit.contain,
+ colorFilter:
+ color != null ? ColorFilter.mode(color, BlendMode.srcIn) : null,
+ );
+}
+Widget vecWidget2(
+ String assets, {
+ double? width,
+ double? height,
+ BoxFit? fit,
+ Color? color,
+ }) {
+ final resolvedColor = WidgetStateProperty.resolveWith((states) {
+ if (states.contains(WidgetState.pressed)) {
+ return Colors.white;
+ }
+ return color;
+ }).resolve({}); // You can pass actual states if needed
+
+ return IconTheme(
+ data: IconThemeData(color: resolvedColor),
+ child: SvgPicture(
+ AssetBytesLoader(assets),
+ width: width,
+ height: height,
+ fit: fit ?? BoxFit.contain,
+ colorFilter: resolvedColor != null
+ ? ColorFilter.mode(resolvedColor, BlendMode.srcIn)
+ : null,
+ ),
+ );
+}
diff --git a/pubspec.yaml b/pubspec.yaml
index bb74dfd..52bb4ec 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -58,34 +58,14 @@ dev_dependencies:
flutter:
uses-material-design: true
- # To add assets to your application, add an assets section, like this:
+
assets:
- assets/icons/
- assets/images/
- assets/logos/
+ - assets/vec/
- # An image asset can refer to one or more resolution-specific "variants", see
- # https://flutter.dev/to/resolution-aware-images
-
- # For details regarding adding assets from package dependencies, see
- # https://flutter.dev/to/asset-from-package
-
- # To add 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/to/font-from-package
+ fonts:
+ - family: yekan
+ fonts:
+ - asset: fonts/iranyekanregularfanum.ttf
diff --git a/vecGeneratoe.sh b/vecGeneratoe.sh
new file mode 100644
index 0000000..4f92558
--- /dev/null
+++ b/vecGeneratoe.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+
+# Directory to read files from
+sourcePath="assets/icons"
+targetPath="assets/vec"
+
+
+if [ ! -e "$targetPath" ]; then
+ echo "📁 Directory does not exist. Creating: $targetPath"
+ mkdir -p "$targetPath"
+fi
+
+
+# Loop and delete old vec file
+for file in "$targetPath"/*
+do
+ if [ -f "$file" ]; then
+
+ echo "Delete old ===> $file"
+ rm "$file"
+ fi
+done
+# Loop through all files in the directory
+for file in "$sourcePath"/*
+do
+ if [ -f "$file" ]; then
+ echo "Generate Vec file ===> $file"
+ fileName=$(basename -- "$file")
+ echo "Generate Vec file ===> $fileName"
+ dart run vector_graphics_compiler -i "$file" -o "$targetPath/$fileName.vec"
+ git add .
+ fi
+done
\ No newline at end of file