diff --git a/assets/back.png b/assets/back.png
new file mode 100644
index 0000000..bb65f3f
Binary files /dev/null and b/assets/back.png differ
diff --git a/assets/cart.svg b/assets/cart.svg
new file mode 100644
index 0000000..6712379
--- /dev/null
+++ b/assets/cart.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/assets/check.svg b/assets/check.svg
new file mode 100644
index 0000000..c9b377d
--- /dev/null
+++ b/assets/check.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/chevron-down.svg b/assets/chevron-down.svg
new file mode 100644
index 0000000..fcd03b7
--- /dev/null
+++ b/assets/chevron-down.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/chevron-left.svg b/assets/chevron-left.svg
new file mode 100644
index 0000000..b20e1e4
--- /dev/null
+++ b/assets/chevron-left.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/chevron-right.svg b/assets/chevron-right.svg
new file mode 100644
index 0000000..fdf3722
--- /dev/null
+++ b/assets/chevron-right.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/close.svg b/assets/close.svg
new file mode 100644
index 0000000..d9d5438
--- /dev/null
+++ b/assets/close.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/closed-eye.svg b/assets/closed-eye.svg
new file mode 100644
index 0000000..0906817
--- /dev/null
+++ b/assets/closed-eye.svg
@@ -0,0 +1,10 @@
+
diff --git a/assets/delete.svg b/assets/delete.svg
new file mode 100644
index 0000000..15b1793
--- /dev/null
+++ b/assets/delete.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/dismiss.svg b/assets/dismiss.svg
new file mode 100644
index 0000000..81e9d95
--- /dev/null
+++ b/assets/dismiss.svg
@@ -0,0 +1,38 @@
+
+
diff --git a/assets/download.svg b/assets/download.svg
new file mode 100644
index 0000000..9b425f7
--- /dev/null
+++ b/assets/download.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/eye.svg b/assets/eye.svg
new file mode 100644
index 0000000..83366c6
--- /dev/null
+++ b/assets/eye.svg
@@ -0,0 +1,11 @@
+
diff --git a/assets/file-text.svg b/assets/file-text.svg
new file mode 100644
index 0000000..90ccc71
--- /dev/null
+++ b/assets/file-text.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/filter.svg b/assets/filter.svg
new file mode 100644
index 0000000..0365b57
--- /dev/null
+++ b/assets/filter.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/filters.png b/assets/filters.png
new file mode 100644
index 0000000..8ffb343
Binary files /dev/null and b/assets/filters.png differ
diff --git a/assets/hidden.png b/assets/hidden.png
new file mode 100644
index 0000000..1608296
Binary files /dev/null and b/assets/hidden.png differ
diff --git a/assets/home-active.png b/assets/home-active.png
new file mode 100644
index 0000000..bc4c7ce
Binary files /dev/null and b/assets/home-active.png differ
diff --git a/assets/home.png b/assets/home.png
new file mode 100644
index 0000000..680ab98
Binary files /dev/null and b/assets/home.png differ
diff --git a/assets/map.svg b/assets/map.svg
new file mode 100644
index 0000000..f35a41c
--- /dev/null
+++ b/assets/map.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/assets/message-circle.svg b/assets/message-circle.svg
new file mode 100644
index 0000000..73e8414
--- /dev/null
+++ b/assets/message-circle.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/mic.svg b/assets/mic.svg
new file mode 100644
index 0000000..8e24820
--- /dev/null
+++ b/assets/mic.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/assets/minus.svg b/assets/minus.svg
new file mode 100644
index 0000000..e26a25e
--- /dev/null
+++ b/assets/minus.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/more-horizontal.svg b/assets/more-horizontal.svg
new file mode 100644
index 0000000..6076bdb
--- /dev/null
+++ b/assets/more-horizontal.svg
@@ -0,0 +1,5 @@
+
diff --git a/assets/paperclip.svg b/assets/paperclip.svg
new file mode 100644
index 0000000..50f4dd0
--- /dev/null
+++ b/assets/paperclip.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/people.png b/assets/people.png
new file mode 100644
index 0000000..47ceae0
Binary files /dev/null and b/assets/people.png differ
diff --git a/assets/plus.svg b/assets/plus.svg
new file mode 100644
index 0000000..27a8b51
--- /dev/null
+++ b/assets/plus.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/profile-active.png b/assets/profile-active.png
new file mode 100644
index 0000000..8d574eb
Binary files /dev/null and b/assets/profile-active.png differ
diff --git a/assets/profile.png b/assets/profile.png
new file mode 100644
index 0000000..7cb662a
Binary files /dev/null and b/assets/profile.png differ
diff --git a/assets/projects-active.png b/assets/projects-active.png
new file mode 100644
index 0000000..d188a00
Binary files /dev/null and b/assets/projects-active.png differ
diff --git a/assets/projects.png b/assets/projects.png
new file mode 100644
index 0000000..9442177
Binary files /dev/null and b/assets/projects.png differ
diff --git a/assets/results-active.png b/assets/results-active.png
new file mode 100644
index 0000000..1f606f8
Binary files /dev/null and b/assets/results-active.png differ
diff --git a/assets/results.png b/assets/results.png
new file mode 100644
index 0000000..c94ddd2
Binary files /dev/null and b/assets/results.png differ
diff --git a/assets/search.svg b/assets/search.svg
new file mode 100644
index 0000000..3f704f7
--- /dev/null
+++ b/assets/search.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/assets/send.svg b/assets/send.svg
new file mode 100644
index 0000000..84a71d7
--- /dev/null
+++ b/assets/send.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/assets/vk.png b/assets/vk.png
new file mode 100644
index 0000000..73eda41
Binary files /dev/null and b/assets/vk.png differ
diff --git a/assets/yandex.png b/assets/yandex.png
new file mode 100644
index 0000000..3e8b1b8
Binary files /dev/null and b/assets/yandex.png differ
diff --git a/example/assets/back.png b/example/assets/back.png
new file mode 100644
index 0000000..bb65f3f
Binary files /dev/null and b/example/assets/back.png differ
diff --git a/example/assets/cart.svg b/example/assets/cart.svg
new file mode 100644
index 0000000..6712379
--- /dev/null
+++ b/example/assets/cart.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/example/assets/check.svg b/example/assets/check.svg
new file mode 100644
index 0000000..c9b377d
--- /dev/null
+++ b/example/assets/check.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/chevron-down.svg b/example/assets/chevron-down.svg
new file mode 100644
index 0000000..fcd03b7
--- /dev/null
+++ b/example/assets/chevron-down.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/chevron-left.svg b/example/assets/chevron-left.svg
new file mode 100644
index 0000000..b20e1e4
--- /dev/null
+++ b/example/assets/chevron-left.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/chevron-right.svg b/example/assets/chevron-right.svg
new file mode 100644
index 0000000..fdf3722
--- /dev/null
+++ b/example/assets/chevron-right.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/close.svg b/example/assets/close.svg
new file mode 100644
index 0000000..d9d5438
--- /dev/null
+++ b/example/assets/close.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/closed-eye.svg b/example/assets/closed-eye.svg
new file mode 100644
index 0000000..0906817
--- /dev/null
+++ b/example/assets/closed-eye.svg
@@ -0,0 +1,10 @@
+
diff --git a/example/assets/delete.svg b/example/assets/delete.svg
new file mode 100644
index 0000000..15b1793
--- /dev/null
+++ b/example/assets/delete.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/dismiss.svg b/example/assets/dismiss.svg
new file mode 100644
index 0000000..81e9d95
--- /dev/null
+++ b/example/assets/dismiss.svg
@@ -0,0 +1,38 @@
+
+
diff --git a/example/assets/divider.svg b/example/assets/divider.svg
new file mode 100644
index 0000000..5af48bf
--- /dev/null
+++ b/example/assets/divider.svg
@@ -0,0 +1,3 @@
+
diff --git a/example/assets/download.svg b/example/assets/download.svg
new file mode 100644
index 0000000..9b425f7
--- /dev/null
+++ b/example/assets/download.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/eye.svg b/example/assets/eye.svg
new file mode 100644
index 0000000..83366c6
--- /dev/null
+++ b/example/assets/eye.svg
@@ -0,0 +1,11 @@
+
diff --git a/example/assets/file-text.svg b/example/assets/file-text.svg
new file mode 100644
index 0000000..90ccc71
--- /dev/null
+++ b/example/assets/file-text.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/filter.svg b/example/assets/filter.svg
new file mode 100644
index 0000000..0365b57
--- /dev/null
+++ b/example/assets/filter.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/filters.png b/example/assets/filters.png
new file mode 100644
index 0000000..8ffb343
Binary files /dev/null and b/example/assets/filters.png differ
diff --git a/example/assets/hidden.png b/example/assets/hidden.png
new file mode 100644
index 0000000..1608296
Binary files /dev/null and b/example/assets/hidden.png differ
diff --git a/example/assets/home-active.png b/example/assets/home-active.png
new file mode 100644
index 0000000..bc4c7ce
Binary files /dev/null and b/example/assets/home-active.png differ
diff --git a/example/assets/home.png b/example/assets/home.png
new file mode 100644
index 0000000..680ab98
Binary files /dev/null and b/example/assets/home.png differ
diff --git a/example/assets/map.svg b/example/assets/map.svg
new file mode 100644
index 0000000..f35a41c
--- /dev/null
+++ b/example/assets/map.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/example/assets/message-circle.svg b/example/assets/message-circle.svg
new file mode 100644
index 0000000..73e8414
--- /dev/null
+++ b/example/assets/message-circle.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/mic.svg b/example/assets/mic.svg
new file mode 100644
index 0000000..8e24820
--- /dev/null
+++ b/example/assets/mic.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/example/assets/minus.svg b/example/assets/minus.svg
new file mode 100644
index 0000000..e26a25e
--- /dev/null
+++ b/example/assets/minus.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/more-horizontal.svg b/example/assets/more-horizontal.svg
new file mode 100644
index 0000000..6076bdb
--- /dev/null
+++ b/example/assets/more-horizontal.svg
@@ -0,0 +1,5 @@
+
diff --git a/example/assets/paperclip.svg b/example/assets/paperclip.svg
new file mode 100644
index 0000000..50f4dd0
--- /dev/null
+++ b/example/assets/paperclip.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/people.png b/example/assets/people.png
new file mode 100644
index 0000000..47ceae0
Binary files /dev/null and b/example/assets/people.png differ
diff --git a/example/assets/plus.svg b/example/assets/plus.svg
new file mode 100644
index 0000000..27a8b51
--- /dev/null
+++ b/example/assets/plus.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/profile-active.png b/example/assets/profile-active.png
new file mode 100644
index 0000000..8d574eb
Binary files /dev/null and b/example/assets/profile-active.png differ
diff --git a/example/assets/profile.png b/example/assets/profile.png
new file mode 100644
index 0000000..7cb662a
Binary files /dev/null and b/example/assets/profile.png differ
diff --git a/example/assets/projects-active.png b/example/assets/projects-active.png
new file mode 100644
index 0000000..d188a00
Binary files /dev/null and b/example/assets/projects-active.png differ
diff --git a/example/assets/projects.png b/example/assets/projects.png
new file mode 100644
index 0000000..9442177
Binary files /dev/null and b/example/assets/projects.png differ
diff --git a/example/assets/results-active.png b/example/assets/results-active.png
new file mode 100644
index 0000000..1f606f8
Binary files /dev/null and b/example/assets/results-active.png differ
diff --git a/example/assets/results.png b/example/assets/results.png
new file mode 100644
index 0000000..c94ddd2
Binary files /dev/null and b/example/assets/results.png differ
diff --git a/example/assets/robotoFlex.ttf b/example/assets/robotoFlex.ttf
new file mode 100644
index 0000000..2e5c2a2
Binary files /dev/null and b/example/assets/robotoFlex.ttf differ
diff --git a/example/assets/search.svg b/example/assets/search.svg
new file mode 100644
index 0000000..3f704f7
--- /dev/null
+++ b/example/assets/search.svg
@@ -0,0 +1,39 @@
+
+
diff --git a/example/assets/send.svg b/example/assets/send.svg
new file mode 100644
index 0000000..84a71d7
--- /dev/null
+++ b/example/assets/send.svg
@@ -0,0 +1,52 @@
+
+
diff --git a/example/assets/vk.png b/example/assets/vk.png
new file mode 100644
index 0000000..73eda41
Binary files /dev/null and b/example/assets/vk.png differ
diff --git a/example/assets/yandex.png b/example/assets/yandex.png
new file mode 100644
index 0000000..3e8b1b8
Binary files /dev/null and b/example/assets/yandex.png differ
diff --git a/example/lib/bottom_sheet_section.dart b/example/lib/bottom_sheet_section.dart
new file mode 100644
index 0000000..bd8ab06
--- /dev/null
+++ b/example/lib/bottom_sheet_section.dart
@@ -0,0 +1,64 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class BottomSheetSection extends StatefulWidget {
+ const BottomSheetSection({super.key});
+
+ @override
+ State createState() => _BottomSheetSectionState();
+}
+
+class _BottomSheetSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.only(top: height(context) * 3),
+ child: Column(
+ children: [
+ ButtonWidget(
+ onPressed: () {
+ showBottomSheetFunc(Column(), context);
+ },
+ label: "Показать Модалку(Background)",
+ variant: 'flat',
+ ),
+ SizedBox(height: height(context) * 3),
+ ButtonWidget(
+ onPressed: () {
+ showBottomSheetFunc(
+ Column(
+ children: [
+ Container(
+ padding: EdgeInsets.symmetric(
+ horizontal: 20,
+ vertical: 24,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ SizedBox(
+ width: width(context) * 60,
+ child: Text(
+ 'Рубашка Воскресенье для машинного вязания',
+ style: title1ExtraBold,
+ ),
+ ),
+ SvgPicture.asset('assets/close.svg'),
+ ],
+ ),
+ ),
+ ],
+ ),
+ context,
+ );
+ },
+ label: 'Показать Модалку',
+ variant: 'flat',
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/example/lib/button_section.dart b/example/lib/button_section.dart
new file mode 100644
index 0000000..974d39f
--- /dev/null
+++ b/example/lib/button_section.dart
@@ -0,0 +1,35 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class ButtonSection extends StatefulWidget {
+ const ButtonSection({super.key});
+
+ @override
+ State createState() => _ButtonSectionState();
+}
+
+class _ButtonSectionState extends State {
+ static final buttonList = ['flat', 'inactive', 'solid', 'ghost'];
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: width(context) * 100,
+ height: height(context) * 40,
+ child: ListView.builder(
+ itemCount: buttonList.length,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = buttonList[index];
+ return Container(
+ margin: EdgeInsets.only(bottom: 10),
+ child: ButtonWidget(
+ onPressed: () {},
+ label: 'Подтвердить',
+ variant: currentItem,
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/card_section.dart b/example/lib/card_section.dart
new file mode 100644
index 0000000..dadc52a
--- /dev/null
+++ b/example/lib/card_section.dart
@@ -0,0 +1,41 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class CardSection extends StatefulWidget {
+ const CardSection({super.key});
+
+ @override
+ State createState() => _CardSectionState();
+}
+
+class _CardSectionState extends State {
+ static final cardsList = [
+ CardWidget(child: SizedBox()),
+ PrimaryCard(
+ title: 'Рубашка Воскресенье для машинного вязания',
+ category: 'Мужская одежда',
+ price: '300',
+ ),
+ CartCard(
+ title: 'Рубашка воскресенье для машинного вязания',
+ price: '300',
+ count: '1',
+ ),
+ ProjectCard(title: 'Мой первый проект', lastDate: '2', onPressed: () {}),
+ ];
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.only(top: height(context) * 3),
+ width: width(context) * 100,
+ height: height(context) * 80,
+ child: ListView.builder(
+ itemCount: cardsList.length,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = cardsList[index];
+ return currentItem;
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/cart_button_section.dart b/example/lib/cart_button_section.dart
new file mode 100644
index 0000000..3d4952f
--- /dev/null
+++ b/example/lib/cart_button_section.dart
@@ -0,0 +1,22 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/cart_button.dart';
+import 'package:ui_kit/utils.dart';
+
+class CartButtonSection extends StatefulWidget {
+ const CartButtonSection({super.key});
+
+ @override
+ State createState() => _CartButtonSectionState();
+}
+
+class _CartButtonSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: EdgeInsets.only(bottom: height(context) * 3),
+ width: width(context) * 100,
+
+ child: CartButton(fullPrice: '500'),
+ );
+ }
+}
diff --git a/example/lib/categories_section.dart b/example/lib/categories_section.dart
new file mode 100644
index 0000000..7c16a29
--- /dev/null
+++ b/example/lib/categories_section.dart
@@ -0,0 +1,24 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/categories.dart';
+import 'package:ui_kit/utils.dart';
+
+class CategoriesSection extends StatefulWidget {
+ const CategoriesSection({super.key});
+
+ @override
+ State createState() => _CategoriesSectionState();
+}
+
+class _CategoriesSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 5),
+ width: width(context) * 100,
+ height: 48,
+ child: CategoriesWidget(
+ itemsList: ['Популярные', 'Женщинам', 'Мужчинам'],
+ ),
+ );
+ }
+}
diff --git a/example/lib/chips_section.dart b/example/lib/chips_section.dart
new file mode 100644
index 0000000..47470ec
--- /dev/null
+++ b/example/lib/chips_section.dart
@@ -0,0 +1,35 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+import 'package:ui_kit/utils.dart';
+
+class ChipsSection extends StatefulWidget {
+ const ChipsSection({super.key});
+
+ @override
+ State createState() => _ChipsSectionState();
+}
+
+class _ChipsSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: 129,
+ height: height(context) * 33,
+ child: ListView.builder(
+ itemCount: 2,
+ itemBuilder: (BuildContext context, int index) {
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 2),
+ child: Chips(
+ buttonText: 'Популярные',
+ buttonStyle: index == 1
+ ? textMedium.copyWith(color: descColor)
+ : textMedium.copyWith(color: whiteColor),
+ bgColor: index == 1 ? inputBgColor : primaryColor,
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/colors_section.dart b/example/lib/colors_section.dart
new file mode 100644
index 0000000..4f922a0
--- /dev/null
+++ b/example/lib/colors_section.dart
@@ -0,0 +1,46 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class ColorsSection extends StatelessWidget {
+ const ColorsSection({super.key});
+
+ static final colorsList = [
+ primaryColor,
+ primaryHoverColor,
+ blackColor,
+ whiteColor,
+ errorColor,
+ successColor,
+ inputBgColor,
+ inputStrokeColor,
+ inputIcon,
+ placeholderColor,
+ descColor,
+ cardColor,
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: width(context) * 100,
+ height: height(context) * 10,
+ margin: EdgeInsets.only(top: height(context) * 5),
+ child: ListView.builder(
+ itemCount: colorsList.length,
+ scrollDirection: Axis.horizontal,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = colorsList[index];
+ return Container(
+ width: 40,
+ height: 40,
+ margin: EdgeInsets.only(right: 10),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(360),
+ color: currentItem,
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/counter_section.dart b/example/lib/counter_section.dart
new file mode 100644
index 0000000..d0067bd
--- /dev/null
+++ b/example/lib/counter_section.dart
@@ -0,0 +1,30 @@
+import 'package:flutter/widgets.dart';
+import 'package:ui_kit/counter.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class CounterSection extends StatefulWidget {
+ const CounterSection({super.key});
+
+ @override
+ State createState() => _CounterSectionState();
+}
+
+class _CounterSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 5),
+ width: 64,
+ height: height(context) * 15,
+ child: ListView.builder(
+ itemCount: 2,
+ itemBuilder: (BuildContext context, int index) {
+ return Container(
+ margin: EdgeInsets.only(bottom: 10),
+ child: CounterWidget(),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/fonts_section.dart b/example/lib/fonts_section.dart
new file mode 100644
index 0000000..44d9dcd
--- /dev/null
+++ b/example/lib/fonts_section.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class FontsSection extends StatelessWidget {
+ const FontsSection({super.key});
+
+ static final typographyText = [
+ title1Semibold,
+ title1ExtraBold,
+ title2Regular,
+ title2Semibold,
+ title2ExtraBold,
+ title3Regular,
+ title3Medium,
+ title3Semibold,
+ headlineRegular,
+ headlineMedium,
+ textRegular,
+ textMedium,
+ captionRegular,
+ captionSemibold,
+ caption2Regular,
+ caption2Bold,
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: width(context) * 100,
+ height: height(context) * 50,
+ child: ListView.builder(
+ itemCount: typographyText.length,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = typographyText[index];
+ return Text('FontTypographyTest', style: currentItem);
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/header_section.dart b/example/lib/header_section.dart
new file mode 100644
index 0000000..8b3dd7c
--- /dev/null
+++ b/example/lib/header_section.dart
@@ -0,0 +1,25 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class HeaderSection extends StatefulWidget {
+ const HeaderSection({super.key});
+
+ @override
+ State createState() => _HeaderSectionState();
+}
+
+class _HeaderSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: width(context) * 100,
+ height: height(context) * 30,
+ child: Column(
+ children: [
+ HeaderWidget(variant: 'main', onPressed: () {}, handleBack: () {}),
+ HeaderWidget(variant: 'default', onPressed: () {}, handleBack: () {}),
+ ],
+ ),
+ );
+ }
+}
diff --git a/example/lib/icons_section.dart b/example/lib/icons_section.dart
new file mode 100644
index 0000000..7adab40
--- /dev/null
+++ b/example/lib/icons_section.dart
@@ -0,0 +1,53 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+
+class IconsSection extends StatefulWidget {
+ const IconsSection({super.key});
+
+ @override
+ State createState() => _IconsSectionState();
+}
+
+class _IconsSectionState extends State {
+ static final iconsList = [
+ 'chevron-left.svg',
+ 'chevron-right.svg',
+ 'chevron-down.svg',
+ 'plus.svg',
+ 'minus.svg',
+ 'message-circle.svg',
+ 'filter.svg',
+ 'download.svg',
+ 'map.svg',
+ 'more-horizontal.svg',
+ 'close.svg',
+ 'delete.svg',
+ 'cart.svg',
+ 'check.svg',
+ 'file-text.svg',
+ 'send.svg',
+ 'mic.svg',
+ 'paperclip.svg',
+ 'closed-eye.svg',
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: width(context) * 100,
+ height: height(context) * 10,
+ child: ListView.builder(
+ itemCount: iconsList.length,
+ scrollDirection: Axis.horizontal,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = iconsList[index];
+ return Container(
+ padding: EdgeInsets.only(right: width(context) * 1),
+ child: SvgPicture.asset('assets/$currentItem'),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/inputs_section.dart b/example/lib/inputs_section.dart
new file mode 100644
index 0000000..0aaefe0
--- /dev/null
+++ b/example/lib/inputs_section.dart
@@ -0,0 +1,51 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class InputsSection extends StatefulWidget {
+ const InputsSection({super.key});
+
+ @override
+ State createState() => _InputsSectionState();
+}
+
+class _InputsSectionState extends State {
+ static final inputsList = [
+ {"initText": ""},
+ {"initText": "Введите имя"},
+ {"initText": "", 'label': "Введите имя"},
+ {"initText": "", 'isError': "true"},
+ {'label': "Введите имя"},
+ {"initText": "Введите имя", 'label': "Введите имя"},
+ {"initText": "*********", 'isPassword': "true"},
+ {'isMask': 'true', 'initText': ""},
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: width(context) * 100,
+ height: height(context) * 30,
+ margin: EdgeInsets.only(top: height(context) * 3),
+ child: ListView.builder(
+ itemCount: inputsList.length,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = inputsList[index];
+ return Container(
+ margin: EdgeInsets.only(bottom: 10),
+ child: InputWidget(
+ controller: TextEditingController(text: currentItem['initText']),
+ label: currentItem['label'],
+ hintText: currentItem['isMask'] == 'true'
+ ? '--.--.----'
+ : 'Введите имя',
+ isError: currentItem['isError'] ?? "",
+ errorText: 'Введите имя',
+ isPassword: currentItem['isPassword'],
+ isMask: currentItem['isMask'],
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/log_in_section.dart b/example/lib/log_in_section.dart
new file mode 100644
index 0000000..e7ef9b2
--- /dev/null
+++ b/example/lib/log_in_section.dart
@@ -0,0 +1,32 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class LogInSection extends StatefulWidget {
+ const LogInSection({super.key});
+
+ @override
+ State createState() => _LogInSectionState();
+}
+
+class _LogInSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 3),
+ width: width(context) * 100,
+ height: height(context) * 33,
+ child: ListView.builder(
+ itemCount: 2,
+ itemBuilder: (BuildContext context, int index) {
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 2),
+ child: LogInCard(
+ image: index == 1 ? 'assets/yandex.png' : 'assets/vk.png',
+ text: index == 1 ? 'Войти с Yandex' : 'Войти с VK',
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/main.dart b/example/lib/main.dart
index a725658..00f537b 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,4 +1,22 @@
+import 'package:example/bottom_sheet_section.dart';
+import 'package:example/button_section.dart';
+import 'package:example/card_section.dart';
+import 'package:example/cart_button_section.dart';
+import 'package:example/categories_section.dart';
+import 'package:example/chips_section.dart';
+import 'package:example/colors_section.dart';
+import 'package:example/counter_section.dart';
+import 'package:example/fonts_section.dart';
+import 'package:example/header_section.dart';
+import 'package:example/icons_section.dart';
+import 'package:example/inputs_section.dart';
+import 'package:example/log_in_section.dart';
+import 'package:example/search_section.dart';
+import 'package:example/select_section.dart';
+import 'package:example/small_button_section.dart';
+import 'package:example/toggle_section.dart';
import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
void main() {
runApp(const MainApp());
@@ -9,10 +27,37 @@ class MainApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return const MaterialApp(
+ return MaterialApp(
+ debugShowCheckedModeBanner: false,
+ color: whiteColor,
home: Scaffold(
- body: Center(
- child: Text('Hello World!'),
+ backgroundColor: whiteColor,
+ body: SingleChildScrollView(
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: width(context) * 5),
+ child: Column(
+ children: [
+ ColorsSection(),
+ FontsSection(),
+ IconsSection(),
+ InputsSection(),
+ SearchSection(),
+ ButtonSection(),
+ SmallButtonSection(),
+ TabBarWidget(),
+ BottomSheetSection(),
+ HeaderSection(),
+ CardSection(),
+ CounterSection(),
+ ToggleSection(),
+ SelectSection(),
+ ChipsSection(),
+ LogInSection(),
+ CartButtonSection(),
+ CategoriesSection(),
+ ],
+ ),
+ ),
),
),
);
diff --git a/example/lib/search_section.dart b/example/lib/search_section.dart
new file mode 100644
index 0000000..1b4a4a7
--- /dev/null
+++ b/example/lib/search_section.dart
@@ -0,0 +1,35 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class SearchSection extends StatefulWidget {
+ const SearchSection({super.key});
+
+ @override
+ State createState() => _SearchSectionState();
+}
+
+class _SearchSectionState extends State {
+ final TextEditingController controller = TextEditingController();
+ @override
+ Widget build(BuildContext context) {
+ final searchList = [true, false];
+ return SizedBox(
+ width: width(context) * 100,
+ height: height(context) * 30,
+ child: ListView.builder(
+ itemCount: 2,
+ itemBuilder: (BuildContext context, int index) {
+ final currentValue = searchList[index];
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 3),
+ child: SearchWidget(
+ controller: controller,
+ hintText: 'Искать описание',
+ isClosable: currentValue,
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/select_section.dart b/example/lib/select_section.dart
new file mode 100644
index 0000000..725f5df
--- /dev/null
+++ b/example/lib/select_section.dart
@@ -0,0 +1,40 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/select.dart';
+import 'package:ui_kit/utils.dart';
+
+class SelectSection extends StatefulWidget {
+ const SelectSection({super.key});
+
+ @override
+ State createState() => _SelectSectionState();
+}
+
+class _SelectSectionState extends State {
+ static final selectItems = [
+ {'value': ''},
+ {'value': 'Мужской'},
+ {'value': 'Гарвард Троцкий', 'image': "assets/people.png"},
+ ];
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: width(context) * 100,
+ height: height(context) * 33,
+ child: ListView.builder(
+ itemCount: selectItems.length,
+ itemBuilder: (BuildContext context, int index) {
+ final currenItem = selectItems[index];
+ return Container(
+ padding: EdgeInsets.only(bottom: height(context) * 2),
+ child: SelectWidget(
+ hintText: 'Пол',
+ selectedValue: currenItem['value'] ?? "",
+ image: currenItem['image'],
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/small_button_section.dart b/example/lib/small_button_section.dart
new file mode 100644
index 0000000..7e3a78f
--- /dev/null
+++ b/example/lib/small_button_section.dart
@@ -0,0 +1,36 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class SmallButtonSection extends StatelessWidget {
+ const SmallButtonSection({super.key});
+
+ static final buttonList = ['flat', 'inactive', 'solid', 'ghost'];
+ static final buttonLabels = ['Добавить', 'Убрать', 'Добавить', 'Подтвердить'];
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 3),
+ width: 96,
+ height: height(context) * 30,
+ child: ListView.builder(
+ itemCount: buttonList.length,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = buttonList[index];
+ final currentLabel = buttonLabels[index];
+
+ return Container(
+ width: 96,
+ margin: EdgeInsets.only(bottom: height(context) * 1),
+ child: ButtonWidget(
+ onPressed: () {},
+ label: currentLabel,
+ variant: currentItem,
+ size: 'small',
+ ),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/lib/tabbar_section.dart b/example/lib/tabbar_section.dart
new file mode 100644
index 0000000..dfe3e8b
--- /dev/null
+++ b/example/lib/tabbar_section.dart
@@ -0,0 +1,16 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class TabBarSection extends StatefulWidget {
+ const TabBarSection({super.key});
+
+ @override
+ State createState() => _TabBarSectionState();
+}
+
+class _TabBarSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return TabBarWidget();
+ }
+}
diff --git a/example/lib/toggle_section.dart b/example/lib/toggle_section.dart
new file mode 100644
index 0000000..2a74886
--- /dev/null
+++ b/example/lib/toggle_section.dart
@@ -0,0 +1,28 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class ToggleSection extends StatefulWidget {
+ const ToggleSection({super.key});
+
+ @override
+ State createState() => _ToggleSectionState();
+}
+
+class _ToggleSectionState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: 48,
+ height: height(context) * 20,
+ child: ListView.builder(
+ itemCount: 2,
+ itemBuilder: (BuildContext context, int index) {
+ return Container(
+ margin: EdgeInsets.only(bottom: height(context) * 1.5),
+ child: ToggleWidget(initialValue: index != 1 ? true : false),
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/example/pubspec.lock b/example/pubspec.lock
index 87cfa09..a1fe29f 100644
--- a/example/pubspec.lock
+++ b/example/pubspec.lock
@@ -1,6 +1,14 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
+ args:
+ dependency: transitive
+ description:
+ name: args
+ sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.7.0"
async:
dependency: transitive
description:
@@ -41,6 +49,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.19.1"
+ dropdown_button2:
+ dependency: "direct main"
+ description:
+ name: dropdown_button2
+ sha256: b0fe8d49a030315e9eef6c7ac84ca964250155a6224d491c1365061bc974a9e1
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.9"
fake_async:
dependency: transitive
description:
@@ -54,6 +70,14 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
+ flutter_advanced_switch:
+ dependency: "direct main"
+ description:
+ name: flutter_advanced_switch
+ sha256: e1147161a3dd9b708a71c65e76174d4d1a0a5908a571b8b38b65c79b142c52a0
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
flutter_lints:
dependency: "direct dev"
description:
@@ -62,11 +86,35 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.0.0"
+ flutter_svg:
+ dependency: "direct dev"
+ description:
+ name: flutter_svg
+ sha256: d44bf546b13025ec7353091516f6881f1d4c633993cb109c3916c3a0159dadf1
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.1.0"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
+ http:
+ dependency: transitive
+ description:
+ name: http
+ sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.4.0"
+ http_parser:
+ dependency: transitive
+ description:
+ name: http_parser
+ sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
+ url: "https://pub.dev"
+ source: hosted
+ version: "4.1.2"
leak_tracker:
dependency: transitive
description:
@@ -99,6 +147,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "5.1.1"
+ mask_text_input_formatter:
+ dependency: "direct main"
+ description:
+ name: mask_text_input_formatter
+ sha256: "978c58ec721c25621ceb468e633f4eef64b64d45424ac4540e0565d4f7c800cd"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.9.0"
matcher:
dependency: transitive
description:
@@ -123,6 +179,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.16.0"
+ modal_bottom_sheet:
+ dependency: "direct main"
+ description:
+ name: modal_bottom_sheet
+ sha256: eac66ef8cb0461bf069a38c5eb0fa728cee525a531a8304bd3f7b2185407c67e
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.0.0"
path:
dependency: transitive
description:
@@ -131,6 +195,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.9.1"
+ path_parsing:
+ dependency: transitive
+ description:
+ name: path_parsing
+ sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.0"
+ petitparser:
+ dependency: transitive
+ description:
+ name: petitparser
+ sha256: "07c8f0b1913bcde1ff0d26e57ace2f3012ccbf2b204e070290dad3bb22797646"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.1.0"
sky_engine:
dependency: transitive
description: flutter
@@ -184,6 +264,45 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.7.4"
+ typed_data:
+ dependency: transitive
+ description:
+ name: typed_data
+ sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.4.0"
+ ui_kit:
+ dependency: "direct main"
+ description:
+ path: ".."
+ relative: true
+ source: path
+ version: "0.0.1"
+ vector_graphics:
+ dependency: transitive
+ description:
+ name: vector_graphics
+ sha256: "44cc7104ff32563122a929e4620cf3efd584194eec6d1d913eb5ba593dbcf6de"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.18"
+ vector_graphics_codec:
+ dependency: transitive
+ description:
+ name: vector_graphics_codec
+ sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.13"
+ vector_graphics_compiler:
+ dependency: transitive
+ description:
+ name: vector_graphics_compiler
+ sha256: "557a315b7d2a6dbb0aaaff84d857967ce6bdc96a63dc6ee2a57ce5a6ee5d3331"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.17"
vector_math:
dependency: transitive
description:
@@ -200,6 +319,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "15.0.0"
+ web:
+ dependency: transitive
+ description:
+ name: web
+ sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.1.1"
+ xml:
+ dependency: transitive
+ description:
+ name: xml
+ sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.5.0"
sdks:
dart: ">=3.8.0 <4.0.0"
- flutter: ">=3.18.0-18.0.pre.54"
+ flutter: ">=3.22.0"
diff --git a/example/pubspec.yaml b/example/pubspec.yaml
index f5dc432..d3c45fd 100644
--- a/example/pubspec.yaml
+++ b/example/pubspec.yaml
@@ -7,13 +7,25 @@ environment:
sdk: ^3.8.0
dependencies:
+ dropdown_button2: ^2.3.9
flutter:
sdk: flutter
+ flutter_advanced_switch: ^3.1.0
+ mask_text_input_formatter: ^2.9.0
+ modal_bottom_sheet: ^3.0.0
+ ui_kit:
+ path: ..
dev_dependencies:
flutter_test:
sdk: flutter
flutter_lints: ^5.0.0
+ flutter_svg: ^2.1.0
flutter:
uses-material-design: true
+
+ assets:
+ - assets/
+
+
diff --git a/lib/bottom_sheet.dart b/lib/bottom_sheet.dart
new file mode 100644
index 0000000..bf454c4
--- /dev/null
+++ b/lib/bottom_sheet.dart
@@ -0,0 +1,17 @@
+// ignore_for_file: prefer_function_declarations_over_variables
+
+import 'package:flutter/material.dart';
+import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+final showBottomSheetFunc = (Widget children, context) {
+ return showCupertinoModalBottomSheet(
+ context: context,
+ backgroundColor: whiteColor,
+ builder: (context) => Container(
+ color: whiteColor,
+ width: width(context) * 100,
+ child: children,
+ ),
+ );
+};
diff --git a/lib/bubbles.dart b/lib/bubbles.dart
new file mode 100644
index 0000000..e51c37d
--- /dev/null
+++ b/lib/bubbles.dart
@@ -0,0 +1,15 @@
+import 'package:flutter/material.dart';
+
+class BubbleWidget extends StatelessWidget {
+ const BubbleWidget({super.key, this.isback = true});
+ final bool? isback;
+
+ @override
+ Widget build(BuildContext context) {
+ return Image.asset(
+ isback == true ? 'assets/back.png' : 'assets/filters.png',
+ width: isback == true ? 32 : 48,
+ height: isback == true ? 32 : 48,
+ );
+ }
+}
diff --git a/lib/button.dart b/lib/button.dart
new file mode 100644
index 0000000..18cd018
--- /dev/null
+++ b/lib/button.dart
@@ -0,0 +1,85 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class ButtonWidget extends StatefulWidget {
+ const ButtonWidget({
+ super.key,
+ required this.onPressed,
+ required this.label,
+ this.textStyle,
+ this.size = 'big',
+ required this.variant,
+ });
+ final VoidCallback onPressed;
+ final String label;
+ final TextStyle? textStyle;
+ final String size;
+ final String variant;
+
+ @override
+ State createState() => _ButtonWidgetState();
+}
+
+class _ButtonWidgetState extends State {
+ late Color bgColor;
+ late TextStyle textStyle;
+ late Color borderColor;
+ @override
+ void initState() {
+ super.initState();
+ if (widget.variant == 'flat') {
+ bgColor = primaryColor;
+ borderColor = Colors.transparent;
+ if (widget.size == 'big') {
+ textStyle = title2Semibold.copyWith(color: whiteColor);
+ } else if (widget.size == 'small') {
+ textStyle = captionSemibold.copyWith(color: whiteColor);
+ }
+ }
+ if (widget.variant == 'inactive') {
+ bgColor = primaryHoverColor;
+ borderColor = Colors.transparent;
+ if (widget.size == 'big') {
+ textStyle = title2Semibold.copyWith(color: whiteColor);
+ } else if (widget.size == 'small') {
+ textStyle = captionSemibold.copyWith(color: whiteColor);
+ }
+ }
+ if (widget.variant == 'solid') {
+ bgColor = Colors.transparent;
+ borderColor = primaryColor;
+
+ if (widget.size == 'big') {
+ textStyle = title2Semibold.copyWith(color: primaryColor);
+ } else if (widget.size == 'small') {
+ textStyle = captionSemibold.copyWith(color: primaryColor);
+ }
+ }
+ if (widget.variant == 'ghost') {
+ bgColor = inputBgColor;
+ borderColor = Colors.transparent;
+ if (widget.size == 'big') {
+ textStyle = title2Semibold.copyWith(color: blackColor);
+ } else if (widget.size == 'small') {
+ textStyle = captionSemibold.copyWith(color: blackColor);
+ }
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ height: widget.size == 'small' ? 40 : 56,
+ width: widget.size == 'small' ? 96 : width(context) * 100,
+ decoration: BoxDecoration(
+ color: bgColor,
+ borderRadius: BorderRadius.circular(10),
+ border: Border.all(color: borderColor),
+ ),
+ child: TextButton(
+ onPressed: widget.onPressed,
+ child: Text(widget.label, style: textStyle),
+ ),
+ );
+ }
+}
diff --git a/lib/card.dart b/lib/card.dart
new file mode 100644
index 0000000..1ec1745
--- /dev/null
+++ b/lib/card.dart
@@ -0,0 +1,28 @@
+import 'package:flutter/widgets.dart';
+import 'package:ui_kit/colors.dart';
+
+class CardWidget extends StatefulWidget {
+ const CardWidget({super.key, required this.child});
+ final Widget child;
+
+ @override
+ State createState() => _CardWidgetState();
+}
+
+class _CardWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: 335,
+ height: 150,
+ padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
+ decoration: BoxDecoration(
+ color: whiteColor,
+ borderRadius: BorderRadius.circular(12),
+ border: Border.all(color: dividerColor, width: 1),
+ boxShadow: [BoxShadow(color: shadowColor, blurRadius: 10)],
+ ),
+ child: widget.child,
+ );
+ }
+}
diff --git a/lib/cards/cart_card.dart b/lib/cards/cart_card.dart
new file mode 100644
index 0000000..9519735
--- /dev/null
+++ b/lib/cards/cart_card.dart
@@ -0,0 +1,60 @@
+import 'package:flutter/widgets.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:ui_kit/card.dart';
+import 'package:ui_kit/counter.dart';
+import 'package:ui_kit/fonts.dart';
+
+class CartCard extends StatefulWidget {
+ const CartCard({
+ super.key,
+ required this.title,
+ required this.price,
+ required this.count,
+ });
+ final String title;
+ final String price;
+
+ final String count;
+
+ @override
+ State createState() => _CartCardState();
+}
+
+class _CartCardState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return CardWidget(
+ child: Column(
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ SizedBox(
+ width: 275,
+ child: Text(widget.title, style: headlineMedium),
+ ),
+ SvgPicture.asset('assets/close.svg'),
+ ],
+ ),
+ SizedBox(height: 34),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text('${widget.price} ₽', style: title3Medium),
+ SizedBox(
+ width: 145,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text('${widget.count} штук', style: textRegular),
+ CounterWidget(),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/cards/log_in_card.dart b/lib/cards/log_in_card.dart
new file mode 100644
index 0000000..6368152
--- /dev/null
+++ b/lib/cards/log_in_card.dart
@@ -0,0 +1,32 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class LogInCard extends StatefulWidget {
+ const LogInCard({super.key, required this.image, required this.text});
+ final String image;
+ final String text;
+
+ @override
+ State createState() => _LogInCardState();
+}
+
+class _LogInCardState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: EdgeInsets.symmetric(horizontal: 14, vertical: 14),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12),
+ border: Border.all(color: inputStrokeColor, width: 1),
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Image.asset(widget.image, width: 32, height: 32),
+ SizedBox(width: 16),
+ Text(widget.text, style: title3Medium),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/cards/primary_card.dart b/lib/cards/primary_card.dart
new file mode 100644
index 0000000..f40a51d
--- /dev/null
+++ b/lib/cards/primary_card.dart
@@ -0,0 +1,70 @@
+import 'package:flutter/widgets.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class PrimaryCard extends StatefulWidget {
+ const PrimaryCard({
+ super.key,
+ required this.title,
+ required this.category,
+ required this.price,
+ });
+ final String title;
+ final String category;
+ final String price;
+
+ @override
+ State createState() => _PrimaryCardState();
+}
+
+class _PrimaryCardState extends State {
+ bool inCart = false;
+
+ @override
+ Widget build(BuildContext context) {
+ return CardWidget(
+ child: Column(
+ children: [
+ Text(widget.title, style: headlineMedium),
+ SizedBox(height: 16),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ widget.category,
+ style: captionSemibold.copyWith(color: captionColor),
+ ),
+ SizedBox(height: 4),
+ Text("${widget.price} ₽", style: title3Semibold),
+ ],
+ ),
+ inCart
+ ? ButtonWidget(
+ onPressed: () {
+ setState(() {
+ inCart = !inCart;
+ });
+ },
+ size: 'small',
+ label: 'Убрать',
+ variant: 'solid',
+ )
+ : ButtonWidget(
+ onPressed: () {
+ setState(() {
+ inCart = !inCart;
+ });
+ },
+ size: 'small',
+ label: "Добавить",
+ variant: 'flat',
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/cards/project_card.dart b/lib/cards/project_card.dart
new file mode 100644
index 0000000..85e00fd
--- /dev/null
+++ b/lib/cards/project_card.dart
@@ -0,0 +1,49 @@
+import 'package:flutter/widgets.dart';
+import 'package:ui_kit/card.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class ProjectCard extends StatefulWidget {
+ const ProjectCard({
+ super.key,
+ required this.title,
+ required this.lastDate,
+ required this.onPressed,
+ });
+ final String title;
+ final String lastDate;
+ final VoidCallback onPressed;
+
+ @override
+ State createState() => _ProjectCardState();
+}
+
+class _ProjectCardState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return CardWidget(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(widget.title, style: headlineMedium),
+ SizedBox(height: 44),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.end,
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Text(
+ 'Прошло ${widget.lastDate} дня',
+ style: captionSemibold.copyWith(color: captionColor),
+ ),
+ ButtonWidget(
+ onPressed: widget.onPressed,
+ label: "Открыть",
+ variant: 'flat',
+ size: 'small',
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/cart_button.dart b/lib/cart_button.dart
new file mode 100644
index 0000000..c71cddf
--- /dev/null
+++ b/lib/cart_button.dart
@@ -0,0 +1,45 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class CartButton extends StatefulWidget {
+ const CartButton({super.key, required this.fullPrice});
+ final String fullPrice;
+
+ @override
+ State createState() => _CartButtonState();
+}
+
+class _CartButtonState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ decoration: BoxDecoration(
+ color: primaryColor,
+ borderRadius: BorderRadius.circular(10),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: Row(
+ children: [
+ SvgPicture.asset('assets/cart.svg'),
+ SizedBox(width: 16),
+ Text(
+ 'В корзину',
+ style: title3Semibold.copyWith(color: whiteColor),
+ ),
+ ],
+ ),
+ ),
+ Text(
+ '${widget.fullPrice} ₽',
+ style: title3Semibold.copyWith(color: whiteColor),
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/categories.dart b/lib/categories.dart
new file mode 100644
index 0000000..9ad87f1
--- /dev/null
+++ b/lib/categories.dart
@@ -0,0 +1,52 @@
+import 'package:flutter/widgets.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class CategoriesWidget extends StatefulWidget {
+ const CategoriesWidget({super.key, required this.itemsList});
+ final List itemsList;
+
+ @override
+ State createState() => _CategoriesWidgetState();
+}
+
+class _CategoriesWidgetState extends State {
+ late String selectedItem;
+ @override
+ void initState() {
+ super.initState();
+ selectedItem = widget.itemsList[0];
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ width: width(context) * 100,
+ child: ListView.builder(
+ scrollDirection: Axis.horizontal,
+ itemCount: widget.itemsList.length,
+ itemBuilder: (BuildContext context, int index) {
+ final currentItem = widget.itemsList[index];
+ Color currentItemColor = selectedItem == widget.itemsList[index]
+ ? primaryColor
+ : inputBgColor;
+ return Chips(
+ onPressed: () => {
+ setState(() {
+ print(currentItem);
+ selectedItem = currentItem;
+ }),
+ },
+ buttonText: widget.itemsList[index],
+ buttonStyle: textMedium.copyWith(
+ fontWeight: FontWeight.w500,
+ color: selectedItem == widget.itemsList[index]
+ ? whiteColor
+ : descColor,
+ ),
+ bgColor: currentItemColor,
+ );
+ },
+ ),
+ );
+ }
+}
diff --git a/lib/chips.dart b/lib/chips.dart
new file mode 100644
index 0000000..de280dd
--- /dev/null
+++ b/lib/chips.dart
@@ -0,0 +1,39 @@
+import 'package:flutter/material.dart';
+
+class Chips extends StatefulWidget {
+ const Chips({
+ super.key,
+ required this.buttonText,
+ required this.buttonStyle,
+ required this.bgColor,
+ this.onPressed,
+ });
+ final String buttonText;
+ final TextStyle buttonStyle;
+ final Color bgColor;
+ final VoidCallback? onPressed;
+
+ @override
+ State createState() => _ChipsState();
+}
+
+class _ChipsState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () {
+ widget.onPressed;
+ },
+ child: Container(
+ width: 129,
+ height: 48,
+ padding: EdgeInsets.symmetric(horizontal: 20, vertical: 14),
+ decoration: BoxDecoration(
+ color: widget.bgColor,
+ borderRadius: BorderRadius.circular(10),
+ ),
+ child: Text(widget.buttonText, style: widget.buttonStyle),
+ ),
+ );
+ }
+}
diff --git a/lib/colors.dart b/lib/colors.dart
new file mode 100644
index 0000000..32e9c99
--- /dev/null
+++ b/lib/colors.dart
@@ -0,0 +1,19 @@
+import 'package:flutter/material.dart';
+
+const primaryColor = Color.fromRGBO(26, 111, 238, 1);
+const primaryHoverColor = Color.fromRGBO(197, 210, 255, 1);
+const blackColor = Color.fromRGBO(45, 44, 44, 1);
+const whiteColor = Color.fromRGBO(247, 247, 247, 1);
+const errorColor = Color.fromRGBO(255, 70, 70, 1);
+const errorBgColor = Color.fromRGBO(253, 53, 53, 0.1);
+const successColor = Color.fromRGBO(255, 70, 70, 1);
+const inputBgColor = Color.fromRGBO(245, 245, 249, 1);
+const inputStrokeColor = Color.fromRGBO(230, 230, 230, 1);
+const inputIcon = Color.fromRGBO(191, 199, 209, 1);
+const placeholderColor = Color.fromRGBO(191, 199, 209, 1);
+const descColor = Color.fromRGBO(135, 135, 161, 1);
+const cardColor = Color.fromRGBO(135, 135, 161, 1);
+const captionColor = Color.fromRGBO(147, 147, 150, 1);
+const iconsColor = Color.fromRGBO(184, 193, 204, 1);
+const dividerColor = Color.fromRGBO(244, 244, 244, 1);
+const shadowColor = Color.fromRGBO(228, 232, 245, 0.6);
diff --git a/lib/counter.dart b/lib/counter.dart
new file mode 100644
index 0000000..9f576ad
--- /dev/null
+++ b/lib/counter.dart
@@ -0,0 +1,33 @@
+import 'package:flutter/widgets.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class CounterWidget extends StatefulWidget {
+ const CounterWidget({super.key});
+
+ @override
+ State createState() => _CounterWidgetState();
+}
+
+class _CounterWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ width: 64,
+ height: 32,
+ padding: EdgeInsets.symmetric(horizontal: 6, vertical: 6),
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8),
+ color: inputBgColor,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ SvgPicture.asset('assets/minus.svg'),
+ SvgPicture.asset('assets/divider.svg'),
+ SvgPicture.asset('assets/plus.svg'),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/fonts.dart b/lib/fonts.dart
new file mode 100644
index 0000000..2a777af
--- /dev/null
+++ b/lib/fonts.dart
@@ -0,0 +1,131 @@
+import 'package:flutter/painting.dart';
+import 'package:ui_kit/colors.dart';
+import 'package:ui_kit/utils.dart';
+
+final title1Semibold = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 24,
+ color: blackColor,
+ fontWeight: FontWeight.w600,
+ letterSpacing: letterSpacing(24, 0.33),
+);
+
+final title1ExtraBold = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 24,
+ color: blackColor,
+ fontWeight: FontWeight.w800,
+ letterSpacing: letterSpacing(24, 0.33),
+);
+
+final title2Regular = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 20,
+ color: blackColor,
+ fontWeight: FontWeight.w400,
+ letterSpacing: letterSpacing(20, 0.38),
+);
+
+final title2Semibold = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 20,
+ color: blackColor,
+ fontWeight: FontWeight.w600,
+ letterSpacing: letterSpacing(20, 0.38),
+);
+
+final title2ExtraBold = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 20,
+ color: blackColor,
+ fontWeight: FontWeight.w600,
+ letterSpacing: letterSpacing(20, 0.38),
+);
+
+final title3Regular = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 17,
+ color: blackColor,
+ fontWeight: FontWeight.w400,
+ letterSpacing: letterSpacing(17, 0),
+);
+
+final title3Medium = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 17,
+ color: blackColor,
+ fontWeight: FontWeight.w500,
+ letterSpacing: letterSpacing(17, 0),
+);
+
+final title3Semibold = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 17,
+ color: blackColor,
+ fontWeight: FontWeight.w600,
+ letterSpacing: letterSpacing(17, 0),
+);
+
+final headlineRegular = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 16,
+ color: blackColor,
+ fontWeight: FontWeight.w400,
+ letterSpacing: letterSpacing(16, -0.32),
+);
+
+final headlineMedium = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 16,
+ color: blackColor,
+ fontWeight: FontWeight.w500,
+ letterSpacing: letterSpacing(16, -0.32),
+);
+
+final textRegular = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 15,
+ color: blackColor,
+ fontWeight: FontWeight.w400,
+ letterSpacing: letterSpacing(16, 0),
+);
+
+final textMedium = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 15,
+ color: blackColor,
+ fontWeight: FontWeight.w500,
+ letterSpacing: letterSpacing(16, 0),
+);
+
+final captionRegular = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 14,
+ color: blackColor,
+ fontWeight: FontWeight.w400,
+ letterSpacing: letterSpacing(16, 0),
+);
+
+final captionSemibold = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 14,
+ color: blackColor,
+ fontWeight: FontWeight.w600,
+ letterSpacing: letterSpacing(16, 0),
+);
+
+final caption2Regular = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 12,
+ color: blackColor,
+ fontWeight: FontWeight.w400,
+ letterSpacing: letterSpacing(16, 0),
+);
+
+final caption2Bold = TextStyle(
+ fontFamily: 'Roboto',
+ fontSize: 12,
+ color: blackColor,
+ fontWeight: FontWeight.w700,
+ letterSpacing: letterSpacing(16, 0),
+);
diff --git a/lib/header.dart b/lib/header.dart
new file mode 100644
index 0000000..71fb383
--- /dev/null
+++ b/lib/header.dart
@@ -0,0 +1,51 @@
+import 'package:flutter/widgets.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:ui_kit/fonts.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class HeaderWidget extends StatefulWidget {
+ const HeaderWidget({
+ super.key,
+ required this.variant,
+ required this.onPressed,
+ required this.handleBack,
+ });
+ final String variant;
+ final VoidCallback onPressed;
+ final VoidCallback handleBack;
+
+ @override
+ State createState() => _HeaderWidgetState();
+}
+
+class _HeaderWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ padding: EdgeInsets.symmetric(horizontal: 16, vertical: 16),
+ child: widget.variant == 'main'
+ ? Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ BubbleWidget(),
+ SvgPicture.asset('assets/delete.svg'),
+ ],
+ ),
+ SizedBox(height: 24),
+ Text('Корзина', style: title1ExtraBold),
+ ],
+ )
+ : Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ BubbleWidget(),
+ Text('Корзина', style: title1ExtraBold),
+ SvgPicture.asset('assets/delete.svg'),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/input.dart b/lib/input.dart
new file mode 100644
index 0000000..4705e84
--- /dev/null
+++ b/lib/input.dart
@@ -0,0 +1,121 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/svg.dart';
+import 'package:mask_text_input_formatter/mask_text_input_formatter.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class InputWidget extends StatefulWidget {
+ const InputWidget({
+ super.key,
+ this.label,
+ required this.controller,
+ required this.hintText,
+ this.isError = 'false',
+ this.errorText,
+ this.isPassword = 'false',
+ this.isMask = 'false',
+ });
+ final TextEditingController controller;
+ final String? label;
+ final String hintText;
+ final String isError;
+ final String? errorText;
+ final String? isPassword;
+ final String? isMask;
+
+ @override
+ State createState() => _InputWidgetState();
+}
+
+class _InputWidgetState extends State {
+ bool obscureText = false;
+ @override
+ void initState() {
+ super.initState();
+ widget.isPassword == 'true' ? obscureText = true : obscureText = false;
+ }
+
+ var maskFormatter = MaskTextInputFormatter(
+ mask: '+# (###) ###-##-##',
+ filter: {"#": RegExp(r'[0-9]')},
+ type: MaskAutoCompletionType.lazy,
+ );
+
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ widget.label != null
+ ? Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ widget.label ?? '',
+ style: captionRegular.copyWith(color: descColor),
+ ),
+ SizedBox(height: 4),
+ ],
+ )
+ : SizedBox(),
+ SizedBox(
+ height: 48,
+ child: TextFormField(
+ controller: widget.controller,
+ obscureText: obscureText,
+ inputFormatters: widget.isMask == 'true' ? [maskFormatter] : [],
+ decoration: InputDecoration(
+ fillColor: widget.isError == 'true' ? errorBgColor : inputBgColor,
+ filled: true,
+ contentPadding: EdgeInsets.symmetric(
+ horizontal: 14,
+ vertical: 14,
+ ),
+ hintText: widget.hintText,
+ suffixIcon: widget.isPassword == 'true'
+ ? IconButton(
+ onPressed: () {
+ setState(() {
+ obscureText = !obscureText;
+ });
+ },
+ icon: SvgPicture.asset(
+ fit: BoxFit.none,
+ obscureText != true
+ ? 'assets/eye.svg'
+ : 'assets/closed-eye.svg',
+ ),
+ )
+ : null,
+ hintStyle: textRegular.copyWith(color: captionColor),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(10),
+ borderSide: BorderSide(
+ color: widget.isError == 'true'
+ ? errorColor
+ : inputStrokeColor,
+ width: 1,
+ ),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(10),
+ borderSide: BorderSide(color: primaryHoverColor, width: 1),
+ ),
+ ),
+ ),
+ ),
+ widget.isError == 'true'
+ ? Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(height: 8),
+ Text(
+ widget.errorText ?? "",
+ style: captionRegular.copyWith(color: errorColor),
+ ),
+ ],
+ )
+ : SizedBox(),
+ ],
+ );
+ }
+}
diff --git a/lib/search.dart b/lib/search.dart
new file mode 100644
index 0000000..d5881c9
--- /dev/null
+++ b/lib/search.dart
@@ -0,0 +1,67 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class SearchWidget extends StatefulWidget {
+ const SearchWidget({
+ super.key,
+ required this.controller,
+ required this.hintText,
+ this.isClosable = true,
+ });
+ final TextEditingController controller;
+ final String hintText;
+ final bool isClosable;
+
+ @override
+ State createState() => _SearchWidgetState();
+}
+
+class _SearchWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(
+ height: 48,
+ child: TextFormField(
+ controller: widget.controller,
+ decoration: InputDecoration(
+ fillColor: inputBgColor,
+ filled: true,
+ contentPadding: EdgeInsets.symmetric(
+ vertical: 14,
+ horizontal: 14,
+ ),
+ suffixIcon: widget.isClosable
+ ? SvgPicture.asset(
+ 'assets/close.svg',
+ fit: BoxFit.none,
+ height: 20,
+ width: 20,
+ )
+ : null,
+ prefixIcon: SvgPicture.asset(
+ 'assets/search.svg',
+ width: 20,
+ height: 20,
+ fit: BoxFit.none,
+ ),
+ hintText: widget.hintText,
+ hintStyle: textRegular.copyWith(color: captionColor),
+ enabledBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(10),
+ borderSide: BorderSide(color: inputStrokeColor, width: 1),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderRadius: BorderRadius.circular(10),
+ borderSide: BorderSide(color: primaryHoverColor, width: 1),
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/select.dart b/lib/select.dart
new file mode 100644
index 0000000..e037ccc
--- /dev/null
+++ b/lib/select.dart
@@ -0,0 +1,72 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_svg/flutter_svg.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class SelectWidget extends StatefulWidget {
+ const SelectWidget({
+ super.key,
+ this.selectedValue = '',
+ this.image,
+ required this.hintText,
+ });
+ final String selectedValue;
+ final String? image;
+ final String hintText;
+
+ @override
+ State createState() => _SelectWidgetState();
+}
+
+class _SelectWidgetState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return GestureDetector(
+ onTap: () {
+ showBottomSheetFunc(Column(), context);
+ },
+ child: Container(
+ height: 48,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(10),
+ color: inputBgColor,
+ border: Border.all(color: inputStrokeColor, width: 1),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 14, vertical: 14),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Expanded(
+ child: Row(
+ children: [
+ widget.image != null
+ ? Row(
+ children: [
+ Image.asset(
+ widget.image ?? '',
+ width: 24,
+ height: 24,
+ ),
+ SizedBox(width: 12),
+ ],
+ )
+ : SizedBox(),
+ Text(
+ widget.selectedValue == ''
+ ? widget.hintText
+ : widget.selectedValue,
+ style: headlineRegular.copyWith(
+ color: widget.selectedValue != ''
+ ? blackColor
+ : captionColor,
+ ),
+ ),
+ ],
+ ),
+ ),
+ SvgPicture.asset('assets/chevron-down.svg'),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/tabbar.dart b/lib/tabbar.dart
new file mode 100644
index 0000000..cab9c86
--- /dev/null
+++ b/lib/tabbar.dart
@@ -0,0 +1,75 @@
+import 'package:flutter/material.dart';
+import 'package:ui_kit/colors.dart';
+import 'package:ui_kit/fonts.dart';
+
+class TabBarWidget extends StatefulWidget {
+ const TabBarWidget({super.key});
+
+ @override
+ State createState() => _TabBarWidgetState();
+}
+
+class _TabBarWidgetState extends State {
+ int _selectedIndex = 0;
+ void _onItemTapped(int index) {
+ setState(() {
+ _selectedIndex = index;
+ });
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return SizedBox(
+ height: 51,
+ child: BottomNavigationBar(
+ showSelectedLabels: true,
+ showUnselectedLabels: true,
+ selectedLabelStyle: caption2Regular,
+ unselectedLabelStyle: caption2Regular,
+ type: BottomNavigationBarType.fixed,
+ unselectedItemColor: iconsColor,
+ items: [
+ BottomNavigationBarItem(
+ icon: Image.asset('assets/home.png', width: 18, height: 20),
+ label: 'Главная',
+ activeIcon: Image.asset(
+ 'assets/home-active.png',
+ width: 18,
+ height: 20,
+ ),
+ ),
+ BottomNavigationBarItem(
+ icon: Image.asset('assets/results.png', width: 18, height: 20),
+ label: 'Каталог',
+ activeIcon: Image.asset(
+ 'assets/results-active.png',
+ width: 18,
+ height: 20,
+ ),
+ ),
+ BottomNavigationBarItem(
+ icon: Image.asset('assets/projects.png', width: 18, height: 20),
+ label: 'Проекты',
+ activeIcon: Image.asset(
+ 'assets/projects-active.png',
+ width: 18,
+ height: 20,
+ ),
+ ),
+ BottomNavigationBarItem(
+ icon: Image.asset('assets/profile.png', width: 18, height: 20),
+ label: 'Профиль',
+ activeIcon: Image.asset(
+ 'assets/profile-active.png',
+ width: 18,
+ height: 20,
+ ),
+ ),
+ ],
+ currentIndex: _selectedIndex,
+ selectedItemColor: primaryColor,
+ onTap: _onItemTapped,
+ ),
+ );
+ }
+}
diff --git a/lib/toggle.dart b/lib/toggle.dart
new file mode 100644
index 0000000..2701e0f
--- /dev/null
+++ b/lib/toggle.dart
@@ -0,0 +1,27 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_advanced_switch/flutter_advanced_switch.dart';
+import 'package:ui_kit/ui_kit.dart';
+
+class ToggleWidget extends StatefulWidget {
+ const ToggleWidget({super.key, this.initialValue = false});
+ final bool initialValue;
+
+ @override
+ State createState() => _ToggleWidgetState();
+}
+
+class _ToggleWidgetState extends State {
+ final controller00 = ValueNotifier(false);
+ @override
+ Widget build(BuildContext context) {
+ return AdvancedSwitch(
+ controller: controller00,
+ width: 48,
+ height: 28,
+ initialValue: widget.initialValue,
+ activeColor: primaryColor,
+ inactiveColor: inputBgColor,
+ enabled: true,
+ );
+ }
+}
diff --git a/lib/ui_kit.dart b/lib/ui_kit.dart
index 298576d..1fa7a0a 100644
--- a/lib/ui_kit.dart
+++ b/lib/ui_kit.dart
@@ -1,5 +1,22 @@
-/// A Calculator.
-class Calculator {
- /// Returns [value] plus 1.
- int addOne(int value) => value + 1;
-}
+// ignore: unnecessary_library_name
+library UI_KIT;
+
+export 'colors.dart';
+export 'fonts.dart';
+export 'utils.dart';
+export 'input.dart';
+export "search.dart";
+export 'button.dart';
+export 'tabbar.dart';
+export 'bottom_sheet.dart';
+export 'header.dart';
+export 'card.dart';
+export 'cards/primary_card.dart';
+export 'cards/cart_card.dart';
+export 'cards/project_card.dart';
+export 'toggle.dart';
+export 'chips.dart';
+export "cards/log_in_card.dart";
+export 'cart_button.dart';
+export 'bubbles.dart';
+export 'categories.dart';
diff --git a/lib/utils.dart b/lib/utils.dart
new file mode 100644
index 0000000..71f87bd
--- /dev/null
+++ b/lib/utils.dart
@@ -0,0 +1,9 @@
+// ignore_for_file: prefer_function_declarations_over_variables
+
+import 'package:flutter/widgets.dart';
+
+final letterSpacing = (fontSize, percent) => fontSize * percent / 100;
+
+final width = (context) => MediaQuery.of(context).size.width / 100;
+
+final height = (context) => MediaQuery.of(context).size.height / 100;
diff --git a/pubspec.yaml b/pubspec.yaml
index 46c8dc9..b0925a4 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -8,8 +8,13 @@ environment:
flutter: ">=1.17.0"
dependencies:
+ dropdown_button2: ^2.3.9
flutter:
sdk: flutter
+ flutter_advanced_switch: ^3.1.0
+ flutter_svg: ^2.1.0
+ mask_text_input_formatter: ^2.9.0
+ modal_bottom_sheet: ^3.0.0
dev_dependencies:
flutter_test:
@@ -19,20 +24,11 @@ dev_dependencies:
flutter:
- # To add assets to your package, add an assets section, like this:
- # assets:
- # - images/a_dot_burr.jpeg
- # - images/a_dot_ham.jpeg
+ assets:
+ - assets/
- # 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
\ No newline at end of file
+ fonts:
+ - family: Roboto
+ fonts:
+ - asset: assets/robotoFlex.ttf
\ No newline at end of file
diff --git a/test/ui_kit_test.dart b/test/ui_kit_test.dart
index 4a3e123..48631b7 100644
--- a/test/ui_kit_test.dart
+++ b/test/ui_kit_test.dart
@@ -1,12 +1,71 @@
+import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
-
import 'package:ui_kit/ui_kit.dart';
void main() {
- test('adds one to input values', () {
- final calculator = Calculator();
- expect(calculator.addOne(2), 3);
- expect(calculator.addOne(-7), -6);
- expect(calculator.addOne(0), 1);
- });
+ testWidgets(
+ "Инпут ошибки. Проверяемые параметры: фон, обводка, Наличие текста ошибки и соответствие его цвета",
+ (WidgetTester tester) async {
+ final TextEditingController controller = TextEditingController();
+ await tester.pumpWidget(
+ MaterialApp(
+ builder: (context, child) => Scaffold(
+ body: Column(
+ children: [
+ InputWidget(
+ controller: controller,
+ hintText: 'This error input',
+ errorText: 'Eror Input Text',
+ isError: 'true',
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ await tester.pumpAndSettle();
+ final input = find.byType(InputWidget);
+ expect(input.hasFound, true);
+ },
+ );
+ testWidgets(
+ "Кнопка chips. Кнопка при значениях status ON и OFF соответствует макету",
+ (WidgetTester tester) async {
+ bool isSelected = false;
+ Color bgColor = primaryColor;
+
+ await tester.pumpWidget(
+ MaterialApp(
+ builder: (context, child) => Scaffold(
+ body: Column(
+ children: [
+ TextButton(
+ onPressed: () {
+ isSelected = !isSelected;
+ bgColor = bgColor == primaryColor
+ ? inputBgColor
+ : primaryColor;
+ },
+ child: Text('Click to make chip enabled'),
+ ),
+ Chips(
+ buttonText: 'Testtest',
+ buttonStyle: title2Semibold,
+ bgColor: bgColor,
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ await tester.pumpAndSettle();
+ final currentWidget = find.widgetWithText(
+ TextButton,
+ 'Click to make chip enabled',
+ );
+ await tester.tap(currentWidget);
+ expect(isSelected, true);
+ expect(bgColor, inputBgColor);
+ },
+ );
}