209 lines
7.0 KiB
Dart
209 lines
7.0 KiB
Dart
import 'package:flex_color_scheme/flex_color_scheme.dart';
|
|
import 'package:flutter/material.dart';
|
|
|
|
@immutable
|
|
class MapflowThemeTokens extends ThemeExtension<MapflowThemeTokens> {
|
|
const MapflowThemeTokens({
|
|
required this.mapPanel,
|
|
required this.mapPanelBorder,
|
|
required this.mapShadow,
|
|
required this.danger,
|
|
required this.onDark,
|
|
required this.darkSurface,
|
|
required this.darkSurfaceAlt,
|
|
required this.voiceAccent,
|
|
required this.voiceAccentSoft,
|
|
required this.onVoiceControl,
|
|
required this.snowflakeLine,
|
|
required this.snowflakeNode,
|
|
required this.snowflakeCenter,
|
|
required this.snowflakeLabel,
|
|
required this.imageScrim,
|
|
required this.panelRadius,
|
|
});
|
|
|
|
final Color mapPanel;
|
|
final Color mapPanelBorder;
|
|
final Color mapShadow;
|
|
final Color danger;
|
|
final Color onDark;
|
|
final Color darkSurface;
|
|
final Color darkSurfaceAlt;
|
|
final Color voiceAccent;
|
|
final Color voiceAccentSoft;
|
|
final Color onVoiceControl;
|
|
final Color snowflakeLine;
|
|
final Color snowflakeNode;
|
|
final Color snowflakeCenter;
|
|
final Color snowflakeLabel;
|
|
final Color imageScrim;
|
|
final double panelRadius;
|
|
|
|
@override
|
|
MapflowThemeTokens copyWith({
|
|
Color? mapPanel,
|
|
Color? mapPanelBorder,
|
|
Color? mapShadow,
|
|
Color? danger,
|
|
Color? onDark,
|
|
Color? darkSurface,
|
|
Color? darkSurfaceAlt,
|
|
Color? voiceAccent,
|
|
Color? voiceAccentSoft,
|
|
Color? onVoiceControl,
|
|
Color? snowflakeLine,
|
|
Color? snowflakeNode,
|
|
Color? snowflakeCenter,
|
|
Color? snowflakeLabel,
|
|
Color? imageScrim,
|
|
double? panelRadius,
|
|
}) {
|
|
return MapflowThemeTokens(
|
|
mapPanel: mapPanel ?? this.mapPanel,
|
|
mapPanelBorder: mapPanelBorder ?? this.mapPanelBorder,
|
|
mapShadow: mapShadow ?? this.mapShadow,
|
|
danger: danger ?? this.danger,
|
|
onDark: onDark ?? this.onDark,
|
|
darkSurface: darkSurface ?? this.darkSurface,
|
|
darkSurfaceAlt: darkSurfaceAlt ?? this.darkSurfaceAlt,
|
|
voiceAccent: voiceAccent ?? this.voiceAccent,
|
|
voiceAccentSoft: voiceAccentSoft ?? this.voiceAccentSoft,
|
|
onVoiceControl: onVoiceControl ?? this.onVoiceControl,
|
|
snowflakeLine: snowflakeLine ?? this.snowflakeLine,
|
|
snowflakeNode: snowflakeNode ?? this.snowflakeNode,
|
|
snowflakeCenter: snowflakeCenter ?? this.snowflakeCenter,
|
|
snowflakeLabel: snowflakeLabel ?? this.snowflakeLabel,
|
|
imageScrim: imageScrim ?? this.imageScrim,
|
|
panelRadius: panelRadius ?? this.panelRadius,
|
|
);
|
|
}
|
|
|
|
@override
|
|
MapflowThemeTokens lerp(
|
|
covariant ThemeExtension<MapflowThemeTokens>? 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)!,
|
|
darkSurface: Color.lerp(darkSurface, other.darkSurface, t)!,
|
|
darkSurfaceAlt: Color.lerp(darkSurfaceAlt, other.darkSurfaceAlt, t)!,
|
|
voiceAccent: Color.lerp(voiceAccent, other.voiceAccent, t)!,
|
|
voiceAccentSoft: Color.lerp(voiceAccentSoft, other.voiceAccentSoft, t)!,
|
|
onVoiceControl: Color.lerp(onVoiceControl, other.onVoiceControl, t)!,
|
|
snowflakeLine: Color.lerp(snowflakeLine, other.snowflakeLine, t)!,
|
|
snowflakeNode: Color.lerp(snowflakeNode, other.snowflakeNode, t)!,
|
|
snowflakeCenter: Color.lerp(snowflakeCenter, other.snowflakeCenter, t)!,
|
|
snowflakeLabel: Color.lerp(snowflakeLabel, other.snowflakeLabel, t)!,
|
|
imageScrim: Color.lerp(imageScrim, other.imageScrim, t)!,
|
|
panelRadius: lerpDouble(panelRadius, other.panelRadius, t),
|
|
);
|
|
}
|
|
}
|
|
|
|
class MapflowTheme {
|
|
const MapflowTheme._();
|
|
|
|
static const tokens = MapflowThemeTokens(
|
|
mapPanel: Color(0xFF15111D),
|
|
mapPanelBorder: Color(0xFF2F263D),
|
|
mapShadow: Color(0x99000000),
|
|
danger: Color(0xFFFF2D75),
|
|
onDark: Colors.white,
|
|
darkSurface: Color(0xFF05030B),
|
|
darkSurfaceAlt: Color(0xFF15111D),
|
|
voiceAccent: Color(0xFFFF2D75),
|
|
voiceAccentSoft: Color(0xFFFF8BB5),
|
|
onVoiceControl: Color(0xFF090613),
|
|
snowflakeLine: Color(0xFF3B304B),
|
|
snowflakeNode: Color(0xFF67567E),
|
|
snowflakeCenter: Color(0xFFFF2D75),
|
|
snowflakeLabel: Color(0xFFCFC1DE),
|
|
imageScrim: Color(0xCC000000),
|
|
panelRadius: 8,
|
|
);
|
|
|
|
static ThemeData dark() {
|
|
return FlexThemeData.dark(
|
|
useMaterial3: true,
|
|
colors: const FlexSchemeColor(
|
|
primary: Color(0xFFFF2D75),
|
|
primaryContainer: Color(0xFF5B1432),
|
|
secondary: Color(0xFFB86BFF),
|
|
secondaryContainer: Color(0xFF3E205A),
|
|
tertiary: Color(0xFFFFB86B),
|
|
tertiaryContainer: Color(0xFF4F2D13),
|
|
appBarColor: Color(0xFF05030B),
|
|
error: Color(0xFFFFB4AB),
|
|
),
|
|
scaffoldBackground: tokens.darkSurface,
|
|
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(0xFF05030B),
|
|
foregroundColor: Colors.white,
|
|
surfaceTintColor: Colors.transparent,
|
|
),
|
|
bottomSheetTheme: const BottomSheetThemeData(
|
|
backgroundColor: Color(0xFF15111D),
|
|
modalBackgroundColor: Color(0xFF15111D),
|
|
surfaceTintColor: Colors.transparent,
|
|
dragHandleColor: Color(0xFF8F7AA7),
|
|
),
|
|
cardTheme: CardThemeData(
|
|
elevation: 0,
|
|
color: tokens.mapPanel,
|
|
surfaceTintColor: Colors.transparent,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(tokens.panelRadius),
|
|
side: BorderSide(color: tokens.mapPanelBorder),
|
|
),
|
|
),
|
|
dialogTheme: const DialogThemeData(
|
|
backgroundColor: Color(0xFF15111D),
|
|
surfaceTintColor: Colors.transparent,
|
|
),
|
|
popupMenuTheme: PopupMenuThemeData(
|
|
color: tokens.mapPanel,
|
|
surfaceTintColor: Colors.transparent,
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(tokens.panelRadius),
|
|
side: BorderSide(color: tokens.mapPanelBorder),
|
|
),
|
|
),
|
|
chipTheme: ChipThemeData(
|
|
backgroundColor: tokens.mapPanel,
|
|
selectedColor: const Color(0xFF5B1432),
|
|
disabledColor: const Color(0xFF211A2B),
|
|
secondarySelectedColor: const Color(0xFF5B1432),
|
|
labelStyle: const TextStyle(color: Color(0xFFF6ECFF)),
|
|
secondaryLabelStyle: const TextStyle(color: Colors.white),
|
|
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<MapflowThemeTokens>()!;
|
|
}
|
|
}
|