feat(shared): legacy presentation/ + shared design system + widgets
- lib/presentation : pages legacy (explore/network, notifications) avec BLoC - lib/shared/design_system : UnionFlow Design System v2 (tokens, components) + MD3 tokens + module_colors par feature - lib/shared/widgets : widgets transversaux (core_card, core_shimmer, error_widget, loading_widget, powered_by_lions_dev, etc.) - lib/shared/constants + utils
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
/// Thème Sophistiqué UnionFlow
|
||||
///
|
||||
/// Implémentation complète du design system avec les dernières tendances UI/UX 2024-2025
|
||||
/// Architecture modulaire et tokens de design cohérents
|
||||
/// Thème Sophistiqué UnionFlow — Material Design 3
|
||||
///
|
||||
/// Palette WCAG 2.1 validée : #2563EB (primary) + #7616E8 (accent)
|
||||
library app_theme_sophisticated;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -10,197 +9,389 @@ import '../tokens/color_tokens.dart';
|
||||
import '../tokens/typography_tokens.dart';
|
||||
import '../tokens/spacing_tokens.dart';
|
||||
|
||||
/// Thème principal de l'application UnionFlow
|
||||
class AppThemeSophisticated {
|
||||
AppThemeSophisticated._();
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// THÈME PRINCIPAL - Configuration complète
|
||||
// THÈME CLAIR
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// Thème clair principal
|
||||
|
||||
static ThemeData get lightTheme {
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: Brightness.light,
|
||||
|
||||
// Couleurs principales
|
||||
colorScheme: _lightColorScheme,
|
||||
|
||||
// Typographie (Playfair Display display + Inter body)
|
||||
textTheme: _textTheme,
|
||||
|
||||
// Configuration de l'AppBar
|
||||
appBarTheme: _appBarTheme,
|
||||
|
||||
// Configuration des cartes
|
||||
cardTheme: _cardTheme,
|
||||
|
||||
// Configuration des boutons
|
||||
elevatedButtonTheme: _elevatedButtonTheme,
|
||||
filledButtonTheme: _filledButtonTheme,
|
||||
outlinedButtonTheme: _outlinedButtonTheme,
|
||||
textButtonTheme: _textButtonTheme,
|
||||
|
||||
// Configuration des champs de saisie
|
||||
inputDecorationTheme: _inputDecorationTheme,
|
||||
|
||||
// Configuration de la navigation
|
||||
navigationBarTheme: _navigationBarTheme,
|
||||
navigationDrawerTheme: _navigationDrawerTheme,
|
||||
|
||||
// Configuration des dialogues
|
||||
dialogTheme: _dialogTheme,
|
||||
|
||||
// Configuration des snackbars
|
||||
snackBarTheme: _snackBarTheme,
|
||||
|
||||
// Configuration des puces
|
||||
chipTheme: _chipTheme,
|
||||
|
||||
// Configuration des listes
|
||||
listTileTheme: _listTileTheme,
|
||||
|
||||
// Configuration des onglets
|
||||
tabBarTheme: _tabBarTheme,
|
||||
|
||||
// Configuration des dividers
|
||||
dividerTheme: _dividerTheme,
|
||||
|
||||
// Configuration des icônes
|
||||
iconTheme: _iconTheme,
|
||||
|
||||
// Configuration des surfaces
|
||||
scaffoldBackgroundColor: ColorTokens.surface,
|
||||
scaffoldBackgroundColor: ColorTokens.background,
|
||||
canvasColor: ColorTokens.surface,
|
||||
|
||||
// Configuration des animations
|
||||
pageTransitionsTheme: _pageTransitionsTheme,
|
||||
|
||||
// Configuration des extensions
|
||||
extensions: const [
|
||||
_customColors,
|
||||
_customSpacing,
|
||||
],
|
||||
extensions: const [_customColors, _customSpacing],
|
||||
);
|
||||
}
|
||||
|
||||
/// Thème sombre — Vert Ardoise (#1A2E1A)
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// THÈME SOMBRE — Navy Profond (#0A0D1A)
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
static ThemeData get darkTheme {
|
||||
return ThemeData(
|
||||
useMaterial3: true,
|
||||
brightness: Brightness.dark,
|
||||
colorScheme: const ColorScheme.dark(
|
||||
primary: Color(0xFF4CAF50), // Vert clair sur fond sombre
|
||||
onPrimary: Color(0xFF003908),
|
||||
primaryContainer: Color(0xFF1E3A1E),
|
||||
onPrimaryContainer: Color(0xFFB9F0B9),
|
||||
secondary: Color(0xFFA5D6A7),
|
||||
onSecondary: Color(0xFF002106),
|
||||
surface: Color(0xFF1A2E1A), // Vert ardoise
|
||||
onSurface: Color(0xFFE0F2E0),
|
||||
surfaceContainerHighest: Color(0xFF243824),
|
||||
onSurfaceVariant: Color(0xFF90B890),
|
||||
error: Color(0xFFEF4444),
|
||||
onError: Colors.white,
|
||||
outline: Color(0xFF3A5E3A),
|
||||
shadow: Color(0xFF0F1A0F),
|
||||
),
|
||||
scaffoldBackgroundColor: const Color(0xFF0F1A0F),
|
||||
colorScheme: _darkColorScheme,
|
||||
textTheme: _textThemeDark,
|
||||
scaffoldBackgroundColor: ColorTokens.backgroundDark,
|
||||
canvasColor: ColorTokens.surfaceDark,
|
||||
appBarTheme: const AppBarTheme(
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
foregroundColor: Color(0xFFE0F2E0),
|
||||
foregroundColor: ColorTokens.onSurfaceDark,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
systemOverlayStyle: SystemUiOverlayStyle(
|
||||
statusBarColor: Colors.transparent,
|
||||
statusBarIconBrightness: Brightness.light, // icônes blanches en dark
|
||||
statusBarBrightness: Brightness.dark, // pour iOS
|
||||
systemNavigationBarColor: Colors.transparent,
|
||||
),
|
||||
),
|
||||
dividerTheme: const DividerThemeData(
|
||||
color: ColorTokens.outlineDark,
|
||||
thickness: 1.0,
|
||||
space: SpacingTokens.md,
|
||||
),
|
||||
cardTheme: CardThemeData(
|
||||
color: ColorTokens.surfaceDark,
|
||||
elevation: 0,
|
||||
shadowColor: Colors.transparent,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusLg),
|
||||
side: const BorderSide(color: ColorTokens.outlineDark),
|
||||
),
|
||||
margin: const EdgeInsets.all(SpacingTokens.cardMargin),
|
||||
),
|
||||
elevatedButtonTheme: ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: SpacingTokens.elevationSm,
|
||||
backgroundColor: ColorTokens.primaryLight,
|
||||
foregroundColor: ColorTokens.onPrimaryContainer,
|
||||
textStyle: TypographyTokens.buttonMedium,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: SpacingTokens.buttonPaddingHorizontal,
|
||||
vertical: SpacingTokens.buttonPaddingVertical,
|
||||
),
|
||||
minimumSize: const Size(SpacingTokens.minButtonWidth, SpacingTokens.buttonHeightMedium),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
),
|
||||
),
|
||||
),
|
||||
filledButtonTheme: FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: ColorTokens.primaryLight,
|
||||
foregroundColor: ColorTokens.onPrimaryContainer,
|
||||
textStyle: TypographyTokens.buttonMedium,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: SpacingTokens.buttonPaddingHorizontal,
|
||||
vertical: SpacingTokens.buttonPaddingVertical,
|
||||
),
|
||||
minimumSize: const Size(SpacingTokens.minButtonWidth, SpacingTokens.buttonHeightMedium),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
),
|
||||
),
|
||||
),
|
||||
outlinedButtonTheme: OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: ColorTokens.primaryLight,
|
||||
textStyle: TypographyTokens.buttonMedium,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: SpacingTokens.buttonPaddingHorizontal,
|
||||
vertical: SpacingTokens.buttonPaddingVertical,
|
||||
),
|
||||
minimumSize: const Size(SpacingTokens.minButtonWidth, SpacingTokens.buttonHeightMedium),
|
||||
side: const BorderSide(color: ColorTokens.outlineDark),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
),
|
||||
),
|
||||
),
|
||||
textButtonTheme: TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: ColorTokens.primaryLight,
|
||||
textStyle: TypographyTokens.buttonMedium,
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: SpacingTokens.buttonPaddingHorizontal,
|
||||
vertical: SpacingTokens.buttonPaddingVertical,
|
||||
),
|
||||
minimumSize: const Size(SpacingTokens.minButtonWidth, SpacingTokens.buttonHeightMedium),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
),
|
||||
),
|
||||
),
|
||||
inputDecorationTheme: InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: ColorTokens.surfaceContainerDark,
|
||||
labelStyle: TypographyTokens.inputLabel.copyWith(
|
||||
color: ColorTokens.onSurfaceVariantDark,
|
||||
),
|
||||
hintStyle: TypographyTokens.inputHint.copyWith(
|
||||
color: ColorTokens.onSurfaceVariantDark,
|
||||
),
|
||||
border: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
borderSide: const BorderSide(color: ColorTokens.outlineDark),
|
||||
),
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
borderSide: const BorderSide(color: ColorTokens.outlineDark),
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
borderSide: const BorderSide(color: ColorTokens.primaryLight, width: 2.0),
|
||||
),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
borderSide: const BorderSide(color: ColorTokens.error),
|
||||
),
|
||||
contentPadding: const EdgeInsets.all(SpacingTokens.formPadding),
|
||||
),
|
||||
navigationBarTheme: NavigationBarThemeData(
|
||||
backgroundColor: ColorTokens.navigationBackgroundDark,
|
||||
indicatorColor: ColorTokens.navigationIndicatorDark,
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return TypographyTokens.navigationLabelSelected.copyWith(
|
||||
color: ColorTokens.navigationSelectedDark,
|
||||
);
|
||||
}
|
||||
return TypographyTokens.navigationLabel.copyWith(
|
||||
color: ColorTokens.navigationUnselectedDark,
|
||||
);
|
||||
}),
|
||||
iconTheme: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return const IconThemeData(color: ColorTokens.navigationSelectedDark);
|
||||
}
|
||||
return const IconThemeData(color: ColorTokens.navigationUnselectedDark);
|
||||
}),
|
||||
),
|
||||
navigationDrawerTheme: NavigationDrawerThemeData(
|
||||
backgroundColor: ColorTokens.surfaceContainerDark,
|
||||
elevation: SpacingTokens.elevationMd,
|
||||
shadowColor: Colors.black,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
indicatorColor: ColorTokens.navigationIndicatorDark,
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
return TypographyTokens.navigationLabelSelected.copyWith(
|
||||
color: ColorTokens.navigationSelectedDark,
|
||||
);
|
||||
}
|
||||
return TypographyTokens.navigationLabel.copyWith(
|
||||
color: ColorTokens.navigationUnselectedDark,
|
||||
);
|
||||
}),
|
||||
),
|
||||
dialogTheme: DialogThemeData(
|
||||
backgroundColor: ColorTokens.surfaceDark,
|
||||
elevation: SpacingTokens.elevationLg,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusXl),
|
||||
),
|
||||
titleTextStyle: TypographyTokens.headlineSmall.copyWith(
|
||||
color: ColorTokens.onSurfaceDark,
|
||||
),
|
||||
contentTextStyle: TypographyTokens.bodyMedium.copyWith(
|
||||
color: ColorTokens.onSurfaceVariantDark,
|
||||
),
|
||||
),
|
||||
snackBarTheme: SnackBarThemeData(
|
||||
backgroundColor: ColorTokens.surfaceVariantDark,
|
||||
contentTextStyle: TypographyTokens.bodyMedium.copyWith(
|
||||
color: ColorTokens.onSurfaceDark,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
),
|
||||
behavior: SnackBarBehavior.fixed,
|
||||
),
|
||||
chipTheme: ChipThemeData(
|
||||
backgroundColor: ColorTokens.surfaceContainerDark,
|
||||
selectedColor: ColorTokens.navigationIndicatorDark,
|
||||
labelStyle: TypographyTokens.labelMedium.copyWith(
|
||||
color: ColorTokens.onSurfaceDark,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: SpacingTokens.md,
|
||||
vertical: SpacingTokens.sm,
|
||||
),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
),
|
||||
),
|
||||
listTileTheme: ListTileThemeData(
|
||||
contentPadding: const EdgeInsets.symmetric(
|
||||
horizontal: SpacingTokens.xl,
|
||||
vertical: SpacingTokens.md,
|
||||
),
|
||||
tileColor: ColorTokens.surfaceDark,
|
||||
titleTextStyle: TypographyTokens.titleMedium.copyWith(
|
||||
color: ColorTokens.onSurfaceDark,
|
||||
),
|
||||
subtitleTextStyle: TypographyTokens.bodyMedium.copyWith(
|
||||
color: ColorTokens.onSurfaceVariantDark,
|
||||
),
|
||||
minVerticalPadding: SpacingTokens.md,
|
||||
),
|
||||
tabBarTheme: TabBarThemeData(
|
||||
labelColor: ColorTokens.primaryLight,
|
||||
unselectedLabelColor: ColorTokens.onSurfaceVariantDark,
|
||||
labelStyle: TypographyTokens.titleSmall,
|
||||
unselectedLabelStyle: TypographyTokens.titleSmall,
|
||||
indicator: UnderlineTabIndicator(
|
||||
borderSide: const BorderSide(color: ColorTokens.primaryLight, width: 2.0),
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusXs),
|
||||
),
|
||||
),
|
||||
iconTheme: const IconThemeData(
|
||||
color: ColorTokens.onSurfaceVariantDark,
|
||||
size: 24.0,
|
||||
),
|
||||
pageTransitionsTheme: _pageTransitionsTheme,
|
||||
extensions: const [_customColors, _customSpacing],
|
||||
);
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// SCHÉMA DE COULEURS
|
||||
// COLOR SCHEME SOMBRE — Navy profond OLED
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
|
||||
static const ColorScheme _darkColorScheme = ColorScheme.dark(
|
||||
primary: ColorTokens.primaryLight, // #60A5FA sur fond sombre
|
||||
onPrimary: ColorTokens.onPrimaryContainer, // #1E3A8A
|
||||
primaryContainer: ColorTokens.navigationIndicatorDark, // #1A2350
|
||||
onPrimaryContainer: Color(0xFFD6E8FF),
|
||||
secondary: ColorTokens.secondaryLight, // #9B59F0
|
||||
onSecondary: ColorTokens.onSecondaryContainer, // #2A006F
|
||||
secondaryContainer: Color(0xFF3B1F6A),
|
||||
onSecondaryContainer: Color(0xFFEAD5FF),
|
||||
surface: ColorTokens.surfaceDark, // #161B26
|
||||
onSurface: ColorTokens.onSurfaceDark, // #F1F5FF
|
||||
surfaceContainerHighest: ColorTokens.surfaceVariantDark, // #1A1F2E
|
||||
onSurfaceVariant: ColorTokens.onSurfaceVariantDark, // #94A3B8
|
||||
error: ColorTokens.error,
|
||||
onError: Colors.white,
|
||||
errorContainer: Color(0xFF5C1111),
|
||||
onErrorContainer: ColorTokens.errorLight,
|
||||
outline: ColorTokens.outlineDark, // #2D3554
|
||||
outlineVariant: Color(0xFF1F2B3E),
|
||||
shadow: ColorTokens.backgroundDark,
|
||||
scrim: Colors.black,
|
||||
inverseSurface: ColorTokens.onSurfaceDark,
|
||||
onInverseSurface: ColorTokens.surfaceDark,
|
||||
inversePrimary: ColorTokens.primary,
|
||||
);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// COLOR SCHEME CLAIR
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
static const ColorScheme _lightColorScheme = ColorScheme.light(
|
||||
// Couleurs primaires
|
||||
primary: ColorTokens.primary,
|
||||
onPrimary: ColorTokens.onPrimary,
|
||||
primaryContainer: ColorTokens.primaryContainer,
|
||||
onPrimaryContainer: ColorTokens.onPrimaryContainer,
|
||||
|
||||
// Couleurs secondaires
|
||||
secondary: ColorTokens.secondary,
|
||||
onSecondary: ColorTokens.onSecondary,
|
||||
secondaryContainer: ColorTokens.secondaryContainer,
|
||||
onSecondaryContainer: ColorTokens.onSecondaryContainer,
|
||||
|
||||
// Couleurs tertiaires
|
||||
tertiary: ColorTokens.tertiary,
|
||||
onTertiary: ColorTokens.onTertiary,
|
||||
tertiaryContainer: ColorTokens.tertiaryContainer,
|
||||
onTertiaryContainer: ColorTokens.onTertiaryContainer,
|
||||
|
||||
// Couleurs d'erreur
|
||||
error: ColorTokens.error,
|
||||
onError: ColorTokens.onError,
|
||||
errorContainer: ColorTokens.errorContainer,
|
||||
onErrorContainer: ColorTokens.onErrorContainer,
|
||||
|
||||
// Couleurs de surface
|
||||
surface: ColorTokens.surface,
|
||||
onSurface: ColorTokens.onSurface,
|
||||
surfaceContainerHighest: ColorTokens.surfaceVariant,
|
||||
onSurfaceVariant: ColorTokens.onSurfaceVariant,
|
||||
|
||||
// Couleurs de contour
|
||||
outline: ColorTokens.outline,
|
||||
outlineVariant: ColorTokens.outlineVariant,
|
||||
|
||||
// Couleurs d'ombre
|
||||
shadow: ColorTokens.shadow,
|
||||
scrim: ColorTokens.shadow,
|
||||
|
||||
// Couleurs d'inversion
|
||||
inverseSurface: ColorTokens.onSurface,
|
||||
onInverseSurface: ColorTokens.surface,
|
||||
inversePrimary: ColorTokens.primaryLight,
|
||||
);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// THÈME TYPOGRAPHIQUE
|
||||
// TYPOGRAPHIE
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
|
||||
static TextTheme get _textTheme => TextTheme(
|
||||
// Display styles — Playfair Display (GoogleFonts, non-const)
|
||||
displayLarge: TypographyTokens.displayLarge,
|
||||
displayMedium: TypographyTokens.displayMedium,
|
||||
displaySmall: TypographyTokens.displaySmall,
|
||||
|
||||
// Headline styles
|
||||
headlineLarge: TypographyTokens.headlineLarge,
|
||||
headlineMedium: TypographyTokens.headlineMedium,
|
||||
headlineSmall: TypographyTokens.headlineSmall,
|
||||
|
||||
// Title styles
|
||||
titleLarge: TypographyTokens.titleLarge,
|
||||
titleMedium: TypographyTokens.titleMedium,
|
||||
titleSmall: TypographyTokens.titleSmall,
|
||||
|
||||
// Label styles
|
||||
labelLarge: TypographyTokens.labelLarge,
|
||||
labelMedium: TypographyTokens.labelMedium,
|
||||
labelSmall: TypographyTokens.labelSmall,
|
||||
|
||||
// Body styles
|
||||
bodyLarge: TypographyTokens.bodyLarge,
|
||||
bodyMedium: TypographyTokens.bodyMedium,
|
||||
bodySmall: TypographyTokens.bodySmall,
|
||||
);
|
||||
|
||||
/// Thème typographique dark — même structure que _textTheme mais avec
|
||||
/// ColorTokens.onSurfaceDark (#F1F5FF) pour que le texte soit lisible
|
||||
/// sur les fonds sombres (#0A0D1A / #161B26).
|
||||
static TextTheme get _textThemeDark => TextTheme(
|
||||
displayLarge: TypographyTokens.displayLarge.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
displayMedium: TypographyTokens.displayMedium.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
displaySmall: TypographyTokens.displaySmall.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
headlineLarge: TypographyTokens.headlineLarge.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
headlineMedium: TypographyTokens.headlineMedium.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
headlineSmall: TypographyTokens.headlineSmall.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
titleLarge: TypographyTokens.titleLarge.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
titleMedium: TypographyTokens.titleMedium.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
titleSmall: TypographyTokens.titleSmall.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
labelLarge: TypographyTokens.labelLarge.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
labelMedium: TypographyTokens.labelMedium.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
labelSmall: TypographyTokens.labelSmall.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
bodyLarge: TypographyTokens.bodyLarge.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
bodyMedium: TypographyTokens.bodyMedium.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
bodySmall: TypographyTokens.bodySmall.copyWith(color: ColorTokens.onSurfaceDark),
|
||||
);
|
||||
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
// THÈMES DE COMPOSANTS
|
||||
// COMPOSANTS
|
||||
// ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
/// Configuration AppBar moderne (sans AppBar traditionnelle)
|
||||
|
||||
static const AppBarTheme _appBarTheme = AppBarTheme(
|
||||
elevation: 0,
|
||||
scrolledUnderElevation: 0,
|
||||
@@ -213,20 +404,21 @@ class AppThemeSophisticated {
|
||||
statusBarBrightness: Brightness.light,
|
||||
),
|
||||
);
|
||||
|
||||
/// Configuration des cartes sophistiquées
|
||||
|
||||
static final CardThemeData _cardTheme = CardThemeData(
|
||||
elevation: SpacingTokens.elevationSm,
|
||||
shadowColor: ColorTokens.shadow,
|
||||
surfaceTintColor: ColorTokens.surfaceContainer,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
color: ColorTokens.surface,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusLg),
|
||||
side: const BorderSide(color: ColorTokens.outline),
|
||||
),
|
||||
margin: const EdgeInsets.all(SpacingTokens.cardMargin),
|
||||
);
|
||||
|
||||
/// Configuration des boutons élevés
|
||||
static final ElevatedButtonThemeData _elevatedButtonTheme = ElevatedButtonThemeData(
|
||||
|
||||
static final ElevatedButtonThemeData _elevatedButtonTheme =
|
||||
ElevatedButtonThemeData(
|
||||
style: ElevatedButton.styleFrom(
|
||||
elevation: SpacingTokens.elevationSm,
|
||||
shadowColor: ColorTokens.shadow,
|
||||
@@ -246,9 +438,9 @@ class AppThemeSophisticated {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/// Configuration des boutons remplis
|
||||
static final FilledButtonThemeData _filledButtonTheme = FilledButtonThemeData(
|
||||
|
||||
static final FilledButtonThemeData _filledButtonTheme =
|
||||
FilledButtonThemeData(
|
||||
style: FilledButton.styleFrom(
|
||||
backgroundColor: ColorTokens.primary,
|
||||
foregroundColor: ColorTokens.onPrimary,
|
||||
@@ -266,9 +458,9 @@ class AppThemeSophisticated {
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/// Configuration des boutons avec contour
|
||||
static final OutlinedButtonThemeData _outlinedButtonTheme = OutlinedButtonThemeData(
|
||||
|
||||
static final OutlinedButtonThemeData _outlinedButtonTheme =
|
||||
OutlinedButtonThemeData(
|
||||
style: OutlinedButton.styleFrom(
|
||||
foregroundColor: ColorTokens.primary,
|
||||
textStyle: TypographyTokens.buttonMedium,
|
||||
@@ -280,17 +472,13 @@ class AppThemeSophisticated {
|
||||
SpacingTokens.minButtonWidth,
|
||||
SpacingTokens.buttonHeightMedium,
|
||||
),
|
||||
side: const BorderSide(
|
||||
color: ColorTokens.outline,
|
||||
width: 1.0,
|
||||
),
|
||||
side: const BorderSide(color: ColorTokens.outline),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusMd),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
/// Configuration des boutons texte
|
||||
|
||||
static final TextButtonThemeData _textButtonTheme = TextButtonThemeData(
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor: ColorTokens.primary,
|
||||
@@ -309,8 +497,8 @@ class AppThemeSophisticated {
|
||||
),
|
||||
);
|
||||
|
||||
/// Configuration des champs de saisie
|
||||
static final InputDecorationTheme _inputDecorationTheme = InputDecorationTheme(
|
||||
static final InputDecorationTheme _inputDecorationTheme =
|
||||
InputDecorationTheme(
|
||||
filled: true,
|
||||
fillColor: ColorTokens.surfaceContainer,
|
||||
labelStyle: TypographyTokens.inputLabel,
|
||||
@@ -334,8 +522,8 @@ class AppThemeSophisticated {
|
||||
contentPadding: const EdgeInsets.all(SpacingTokens.formPadding),
|
||||
);
|
||||
|
||||
/// Configuration de la barre de navigation
|
||||
static final NavigationBarThemeData _navigationBarTheme = NavigationBarThemeData(
|
||||
static final NavigationBarThemeData _navigationBarTheme =
|
||||
NavigationBarThemeData(
|
||||
backgroundColor: ColorTokens.navigationBackground,
|
||||
indicatorColor: ColorTokens.navigationIndicator,
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
@@ -352,12 +540,12 @@ class AppThemeSophisticated {
|
||||
}),
|
||||
);
|
||||
|
||||
/// Configuration du drawer de navigation
|
||||
static final NavigationDrawerThemeData _navigationDrawerTheme = NavigationDrawerThemeData(
|
||||
static final NavigationDrawerThemeData _navigationDrawerTheme =
|
||||
NavigationDrawerThemeData(
|
||||
backgroundColor: ColorTokens.surfaceContainer,
|
||||
elevation: SpacingTokens.elevationMd,
|
||||
shadowColor: ColorTokens.shadow,
|
||||
surfaceTintColor: ColorTokens.surfaceContainer,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
indicatorColor: ColorTokens.primaryContainer,
|
||||
labelTextStyle: WidgetStateProperty.resolveWith((states) {
|
||||
if (states.contains(WidgetState.selected)) {
|
||||
@@ -367,12 +555,11 @@ class AppThemeSophisticated {
|
||||
}),
|
||||
);
|
||||
|
||||
/// Configuration des dialogues
|
||||
static final DialogThemeData _dialogTheme = DialogThemeData(
|
||||
backgroundColor: ColorTokens.surfaceContainer,
|
||||
backgroundColor: ColorTokens.surface,
|
||||
elevation: SpacingTokens.elevationLg,
|
||||
shadowColor: ColorTokens.shadow,
|
||||
surfaceTintColor: ColorTokens.surfaceContainer,
|
||||
surfaceTintColor: Colors.transparent,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(SpacingTokens.radiusXl),
|
||||
),
|
||||
@@ -380,7 +567,6 @@ class AppThemeSophisticated {
|
||||
contentTextStyle: TypographyTokens.bodyMedium,
|
||||
);
|
||||
|
||||
/// Configuration des snackbars (fixed pour éviter "Floating SnackBar off screen" avec bottomNavigationBar)
|
||||
static final SnackBarThemeData _snackBarTheme = SnackBarThemeData(
|
||||
backgroundColor: ColorTokens.onSurface,
|
||||
contentTextStyle: TypographyTokens.bodyMedium.copyWith(
|
||||
@@ -392,7 +578,6 @@ class AppThemeSophisticated {
|
||||
behavior: SnackBarBehavior.fixed,
|
||||
);
|
||||
|
||||
/// Configuration des puces
|
||||
static final ChipThemeData _chipTheme = ChipThemeData(
|
||||
backgroundColor: ColorTokens.surfaceVariant,
|
||||
selectedColor: ColorTokens.primaryContainer,
|
||||
@@ -406,7 +591,6 @@ class AppThemeSophisticated {
|
||||
),
|
||||
);
|
||||
|
||||
/// Configuration des éléments de liste
|
||||
static const ListTileThemeData _listTileTheme = ListTileThemeData(
|
||||
contentPadding: EdgeInsets.symmetric(
|
||||
horizontal: SpacingTokens.xl,
|
||||
@@ -418,7 +602,6 @@ class AppThemeSophisticated {
|
||||
minVerticalPadding: SpacingTokens.md,
|
||||
);
|
||||
|
||||
/// Configuration des onglets
|
||||
static final TabBarThemeData _tabBarTheme = TabBarThemeData(
|
||||
labelColor: ColorTokens.primary,
|
||||
unselectedLabelColor: ColorTokens.onSurfaceVariant,
|
||||
@@ -433,56 +616,43 @@ class AppThemeSophisticated {
|
||||
),
|
||||
);
|
||||
|
||||
/// Configuration des dividers
|
||||
static const DividerThemeData _dividerTheme = DividerThemeData(
|
||||
color: ColorTokens.outline,
|
||||
thickness: 1.0,
|
||||
space: SpacingTokens.md,
|
||||
);
|
||||
|
||||
/// Configuration des icônes
|
||||
static const IconThemeData _iconTheme = IconThemeData(
|
||||
color: ColorTokens.onSurfaceVariant,
|
||||
size: 24.0,
|
||||
);
|
||||
|
||||
/// Configuration des transitions de page
|
||||
static const PageTransitionsTheme _pageTransitionsTheme = PageTransitionsTheme(
|
||||
static const PageTransitionsTheme _pageTransitionsTheme =
|
||||
PageTransitionsTheme(
|
||||
builders: {
|
||||
TargetPlatform.android: CupertinoPageTransitionsBuilder(),
|
||||
TargetPlatform.iOS: CupertinoPageTransitionsBuilder(),
|
||||
},
|
||||
);
|
||||
|
||||
/// Extensions personnalisées - Couleurs
|
||||
static const CustomColors _customColors = CustomColors();
|
||||
|
||||
/// Extensions personnalisées - Espacements
|
||||
static const CustomSpacing _customSpacing = CustomSpacing();
|
||||
}
|
||||
|
||||
/// Extension de couleurs personnalisées
|
||||
class CustomColors extends ThemeExtension<CustomColors> {
|
||||
const CustomColors();
|
||||
|
||||
@override
|
||||
CustomColors copyWith() => const CustomColors();
|
||||
|
||||
@override
|
||||
CustomColors lerp(ThemeExtension<CustomColors>? other, double t) {
|
||||
return const CustomColors();
|
||||
}
|
||||
CustomColors lerp(ThemeExtension<CustomColors>? other, double t) =>
|
||||
const CustomColors();
|
||||
}
|
||||
|
||||
/// Extension d'espacements personnalisés
|
||||
class CustomSpacing extends ThemeExtension<CustomSpacing> {
|
||||
const CustomSpacing();
|
||||
|
||||
@override
|
||||
CustomSpacing copyWith() => const CustomSpacing();
|
||||
|
||||
@override
|
||||
CustomSpacing lerp(ThemeExtension<CustomSpacing>? other, double t) {
|
||||
return const CustomSpacing();
|
||||
}
|
||||
CustomSpacing lerp(ThemeExtension<CustomSpacing>? other, double t) =>
|
||||
const CustomSpacing();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user