fix(mobile): keep sticky date headings as screen-reader headings

Flutter 3.47 maps iOS and Android heading semantics from headingLevel and
ignores Semantics.header, so the conversation date headings lost their role.

Co-authored-by: Will Pfleger <pfleger.will@gmail.com>
Signed-off-by: Will Pfleger <pfleger.will@gmail.com>
This commit is contained in:
Hayt
2026-10-02 11:53:37 -04:00
parent 1c5f71cbb0
commit 53a9f04c46
2 changed files with 20 additions and 2 deletions

View File

@@ -107,7 +107,7 @@ class StickyDateHeader extends StatelessWidget {
vertical: Grid.half,
),
child: Semantics(
header: true,
headingLevel: 1,
child: Text(
label,
maxLines: 1,
@@ -206,7 +206,7 @@ class _IosStickyDateGlass extends HookWidget {
}, [nativeChannel.value, label, brightness]);
return Semantics(
header: true,
headingLevel: 1,
label: label,
child: ExcludeSemantics(
child: SizedBox(

View File

@@ -6,11 +6,23 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
void expectDateHeading(WidgetTester tester, String label) {
expect(
tester
.getSemantics(find.bySemanticsLabel(label))
.getSemanticsData()
.headingLevel,
1,
reason: 'Flutter 3.47 maps headings from headingLevel, not header.',
);
}
void main() {
testWidgets(
'keeps the native iOS date compact and stationary during push-off',
(tester) async {
debugDefaultTargetPlatformOverride = TargetPlatform.iOS;
final semantics = tester.ensureSemantics();
final state = ValueNotifier(
const StickyDateHeaderState(label: 'Yesterday'),
);
@@ -30,6 +42,8 @@ void main() {
),
);
expectDateHeading(tester, 'Yesterday');
var nativeView = tester.widget<UiKitView>(find.byType(UiKitView));
expect(nativeView.viewType, 'buzz/sticky_date_glass');
expect(nativeView.creationParams, <String, Object>{
@@ -144,6 +158,7 @@ void main() {
null,
);
state.dispose();
semantics.dispose();
debugDefaultTargetPlatformOverride = null;
}
},
@@ -153,6 +168,7 @@ void main() {
tester,
) async {
debugDefaultTargetPlatformOverride = TargetPlatform.android;
final semantics = tester.ensureSemantics();
final state = ValueNotifier(const StickyDateHeaderState(label: 'Today'));
try {
await tester.pumpWidget(
@@ -165,6 +181,7 @@ void main() {
expect(find.byType(UiKitView), findsNothing);
expect(find.byType(BackdropFilter), findsOneWidget);
expect(find.text('Today'), findsOneWidget);
expectDateHeading(tester, 'Today');
expect(
find.byKey(const ValueKey('sticky-date-header-clip')),
findsNothing,
@@ -205,6 +222,7 @@ void main() {
);
} finally {
state.dispose();
semantics.dispose();
debugDefaultTargetPlatformOverride = null;
}
});