flexThemeDark function

ThemeData flexThemeDark(
  1. ThemeController controller
)

This function calls flexColorSchemeDark and uses FlexColorScheme.toTheme to return the ThemeData object represented by the returned FlexColorScheme setup.

We do it this way and not directly, or by setting it all up with the convenience extension helper FlexThemeData.dark, because when we create a standard Flutter SDK theme with ThemeData.from a ColorScheme factory, we will use the same flexColorSchemeDark dark function to return the ColorScheme it represents with its FlexColorScheme.toScheme method.

The ThemeData.from a ColorScheme will be used to demonstrate difference using the exact same ColorScheme, but using just default ThemeData with no FlexColorScheme theming applied.

Implementation

ThemeData flexThemeDark(ThemeController controller) {
  // Get the effective theme primary color, so we can use it as source color to
  // harmonize the CodeTheme extension colors towards it. Which is done by using
  // the M3 package MaterialColorUtilities function Blend.harmonize. At this
  // point the source color does not matter.
  //
  // Here it is worth pointing out this creates an extra FlexColorScheme that we
  // never use to make our ThemeData, we only use it to get its identical
  // effective ColorScheme and then grab the effective primary color. We then
  // proceed to make an almost identical FlexColorScheme, but with the effective
  // primary color we got as its color, and use it as source color to harmonize
  // our custom theme extension colors with it.
  //
  // The way the M3 seed based color algorithm and the harmonize color functions
  // work. We could actually use our ThemeController `controller` here and get
  // the effective input color via it. Then use that as source color for
  // the harmonization. In tests this produced same harmonization results as
  // when using the actual effective tint color created when also using it
  // as a seed to make the effective ColorScheme.
  // However, in dark mode, when not using seeds, but generating dark mode
  // colors from light mode primary color, with or without swap primary and
  // container colors on, by using `toDark` to compute the dark mode tint
  // color from the light mode primary input color. The harmonization results
  // diverge a bit from the harmonization result based on actual effective dark
  // mode tint color and using the in the controller accessible input color
  // as source color. This way by getting the actual effective ColorScheme is
  // simpler and guaranteed to always produce the right M3 intended color
  // harmonization towards the effective surface tint color. Regardless of what
  // settings and config we have used in the Themes Playground to define and
  // make our surface tint color, even custom one is adjusted for.
  final Color source = flexColorSchemeDark(controller, Colors.black).toScheme.surfaceTint;
  // Now we can use a function that takes our ThemeController and source color,
  // which is the effective primary color, the get the effective ThemeData.
  return flexColorSchemeDark(controller, source).toTheme.copyWith(
        // TODO(rydmike): Remove Drawer workaround when Flutter SDK has a fix.
        // This is a fix to avoid the Flutter Drawer width bug,
        // https://github.com/flutter/flutter/issues/123507 and overflow bug
        // https://github.com/flutter/flutter/issues/123380
        // when it animates via zero width in null default to widget default.
        drawerTheme: controller.useSubThemes ? null : DrawerThemeData(width: controller.useMaterial3 ? 360 : 304),
      );
}