flutter-theming

Migrate Flutter apps from Material 2 to Material 3 with automated component and theme updates. Identifies and replaces deprecated Material 2 components (FlatButton, RaisedButton, BottomNavigationBar, Drawer) with their Material 3 equivalents using a decision tree Converts legacy theme properties to Material 3 ColorScheme and removes deprecated accent color references (accentColor, accentColorBrightness, etc.) Normalizes all component themes to use *ThemeData classes and ensures useMaterial3: true across light and dark themes Applies platform-specific UI idioms for scrollbars, text selection, and button ordering across iOS, Android, Windows, macOS, Linux, and Web Validates output to eliminate legacy button classes and enforce single-source-of-truth color derivation from ColorScheme

INSTALLATION
npx skills add https://github.com/flutter/skills --skill flutter-theming
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$2a

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 ThemeData to use their *ThemeData equivalents. Do not use the base theme classes for configuration.

  • cardTheme -> CardThemeData
  • dialogTheme -> DialogThemeData
  • tabBarTheme -> TabBarThemeData
  • appBarTheme -> AppBarThemeData (Replace color with backgroundColor)
  • bottomAppBarTheme -> BottomAppBarThemeData
  • inputDecorationTheme -> InputDecorationThemeData
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,

  ),

);

-

Migrate Buttons and Button Styles

Replace legacy buttons. Use the styleFrom() static method for simple overrides, or ButtonStyle with MaterialStateProperty for 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.

  • 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.
// 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'),

        ),

      ],

    ),

  ],

)

-

Validate-and-Fix

Scan the generated code to verify that no FlatButton, RaisedButton, OutlineButton, or ButtonTheme classes remain. Verify that AppBarTheme does not use the color property. 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, or OutlineButton.
  • No Accent Properties: Never use accentColor, accentColorBrightness, accentTextTheme, or accentIconTheme. Use colorScheme.secondary and colorScheme.onSecondary instead.
  • Component Theme Suffixes: Always append Data to component themes when configuring ThemeData (e.g., CardThemeData, not CardTheme).
  • AppBar Background: Never use the color property in AppBarTheme or AppBarThemeData; strictly use backgroundColor.
BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills →

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free · no credit card