11import 'dart:async' ;
2- import 'dart:ui' ;
32
43import 'package:flutter/material.dart' ;
4+ import 'package:flutter/rendering.dart' ;
55
66import '../generated/l10n/zulip_localizations.dart' ;
77import '../model/narrow.dart' ;
@@ -48,6 +48,9 @@ class HomePage extends StatefulWidget {
4848 HomePage .buildRoute (accountId: accountId)));
4949 }
5050
51+ static String contentSemanticsIdentifier = 'home-page-content' ;
52+ static String titleSemanticsIdentifier = 'home-page-title' ;
53+
5154 @override
5255 State <HomePage > createState () => _HomePageState ();
5356}
@@ -96,15 +99,20 @@ class _HomePageState extends State<HomePage> {
9699
97100 return Scaffold (
98101 appBar: ZulipAppBar (titleSpacing: 16 ,
99- title: Text (_currentTabTitle)),
100- body: Stack (
101- children: [
102- for (final (tab, body) in pageBodies)
103- // TODO(#535): Decide if we find it helpful to use something like
104- // [SemanticsProperties.namesRoute] to structure this UI better
105- // for screen-reader software.
106- Offstage (offstage: tab != _tab.value, child: body),
107- ]),
102+ title: Semantics (
103+ identifier: HomePage .titleSemanticsIdentifier,
104+ namesRoute: true ,
105+ child: Text (_currentTabTitle))),
106+ body: Semantics (
107+ role: SemanticsRole .tabPanel,
108+ identifier: HomePage .contentSemanticsIdentifier,
109+ container: true ,
110+ explicitChildNodes: true ,
111+ child: Stack (
112+ children: [
113+ for (final (tab, body) in pageBodies)
114+ Offstage (offstage: tab != _tab.value, child: body),
115+ ])),
108116 bottomNavigationBar: _BottomNavBar (tabNotifier: _tab));
109117 }
110118}
@@ -156,7 +164,7 @@ class _BottomNavBar extends StatelessWidget {
156164 onPressed: () => _showMainMenu (context, tabNotifier: tabNotifier)),
157165 ];
158166
159- return DecoratedBox (
167+ Widget result = DecoratedBox (
160168 decoration: BoxDecoration (
161169 border: Border (top: BorderSide (color: designVariables.borderBar)),
162170 color: designVariables.bgBotBar),
@@ -172,6 +180,14 @@ class _BottomNavBar extends StatelessWidget {
172180 for (final navigationBarButton in navigationBarButtons)
173181 Expanded (child: navigationBarButton),
174182 ])))));
183+
184+ result = Semantics (
185+ container: true ,
186+ explicitChildNodes: true ,
187+ role: SemanticsRole .tabBar,
188+ child: result);
189+
190+ return result;
175191 }
176192}
177193
@@ -271,7 +287,7 @@ class _NavigationBarButton extends StatelessWidget {
271287 final designVariables = DesignVariables .of (context);
272288 final color = selected ? designVariables.iconSelected : designVariables.icon;
273289
274- return AnimatedScaleOnTap (
290+ Widget result = AnimatedScaleOnTap (
275291 scaleEnd: 0.875 ,
276292 duration: const Duration (milliseconds: 100 ),
277293 child: Material (
@@ -287,21 +303,31 @@ class _NavigationBarButton extends StatelessWidget {
287303 // text wrap before getting too close to the button's edge, which is
288304 // visible on tap-down.)
289305 padding: const EdgeInsets .fromLTRB (3 , 6 , 3 , 3 ),
290- child: Semantics (
291- role: SemanticsRole .tab,
292- selected: selected,
293- child: Column (
294- spacing: 3 ,
295- mainAxisSize: MainAxisSize .min,
296- children: [
297- Icon (icon, size: 24 , color: color),
298- Flexible (
299- child: Text (
300- label,
301- style: TextStyle (fontSize: 12 , color: color, height: 12 / 12 ),
302- textAlign: TextAlign .center,
303- textScaler: MediaQuery .textScalerOf (context).clamp (maxScaleFactor: 1.5 ))),
304- ]))))));
306+ child: Column (
307+ spacing: 3 ,
308+ mainAxisSize: MainAxisSize .min,
309+ children: [
310+ Icon (icon, size: 24 , color: color),
311+ Flexible (
312+ child: Text (
313+ label,
314+ style: TextStyle (fontSize: 12 , color: color, height: 12 / 12 ),
315+ textAlign: TextAlign .center,
316+ textScaler: MediaQuery .textScalerOf (context).clamp (maxScaleFactor: 1.5 ))),
317+ ])))));
318+
319+ result = MergeSemantics (
320+ child: Semantics (
321+ role: SemanticsRole .tab,
322+ controlsNodes: {
323+ HomePage .contentSemanticsIdentifier,
324+ HomePage .titleSemanticsIdentifier,
325+ },
326+ selected: selected,
327+ onTap: onPressed,
328+ child: result));
329+
330+ return result;
305331 }
306332}
307333
0 commit comments