2025-03-21 11:33:58 -04:00

190 lines
7.4 KiB
Dart

import 'package:flutter/material.dart';
import 'scale_input_decorator_theme.dart';
import 'scale_scheme.dart';
export 'scale_app_bar_theme.dart';
export 'scale_color.dart';
export 'scale_input_decorator_theme.dart';
export 'scale_scheme.dart';
export 'scale_tile_theme.dart';
export 'scale_toast_theme.dart';
class ScaleTheme extends ThemeExtension<ScaleTheme> {
ScaleTheme({
required this.textTheme,
required this.scheme,
required this.config,
});
final TextTheme textTheme;
final ScaleScheme scheme;
final ScaleConfig config;
@override
ScaleTheme copyWith({
TextTheme? textTheme,
ScaleScheme? scheme,
ScaleConfig? config,
}) =>
ScaleTheme(
textTheme: textTheme ?? this.textTheme,
scheme: scheme ?? this.scheme,
config: config ?? this.config,
);
@override
ScaleTheme lerp(ScaleTheme? other, double t) {
if (other is! ScaleTheme) {
return this;
}
return ScaleTheme(
textTheme: TextTheme.lerp(textTheme, other.textTheme, t),
scheme: scheme.lerp(other.scheme, t),
config: config.lerp(other.config, t));
}
WidgetStateProperty<BorderSide?> elementBorderWidgetStateProperty() =>
WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.disabled)) {
return BorderSide(
color: scheme.grayScale.border.withAlpha(0x7F),
strokeAlign: BorderSide.strokeAlignOutside);
} else if (states.contains(WidgetState.pressed)) {
return BorderSide(
color: scheme.primaryScale.border,
);
} else if (states.contains(WidgetState.hovered)) {
return BorderSide(
color: scheme.primaryScale.hoverBorder,
strokeAlign: BorderSide.strokeAlignOutside);
} else if (states.contains(WidgetState.focused)) {
return BorderSide(
color: scheme.primaryScale.hoverBorder,
width: 2,
strokeAlign: BorderSide.strokeAlignOutside);
}
return BorderSide(
color: scheme.primaryScale.border,
strokeAlign: BorderSide.strokeAlignOutside);
});
WidgetStateProperty<Color?> elementColorWidgetStateProperty() =>
WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.disabled)) {
return scheme.grayScale.primary.withAlpha(0x7F);
} else if (states.contains(WidgetState.pressed)) {
return scheme.primaryScale.borderText;
} else if (states.contains(WidgetState.hovered)) {
return scheme.primaryScale.borderText;
} else if (states.contains(WidgetState.focused)) {
return scheme.primaryScale.borderText;
}
return Color.lerp(
scheme.primaryScale.borderText, scheme.primaryScale.primary, 0.25);
});
WidgetStateProperty<Color?> checkboxFillColorWidgetStateProperty() =>
WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.selected)) {
if (states.contains(WidgetState.disabled)) {
return scheme.grayScale.primary.withAlpha(0x7F);
} else if (states.contains(WidgetState.pressed)) {
return scheme.primaryScale.hoverBorder;
} else if (states.contains(WidgetState.hovered)) {
return scheme.primaryScale.hoverBorder;
} else if (states.contains(WidgetState.focused)) {
return scheme.primaryScale.border;
}
return scheme.primaryScale.border;
} else {
return Colors.transparent;
}
});
// WidgetStateProperty<Color?> elementBackgroundWidgetStateProperty() {
// return null;
// }
ThemeData toThemeData(Brightness brightness) {
final colorScheme = scheme.toColorScheme(brightness);
final baseThemeData = ThemeData.from(
colorScheme: colorScheme, textTheme: textTheme, useMaterial3: true);
final elevatedButtonTheme = ElevatedButtonThemeData(
style: ElevatedButton.styleFrom(
elevation: 0,
textStyle: textTheme.labelSmall,
backgroundColor: scheme.primaryScale.elementBackground,
disabledBackgroundColor:
scheme.grayScale.elementBackground.withAlpha(0x7F),
disabledForegroundColor:
scheme.grayScale.primary.withAlpha(0x7F),
shape: RoundedRectangleBorder(
side: BorderSide(color: scheme.primaryScale.border),
borderRadius:
BorderRadius.circular(8 * config.borderRadiusScale)))
.copyWith(
foregroundColor: elementColorWidgetStateProperty(),
side: elementBorderWidgetStateProperty(),
iconColor: elementColorWidgetStateProperty(),
));
final themeData = baseThemeData.copyWith(
scrollbarTheme: baseThemeData.scrollbarTheme.copyWith(
thumbColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.pressed)) {
return scheme.primaryScale.border;
} else if (states.contains(WidgetState.hovered)) {
return scheme.primaryScale.hoverBorder;
}
return scheme.primaryScale.subtleBorder;
}), trackColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.pressed)) {
return scheme.primaryScale.activeElementBackground;
} else if (states.contains(WidgetState.hovered)) {
return scheme.primaryScale.hoverElementBackground;
}
return scheme.primaryScale.elementBackground;
}), trackBorderColor: WidgetStateProperty.resolveWith((states) {
if (states.contains(WidgetState.pressed)) {
return scheme.primaryScale.subtleBorder;
} else if (states.contains(WidgetState.hovered)) {
return scheme.primaryScale.subtleBorder;
}
return scheme.primaryScale.subtleBorder;
})),
appBarTheme: baseThemeData.appBarTheme.copyWith(
backgroundColor: scheme.primaryScale.border,
foregroundColor: scheme.primaryScale.borderText,
toolbarHeight: 48,
),
bottomSheetTheme: baseThemeData.bottomSheetTheme.copyWith(
elevation: 0,
modalElevation: 0,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topLeft: Radius.circular(16 * config.borderRadiusScale),
topRight: Radius.circular(16 * config.borderRadiusScale)))),
canvasColor: scheme.primaryScale.subtleBackground,
checkboxTheme: baseThemeData.checkboxTheme.copyWith(
side: BorderSide(color: scheme.primaryScale.border, width: 2),
checkColor: elementColorWidgetStateProperty(),
fillColor: checkboxFillColorWidgetStateProperty(),
),
chipTheme: baseThemeData.chipTheme.copyWith(
backgroundColor: scheme.primaryScale.elementBackground,
selectedColor: scheme.primaryScale.activeElementBackground,
surfaceTintColor: scheme.primaryScale.hoverElementBackground,
checkmarkColor: scheme.primaryScale.primary,
side: BorderSide(color: scheme.primaryScale.border)),
elevatedButtonTheme: elevatedButtonTheme,
inputDecorationTheme:
ScaleInputDecoratorTheme(scheme, config, textTheme),
extensions: <ThemeExtension<dynamic>>[scheme, config, this]);
return themeData;
}
}