@@ -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
@@ -692,18 +688,23 @@ final class GenericRole extends SemanticRole {
692688 return ;
693689 }
694690
695- // Assign one of two roles to the element: group or text.
691+ // Assign one of three roles to the element: group, heading, text.
696692 //
697693 // - "group" is used when the node has children, irrespective of whether the
698694 // node is marked as a header or not. This is because marking a group
699695 // as a "heading" will prevent the AT from reaching its children.
696+ // - "heading" is used when the framework explicitly marks the node as a
697+ // heading and the node does not have children.
700698 // - If a node has a label and no children, assume is a paragraph of text.
701699 // In HTML text has no ARIA role. It's just a DOM node with text inside
702700 // it. Previously, role="text" was used, but it was only supported by
703701 // Safari, and it was removed starting Safari 17.
704702 if (semanticsObject.hasChildren) {
705703 labelAndValue! .preferredRepresentation = LabelRepresentation .ariaLabel;
706704 setAriaRole ('group' );
705+ } else if (semanticsObject.hasFlag (ui.SemanticsFlag .isHeader)) {
706+ labelAndValue! .preferredRepresentation = LabelRepresentation .domText;
707+ setAriaRole ('heading' );
707708 } else {
708709 labelAndValue! .preferredRepresentation = LabelRepresentation .sizedSpan;
709710 removeAttribute ('role' );
@@ -1271,24 +1272,11 @@ class SemanticsObject {
12711272 bool get isTextField => hasFlag (ui.SemanticsFlag .isTextField);
12721273
12731274 /// Whether this object represents a heading element.
1274- ///
1275- /// Typically, a heading is a prominent piece of text that describes what the
1276- /// rest of the screen or page is about.
1277- ///
1278- /// Not to be confused with [isHeader] .
12791275 bool get isHeading => headingLevel != 0 ;
12801276
1281- /// Whether this object represents an interactive link .
1277+ /// Whether this object represents an editable text field .
12821278 bool get isLink => hasFlag (ui.SemanticsFlag .isLink);
12831279
1284- /// Whether this object represents a header.
1285- ///
1286- /// A header is a group of widgets that introduce the content of the screen
1287- /// or a page.
1288- ///
1289- /// Not to be confused with [isHeading] .
1290- bool get isHeader => hasFlag (ui.SemanticsFlag .isHeader);
1291-
12921280 /// Whether this object needs screen readers attention right away.
12931281 bool get isLiveRegion =>
12941282 hasFlag (ui.SemanticsFlag .isLiveRegion) &&
@@ -1702,8 +1690,6 @@ class SemanticsObject {
17021690 return SemanticRoleKind .route;
17031691 } else if (isLink) {
17041692 return SemanticRoleKind .link;
1705- } else if (isHeader) {
1706- return SemanticRoleKind .header;
17071693 } else {
17081694 return SemanticRoleKind .generic;
17091695 }
@@ -1721,7 +1707,6 @@ class SemanticsObject {
17211707 SemanticRoleKind .platformView => SemanticPlatformView (this ),
17221708 SemanticRoleKind .link => SemanticLink (this ),
17231709 SemanticRoleKind .heading => SemanticHeading (this ),
1724- SemanticRoleKind .header => SemanticHeader (this ),
17251710 SemanticRoleKind .generic => GenericRole (this ),
17261711 };
17271712 }
0 commit comments