Major UI overhaul
This commit is contained in:
+65
-13
@@ -1,25 +1,39 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
|
||||
import 'app_typography.dart';
|
||||
|
||||
class AppTheme {
|
||||
static ThemeData light() {
|
||||
final base = ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF0C4A6E),
|
||||
seedColor: const Color(0xFF334155),
|
||||
brightness: Brightness.light,
|
||||
),
|
||||
useMaterial3: true,
|
||||
);
|
||||
|
||||
final textTheme = GoogleFonts.spaceGroteskTextTheme(base.textTheme);
|
||||
final monoTheme = GoogleFonts.robotoMonoTextTheme(base.textTheme);
|
||||
final mono = AppMonoText(
|
||||
label:
|
||||
monoTheme.labelMedium?.copyWith(letterSpacing: 0.3) ??
|
||||
const TextStyle(letterSpacing: 0.3),
|
||||
body:
|
||||
monoTheme.bodyMedium?.copyWith(letterSpacing: 0.2) ??
|
||||
const TextStyle(letterSpacing: 0.2),
|
||||
);
|
||||
|
||||
return base.copyWith(
|
||||
textTheme: textTheme,
|
||||
scaffoldBackgroundColor: const Color(0xFFF6F8FA),
|
||||
scaffoldBackgroundColor: base.colorScheme.surfaceContainerLowest,
|
||||
extensions: [mono],
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
foregroundColor: base.colorScheme.onSurface,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 1,
|
||||
surfaceTintColor: base.colorScheme.surfaceTint,
|
||||
centerTitle: false,
|
||||
titleTextStyle: textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
@@ -28,20 +42,26 @@ class AppTheme {
|
||||
),
|
||||
cardTheme: CardThemeData(
|
||||
color: base.colorScheme.surface,
|
||||
elevation: 0.6,
|
||||
elevation: 0,
|
||||
margin: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
side: BorderSide(color: base.colorScheme.outlineVariant),
|
||||
),
|
||||
),
|
||||
chipTheme: ChipThemeData(
|
||||
backgroundColor: base.colorScheme.surfaceContainerHighest,
|
||||
side: BorderSide(color: base.colorScheme.outlineVariant),
|
||||
labelStyle: textTheme.labelSmall,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
dividerTheme: DividerThemeData(
|
||||
color: base.colorScheme.outlineVariant,
|
||||
thickness: 1,
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: base.colorScheme.surface,
|
||||
fillColor: base.colorScheme.surfaceContainerLow,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(color: base.colorScheme.outlineVariant),
|
||||
@@ -72,6 +92,11 @@ class AppTheme {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 12),
|
||||
),
|
||||
),
|
||||
navigationDrawerTheme: NavigationDrawerThemeData(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
indicatorColor: base.colorScheme.secondaryContainer,
|
||||
tileHeight: 52,
|
||||
),
|
||||
navigationRailTheme: NavigationRailThemeData(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
selectedIconTheme: IconThemeData(color: base.colorScheme.primary),
|
||||
@@ -79,6 +104,7 @@ class AppTheme {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
unselectedIconTheme: IconThemeData(color: base.colorScheme.onSurface),
|
||||
indicatorColor: base.colorScheme.secondaryContainer,
|
||||
),
|
||||
navigationBarTheme: NavigationBarThemeData(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
@@ -88,8 +114,9 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
listTileTheme: ListTileThemeData(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
tileColor: base.colorScheme.surface,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -97,21 +124,33 @@ class AppTheme {
|
||||
static ThemeData dark() {
|
||||
final base = ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(
|
||||
seedColor: const Color(0xFF38BDF8),
|
||||
seedColor: const Color(0xFF334155),
|
||||
brightness: Brightness.dark,
|
||||
),
|
||||
useMaterial3: true,
|
||||
);
|
||||
|
||||
final textTheme = GoogleFonts.spaceGroteskTextTheme(base.textTheme);
|
||||
final monoTheme = GoogleFonts.robotoMonoTextTheme(base.textTheme);
|
||||
final mono = AppMonoText(
|
||||
label:
|
||||
monoTheme.labelMedium?.copyWith(letterSpacing: 0.3) ??
|
||||
const TextStyle(letterSpacing: 0.3),
|
||||
body:
|
||||
monoTheme.bodyMedium?.copyWith(letterSpacing: 0.2) ??
|
||||
const TextStyle(letterSpacing: 0.2),
|
||||
);
|
||||
|
||||
return base.copyWith(
|
||||
textTheme: textTheme,
|
||||
scaffoldBackgroundColor: const Color(0xFF0B111A),
|
||||
scaffoldBackgroundColor: base.colorScheme.surface,
|
||||
extensions: [mono],
|
||||
appBarTheme: AppBarTheme(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
foregroundColor: base.colorScheme.onSurface,
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 1,
|
||||
surfaceTintColor: base.colorScheme.surfaceTint,
|
||||
centerTitle: false,
|
||||
titleTextStyle: textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.w700,
|
||||
@@ -119,21 +158,27 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
cardTheme: CardThemeData(
|
||||
color: const Color(0xFF121A24),
|
||||
color: base.colorScheme.surfaceContainer,
|
||||
elevation: 0,
|
||||
margin: EdgeInsets.zero,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(20),
|
||||
side: BorderSide(color: base.colorScheme.outlineVariant),
|
||||
),
|
||||
),
|
||||
chipTheme: ChipThemeData(
|
||||
backgroundColor: base.colorScheme.surfaceContainerHighest,
|
||||
side: BorderSide(color: base.colorScheme.outlineVariant),
|
||||
labelStyle: textTheme.labelSmall,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
dividerTheme: DividerThemeData(
|
||||
color: base.colorScheme.outlineVariant,
|
||||
thickness: 1,
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: const Color(0xFF121A24),
|
||||
fillColor: base.colorScheme.surfaceContainerLow,
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
borderSide: BorderSide(color: base.colorScheme.outlineVariant),
|
||||
@@ -164,6 +209,11 @@ class AppTheme {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 18, vertical: 12),
|
||||
),
|
||||
),
|
||||
navigationDrawerTheme: NavigationDrawerThemeData(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
indicatorColor: base.colorScheme.secondaryContainer,
|
||||
tileHeight: 52,
|
||||
),
|
||||
navigationRailTheme: NavigationRailThemeData(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
selectedIconTheme: IconThemeData(color: base.colorScheme.primary),
|
||||
@@ -171,6 +221,7 @@ class AppTheme {
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
unselectedIconTheme: IconThemeData(color: base.colorScheme.onSurface),
|
||||
indicatorColor: base.colorScheme.secondaryContainer,
|
||||
),
|
||||
navigationBarTheme: NavigationBarThemeData(
|
||||
backgroundColor: base.colorScheme.surface,
|
||||
@@ -180,8 +231,9 @@ class AppTheme {
|
||||
),
|
||||
),
|
||||
listTileTheme: ListTileThemeData(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
||||
tileColor: const Color(0xFF121A24),
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
tileColor: base.colorScheme.surfaceContainer,
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
@immutable
|
||||
class AppMonoText extends ThemeExtension<AppMonoText> {
|
||||
const AppMonoText({required this.label, required this.body});
|
||||
|
||||
final TextStyle label;
|
||||
final TextStyle body;
|
||||
|
||||
@override
|
||||
AppMonoText copyWith({TextStyle? label, TextStyle? body}) {
|
||||
return AppMonoText(label: label ?? this.label, body: body ?? this.body);
|
||||
}
|
||||
|
||||
@override
|
||||
AppMonoText lerp(ThemeExtension<AppMonoText>? other, double t) {
|
||||
if (other is! AppMonoText) return this;
|
||||
return AppMonoText(
|
||||
label: TextStyle.lerp(label, other.label, t) ?? label,
|
||||
body: TextStyle.lerp(body, other.body, t) ?? body,
|
||||
);
|
||||
}
|
||||
|
||||
static AppMonoText of(BuildContext context) {
|
||||
final ext = Theme.of(context).extension<AppMonoText>();
|
||||
return ext ?? const AppMonoText(label: TextStyle(), body: TextStyle());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user