Files
Casha/lib/app/theme.dart
T
2026-03-22 17:12:40 +03:00

244 lines
8.1 KiB
Dart

import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart';
import '../core/constants.dart';
TextStyle? _f(TextStyle? s) {
final result = s?.copyWith(fontFamilyFallback: ['NunitoCyrillic']);
debugPrint('fallback: ${result?.fontFamilyFallback}'); // проверь в логах
return result;
}
TextTheme _withCyrillicFallback(TextTheme t) => TextTheme(
displayLarge: _f(t.displayLarge),
displayMedium: _f(t.displayMedium),
displaySmall: _f(t.displaySmall),
headlineLarge: _f(t.headlineLarge),
headlineMedium: _f(t.headlineMedium),
headlineSmall: _f(t.headlineSmall),
titleLarge: _f(t.titleLarge),
titleMedium: _f(t.titleMedium),
titleSmall: _f(t.titleSmall),
bodyLarge: _f(t.bodyLarge),
bodyMedium: _f(t.bodyMedium),
bodySmall: _f(t.bodySmall),
labelLarge: _f(t.labelLarge),
labelMedium: _f(t.labelMedium),
labelSmall: _f(t.labelSmall),
);
class AppTheme {
static ThemeData get darkTheme {
final base = ThemeData.dark(useMaterial3: true);
final textTheme = _withCyrillicFallback(
base.textTheme.apply(
fontFamily: 'Poppins',
bodyColor: AppColors.textPrimary,
displayColor: AppColors.textPrimary,
),
);
return base.copyWith(
textTheme: textTheme,
scaffoldBackgroundColor: AppColors.background,
colorScheme: const ColorScheme.dark(
surface: AppColors.surface,
primary: AppColors.accent,
secondary: AppColors.accent,
onPrimary: Colors.white,
onSurface: AppColors.textPrimary,
),
cardTheme: CardThemeData(
color: AppColors.surface,
elevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
margin: EdgeInsets.zero,
),
appBarTheme: AppBarTheme(
backgroundColor: AppColors.background,
elevation: 0,
centerTitle: false,
titleTextStyle: GoogleFonts.poppins(
color: AppColors.textPrimary,
fontSize: 20,
fontWeight: FontWeight.w600,
),
iconTheme: const IconThemeData(color: AppColors.textPrimary),
),
navigationBarTheme: NavigationBarThemeData(
backgroundColor: AppColors.surface,
indicatorColor: AppColors.accent.withOpacity(0.2),
labelTextStyle: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return GoogleFonts.poppins(
color: AppColors.accent,
fontSize: 12,
fontWeight: FontWeight.w600,
);
}
return GoogleFonts.poppins(
color: AppColors.textSecondary,
fontSize: 12,
);
}),
iconTheme: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return const IconThemeData(color: AppColors.accent);
}
return const IconThemeData(color: AppColors.textSecondary);
}),
),
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: AppColors.surface,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: AppColors.divider),
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: AppColors.divider),
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(12),
borderSide: const BorderSide(color: AppColors.accent, width: 1.5),
),
labelStyle: const TextStyle(color: AppColors.textSecondary),
hintStyle: const TextStyle(color: AppColors.textSecondary),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.accent,
foregroundColor: Colors.white,
minimumSize: const Size(double.infinity, 52),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
textStyle: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
dividerTheme: const DividerThemeData(
color: AppColors.divider,
thickness: 1,
),
);
}
static ThemeData get lightTheme {
final base = ThemeData.light(useMaterial3: true);
final textTheme = GoogleFonts.poppinsTextTheme(base.textTheme).apply(
bodyColor: const Color(0xFF1A1A2E),
displayColor: const Color(0xFF1A1A2E),
fontFamilyFallback: ['Roboto'], // Ensures Cyrillic renders with same visual style
);
return base.copyWith(
textTheme: textTheme,
scaffoldBackgroundColor: const Color(0xFFF0F0F7),
colorScheme: const ColorScheme.light(
surface: Colors.white,
primary: AppColors.accent,
secondary: AppColors.accent,
onPrimary: Colors.white,
onSurface: Color(0xFF1A1A2E),
),
cardTheme: CardThemeData(
color: Colors.white,
elevation: 2,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(16),
),
margin: EdgeInsets.zero,
),
appBarTheme: AppBarTheme(
backgroundColor: Colors.white,
foregroundColor: const Color(0xFF1A1A2E),
elevation: 0,
centerTitle: false,
titleTextStyle: GoogleFonts.poppins(
color: const Color(0xFF1A1A2E),
fontSize: 20,
fontWeight: FontWeight.w600,
),
iconTheme: const IconThemeData(color: AppColors.accent),
),
navigationBarTheme: NavigationBarThemeData(
backgroundColor: Colors.white,
indicatorColor: AppColors.accent.withOpacity(0.2),
labelTextStyle: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return GoogleFonts.poppins(
color: AppColors.accent,
fontSize: 12,
fontWeight: FontWeight.w600,
);
}
return GoogleFonts.poppins(
color: const Color(0xFF9999BB),
fontSize: 12,
);
}),
iconTheme: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
return const IconThemeData(color: AppColors.accent);
}
return const IconThemeData(color: Color(0xFF9999BB));
}),
),
inputDecorationTheme: InputDecorationTheme(
filled: true,
fillColor: const Color(0xFFEEEEF8),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
enabledBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: BorderSide.none,
),
focusedBorder: OutlineInputBorder(
borderRadius: BorderRadius.circular(8),
borderSide: const BorderSide(color: AppColors.accent, width: 1.5),
),
labelStyle: const TextStyle(color: Color(0xFF9999BB)),
hintStyle: const TextStyle(color: Color(0xFF9999BB)),
),
elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
backgroundColor: AppColors.accent,
foregroundColor: Colors.white,
minimumSize: const Size(double.infinity, 52),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(14),
),
textStyle: GoogleFonts.poppins(
fontSize: 16,
fontWeight: FontWeight.w600,
),
),
),
dividerTheme: const DividerThemeData(
color: Color(0xFFDDDDEE),
thickness: 1,
),
iconTheme: const IconThemeData(color: AppColors.accent),
chipTheme: ChipThemeData(
backgroundColor: const Color(0xFFEEEEF8),
selectedColor: AppColors.accent,
labelStyle: GoogleFonts.poppins(
color: const Color(0xFF1A1A2E),
),
),
);
}
}
ThemeData buildAppTheme() => AppTheme.darkTheme;