diff --git a/packages/material_ui/lib/src/theme.dart b/packages/material_ui/lib/src/theme.dart index a3d91f498ff..487f5dc7f9b 100644 --- a/packages/material_ui/lib/src/theme.dart +++ b/packages/material_ui/lib/src/theme.dart @@ -141,14 +141,17 @@ class Theme extends StatelessWidget { MaterialLocalizations, ); final ScriptCategory category = localizations?.scriptCategory ?? ScriptCategory.englishLike; - final InheritedCupertinoTheme? inheritedCupertinoTheme = context - .dependOnInheritedWidgetOfExactType(); - final ThemeData theme = - inheritedTheme?.theme.data ?? - (inheritedCupertinoTheme != null - ? CupertinoBasedMaterialThemeData(themeData: inheritedCupertinoTheme.theme.data) - .materialTheme - : _fallbackTheme); + final ThemeData theme; + if (inheritedTheme != null) { + theme = inheritedTheme.theme.data; + } else { + final InheritedCupertinoTheme? inheritedCupertinoTheme = context + .dependOnInheritedWidgetOfExactType(); + theme = inheritedCupertinoTheme != null + ? CupertinoBasedMaterialThemeData(themeData: inheritedCupertinoTheme.theme.data) + .materialTheme + : _fallbackTheme; + } return ThemeData.localize(theme, theme.typography.geometryThemeFor(category)); } diff --git a/packages/material_ui/lib/src/theme_data.dart b/packages/material_ui/lib/src/theme_data.dart index 3669b964de5..462640b410e 100644 --- a/packages/material_ui/lib/src/theme_data.dart +++ b/packages/material_ui/lib/src/theme_data.dart @@ -3092,7 +3092,7 @@ class MaterialBasedCupertinoThemeData extends CupertinoThemeData { MaterialBasedCupertinoThemeData({required ThemeData materialTheme}) : this._( materialTheme, - (materialTheme.cupertinoOverrideTheme ?? const CupertinoThemeData()).noDefault(), + materialTheme.cupertinoOverrideTheme?.noDefault() ?? const NoDefaultCupertinoThemeData(), ); MaterialBasedCupertinoThemeData._(this._materialTheme, this._cupertinoOverrideTheme) @@ -3192,14 +3192,17 @@ class CupertinoBasedMaterialThemeData { /// Creates a Material theme with a color scheme based off of the colors from /// a [CupertinoThemeData]. CupertinoBasedMaterialThemeData({required CupertinoThemeData themeData}) - : materialTheme = ThemeData( - colorScheme: ColorScheme.fromSeed( - seedColor: themeData.primaryColor, - brightness: themeData.brightness ?? Brightness.light, - primary: themeData.primaryColor, - onPrimary: themeData.primaryContrastingColor, + : materialTheme = switch (themeData) { + MaterialBasedCupertinoThemeData() => themeData._materialTheme, + _ => ThemeData( + colorScheme: ColorScheme.fromSeed( + seedColor: themeData.primaryColor, + brightness: themeData.brightness ?? Brightness.light, + primary: themeData.primaryColor, + onPrimary: themeData.primaryContrastingColor, + ), ), - ); + }; /// The Material theme data with colors based on an existing [CupertinoThemeData]. final ThemeData materialTheme; diff --git a/packages/material_ui/pending_changelogs/change_2026_10_31_theme_of_cupertino_treeshake.yaml b/packages/material_ui/pending_changelogs/change_2026_10_31_theme_of_cupertino_treeshake.yaml new file mode 100644 index 00000000000..d0a82aee413 --- /dev/null +++ b/packages/material_ui/pending_changelogs/change_2026_10_31_theme_of_cupertino_treeshake.yaml @@ -0,0 +1,3 @@ +changelog: | + - Avoids looking up `InheritedCupertinoTheme` in `Theme.of` when a Material `Theme` ancestor is present and preserves `MaterialBasedCupertinoThemeData` in `CupertinoBasedMaterialThemeData`, allowing unused `ColorScheme.fromSeed` and `material_color_utilities` code to be tree-shaken. +version: patch diff --git a/packages/material_ui/test/theme_test.dart b/packages/material_ui/test/theme_test.dart index 741ce7fc34f..10b4025e934 100644 --- a/packages/material_ui/test/theme_test.dart +++ b/packages/material_ui/test/theme_test.dart @@ -1174,6 +1174,40 @@ void main() { expect(theme.primaryColor, Colors.blue); expect(theme.primaryContrastingColor, CupertinoColors.destructiveRed); }); + + testWidgets( + 'Theme.of does not depend on InheritedCupertinoTheme when Theme ancestor is present', + (WidgetTester tester) async { + testBuildCalled = 0; + final themeData = ThemeData(primaryColor: const Color(0xFF000000)); + + Widget buildTree(CupertinoThemeData cupertinoTheme) { + return Theme( + data: themeData, + child: CupertinoTheme(data: cupertinoTheme, child: const Test()), + ); + } + + await tester.pumpWidget( + buildTree(const CupertinoThemeData(primaryColor: CupertinoColors.activeBlue)), + ); + expect(testBuildCalled, 1); + + await tester.pumpWidget( + buildTree(const CupertinoThemeData(primaryColor: CupertinoColors.activeGreen)), + ); + expect(testBuildCalled, 1); + }, + ); + + test('CupertinoBasedMaterialThemeData returns underlying ThemeData for MaterialBasedCupertinoThemeData', () { + final materialTheme = ThemeData(colorScheme: const ColorScheme.light(primary: Colors.purple)); + final cupertinoTheme = MaterialBasedCupertinoThemeData(materialTheme: materialTheme); + expect( + CupertinoBasedMaterialThemeData(themeData: cupertinoTheme).materialTheme, + same(materialTheme), + ); + }); }); }