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); + }, + ); }