Goal
Updates and manages Flutter application styling by migrating legacy Material 2 implementations to Material 3, normalizing component themes, updating deprecated button classes, and adapting UI idioms for cross-platform consistency. Assumes a Flutter environment using Dart.
Instructions
- Analyze Current Theme State Review the existing Flutter codebase to identify legacy Material 2 components, deprecated button classes (
FlatButton,RaisedButton,OutlineButton), and outdated theme properties (e.g.,accentColor,colorinAppBarTheme). STOP AND ASK THE USER: "What is the primary seed color for the new Material 3 ColorScheme, and which target platforms (iOS, Android, Windows, macOS, Linux, Web) should be prioritized for platform idioms?" - Decision Logic: Component Migration When encountering legacy widgets, use the following decision tree to determine the replacement:
- IF BottomNavigationBar -> REPLACE WITH NavigationBar (uses NavigationDestination). - IF Drawer -> REPLACE WITH NavigationDrawer (uses NavigationDrawerDestination). - IF ToggleButtons -> REPLACE WITH SegmentedButton (uses ButtonSegment and Set for selection). - IF FlatButton -> REPLACE WITH TextButton. - IF RaisedButton -> REPLACE WITH ElevatedButton (or FilledButton for no elevation). - IF OutlineButton -> REPLACE WITH OutlinedButton.
- Implement App-Wide Material 3 Theme Define the global
ThemeDatausingColorScheme.fromSeed. EnsureuseMaterial3is implicitly or explicitly true. Remove all references to deprecated accent properties (accentColor,accentColorBrightness,accentTextTheme,accentIconTheme).MaterialApp(title: 'App Name', theme: ThemeData(useMaterial3: true, colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple, brightness: Brightness.light,), // Use colorScheme.secondary instead of accentColor), darkTheme: ThemeData(useMaterial3: true, colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple, brightness: Brightness.dark,),), home: const MyHomePage(),); - Normalize Component Themes Update all component theme definitions in
ThemeDatato use their*ThemeDataequivalents. Do not use the base theme classes for configuration.ThemeData(colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), appBarTheme: const AppBarThemeData(backgroundColor: Colors.blue, // Do not use 'color' elevation: 4.0,), cardTheme: const CardThemeData(elevation: 2.0,),);
- cardTheme -> CardThemeData - dialogTheme -> DialogThemeData - tabBarTheme -> TabBarThemeData - appBarTheme -> AppBarThemeData (Replace color with backgroundColor) - bottomAppBarTheme -> BottomAppBarThemeData - inputDecorationTheme -> InputDecorationThemeData
- Migrate Buttons and Button Styles Replace legacy buttons. Use the
styleFrom()static method for simple overrides, orButtonStylewithMaterialStatePropertyfor state-dependent styling.// Simple override using styleFrom TextButton(style: TextButton.styleFrom(foregroundColor: Colors.blue, disabledForegroundColor: Colors.red,), onPressed: () {}, child: const Text('TextButton'),) // State-dependent override using MaterialStateProperty OutlinedButton(style: ButtonStyle(side: MaterialStateProperty.resolveWith<BorderSide>((Set<MaterialState> states) {if (states.contains(MaterialState.pressed)) {return const BorderSide(color: Colors.blue, width: 2);} return const BorderSide(color: Colors.grey, width: 1);}),), onPressed: () {}, child: const Text('OutlinedButton'),) - Decision Logic: Platform Idioms Apply platform-specific adaptations based on the host OS to reduce cognitive load and build user trust.
// Platform-aware button ordering TextDirection btnDirection = Platform.isWindows? TextDirection.rtl: TextDirection.ltr; Row(children: [const Spacer(), Row(textDirection: btnDirection, children: [TextButton(onPressed: () => Navigator.pop(context, false), child: const Text('Cancel'),), ElevatedButton(onPressed: () => Navigator.pop(context, true), child: const Text('OK'),),],),],)
- Scrollbars: IF desktop platform -> Set thumbVisibility: true (or alwaysShown). IF mobile -> Use default auto-hiding behavior. - Text Selection: IF text is informational and non-interactive -> Wrap in SelectableText to allow mouse selection on Web/Desktop. - Button Ordering: IF Windows -> Place confirmation button on the LEFT. IF macOS/Linux/Android/iOS -> Place confirmation button on the RIGHT.
- Validate-and-Fix Scan the generated code to verify that no
FlatButton,RaisedButton,OutlineButton, orButtonThemeclasses remain. Verify thatAppBarThemedoes not use thecolorproperty. Fix any instances found.
Constraints
- Single Source of Truth: All colors must be derived from the
ColorScheme(e.g.,Theme.of(context).colorScheme.primary). Do not hardcode hex colors unless explicitly requested. - No Legacy Buttons: Never output
FlatButton,RaisedButton, orOutlineButton. - No Accent Properties: Never use
accentColor,accentColorBrightness,accentTextTheme, oraccentIconTheme. UsecolorScheme.secondaryandcolorScheme.onSecondaryinstead. - Component Theme Suffixes: Always append
Datato component themes when configuringThemeData(e.g.,CardThemeData, notCardTheme). - AppBar Background: Never use the
colorproperty inAppBarThemeorAppBarThemeData; strictly usebackgroundColor.