mirror of
https://github.com/zarzet/SpotiFLAC-Mobile.git
synced 2026-09-28 04:12:07 +02:00
feat(theme): add shared design tokens
This commit is contained in:
+38
-17
@@ -2,10 +2,15 @@ import 'package:flutter/cupertino.dart' show CupertinoPageTransitionsBuilder;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:spotiflac_android/models/theme_settings.dart';
|
||||
import 'package:spotiflac_android/theme/app_tokens.dart';
|
||||
|
||||
class AppTheme {
|
||||
static const Color defaultSeedColor = Color(kDefaultSeedColor);
|
||||
|
||||
/// Component radii resolve from the same tokens the widgets read, so the
|
||||
/// scale cannot drift between `ThemeData` and hand-built containers.
|
||||
static const AppTokens _tokens = AppTokens.standard;
|
||||
|
||||
// Override Flutter's default page transitions. Recent Flutter defaults the
|
||||
// Android route transition to PredictiveBackPageTransitionsBuilder, whose
|
||||
// gesture detector mis-routes the predictive-back gesture to a nested
|
||||
@@ -52,6 +57,7 @@ class AppTheme {
|
||||
switchTheme: _switchTheme(scheme),
|
||||
chipTheme: _chipTheme(scheme),
|
||||
dividerTheme: _dividerTheme(scheme),
|
||||
extensions: const <ThemeExtension<dynamic>>[AppTokens.standard],
|
||||
fontFamily: 'Google Sans Flex',
|
||||
);
|
||||
}
|
||||
@@ -90,6 +96,7 @@ class AppTheme {
|
||||
switchTheme: _switchTheme(scheme),
|
||||
chipTheme: _chipTheme(scheme),
|
||||
dividerTheme: _dividerTheme(scheme),
|
||||
extensions: const <ThemeExtension<dynamic>>[AppTokens.standard],
|
||||
fontFamily: 'Google Sans Flex',
|
||||
);
|
||||
}
|
||||
@@ -125,7 +132,9 @@ class AppTheme {
|
||||
|
||||
static CardThemeData _cardTheme(ColorScheme scheme) => CardThemeData(
|
||||
elevation: 0,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
),
|
||||
color: scheme.surfaceContainerLow,
|
||||
surfaceTintColor: scheme.surfaceTint,
|
||||
);
|
||||
@@ -135,7 +144,7 @@ class AppTheme {
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: 1,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
),
|
||||
@@ -145,7 +154,7 @@ class AppTheme {
|
||||
FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
),
|
||||
@@ -155,7 +164,7 @@ class AppTheme {
|
||||
OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
|
||||
),
|
||||
@@ -165,7 +174,7 @@ class AppTheme {
|
||||
TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
|
||||
),
|
||||
@@ -174,7 +183,9 @@ class AppTheme {
|
||||
static FloatingActionButtonThemeData _fabTheme(ColorScheme scheme) =>
|
||||
FloatingActionButtonThemeData(
|
||||
elevation: 3,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
),
|
||||
backgroundColor: scheme.primaryContainer,
|
||||
foregroundColor: scheme.onPrimaryContainer,
|
||||
);
|
||||
@@ -184,19 +195,19 @@ class AppTheme {
|
||||
filled: true,
|
||||
fillColor: scheme.surfaceContainerHighest.withValues(alpha: 0.3),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
borderSide: BorderSide.none,
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
borderSide: BorderSide(color: scheme.primary, width: 2),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
borderSide: BorderSide(color: scheme.error, width: 1),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
@@ -207,20 +218,26 @@ class AppTheme {
|
||||
|
||||
static ListTileThemeData _listTileTheme(ColorScheme scheme) =>
|
||||
ListTileThemeData(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusControl),
|
||||
),
|
||||
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
|
||||
);
|
||||
|
||||
// Caps modal sheet width on tablets/landscape (no effect on phones, whose
|
||||
// screens are narrower); Flutter centers the sheet when narrower than the
|
||||
// screen.
|
||||
static const BottomSheetThemeData _bottomSheetTheme = BottomSheetThemeData(
|
||||
constraints: BoxConstraints(maxWidth: 640),
|
||||
// screen. The shape is set here so no call site has to repeat it — every
|
||||
// sheet inherits the token radius.
|
||||
static final BottomSheetThemeData _bottomSheetTheme = BottomSheetThemeData(
|
||||
constraints: const BoxConstraints(maxWidth: 640),
|
||||
shape: _tokens.sheetShape,
|
||||
);
|
||||
|
||||
static DialogThemeData _dialogTheme(ColorScheme scheme) => DialogThemeData(
|
||||
elevation: 6,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(28)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusSheet),
|
||||
),
|
||||
backgroundColor: scheme.surfaceContainerHigh,
|
||||
surfaceTintColor: scheme.surfaceTint,
|
||||
);
|
||||
@@ -239,7 +256,9 @@ class AppTheme {
|
||||
static SnackBarThemeData _snackBarTheme(ColorScheme scheme) =>
|
||||
SnackBarThemeData(
|
||||
behavior: SnackBarBehavior.floating,
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusThumb),
|
||||
),
|
||||
backgroundColor: scheme.inverseSurface,
|
||||
contentTextStyle: TextStyle(color: scheme.onInverseSurface),
|
||||
);
|
||||
@@ -274,7 +293,9 @@ class AppTheme {
|
||||
);
|
||||
|
||||
static ChipThemeData _chipTheme(ColorScheme scheme) => ChipThemeData(
|
||||
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(_tokens.radiusCard),
|
||||
),
|
||||
backgroundColor: scheme.surfaceContainerLow,
|
||||
selectedColor: scheme.secondaryContainer,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user