From 12e94257028d82ffc718991d858a7ad009b42fae Mon Sep 17 00:00:00 2001 From: Codefarmer Date: Mon, 16 Sep 2024 08:46:26 +0100 Subject: [PATCH] chore: add dropdown component --- .gitignore | 3 +- .vscode/launch.json | 55 ---- packages/catalog/.gitignore | 2 + packages/catalog/.metadata | 25 +- packages/catalog/lib/usecases/dropdown.dart | 65 ++++ packages/catalog/pubspec.lock | 16 + .../cave/lib/themes/text_field_theme.dart | 40 ++- packages/cave/lib/themes/theme_data.dart | 7 +- packages/cave/lib/themes/typography.dart | 292 +++++++++--------- packages/cave/lib/widgets/drop_down.dart | 184 +++++++++++ packages/cave/lib/widgets/text_field.dart | 52 +++- packages/cave/lib/widgets/widgets.dart | 1 + packages/cave/pubspec.yaml | 1 + packages/conferenceapp/pubspec.lock | 16 + packages/volunteerapp/pubspec.lock | 16 + 15 files changed, 536 insertions(+), 239 deletions(-) delete mode 100644 .vscode/launch.json create mode 100644 packages/catalog/lib/usecases/dropdown.dart create mode 100644 packages/cave/lib/widgets/drop_down.dart diff --git a/.gitignore b/.gitignore index 5446690..f2871e2 100644 --- a/.gitignore +++ b/.gitignore @@ -54,4 +54,5 @@ unlinked.ds unlinked_spec.ds # FVM Version Cache -.fvm/ \ No newline at end of file +.fvm/ +.vscode/launch.json \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 6209719..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "component library", - "cwd": "packages/catalog", - "request": "launch", - "type": "dart", - "deviceId": "chrome" - }, - { - "name": "conferenceapp", - "cwd": "packages/conferenceapp", - "request": "launch", - "type": "dart" - }, - { - "name": "conferenceapp (profile mode)", - "cwd": "packages/conferenceapp", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "conferenceapp (release mode)", - "cwd": "packages/conferenceapp", - "request": "launch", - "type": "dart", - "flutterMode": "release" - }, - { - "name": "volunteerapp", - "cwd": "packages/volunteerapp", - "request": "launch", - "type": "dart" - }, - { - "name": "volunteerapp (profile mode)", - "cwd": "packages/volunteerapp", - "request": "launch", - "type": "dart", - "flutterMode": "profile" - }, - { - "name": "volunteerapp (release mode)", - "cwd": "packages/volunteerapp", - "request": "launch", - "type": "dart", - "flutterMode": "release" - } - ] -} \ No newline at end of file diff --git a/packages/catalog/.gitignore b/packages/catalog/.gitignore index 29a3a50..04d1bc7 100644 --- a/packages/catalog/.gitignore +++ b/packages/catalog/.gitignore @@ -41,3 +41,5 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +macos/ diff --git a/packages/catalog/.metadata b/packages/catalog/.metadata index 9d32c61..395986d 100644 --- a/packages/catalog/.metadata +++ b/packages/catalog/.metadata @@ -4,7 +4,7 @@ # This file should be version controlled and should not be manually edited. version: - revision: "b0850beeb25f6d5b10426284f506557f66181b36" + revision: "2663184aa79047d0a33a14a3b607954f8fdd8730" channel: "stable" project_type: app @@ -13,26 +13,11 @@ project_type: app migration: platforms: - platform: root - create_revision: b0850beeb25f6d5b10426284f506557f66181b36 - base_revision: b0850beeb25f6d5b10426284f506557f66181b36 - - platform: android - create_revision: b0850beeb25f6d5b10426284f506557f66181b36 - base_revision: b0850beeb25f6d5b10426284f506557f66181b36 - - platform: ios - create_revision: b0850beeb25f6d5b10426284f506557f66181b36 - base_revision: b0850beeb25f6d5b10426284f506557f66181b36 - - platform: linux - create_revision: b0850beeb25f6d5b10426284f506557f66181b36 - base_revision: b0850beeb25f6d5b10426284f506557f66181b36 + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 - platform: macos - create_revision: b0850beeb25f6d5b10426284f506557f66181b36 - base_revision: b0850beeb25f6d5b10426284f506557f66181b36 - - platform: web - create_revision: b0850beeb25f6d5b10426284f506557f66181b36 - base_revision: b0850beeb25f6d5b10426284f506557f66181b36 - - platform: windows - create_revision: b0850beeb25f6d5b10426284f506557f66181b36 - base_revision: b0850beeb25f6d5b10426284f506557f66181b36 + create_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 + base_revision: 2663184aa79047d0a33a14a3b607954f8fdd8730 # User provided section diff --git a/packages/catalog/lib/usecases/dropdown.dart b/packages/catalog/lib/usecases/dropdown.dart new file mode 100644 index 0000000..718157d --- /dev/null +++ b/packages/catalog/lib/usecases/dropdown.dart @@ -0,0 +1,65 @@ +import 'package:cave/cave.dart'; +import 'package:flutter/material.dart'; +import 'package:widgetbook_annotation/widgetbook_annotation.dart' as widgetbook; + +List locations = [ + "Exhibition Room", + "Room 1", + "Room 2", + "Room 3", + "Hallway", + "Toilet", + "Stairway", + "Room 4", +]; + +@widgetbook.UseCase( + name: 'DevFest Dropdown', + type: DevfestDropDown, + designLink: + "https://www.figma.com/design/CMEZj7OPDW09hOuTg1tAgF/DevFest-Lagos-'24---Mobile-App.?node-id=5457-8141&node-type=FRAME&t=13HTMdJAt4XcDqvU-0", +) +Widget devfestDropdown(BuildContext context) { + String? currentLocation; + String? destination; + return StatefulBuilder(builder: (context, setState) { + return Scaffold( + backgroundColor: DevfestTheme.of(context).backgroundColor, + body: Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + DevfestDropDown( + items: locations, + selectedItem: currentLocation, + onChanged: (value) { + currentLocation = value; + setState(() {}); + }, + title: 'Where are you in Landmark?', + hint: 'Current location', + prefixIcon: const Icon(IconsaxOutline.location), + suffixIcon: const Icon(IconsaxOutline.arrow_down_1), + ), + const SizedBox(height: 16), + DevfestDropDown( + items: locations, + selectedItem: destination, + onChanged: (value) { + destination = value; + setState(() {}); + }, + title: 'Where are you headed?', + hint: 'Desired destination', + prefixIcon: const Icon(IconsaxOutline.location_tick), + suffixIcon: const Icon(IconsaxOutline.arrow_down_1), + ), + ], + ), + ), + ), + ); + }); +} diff --git a/packages/catalog/pubspec.lock b/packages/catalog/pubspec.lock index 3d5c938..9b347a4 100644 --- a/packages/catalog/pubspec.lock +++ b/packages/catalog/pubspec.lock @@ -242,6 +242,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_animate: + dependency: transitive + description: + name: flutter_animate + sha256: "7c8a6594a9252dad30cc2ef16e33270b6248c4dedc3b3d06c86c4f3f4dc05ae5" + url: "https://pub.dev" + source: hosted + version: "4.5.0" flutter_lints: dependency: "direct dev" description: @@ -258,6 +266,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.9.3" + flutter_shaders: + dependency: transitive + description: + name: flutter_shaders + sha256: "02750b545c01ff4d8e9bbe8f27a7731aa3778402506c67daa1de7f5fc3f4befe" + url: "https://pub.dev" + source: hosted + version: "0.1.2" flutter_test: dependency: "direct dev" description: flutter diff --git a/packages/cave/lib/themes/text_field_theme.dart b/packages/cave/lib/themes/text_field_theme.dart index a723cbf..fa55aa9 100644 --- a/packages/cave/lib/themes/text_field_theme.dart +++ b/packages/cave/lib/themes/text_field_theme.dart @@ -6,15 +6,17 @@ import 'effects.dart'; @immutable class DevfestTextFieldTheme extends ThemeExtension { - final InputBorder border; - final InputBorder enabledBorder; - final InputBorder focusedBorder; - final InputBorder errorBorder; - final TextStyle errorStyle; - final TextStyle hintStyle; - final TextStyle style; + final InputBorder? border; + final InputBorder? enabledBorder; + final InputBorder? focusedBorder; + final InputBorder? errorBorder; + final TextStyle? errorStyle; + final TextStyle? hintStyle; + final TextStyle? style; + final Color? prefixColor; + final Color? suffixColor; - const DevfestTextFieldTheme._({ + const DevfestTextFieldTheme({ required this.border, required this.enabledBorder, required this.errorBorder, @@ -22,10 +24,14 @@ class DevfestTextFieldTheme extends ThemeExtension { required this.errorStyle, required this.hintStyle, required this.style, + required this.prefixColor, + required this.suffixColor, }); DevfestTextFieldTheme.light() - : this._( + : this( + prefixColor: DevfestColors.grey10, + suffixColor: DevfestColors.grey10, border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(16)), borderSide: BorderSide(color: DevfestColors.grey80, width: 1.4), @@ -72,7 +78,9 @@ class DevfestTextFieldTheme extends ThemeExtension { ); DevfestTextFieldTheme.dark() - : this._( + : this( + prefixColor: DevfestColors.grey100, + suffixColor: DevfestColors.grey100, border: const OutlineInputBorder( borderRadius: BorderRadius.all(Radius.circular(16)), borderSide: BorderSide(color: DevfestColors.grey80, width: 1.4), @@ -114,7 +122,7 @@ class DevfestTextFieldTheme extends ThemeExtension { style: const TextStyle( fontSize: 16, fontWeight: FontWeight.w500, - color: DevfestColors.grey10, + color: DevfestColors.grey70, ), errorStyle: const TextStyle( fontSize: 16, @@ -124,7 +132,7 @@ class DevfestTextFieldTheme extends ThemeExtension { ); @override - ThemeExtension copyWith({ + DevfestTextFieldTheme copyWith({ InputBorder? border, InputBorder? focusedBorder, InputBorder? enabledBorder, @@ -132,8 +140,10 @@ class DevfestTextFieldTheme extends ThemeExtension { TextStyle? hintStyle, TextStyle? errorStyle, TextStyle? style, + Color? prefixColor, + Color? suffixColor, }) { - return DevfestTextFieldTheme._( + return DevfestTextFieldTheme( border: border ?? this.border, enabledBorder: enabledBorder ?? this.enabledBorder, focusedBorder: focusedBorder ?? this.focusedBorder, @@ -141,11 +151,13 @@ class DevfestTextFieldTheme extends ThemeExtension { hintStyle: hintStyle ?? this.hintStyle, errorStyle: errorStyle ?? this.errorStyle, style: style ?? this.style, + prefixColor: prefixColor ?? this.prefixColor, + suffixColor: suffixColor ?? this.suffixColor, ); } @override - ThemeExtension lerp( + DevfestTextFieldTheme lerp( covariant ThemeExtension? other, double t) { return this; } diff --git a/packages/cave/lib/themes/theme_data.dart b/packages/cave/lib/themes/theme_data.dart index e12e5b9..ad8b018 100644 --- a/packages/cave/lib/themes/theme_data.dart +++ b/packages/cave/lib/themes/theme_data.dart @@ -26,7 +26,7 @@ class DevFestThemeData extends ThemeExtension { DevFestThemeData.light() : this( - textTheme: DevfestTextTheme.light(), + textTheme: const DevfestTextTheme.light(), backgroundColor: DevfestColors.primariesYellow100, buttonTheme: const DevfestButtonTheme.light(), outlinedButtonTheme: const DevfestOutlinedButtonTheme.light(), @@ -36,7 +36,7 @@ class DevFestThemeData extends ThemeExtension { DevFestThemeData.dark() : this( - textTheme: DevfestTextTheme.dark(), + textTheme: const DevfestTextTheme.dark(), backgroundColor: DevfestColors.backgroundDark, textFieldTheme: DevfestTextFieldTheme.dark(), buttonTheme: const DevfestButtonTheme.dark(), @@ -50,12 +50,14 @@ class DevFestThemeData extends ThemeExtension { DevfestButtonTheme? buttonTheme, DevfestOutlinedButtonTheme? outlinedButtonTheme, DevfestBottomNavTheme? bottomNavTheme, + DevfestTextFieldTheme? textFieldTheme, }) { return DevFestThemeData( textTheme: textTheme ?? this.textTheme, buttonTheme: buttonTheme ?? this.buttonTheme, outlinedButtonTheme: outlinedButtonTheme ?? this.outlinedButtonTheme, bottomNavTheme: bottomNavTheme ?? this.bottomNavTheme, + textFieldTheme: textFieldTheme ?? this.textFieldTheme, ); } @@ -69,6 +71,7 @@ class DevFestThemeData extends ThemeExtension { outlinedButtonTheme: outlinedButtonTheme?.lerp(other.outlinedButtonTheme, t), bottomNavTheme: bottomNavTheme?.lerp(other.bottomNavTheme, t), + textFieldTheme: textFieldTheme?.lerp(other.textFieldTheme, t), ); } } diff --git a/packages/cave/lib/themes/typography.dart b/packages/cave/lib/themes/typography.dart index fe79b7a..e6c1d60 100644 --- a/packages/cave/lib/themes/typography.dart +++ b/packages/cave/lib/themes/typography.dart @@ -79,285 +79,285 @@ class DevfestTextTheme extends ThemeExtension { this.buttonSmallBold, }); - DevfestTextTheme.light() + const DevfestTextTheme.light() : this( - headerH1: TextStyle( - fontSize: 80.sp, + headerH1: const TextStyle( + fontSize: 80, fontWeight: FontWeight.w700, height: 1.15, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - headerH2: TextStyle( - fontSize: 62.sp, + headerH2: const TextStyle( + fontSize: 62, fontWeight: FontWeight.w700, height: 1.23, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - headerH3: TextStyle( - fontSize: 56.sp, + headerH3: const TextStyle( + fontSize: 56, fontWeight: FontWeight.w700, height: 1.25, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - headerH4: TextStyle( - fontSize: 40.sp, + headerH4: const TextStyle( + fontSize: 40, fontWeight: FontWeight.w700, height: 1.2, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - headerH5: TextStyle( - fontSize: 32.sp, + headerH5: const TextStyle( + fontSize: 32, fontWeight: FontWeight.w700, height: 1.25, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - headerH6: TextStyle( - fontSize: 28.sp, + headerH6: const TextStyle( + fontSize: 28, fontWeight: FontWeight.w400, height: 1.29, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - titleTitle1Regular: TextStyle( - fontSize: 24.sp, + titleTitle1Regular: const TextStyle( + fontSize: 24, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - titleTitle1Medium: TextStyle( - fontSize: 24.sp, + titleTitle1Medium: const TextStyle( + fontSize: 24, fontWeight: FontWeight.w500, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - titleTitle1Semibold: TextStyle( - fontSize: 24.sp, + titleTitle1Semibold: const TextStyle( + fontSize: 24, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - titleTitle2Regular: TextStyle( - fontSize: 22.sp, + titleTitle2Regular: const TextStyle( + fontSize: 22, fontWeight: FontWeight.w400, height: 1.45, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - titleTitle2Medium: TextStyle( - fontSize: 22.sp, + titleTitle2Medium: const TextStyle( + fontSize: 22, fontWeight: FontWeight.w500, height: 1.45, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - titleTitle2Semibold: TextStyle( - fontSize: 22.sp, + titleTitle2Semibold: const TextStyle( + fontSize: 22, fontWeight: FontWeight.w400, height: 1.45, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody1Regular: TextStyle( - fontSize: 18.sp, + bodyBody1Regular: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody1Medium: TextStyle( - fontSize: 18.sp, + bodyBody1Medium: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w500, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody1Semibold: TextStyle( - fontSize: 18.sp, + bodyBody1Semibold: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody2Regular: TextStyle( - fontSize: 16.sp, + bodyBody2Regular: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody2Medium: TextStyle( - fontSize: 16.sp, + bodyBody2Medium: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w500, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody2Semibold: TextStyle( - fontSize: 16.sp, + bodyBody2Semibold: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody3Regular: TextStyle( - fontSize: 14.sp, + bodyBody3Regular: const TextStyle( + fontSize: 14, fontWeight: FontWeight.w400, height: 1.43, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody3Medium: TextStyle( - fontSize: 14.sp, + bodyBody3Medium: const TextStyle( + fontSize: 14, fontWeight: FontWeight.w500, height: 1.43, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody3Semibold: TextStyle( - fontSize: 14.sp, + bodyBody3Semibold: const TextStyle( + fontSize: 14, fontWeight: FontWeight.w400, height: 1.43, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody4Regular: TextStyle( - fontSize: 12.sp, + bodyBody4Regular: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody4Medium: TextStyle( - fontSize: 12.sp, + bodyBody4Medium: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w500, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody4Semibold: TextStyle( - fontSize: 12.sp, + bodyBody4Semibold: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody5Regular: TextStyle( - fontSize: 10.sp, + bodyBody5Regular: const TextStyle( + fontSize: 10, fontWeight: FontWeight.w400, height: 1.4, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody5Medium: TextStyle( - fontSize: 10.sp, + bodyBody5Medium: const TextStyle( + fontSize: 10, fontWeight: FontWeight.w500, height: 1.4, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - bodyBody5Semibold: TextStyle( - fontSize: 10.sp, + bodyBody5Semibold: const TextStyle( + fontSize: 10, fontWeight: FontWeight.w400, height: 1.4, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonLargeMedium: TextStyle( - fontSize: 18.sp, + buttonLargeMedium: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w500, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonLargeSemibold: TextStyle( - fontSize: 18.sp, + buttonLargeSemibold: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonLargeBold: TextStyle( - fontSize: 18.sp, + buttonLargeBold: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w700, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonMediumMedium: TextStyle( - fontSize: 16.sp, + buttonMediumMedium: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w500, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonMediumSemibold: TextStyle( - fontSize: 16.sp, + buttonMediumSemibold: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w400, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonMediumBold: TextStyle( - fontSize: 16.sp, + buttonMediumBold: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w700, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonSmallMedium: TextStyle( - fontSize: 12.sp, + buttonSmallMedium: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w500, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonSmallSemibold: TextStyle( - fontSize: 12.sp, + buttonSmallSemibold: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w400, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey10, leadingDistribution: TextLeadingDistribution.even), - buttonSmallBold: TextStyle( - fontSize: 12.sp, + buttonSmallBold: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w700, fontStyle: FontStyle.normal, decoration: TextDecoration.none, @@ -365,285 +365,285 @@ class DevfestTextTheme extends ThemeExtension { leadingDistribution: TextLeadingDistribution.even), ); - DevfestTextTheme.dark() + const DevfestTextTheme.dark() : this( - headerH1: TextStyle( - fontSize: 80.sp, + headerH1: const TextStyle( + fontSize: 80, fontWeight: FontWeight.w700, height: 1.15, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - headerH2: TextStyle( - fontSize: 62.sp, + headerH2: const TextStyle( + fontSize: 62, fontWeight: FontWeight.w700, height: 1.23, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - headerH3: TextStyle( - fontSize: 56.sp, + headerH3: const TextStyle( + fontSize: 56, fontWeight: FontWeight.w700, height: 1.25, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - headerH4: TextStyle( - fontSize: 40.sp, + headerH4: const TextStyle( + fontSize: 40, fontWeight: FontWeight.w700, height: 1.2, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - headerH5: TextStyle( - fontSize: 32.sp, + headerH5: const TextStyle( + fontSize: 32, fontWeight: FontWeight.w700, height: 1.25, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - headerH6: TextStyle( - fontSize: 28.sp, + headerH6: const TextStyle( + fontSize: 28, fontWeight: FontWeight.w400, height: 1.29, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - titleTitle1Regular: TextStyle( - fontSize: 24.sp, + titleTitle1Regular: const TextStyle( + fontSize: 24, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - titleTitle1Medium: TextStyle( - fontSize: 24.sp, + titleTitle1Medium: const TextStyle( + fontSize: 24, fontWeight: FontWeight.w500, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - titleTitle1Semibold: TextStyle( - fontSize: 24.sp, + titleTitle1Semibold: const TextStyle( + fontSize: 24, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - titleTitle2Regular: TextStyle( - fontSize: 22.sp, + titleTitle2Regular: const TextStyle( + fontSize: 22, fontWeight: FontWeight.w400, height: 1.45, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - titleTitle2Medium: TextStyle( - fontSize: 22.sp, + titleTitle2Medium: const TextStyle( + fontSize: 22, fontWeight: FontWeight.w500, height: 1.45, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - titleTitle2Semibold: TextStyle( - fontSize: 22.sp, + titleTitle2Semibold: const TextStyle( + fontSize: 22, fontWeight: FontWeight.w400, height: 1.45, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody1Regular: TextStyle( - fontSize: 18.sp, + bodyBody1Regular: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody1Medium: TextStyle( - fontSize: 18.sp, + bodyBody1Medium: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w500, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody1Semibold: TextStyle( - fontSize: 18.sp, + bodyBody1Semibold: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody2Regular: TextStyle( - fontSize: 16.sp, + bodyBody2Regular: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody2Medium: TextStyle( - fontSize: 16.sp, + bodyBody2Medium: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w500, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody2Semibold: TextStyle( - fontSize: 16.sp, + bodyBody2Semibold: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody3Regular: TextStyle( - fontSize: 14.sp, + bodyBody3Regular: const TextStyle( + fontSize: 14, fontWeight: FontWeight.w400, height: 1.43, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody3Medium: TextStyle( - fontSize: 14.sp, + bodyBody3Medium: const TextStyle( + fontSize: 14, fontWeight: FontWeight.w500, height: 1.43, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody3Semibold: TextStyle( - fontSize: 14.sp, + bodyBody3Semibold: const TextStyle( + fontSize: 14, fontWeight: FontWeight.w400, height: 1.43, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody4Regular: TextStyle( - fontSize: 12.sp, + bodyBody4Regular: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody4Medium: TextStyle( - fontSize: 12.sp, + bodyBody4Medium: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w500, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody4Semibold: TextStyle( - fontSize: 12.sp, + bodyBody4Semibold: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w400, height: 1.5, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody5Regular: TextStyle( - fontSize: 10.sp, + bodyBody5Regular: const TextStyle( + fontSize: 10, fontWeight: FontWeight.w400, height: 1.4, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody5Medium: TextStyle( - fontSize: 10.sp, + bodyBody5Medium: const TextStyle( + fontSize: 10, fontWeight: FontWeight.w500, height: 1.4, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - bodyBody5Semibold: TextStyle( - fontSize: 10.sp, + bodyBody5Semibold: const TextStyle( + fontSize: 10, fontWeight: FontWeight.w400, height: 1.4, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonLargeMedium: TextStyle( - fontSize: 18.sp, + buttonLargeMedium: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w500, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonLargeSemibold: TextStyle( - fontSize: 18.sp, + buttonLargeSemibold: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w400, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonLargeBold: TextStyle( - fontSize: 18.sp, + buttonLargeBold: const TextStyle( + fontSize: 18, fontWeight: FontWeight.w700, height: 1.33, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonMediumMedium: TextStyle( - fontSize: 16.sp, + buttonMediumMedium: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w500, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonMediumSemibold: TextStyle( - fontSize: 16.sp, + buttonMediumSemibold: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w400, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonMediumBold: TextStyle( - fontSize: 16.sp, + buttonMediumBold: const TextStyle( + fontSize: 16, fontWeight: FontWeight.w700, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonSmallMedium: TextStyle( - fontSize: 12.sp, + buttonSmallMedium: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w500, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonSmallSemibold: TextStyle( - fontSize: 12.sp, + buttonSmallSemibold: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w400, fontStyle: FontStyle.normal, decoration: TextDecoration.none, color: DevfestColors.grey100, leadingDistribution: TextLeadingDistribution.even), - buttonSmallBold: TextStyle( - fontSize: 12.sp, + buttonSmallBold: const TextStyle( + fontSize: 12, fontWeight: FontWeight.w700, fontStyle: FontStyle.normal, decoration: TextDecoration.none, diff --git a/packages/cave/lib/widgets/drop_down.dart b/packages/cave/lib/widgets/drop_down.dart new file mode 100644 index 0000000..3ce8dde --- /dev/null +++ b/packages/cave/lib/widgets/drop_down.dart @@ -0,0 +1,184 @@ +import 'package:cave/themes/text_field_theme.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_animate/flutter_animate.dart'; + +import '../themes/themes.dart'; +import 'text_field.dart'; + +class DevfestDropDown extends StatefulWidget { + const DevfestDropDown({ + super.key, + required this.items, + this.selectedItem, + this.onChanged, + this.title, + this.hint, + this.prefixIcon, + this.suffixIcon, + this.prefixIconColor, + this.suffixIconColor, + }); + + final List items; + final T? selectedItem; + final void Function(T? value)? onChanged; + final String? title; + final String? hint; + final Widget? prefixIcon; + final Widget? suffixIcon; + final Color? prefixIconColor; + final Color? suffixIconColor; + + @override + State> createState() => _DevfestDropDownState(); +} + +class _DevfestDropDownState extends State> { + final OverlayPortalController _tooltipController = OverlayPortalController(); + final TextEditingController _fieldController = TextEditingController(); + + final _link = LayerLink(); + double? _buttonWidth; + T? _hoveredItem; + + @override + Widget build(BuildContext context) { + final textFieldTheme = DevfestTheme.of(context).textFieldTheme; + final backgroundColor = DevfestTheme.of(context).backgroundColor; + return CompositedTransformTarget( + link: _link, + child: OverlayPortal( + controller: _tooltipController, + overlayChildBuilder: (BuildContext context) { + final overlay = + Overlay.of(context).context.findRenderObject()! as RenderBox; + return ConstrainedBox( + constraints: BoxConstraints.loose(overlay.paintBounds.size), + child: TapRegion( + onTapOutside: (_) { + _tooltipController.toggle(); + }, + child: CompositedTransformFollower( + link: _link, + targetAnchor: Alignment.bottomLeft, + child: Align( + alignment: AlignmentDirectional.topStart, + child: Animate( + effects: const [ + FadeEffect(duration: Duration(milliseconds: 100)), + ScaleEffect( + begin: Offset(.95, .95), + end: Offset(1, 1), + duration: Duration(milliseconds: 100), + ), + MoveEffect( + begin: Offset(0, 2), + end: Offset.zero, + duration: Duration(milliseconds: 100), + ), + ], + child: Container( + width: _buttonWidth, + decoration: ShapeDecoration( + color: backgroundColor, + shape: RoundedRectangleBorder( + side: textFieldTheme?.border?.borderSide.copyWith( + color: Colors.grey.withOpacity(0.12), + width: 1.0) ?? + BorderSide.none, + borderRadius: + const BorderRadius.all(Radius.circular(16)), + ), + ), + padding: const EdgeInsets.symmetric( + horizontal: 12, vertical: 6), + child: Column( + mainAxisSize: MainAxisSize.min, + children: widget.items + .map( + (item) => MouseRegion( + onEnter: (_) { + setState(() { + _hoveredItem = item; + }); + }, + onExit: (_) { + setState(() { + _hoveredItem = null; + }); + }, + cursor: SystemMouseCursors.click, + child: GestureDetector( + onTap: () { + _fieldController.text = item.toString(); + widget.onChanged?.call(item); + _tooltipController.toggle(); + }, + child: Container( + width: double.infinity, + padding: const EdgeInsets.all(8.0), + decoration: BoxDecoration( + color: _getItemBackgroundColor(item), + borderRadius: BorderRadius.circular(8), + ), + child: Text( + item.toString(), + ), + ), + ), + ), + ) + .toList(), + ), + ), + ), + ), + ), + ), + ); + }, + child: DevfestTheme( + data: DevfestTheme.of(context).copyWith( + textFieldTheme: DevfestTextFieldTheme( + border: textFieldTheme?.border, + enabledBorder: textFieldTheme?.border, + errorBorder: textFieldTheme?.border, + focusedBorder: textFieldTheme?.border, + errorStyle: textFieldTheme?.errorStyle, + hintStyle: textFieldTheme?.hintStyle, + style: textFieldTheme?.style, + suffixColor: textFieldTheme?.suffixColor, + prefixColor: textFieldTheme?.prefixColor, + ), + ), + child: GestureDetector( + onTap: onTap, + child: DevfestTextFormField( + title: widget.title, + hint: widget.hint, + controller: _fieldController, + prefixIcon: widget.prefixIcon, + suffixIcon: widget.suffixIcon, + enabled: false, + readOnly: true, + ), + ), + ), + ), + ); + } + + Color? _getItemBackgroundColor(T item) { + if (item == widget.selectedItem) { + return Colors.grey.withOpacity(0.2); + } else if (item == _hoveredItem) { + return Colors.grey.withOpacity(0.1); + } + return Colors.transparent; + } + + void onTap() { + _buttonWidth = context.size?.width; + _tooltipController.toggle(); + } +} diff --git a/packages/cave/lib/widgets/text_field.dart b/packages/cave/lib/widgets/text_field.dart index 368cd41..b7d9205 100644 --- a/packages/cave/lib/widgets/text_field.dart +++ b/packages/cave/lib/widgets/text_field.dart @@ -14,27 +14,73 @@ class DevfestTextFormField extends StatelessWidget { this.info, TextInputType? keyboardType, Color? iconColor, + bool? readOnly, + IconData? prefixIconData, + IconData? suffixIconData, + this.enabled, this.onChanged, this.validator, this.textInputAction, this.autovalidateMode, + this.onTap, + this.prefixIcon, + this.prefixIconColor, + this.suffixIconColor, + this.suffixIcon, }) : keyboardType = keyboardType ?? TextInputType.text, + readOnly = readOnly ?? false, iconColor = iconColor ?? DevfestColors.grey10; final String? title; final String? info; final String? hint; final TextEditingController? controller; final TextInputType keyboardType; + final bool readOnly; + final bool? enabled; final Color iconColor; final ValueChanged? onChanged; final String? Function(String?)? validator; final TextInputAction? textInputAction; final AutovalidateMode? autovalidateMode; + final GestureTapCallback? onTap; + final Widget? prefixIcon; + final Widget? suffixIcon; + final Color? prefixIconColor; + final Color? suffixIconColor; @override Widget build(BuildContext context) { + Widget? prefixIcon; + Widget? suffixIcon; final textFieldTheme = DevfestTheme.of(context).textFieldTheme ?? DevfestTextFieldTheme.light(); + + switch (this.prefixIcon) { + case _?: + switch (this.prefixIcon) { + case Icon(): + prefixIcon = Icon( + (this.prefixIcon! as Icon).icon, + color: prefixIconColor ?? textFieldTheme.prefixColor, + ); + default: + prefixIcon = this.prefixIcon; + } + } + + switch (this.suffixIcon) { + case _?: + switch (this.suffixIcon) { + case Icon(): + suffixIcon = Icon( + (this.suffixIcon! as Icon).icon, + color: suffixIconColor ?? textFieldTheme.suffixColor, + ); + default: + suffixIcon = this.suffixIcon; + } + } + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -48,6 +94,9 @@ class DevfestTextFormField extends StatelessWidget { TextFormField( controller: controller, keyboardType: keyboardType, + onTap: onTap, + readOnly: readOnly, + enabled: enabled, onChanged: onChanged, validator: validator, textInputAction: textInputAction, @@ -55,6 +104,8 @@ class DevfestTextFormField extends StatelessWidget { keyboardAppearance: Brightness.dark, style: textFieldTheme.style, decoration: InputDecoration( + prefixIcon: prefixIcon, + suffixIcon: suffixIcon, hintText: hint, hintStyle: textFieldTheme.hintStyle, errorStyle: textFieldTheme.errorStyle, @@ -67,7 +118,6 @@ class DevfestTextFormField extends StatelessWidget { focusedErrorBorder: textFieldTheme.errorBorder, ), ), - Constants.largeVerticalGutter.verticalSpace, ], ); } diff --git a/packages/cave/lib/widgets/widgets.dart b/packages/cave/lib/widgets/widgets.dart index 1c836cc..628f022 100644 --- a/packages/cave/lib/widgets/widgets.dart +++ b/packages/cave/lib/widgets/widgets.dart @@ -1,3 +1,4 @@ export 'bottom_nav.dart'; export 'buttons.dart'; +export 'drop_down.dart'; export 'text_field.dart'; diff --git a/packages/cave/pubspec.yaml b/packages/cave/pubspec.yaml index 0159000..f2b25de 100644 --- a/packages/cave/pubspec.yaml +++ b/packages/cave/pubspec.yaml @@ -12,6 +12,7 @@ dependencies: ficonsax: ^0.0.3 flutter: sdk: flutter + flutter_animate: ^4.5.0 flutter_screenutil: ^5.9.3 dev_dependencies: diff --git a/packages/conferenceapp/pubspec.lock b/packages/conferenceapp/pubspec.lock index 811fa9a..adf08ce 100644 --- a/packages/conferenceapp/pubspec.lock +++ b/packages/conferenceapp/pubspec.lock @@ -117,6 +117,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_animate: + dependency: transitive + description: + name: flutter_animate + sha256: "7c8a6594a9252dad30cc2ef16e33270b6248c4dedc3b3d06c86c4f3f4dc05ae5" + url: "https://pub.dev" + source: hosted + version: "4.5.0" flutter_lints: dependency: "direct dev" description: @@ -141,6 +149,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.9.3" + flutter_shaders: + dependency: transitive + description: + name: flutter_shaders + sha256: "02750b545c01ff4d8e9bbe8f27a7731aa3778402506c67daa1de7f5fc3f4befe" + url: "https://pub.dev" + source: hosted + version: "0.1.2" flutter_svg: dependency: "direct main" description: diff --git a/packages/volunteerapp/pubspec.lock b/packages/volunteerapp/pubspec.lock index 5c463bc..f5665f7 100644 --- a/packages/volunteerapp/pubspec.lock +++ b/packages/volunteerapp/pubspec.lock @@ -101,6 +101,14 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_animate: + dependency: transitive + description: + name: flutter_animate + sha256: "7c8a6594a9252dad30cc2ef16e33270b6248c4dedc3b3d06c86c4f3f4dc05ae5" + url: "https://pub.dev" + source: hosted + version: "4.5.0" flutter_lints: dependency: "direct dev" description: @@ -125,6 +133,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.9.3" + flutter_shaders: + dependency: transitive + description: + name: flutter_shaders + sha256: "02750b545c01ff4d8e9bbe8f27a7731aa3778402506c67daa1de7f5fc3f4befe" + url: "https://pub.dev" + source: hosted + version: "0.1.2" flutter_test: dependency: "direct dev" description: flutter