Implementation
ThemeData createThemeData(BuildContext context) {
final textDirection = Directionality.maybeOf(context) ?? TextDirection.ltr;
final textScaler = MediaQuery.textScalerOf(context);
final devicePixelRatio = MediaQuery.devicePixelRatioOf(context);
final key = (
this,
textDirection,
textScaler,
devicePixelRatio,
defaultTargetPlatform,
);
final cachedRef = _themeCache[key];
final cached = cachedRef?.target;
if (cached != null) {
return cached;
}
final primaryColorLight =
Hct.fromColor(primary.fill, model: colorModel).tone >
Hct.fromColor(primary.color, model: colorModel).tone
? primary.fill
: primary.color;
final primaryColorDark = primaryColorLight == primary.fill
? primary.color
: primary.fill;
final colorScheme = _createColorScheme(
brightness,
primary,
secondary,
tertiary,
contrast,
algo,
Hct.colorFrom(0, 0, backgroundTone, model: colorModel),
backgroundTone,
colorModel,
);
final typographyData =
typography?.call(colorScheme) ?? _typography(colorScheme);
final textTheme = createTextTheme(
typographyData,
textScaler,
scale,
devicePixelRatio,
);
final shapes = this.shapes;
final themeData = ThemeData(
// Hack-y, idea is, in dark mode, apply on surface (usually lighter)
// with opacity to surface to make elevated surfaces lighter. Doesn't
// make sense once you don't only have opacity for lightening, but color.
applyElevationOverlayColor: false,
cupertinoOverrideTheme: null,
// Not sure this is used all that much, it's not affecting buttons on
// macOS at all. Default to shrinkWrap, because the components tend to
// be excessively large due to being designed for touch.
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
// Use default (slide on iOS/macOS, zoom on others)
pageTransitionsTheme: const PageTransitionsTheme(),
scrollbarTheme: scrollbarThemeData(primary),
// Copy logic from ThemeData, modulo useMaterial3 always is true
splashFactory: splashFactory,
useMaterial3: true,
visualDensity: VisualDensity.adaptivePlatformDensity,
brightness: brightness,
canvasColor: primary.background,
cardColor: primary.background,
colorScheme: colorScheme,
disabledColor: primary.color,
dividerColor: primary.backgroundText,
hoverColor: primary.fill.withOpacityNeue(0.2),
splashColor: primary.fill.withOpacityNeue(0.4),
focusColor: primary.fill.withOpacityNeue(0.4),
highlightColor: Colors.transparent,
hintColor: primary.backgroundText,
// ThemeData uses white if primary = secondary, otherwise, secondary
primaryColor: primary.color,
primaryColorDark: primaryColorDark,
primaryColorLight: primaryColorLight,
scaffoldBackgroundColor: primary.background,
secondaryHeaderColor: secondary.backgroundText,
// Avoid setting a default, as each widget may be a different color and
// thus should be set explicitly.
shadowColor: Colors.transparent,
// Material uses 70% white in dark mode, 54% black in light mode
// Is transparency important? Where is this used?
// For now, treat it like text
unselectedWidgetColor: primary.backgroundText,
iconTheme: iconThemeData(primary, scale),
primaryIconTheme: iconThemeData(primary, scale),
primaryTextTheme: textTheme,
textTheme: textTheme,
typography: typographyData,
// BEGIN ALL THE ACCOUTREMENTS
actionIconTheme: actionIconTheme(),
appBarTheme: appBarTheme(primary, textTheme, scale),
badgeTheme: badgeThemeData(context, primary, textTheme),
bannerTheme: bannerThemeData(primary, textTheme),
bottomAppBarTheme: bottomAppBarTheme(primary),
bottomNavigationBarTheme: bottomNavigationBarThemeData(
primary,
scale,
textTheme,
),
bottomSheetTheme: bottomSheetThemeData(primary),
buttonTheme: buttonThemeData(),
cardTheme: cardTheme(primary, shapes),
checkboxTheme: checkboxThemeData(primary),
chipTheme: chipThemeData(brightness, primary, textTheme),
dataTableTheme: dataTableThemeData(textTheme),
datePickerTheme: datePickerThemeData(
brightness,
primary,
textTheme,
shapes,
),
dialogTheme: createDialogTheme(primary, textTheme, shapes),
dividerTheme: dividerThemeData(primary),
drawerTheme: drawerThemeData(primary),
dropdownMenuTheme: dropdownMenuThemeData(primary, textTheme, shapes),
elevatedButtonTheme: elevatedButtonTheme(
colors: primary,
scale: scale,
shape: shapes.border(),
),
expansionTileTheme: expansionTileThemeData(primary, shapes),
filledButtonTheme: filledButtonTheme(
colors: primary,
scale: scale,
shape: shapes.border(),
),
floatingActionButtonTheme: fabThemeData(primary, textTheme),
iconButtonTheme: iconButtonThemeData(primary),
inputDecorationTheme: inputDecorationTheme(
primary,
textTheme,
shapes,
textDirection,
),
listTileTheme: listTileThemeData(primary, textTheme),
menuBarTheme: menuBarThemeData(primary),
menuButtonTheme: menuButtonThemeData(
colors: primary,
scale: scale,
shape: shapes.border(),
),
menuTheme: menuThemeData(primary, shapes),
navigationBarTheme: navigationBarThemeData(primary, textTheme),
navigationDrawerTheme: navigationDrawerThemeData(primary, textTheme),
navigationRailTheme: navigationRailThemeData(primary, scale, textTheme),
outlinedButtonTheme: outlinedButtonTheme(
colors: primary,
scale: scale,
shape: shapes.border(),
),
popupMenuTheme: popupMenuThemeData(primary, textTheme, shapes),
progressIndicatorTheme: progressIndicatorThemeData(primary),
radioTheme: radioThemeData(primary),
searchBarTheme: searchBarThemeData(primary, textTheme, shapes),
searchViewTheme: searchViewThemeData(primary, textTheme, shapes),
segmentedButtonTheme: segmentedButtonThemeData(primary),
sliderTheme: sliderThemeData(primary, textTheme),
snackBarTheme: snackBarThemeData(primary, textTheme, shapes),
switchTheme: switchThemeData(primary),
tabBarTheme: createTabBarTheme(primary, textTheme),
textButtonTheme: textButtonTheme(primary, shapes.border()),
textSelectionTheme: textSelectionThemeData(primary),
timePickerTheme: timePickerThemeData(primary, textTheme, scale, shapes),
toggleButtonsTheme: toggleButtonsThemeData(primary, textTheme),
tooltipTheme: tooltipThemeData(primary, textTheme, shapes),
);
final cupertinoOverrideTheme = MaterialBasedCupertinoThemeData(
materialTheme: themeData,
);
final finalThemeData = themeData.copyWith(
cupertinoOverrideTheme: cupertinoOverrideTheme,
);
_themeCache[key] = WeakReference(finalThemeData);
return finalThemeData;
}