diff --git a/lib/app/app_context_ext.dart b/lib/app/app_context_ext.dart index 7dd0f43..fa36685 100644 --- a/lib/app/app_context_ext.dart +++ b/lib/app/app_context_ext.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:friflex_starter/app/theme/app_colors_scheme.dart'; import 'package:friflex_starter/app/theme/theme_notifier.dart'; import 'package:friflex_starter/di/di_container.dart'; import 'package:friflex_starter/l10n/gen/app_localizations.dart'; @@ -11,7 +12,7 @@ extension AppContextExt on BuildContext { DiContainer get di => read(); /// Геттер для получения цветовой схемы - ColorScheme get colors => Theme.of(this).colorScheme; + AppColors get colors => Theme.of(this).extension()!; /// Геттер для получения темы ThemeNotifier get theme => read(); diff --git a/lib/app/theme/app_colors_scheme.dart b/lib/app/theme/app_colors_scheme.dart index 3a968fe..80df22c 100644 --- a/lib/app/theme/app_colors_scheme.dart +++ b/lib/app/theme/app_colors_scheme.dart @@ -1,18 +1,103 @@ +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +/// {@template app_colors} /// Класс, реализующий расширение для добавления токенов в цветовую схему -extension AppColorsScheme on ColorScheme { - bool get _isDark => brightness == Brightness.dark; +/// {@endtemplate} +class AppColors extends ThemeExtension with DiagnosticableTreeMixin { + /// {@macro app_colors} + /// + /// Принимает: + /// + /// * [testColor] - цвет тестового текста + /// * [errorSnackbarBackground] - цвет фона снекбара ошибки + /// * [successSnackbarBackground] - цвет фона снекбара успеха + /// * [infoSnackbarBackground] - цвет фона снекбара информации + /// * [itemTextColor] - цвет элемента текста + const AppColors({ + required this.testColor, + required this.itemTextColor, + required this.errorSnackbarBackground, + required this.successSnackbarBackground, + required this.infoSnackbarBackground, + }); - // Тестовый цвет - Color get testColor => _isDark ? Colors.green : Colors.red; + /// Цвет тестовый + final Color testColor; - /// Цвет заднего фона снекбара с ошибкой - Color get errorSnackbarBackground => const Color(0xFFD24720); + /// Цвет элемента текста + final Color itemTextColor; - /// Цвет заднего фона снекбара с успехом - Color get successSnackbarBackground => const Color(0xFF6FB62C); + /// Цвет фона снекбара ошибки + final Color errorSnackbarBackground; - /// Цвет заднего фона снекбара с информацией - Color get infoSnackbarBackground => const Color.fromARGB(255, 220, 108, 77); + /// Цвет фона снекбара успеха + final Color successSnackbarBackground; + + /// Цвет фона снекбара информации + final Color infoSnackbarBackground; + + /// Цвета светлой темы + static final AppColors light = AppColors( + testColor: Colors.red, + errorSnackbarBackground: const Color(0xFFD24720), + successSnackbarBackground: const Color(0xFF6FB62C), + infoSnackbarBackground: const Color.fromARGB(255, 220, 108, 77), + itemTextColor: const Color(0xFFFAF3EB), + ); + + /// Цвета тёмной темы + static final AppColors dark = AppColors( + testColor: Colors.green, + errorSnackbarBackground: const Color(0xFF638B8B), + successSnackbarBackground: const Color(0xFF93C499), + infoSnackbarBackground: const Color.fromARGB(255, 35, 147, 178), + itemTextColor: Colors.white, + ); + + @override + ThemeExtension copyWith({ + Color? testColor, + Color? errorSnackbarBackground, + Color? successSnackbarBackground, + Color? infoSnackbarBackground, + Color? itemTextColor, + }) => AppColors( + testColor: testColor ?? this.testColor, + errorSnackbarBackground: + errorSnackbarBackground ?? this.errorSnackbarBackground, + successSnackbarBackground: + successSnackbarBackground ?? this.successSnackbarBackground, + infoSnackbarBackground: + infoSnackbarBackground ?? this.infoSnackbarBackground, + itemTextColor: itemTextColor ?? this.itemTextColor, + ); + + @override + ThemeExtension lerp( + covariant ThemeExtension? other, + double t, + ) { + if (other is! AppColors) return this; + + return AppColors( + testColor: Color.lerp(testColor, other.testColor, t)!, + errorSnackbarBackground: Color.lerp( + errorSnackbarBackground, + other.errorSnackbarBackground, + t, + )!, + successSnackbarBackground: Color.lerp( + successSnackbarBackground, + other.successSnackbarBackground, + t, + )!, + infoSnackbarBackground: Color.lerp( + infoSnackbarBackground, + other.infoSnackbarBackground, + t, + )!, + itemTextColor: Color.lerp(itemTextColor, other.itemTextColor, t)!, + ); + } } diff --git a/lib/app/theme/app_theme.dart b/lib/app/theme/app_theme.dart index 4a88777..e5dd811 100644 --- a/lib/app/theme/app_theme.dart +++ b/lib/app/theme/app_theme.dart @@ -1,10 +1,15 @@ import 'package:flutter/material.dart'; +import 'package:friflex_starter/app/theme/app_colors_scheme.dart'; /// Класс для конфигурации светлой/темной темы приложения abstract class AppTheme { /// Геттер для получения светлой темы - static ThemeData get light => ThemeData.light(); + static ThemeData get light => ThemeData.light().copyWith( + extensions: >[AppColors.light], + ); /// Геттер для получения темной темы - static ThemeData get dark => ThemeData.dark(); + static ThemeData get dark => ThemeData.dark().copyWith( + extensions: >[AppColors.dark], + ); } diff --git a/lib/app/ui_kit/app_snackbar.dart b/lib/app/ui_kit/app_snackbar.dart index 82dc0e4..85f37d8 100644 --- a/lib/app/ui_kit/app_snackbar.dart +++ b/lib/app/ui_kit/app_snackbar.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:friflex_starter/app/app_context_ext.dart'; -import 'package:friflex_starter/app/theme/app_colors_scheme.dart'; import 'package:friflex_starter/app/ui_kit/app_box.dart'; /// {@template app_snackbar} diff --git a/lib/features/debug/screens/lang_screen.dart b/lib/features/debug/screens/lang_screen.dart index f8f91a0..fe98734 100644 --- a/lib/features/debug/screens/lang_screen.dart +++ b/lib/features/debug/screens/lang_screen.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:friflex_starter/app/app_context_ext.dart'; -import 'package:friflex_starter/app/theme/app_colors_scheme.dart'; import 'package:friflex_starter/gen/assets.gen.dart'; import 'package:friflex_starter/gen/fonts.gen.dart'; diff --git a/lib/features/debug/screens/theme_screen.dart b/lib/features/debug/screens/theme_screen.dart index a847651..4d591af 100644 --- a/lib/features/debug/screens/theme_screen.dart +++ b/lib/features/debug/screens/theme_screen.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:friflex_starter/app/app_context_ext.dart'; -import 'package:friflex_starter/app/theme/app_colors_scheme.dart'; /// {@template ThemeScreen} /// Экран для отладки темы приложения @@ -11,6 +10,7 @@ class ThemeScreen extends StatelessWidget { @override Widget build(BuildContext context) { + final colors = context.colors; return Scaffold( appBar: AppBar(title: const Text('Theme')), body: Center( @@ -29,7 +29,25 @@ class ThemeScreen extends StatelessWidget { child: const SizedBox(height: 100, width: 100), ), const SizedBox(height: 16), - Text('Текущая тема: ${context.theme.themeMode}'), + Card( + elevation: 4, + shadowColor: colors.infoSnackbarBackground, + margin: const EdgeInsets.symmetric(vertical: 10), + color: colors.infoSnackbarBackground, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(16), + ), + child: ListTile( + title: Text( + 'Текущая тема: ${context.theme.themeMode}', + style: TextStyle( + color: colors.itemTextColor, + fontWeight: FontWeight.bold, + ), + ), + trailing: Icon(Icons.color_lens, color: colors.itemTextColor), + ), + ), ], ), ),