Path:
lib/presentation/theme/app_theme.dart
Lines:
273
Non-empty lines:
250
Non-empty lines covered with requirements:
250 / 250 (100.0%)
Functions:
0
Functions covered by requirements:
0 / 0 (0.0%)
1
import 'package:bioflow_pro/domain/value_objects/ui/theme_type.dart';
2
import 'package:bioflow_pro/presentation/theme/bioflow_theme_extension.dart';
3
import 'package:bioflow_pro/presentation/theme/design_system.dart';
4
import 'package:flutter/material.dart';
5
6
// @relation(ARCH-011, scope=file)7
/// Application theme configuration with BioFlow design system8
///9
/// Integrates Material Design 3 with BioFlow's medical purple palette10
/// and custom glassmorphism theme extension.11
class AppTheme {
12
/// Create ThemeData for a specific preset theme type
13
static ThemeData forPreset(ThemeType themeType) {
14
switch (themeType) {
15
case ThemeType.minimal:
16
return _minimalTheme;
17
case ThemeType.darkGlass:
18
return _darkGlassTheme;
19
case ThemeType.minimalLight:
20
return _minimalLightTheme;
21
}
22
}
23
24
/// Dark Glass theme - Main glassmorphism theme
25
static ThemeData get _darkGlassTheme {
26
return _baseTheme(
27
brightness: Brightness.light,
28
extension: BioFlowThemeExtension.darkGlass(),
29
);
30
}
31
32
/// Minimal theme - Opaque backgrounds, no blur
33
static ThemeData get _minimalTheme {
34
return _baseTheme(
35
brightness: Brightness.dark,
36
extension: BioFlowThemeExtension.minimal(),
37
);
38
}
39
40
/// Minimal Light theme - Light opaque backgrounds, no blur
41
static ThemeData get _minimalLightTheme {
42
return _baseLightTheme(
43
extension: BioFlowThemeExtension.minimalLight(),
44
);
45
}
46
47
/// Base theme configuration with BioFlow colors
48
static ThemeData _baseTheme({
49
required Brightness brightness,
50
required BioFlowThemeExtension extension,
51
}) {
52
// Use BioFlow medical purple palette
53
const primaryColor = BioFlowColors.electricViolet;
54
const secondaryColor = BioFlowColors.glassPurple;
55
final backgroundColor = brightness == Brightness.dark
56
? BioFlowColors.primaryDark
57
: BioFlowColors.backgroundPrimary;
58
final surfaceColor = brightness == Brightness.dark
59
? BioFlowColors.primaryDark
60
: BioFlowColors.backgroundSecondary;
61
62
return ThemeData(
63
useMaterial3: true,
64
brightness: brightness,
65
colorScheme: ColorScheme.fromSeed(
66
seedColor: primaryColor,
67
brightness: brightness,
68
primary: primaryColor,
69
secondary: secondaryColor,
70
surface: surfaceColor,
71
error: BioFlowColors.medicalRed,
72
),
73
scaffoldBackgroundColor: backgroundColor,
74
extensions: [extension],
75
76
// AppBar theme with glassmorphism effect
77
appBarTheme: AppBarTheme(
78
centerTitle: false,
79
elevation: 0,
80
backgroundColor: Colors.transparent,
81
foregroundColor: primaryColor,
82
titleTextStyle: TextStyle(
83
color: BioFlowColors.textPrimary,
84
fontSize: 20,
85
fontWeight: FontWeight.w600,
86
),
87
),
88
89
// Card theme with glassmorphism
90
cardTheme: CardThemeData(
91
elevation: 0,
92
color: surfaceColor.withValues(alpha: 0.8),
93
shape: RoundedRectangleBorder(
94
borderRadius: BorderRadius.circular(BioFlowRadius.lg),
95
),
96
),
97
98
// Elevated button theme
99
elevatedButtonTheme: ElevatedButtonThemeData(
100
style: ElevatedButton.styleFrom(
101
elevation: 0,
102
padding: const EdgeInsets.symmetric(
103
horizontal: BioFlowSpacing.lg,
104
vertical: BioFlowSpacing.md,
105
),
106
shape: RoundedRectangleBorder(
107
borderRadius: BorderRadius.circular(BioFlowRadius.md),
108
),
109
),
110
),
111
112
// Input decoration theme
113
inputDecorationTheme: InputDecorationTheme(
114
filled: true,
115
fillColor: surfaceColor.withValues(alpha: 0.5),
116
border: OutlineInputBorder(
117
borderRadius: BorderRadius.circular(BioFlowRadius.md),
118
borderSide: BorderSide.none,
119
),
120
enabledBorder: OutlineInputBorder(
121
borderRadius: BorderRadius.circular(BioFlowRadius.md),
122
borderSide: BorderSide(
123
color: primaryColor.withValues(alpha: 0.2),
124
width: 1,
125
),
126
),
127
focusedBorder: OutlineInputBorder(
128
borderRadius: BorderRadius.circular(BioFlowRadius.md),
129
borderSide: const BorderSide(
130
color: primaryColor,
131
width: 2,
132
),
133
),
134
),
135
136
// SnackBar theme with centered behavior
137
snackBarTheme: SnackBarThemeData(
138
behavior: SnackBarBehavior.floating,
139
backgroundColor: surfaceColor,
140
contentTextStyle: const TextStyle(
141
fontSize: 14,
142
fontWeight: FontWeight.w500,
143
),
144
),
145
);
146
}
147
148
/// Base light theme configuration for Minimal Light theme
149
static ThemeData _baseLightTheme({
150
required BioFlowThemeExtension extension,
151
}) {
152
const primaryColor = BioFlowColors.electricViolet;
153
const secondaryColor = BioFlowColors.glassPurple;
154
const backgroundColor = BioFlowColors.backgroundLightPrimary;
155
const surfaceColor = BioFlowColors.backgroundLightSecondary;
156
157
return ThemeData(
158
useMaterial3: true,
159
brightness: Brightness.light,
160
colorScheme: ColorScheme.fromSeed(
161
seedColor: primaryColor,
162
brightness: Brightness.light,
163
primary: primaryColor,
164
secondary: secondaryColor,
165
surface: surfaceColor,
166
error: BioFlowColors.medicalRed,
167
),
168
scaffoldBackgroundColor: backgroundColor,
169
extensions: [extension],
170
171
// AppBar theme
172
appBarTheme: const AppBarTheme(
173
centerTitle: false,
174
elevation: 0,
175
backgroundColor: Colors.transparent,
176
foregroundColor: primaryColor,
177
titleTextStyle: TextStyle(
178
color: BioFlowColors.textLightPrimary,
179
fontSize: 20,
180
fontWeight: FontWeight.w600,
181
),
182
),
183
184
// Card theme
185
cardTheme: CardThemeData(
186
elevation: 0,
187
color: surfaceColor,
188
shape: RoundedRectangleBorder(
189
borderRadius: BorderRadius.circular(BioFlowRadius.lg),
190
),
191
),
192
193
// Elevated button theme
194
elevatedButtonTheme: ElevatedButtonThemeData(
195
style: ElevatedButton.styleFrom(
196
elevation: 0,
197
padding: const EdgeInsets.symmetric(
198
horizontal: BioFlowSpacing.lg,
199
vertical: BioFlowSpacing.md,
200
),
201
shape: RoundedRectangleBorder(
202
borderRadius: BorderRadius.circular(BioFlowRadius.md),
203
),
204
),
205
),
206
207
// Input decoration theme
208
inputDecorationTheme: InputDecorationTheme(
209
filled: true,
210
fillColor: surfaceColor,
211
border: OutlineInputBorder(
212
borderRadius: BorderRadius.circular(BioFlowRadius.md),
213
borderSide: BorderSide.none,
214
),
215
enabledBorder: OutlineInputBorder(
216
borderRadius: BorderRadius.circular(BioFlowRadius.md),
217
borderSide: BorderSide(
218
color: BioFlowColors.borderLightSecondary,
219
width: 1,
220
),
221
),
222
focusedBorder: OutlineInputBorder(
223
borderRadius: BorderRadius.circular(BioFlowRadius.md),
224
borderSide: const BorderSide(
225
color: primaryColor,
226
width: 2,
227
),
228
),
229
),
230
231
// SnackBar theme with centered behavior
232
snackBarTheme: const SnackBarThemeData(
233
behavior: SnackBarBehavior.floating,
234
contentTextStyle: TextStyle(
235
fontSize: 14,
236
fontWeight: FontWeight.w500,
237
),
238
),
239
240
// Text theme with dark text colors for light background
241
textTheme: const TextTheme(
242
bodyLarge: TextStyle(color: BioFlowColors.textLightPrimary),
243
bodyMedium: TextStyle(color: BioFlowColors.textLightSecondary),
244
bodySmall: TextStyle(color: BioFlowColors.textLightTertiary),
245
titleLarge: TextStyle(color: BioFlowColors.textLightPrimary),
246
titleMedium: TextStyle(color: BioFlowColors.textLightPrimary),
247
titleSmall: TextStyle(color: BioFlowColors.textLightPrimary),
248
labelLarge: TextStyle(color: BioFlowColors.textLightPrimary),
249
labelMedium: TextStyle(color: BioFlowColors.textLightSecondary),
250
labelSmall: TextStyle(color: BioFlowColors.textLightTertiary),
251
),
252
253
// Icon theme
254
iconTheme: const IconThemeData(
255
color: BioFlowColors.textLightPrimary,
256
),
257
);
258
}
259
260
// ==================== Backward Compatibility ====================
261
262
/// Light theme - Defaults to Dark Glass theme
263
///
264
/// For backward compatibility. New code should use forPreset() instead.
265
@Deprecated('Use AppTheme.forPreset(ThemeType) instead')
266
static ThemeData get lightTheme => _darkGlassTheme;
267
268
/// Dark theme - Defaults to Minimal theme
269
///
270
/// For backward compatibility. New code should use forPreset() instead.
271
@Deprecated('Use AppTheme.forPreset(ThemeType) instead')
272
static ThemeData get darkTheme => _minimalTheme;
273
}