@@ -21,7 +21,6 @@ import '../window.dart';
2121import 'accessibility.dart' ;
2222import 'checkable.dart' ;
2323import 'focusable.dart' ;
24- import 'header.dart' ;
2524import 'heading.dart' ;
2625import 'image.dart' ;
2726import 'incrementable.dart' ;
@@ -397,17 +396,14 @@ enum SemanticRoleKind {
397396 /// The node's role is to host a platform view.
398397 platformView,
399398
400- /// Contains a link.
401- link,
402-
403- /// Denotes a header.
404- header,
405-
406399 /// A role used when a more specific role cannot be assigend to
407400 /// a [SemanticsObject] .
408401 ///
409402 /// Provides a label or a value.
410403 generic,
404+
405+ /// Contains a link.
406+ link,
411407}
412408
413409/// Responsible for setting the `role` ARIA attribute, for attaching
@@ -681,18 +677,23 @@ final class GenericRole extends SemanticRole {
681677 return ;
682678 }
683679
684- // Assign one of two roles to the element: group or text.
680+ // Assign one of three roles to the element: group, heading, text.
685681 //
686682 // - "group" is used when the node has children, irrespective of whether the
687683 // node is marked as a header or not. This is because marking a group
688684 // as a "heading" will prevent the AT from reaching its children.
685+ // - "heading" is used when the framework explicitly marks the node as a
686+ // heading and the node does not have children.
689687 // - If a node has a label and no children, assume is a paragraph of text.
690688 // In HTML text has no ARIA role. It's just a DOM node with text inside
691689 // it. Previously, role="text" was used, but it was only supported by
692690 // Safari, and it was removed starting Safari 17.
693691 if (semanticsObject.hasChildren) {
694692 labelAndValue! .preferredRepresentation = LabelRepresentation .ariaLabel;
695693 setAriaRole ('group' );
694+ } else if (semanticsObject.hasFlag (ui.SemanticsFlag .isHeader)) {
695+ labelAndValue! .preferredRepresentation = LabelRepresentation .domText;
696+ setAriaRole ('heading' );
696697 } else {
697698 labelAndValue! .preferredRepresentation = LabelRepresentation .sizedSpan;
698699 removeAttribute ('role' );
@@ -1260,24 +1261,11 @@ class SemanticsObject {
12601261 bool get isTextField => hasFlag (ui.SemanticsFlag .isTextField);
12611262
12621263 /// Whether this object represents a heading element.
1263- ///
1264- /// Typically, a heading is a prominent piece of text that describes what the
1265- /// rest of the screen or page is about.
1266- ///
1267- /// Not to be confused with [isHeader] .
12681264 bool get isHeading => headingLevel != 0 ;
12691265
1270- /// Whether this object represents an interactive link .
1266+ /// Whether this object represents an editable text field .
12711267 bool get isLink => hasFlag (ui.SemanticsFlag .isLink);
12721268
1273- /// Whether this object represents a header.
1274- ///
1275- /// A header is a group of widgets that introduce the content of the screen
1276- /// or a page.
1277- ///
1278- /// Not to be confused with [isHeading] .
1279- bool get isHeader => hasFlag (ui.SemanticsFlag .isHeader);
1280-
12811269 /// Whether this object needs screen readers attention right away.
12821270 bool get isLiveRegion =>
12831271 hasFlag (ui.SemanticsFlag .isLiveRegion) &&
@@ -1691,8 +1679,6 @@ class SemanticsObject {
16911679 return SemanticRoleKind .route;
16921680 } else if (isLink) {
16931681 return SemanticRoleKind .link;
1694- } else if (isHeader) {
1695- return SemanticRoleKind .header;
16961682 } else {
16971683 return SemanticRoleKind .generic;
16981684 }
@@ -1710,7 +1696,6 @@ class SemanticsObject {
17101696 SemanticRoleKind .platformView => SemanticPlatformView (this ),
17111697 SemanticRoleKind .link => SemanticLink (this ),
17121698 SemanticRoleKind .heading => SemanticHeading (this ),
1713- SemanticRoleKind .header => SemanticHeader (this ),
17141699 SemanticRoleKind .generic => GenericRole (this ),
17151700 };
17161701 }
0 commit comments