import 'package:flex_color_scheme/flex_color_scheme.dart'; import 'package:flutter/material.dart'; @immutable class MapflowThemeTokens extends ThemeExtension { const MapflowThemeTokens({ required this.mapPanel, required this.mapPanelBorder, required this.mapShadow, required this.danger, required this.onDark, required this.panelRadius, }); final Color mapPanel; final Color mapPanelBorder; final Color mapShadow; final Color danger; final Color onDark; final double panelRadius; @override MapflowThemeTokens copyWith({ Color? mapPanel, Color? mapPanelBorder, Color? mapShadow, Color? danger, Color? onDark, double? panelRadius, }) { return MapflowThemeTokens( mapPanel: mapPanel ?? this.mapPanel, mapPanelBorder: mapPanelBorder ?? this.mapPanelBorder, mapShadow: mapShadow ?? this.mapShadow, danger: danger ?? this.danger, onDark: onDark ?? this.onDark, panelRadius: panelRadius ?? this.panelRadius, ); } @override MapflowThemeTokens lerp( covariant ThemeExtension? other, double t, ) { if (other is! MapflowThemeTokens) { return this; } return MapflowThemeTokens( mapPanel: Color.lerp(mapPanel, other.mapPanel, t)!, mapPanelBorder: Color.lerp(mapPanelBorder, other.mapPanelBorder, t)!, mapShadow: Color.lerp(mapShadow, other.mapShadow, t)!, danger: Color.lerp(danger, other.danger, t)!, onDark: Color.lerp(onDark, other.onDark, t)!, panelRadius: lerpDouble(panelRadius, other.panelRadius, t), ); } } class MapflowTheme { const MapflowTheme._(); static const tokens = MapflowThemeTokens( mapPanel: Color(0xFFFFFBF5), mapPanelBorder: Color(0xFFE0D8CA), mapShadow: Color(0x33000000), danger: Color(0xFFE11D48), onDark: Colors.white, panelRadius: 8, ); static ThemeData light() { return FlexThemeData.light( useMaterial3: true, colors: const FlexSchemeColor( primary: Color(0xFF0F766E), primaryContainer: Color(0xFFBFE7DF), secondary: Color(0xFFE11D48), secondaryContainer: Color(0xFFFFD9E1), tertiary: Color(0xFF7C3AED), tertiaryContainer: Color(0xFFE9DDFF), appBarColor: Color(0xFFF7F3EA), error: Color(0xFFB3261E), ), scaffoldBackground: const Color(0xFFF7F3EA), surface: tokens.mapPanel, subThemesData: const FlexSubThemesData( defaultRadius: 8, inputDecoratorRadius: 8, cardRadius: 8, chipRadius: 8, filledButtonRadius: 8, ), fontFamily: 'SF Pro Display', extensions: const [tokens], ).copyWith( appBarTheme: const AppBarTheme( backgroundColor: Color(0xFFF7F3EA), foregroundColor: Color(0xFF17211D), surfaceTintColor: Colors.transparent, ), cardTheme: CardThemeData( elevation: 0, color: tokens.mapPanel, surfaceTintColor: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(tokens.panelRadius), side: BorderSide(color: tokens.mapPanelBorder), ), ), chipTheme: ChipThemeData( shape: StadiumBorder(side: BorderSide(color: tokens.mapPanelBorder)), ), ); } } double lerpDouble(double a, double b, double t) => a + (b - a) * t; extension MapflowThemeContext on BuildContext { MapflowThemeTokens get mapflowTokens { return Theme.of(this).extension()!; } }