From 13154a9c13d9ea04a455268c0d474e96277257df Mon Sep 17 00:00:00 2001 From: ahamSel <77988808+ahamSel@users.noreply.github.com> Date: Thu, 6 Aug 2026 10:45:05 -0230 Subject: [PATCH 1/3] [material_ui] Fix ExpansionTile WidgetSpan semantics --- .../material_ui/lib/src/expansion_tile.dart | 4 +- ...2026_08_06_expansion_tile_widget_span.yaml | 3 ++ .../material_ui/test/expansion_tile_test.dart | 41 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml diff --git a/packages/material_ui/lib/src/expansion_tile.dart b/packages/material_ui/lib/src/expansion_tile.dart index 3d59612ccc4e..b77fbad2a0fc 100644 --- a/packages/material_ui/lib/src/expansion_tile.dart +++ b/packages/material_ui/lib/src/expansion_tile.dart @@ -693,7 +693,9 @@ class _ExpansionTileState extends State { return Semantics( // Live region used to announce state changes (e.g., "expanded" or "collapsed") // without taking focus. - // blockNode prevents this node from being part of the focus traversal. + // The container ensures the live region forms the node that blockNode + // removes from focus traversal. + container: true, label: semanticsHint, liveRegion: true, accessibilityFocusBlockType: AccessibilityFocusBlockType.blockNode, diff --git a/packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml b/packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml new file mode 100644 index 000000000000..7dd8d57de162 --- /dev/null +++ b/packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml @@ -0,0 +1,3 @@ +changelog: | + - Fixes an Android semantics assertion when an ExpansionTile title contains a nested WidgetSpan. +version: patch diff --git a/packages/material_ui/test/expansion_tile_test.dart b/packages/material_ui/test/expansion_tile_test.dart index bfdb8b020b1f..d0b41f9fdd5f 100644 --- a/packages/material_ui/test/expansion_tile_test.dart +++ b/packages/material_ui/test/expansion_tile_test.dart @@ -2230,6 +2230,47 @@ void main() { ); }); group('Semantics tests for android platform', () { + // Regression test for https://github.com/flutter/flutter/issues/188298. + testWidgets('ExpansionTile supports a nested WidgetSpan title', (WidgetTester tester) async { + final SemanticsHandle handle = tester.ensureSemantics(); + + await tester.pumpWidget( + const MaterialApp( + home: Scaffold( + body: Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: SizedBox( + width: 400, + child: ExpansionTile( + title: Text.rich( + TextSpan( + children: [ + WidgetSpan( + child: Text.rich( + TextSpan( + style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold), + text: 'Header', + ), + ), + ), + ], + ), + ), + children: [Text('These are the details.')], + ), + ), + ), + ], + ), + ), + ), + ), + ); + handle.dispose(); + }, variant: const TargetPlatformVariant({TargetPlatform.android})); + testWidgets('Semantics liveregion updates when expansion state changes', ( WidgetTester tester, ) async { From 42e5bd1bacb0ca52fab90e107d01b37e980ca10b Mon Sep 17 00:00:00 2001 From: ahamSel <77988808+ahamSel@users.noreply.github.com> Date: Sat, 5 Sep 2026 09:26:27 -0230 Subject: [PATCH 2/3] [material_ui] Simplify ExpansionTile WidgetSpan regression test --- ...2026_08_06_expansion_tile_widget_span.yaml | 2 +- .../material_ui/test/expansion_tile_test.dart | 27 +++++-------------- 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml b/packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml index 7dd8d57de162..8b397ca1d4f8 100644 --- a/packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml +++ b/packages/material_ui/pending_changelogs/change_2026_08_06_expansion_tile_widget_span.yaml @@ -1,3 +1,3 @@ changelog: | - - Fixes an Android semantics assertion when an ExpansionTile title contains a nested WidgetSpan. + - Fixes an Android semantics assertion when an `ExpansionTile` is embedded in a `WidgetSpan`. version: patch diff --git a/packages/material_ui/test/expansion_tile_test.dart b/packages/material_ui/test/expansion_tile_test.dart index d0b41f9fdd5f..ee3436261f6d 100644 --- a/packages/material_ui/test/expansion_tile_test.dart +++ b/packages/material_ui/test/expansion_tile_test.dart @@ -2231,7 +2231,9 @@ void main() { }); group('Semantics tests for android platform', () { // Regression test for https://github.com/flutter/flutter/issues/188298. - testWidgets('ExpansionTile supports a nested WidgetSpan title', (WidgetTester tester) async { + testWidgets('ExpansionTile supports being embedded in a WidgetSpan', ( + WidgetTester tester, + ) async { final SemanticsHandle handle = tester.ensureSemantics(); await tester.pumpWidget( @@ -2241,25 +2243,9 @@ void main() { TextSpan( children: [ WidgetSpan( - child: SizedBox( - width: 400, - child: ExpansionTile( - title: Text.rich( - TextSpan( - children: [ - WidgetSpan( - child: Text.rich( - TextSpan( - style: TextStyle(fontSize: 32, fontWeight: FontWeight.bold), - text: 'Header', - ), - ), - ), - ], - ), - ), - children: [Text('These are the details.')], - ), + child: ExpansionTile( + title: Text('Header'), + children: [Text('Details')], ), ), ], @@ -2268,6 +2254,7 @@ void main() { ), ), ); + expect(find.text('Header'), findsOneWidget); handle.dispose(); }, variant: const TargetPlatformVariant({TargetPlatform.android})); From 1d2f389ee34dcbebeb98bb1e4b1d657d0d23f5cb Mon Sep 17 00:00:00 2001 From: ahamSel <77988808+ahamSel@users.noreply.github.com> Date: Wed, 9 Sep 2026 13:09:07 -0230 Subject: [PATCH 3/3] [material_ui] Let testWidgets manage regression-test semantics --- packages/material_ui/test/expansion_tile_test.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/material_ui/test/expansion_tile_test.dart b/packages/material_ui/test/expansion_tile_test.dart index ee3436261f6d..e48160e90138 100644 --- a/packages/material_ui/test/expansion_tile_test.dart +++ b/packages/material_ui/test/expansion_tile_test.dart @@ -2234,8 +2234,6 @@ void main() { testWidgets('ExpansionTile supports being embedded in a WidgetSpan', ( WidgetTester tester, ) async { - final SemanticsHandle handle = tester.ensureSemantics(); - await tester.pumpWidget( const MaterialApp( home: Scaffold( @@ -2255,7 +2253,6 @@ void main() { ), ); expect(find.text('Header'), findsOneWidget); - handle.dispose(); }, variant: const TargetPlatformVariant({TargetPlatform.android})); testWidgets('Semantics liveregion updates when expansion state changes', (