-
-
Save florentinobenedictus/c0771585e93f026dc1c87ec21369e29b to your computer and use it in GitHub Desktop.
lib/src/shared/providers/theme.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2022 The Flutter Authors. All rights reserved. | |
// Use of this source code is governed by a BSD-style license that can be | |
// found in the LICENSE file. | |
import 'dart:math'; | |
import 'package:flutter/material.dart'; | |
import 'package:material_color_utilities/material_color_utilities.dart'; | |
class NoAnimationPageTransitionsBuilder extends PageTransitionsBuilder { | |
const NoAnimationPageTransitionsBuilder(); | |
@override | |
Widget buildTransitions<T>( | |
PageRoute<T> route, | |
BuildContext context, | |
Animation<double> animation, | |
Animation<double> secondaryAnimation, | |
Widget child, | |
) { | |
return child; | |
} | |
} | |
class ThemeSettingChange extends Notification { | |
ThemeSettingChange({required this.settings}); | |
final ThemeSettings settings; | |
} | |
class ThemeProvider extends InheritedWidget { | |
const ThemeProvider( | |
{super.key, | |
required this.settings, | |
required this.lightDynamic, | |
required this.darkDynamic, | |
required super.child}); | |
final ValueNotifier<ThemeSettings> settings; | |
final ColorScheme? lightDynamic; | |
final ColorScheme? darkDynamic; | |
final pageTransitionsTheme = const PageTransitionsTheme( | |
builders: <TargetPlatform, PageTransitionsBuilder>{ | |
TargetPlatform.android: FadeUpwardsPageTransitionsBuilder(), | |
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(), | |
TargetPlatform.linux: NoAnimationPageTransitionsBuilder(), | |
TargetPlatform.macOS: NoAnimationPageTransitionsBuilder(), | |
TargetPlatform.windows: NoAnimationPageTransitionsBuilder(), | |
}, | |
); | |
Color custom(CustomColor custom) { | |
if (custom.blend) { | |
return blend(custom.color); | |
} else { | |
return custom.color; | |
} | |
} | |
Color blend(Color targetColor) { | |
return Color( | |
Blend.harmonize(targetColor.value, settings.value.sourceColor.value)); | |
} | |
Color source(Color? target) { | |
Color source = settings.value.sourceColor; | |
if (target != null) { | |
source = blend(target); | |
} | |
return source; | |
} | |
ColorScheme colors(Brightness brightness, Color? targetColor) { | |
final dynamicPrimary = brightness == Brightness.light | |
? lightDynamic?.primary | |
: darkDynamic?.primary; | |
return ColorScheme.fromSeed( | |
seedColor: dynamicPrimary ?? source(targetColor), | |
brightness: brightness, | |
); | |
} | |
ShapeBorder get shapeMedium => RoundedRectangleBorder( | |
borderRadius: BorderRadius.circular(8), | |
); | |
CardTheme cardTheme() { | |
return CardTheme( | |
elevation: 0, | |
shape: shapeMedium, | |
clipBehavior: Clip.antiAlias, | |
); | |
} | |
ListTileThemeData listTileTheme(ColorScheme colors) { | |
return ListTileThemeData( | |
shape: shapeMedium, | |
selectedColor: colors.secondary, | |
); | |
} | |
AppBarTheme appBarTheme(ColorScheme colors) { | |
return AppBarTheme( | |
elevation: 0, | |
backgroundColor: colors.surface, | |
foregroundColor: colors.onSurface, | |
); | |
} | |
TabBarTheme tabBarTheme(ColorScheme colors) { | |
return TabBarTheme( | |
labelColor: colors.secondary, | |
unselectedLabelColor: colors.onSurfaceVariant, | |
indicator: BoxDecoration( | |
border: Border( | |
bottom: BorderSide( | |
color: colors.secondary, | |
width: 2, | |
), | |
), | |
), | |
); | |
} | |
BottomAppBarTheme bottomAppBarTheme(ColorScheme colors) { | |
return BottomAppBarTheme( | |
color: colors.surface, | |
elevation: 0, | |
); | |
} | |
BottomNavigationBarThemeData bottomNavigationBarTheme(ColorScheme colors) { | |
return BottomNavigationBarThemeData( | |
type: BottomNavigationBarType.fixed, | |
backgroundColor: colors.surfaceContainerHighest, | |
selectedItemColor: colors.onSurface, | |
unselectedItemColor: colors.onSurfaceVariant, | |
elevation: 0, | |
landscapeLayout: BottomNavigationBarLandscapeLayout.centered, | |
); | |
} | |
NavigationRailThemeData navigationRailTheme(ColorScheme colors) { | |
return const NavigationRailThemeData(); | |
} | |
DrawerThemeData drawerTheme(ColorScheme colors) { | |
return DrawerThemeData( | |
backgroundColor: colors.surface, | |
); | |
} | |
ThemeData light([Color? targetColor]) { | |
final colorScheme = colors(Brightness.light, targetColor); | |
return ThemeData.light(useMaterial3: true).copyWith( | |
// Add page transitions | |
pageTransitionsTheme: pageTransitionsTheme, // Add this line | |
colorScheme: colorScheme, | |
appBarTheme: appBarTheme(colorScheme), | |
cardTheme: cardTheme(), | |
listTileTheme: listTileTheme(colorScheme), | |
bottomAppBarTheme: bottomAppBarTheme(colorScheme), | |
bottomNavigationBarTheme: bottomNavigationBarTheme(colorScheme), | |
navigationRailTheme: navigationRailTheme(colorScheme), | |
tabBarTheme: tabBarTheme(colorScheme), | |
drawerTheme: drawerTheme(colorScheme), | |
scaffoldBackgroundColor: colorScheme.surface, | |
); | |
} | |
ThemeData dark([Color? targetColor]) { | |
final colorScheme = colors(Brightness.dark, targetColor); | |
return ThemeData.dark(useMaterial3: true).copyWith( | |
// Add page transitions | |
pageTransitionsTheme: pageTransitionsTheme, // Add this line | |
colorScheme: colorScheme, | |
appBarTheme: appBarTheme(colorScheme), | |
cardTheme: cardTheme(), | |
listTileTheme: listTileTheme(colorScheme), | |
bottomAppBarTheme: bottomAppBarTheme(colorScheme), | |
bottomNavigationBarTheme: bottomNavigationBarTheme(colorScheme), | |
navigationRailTheme: navigationRailTheme(colorScheme), | |
tabBarTheme: tabBarTheme(colorScheme), | |
drawerTheme: drawerTheme(colorScheme), | |
scaffoldBackgroundColor: colorScheme.surface, | |
); | |
} | |
ThemeMode themeMode() { | |
return settings.value.themeMode; | |
} | |
ThemeData theme(BuildContext context, [Color? targetColor]) { | |
final brightness = MediaQuery.of(context).platformBrightness; | |
return brightness == Brightness.light | |
? light(targetColor) | |
: dark(targetColor); | |
} | |
static ThemeProvider of(BuildContext context) { | |
return context.dependOnInheritedWidgetOfExactType<ThemeProvider>()!; | |
} | |
@override | |
bool updateShouldNotify(covariant ThemeProvider oldWidget) { | |
return oldWidget.settings != settings; | |
} | |
} | |
class ThemeSettings { | |
ThemeSettings({ | |
required this.sourceColor, | |
required this.themeMode, | |
}); | |
final Color sourceColor; | |
final ThemeMode themeMode; | |
} | |
Color randomColor() { | |
return Color(Random().nextInt(0xFFFFFFFF)); | |
} | |
// Custom Colors | |
const linkColor = CustomColor( | |
name: 'Link Color', | |
color: Color(0xFF00B0FF), | |
); | |
class CustomColor { | |
const CustomColor({ | |
required this.name, | |
required this.color, | |
this.blend = true, | |
}); | |
final String name; | |
final Color color; | |
final bool blend; | |
Color value(ThemeProvider provider) { | |
return provider.custom(this); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment