Skip to content

Commit

Permalink
feat: Improve a11n by forcing a label on Nutri-Score / Eco-score / NO…
Browse files Browse the repository at this point in the history
…VA buttons (#4356)

* Improve a11n by forcing a label on Nutri-Score and Eco-score buttons

* Fix a typo

* Add more cases + NOVA

* Remove a print statement

* Improve a bit the score card

* Improve accessibility for KP title cards

* Update packages/smooth_app/lib/l10n/app_en.arb

Co-authored-by: Pierre Slamich <pierre.slamich@gmail.com>

* Update packages/smooth_app/lib/l10n/app_en.arb

Co-authored-by: Pierre Slamich <pierre.slamich@gmail.com>

---------

Co-authored-by: Pierre Slamich <pierre.slamich@gmail.com>
  • Loading branch information
g123k and teolemon committed Jul 29, 2023
1 parent b03cf26 commit fe7189c
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 57 deletions.
29 changes: 29 additions & 0 deletions packages/smooth_app/lib/cards/category_cards/svg_cache.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:smooth_app/cards/category_cards/abstract_cache.dart';
import 'package:smooth_app/cards/category_cards/asset_cache_helper.dart';
Expand Down Expand Up @@ -62,6 +63,7 @@ class SvgCache extends AbstractCache {
width: width,
height: height,
fit: BoxFit.contain,
semanticsLabel: getSemanticsLabel(context, iconUrl!),
placeholderBuilder: (BuildContext context) => displayAssetWhileWaiting
? SvgAsyncAsset(
AssetCacheHelper(
Expand All @@ -75,4 +77,31 @@ class SvgCache extends AbstractCache {
: getCircularProgressIndicator(),
);
}

static String? getSemanticsLabel(BuildContext context, String iconUrl) {
final AppLocalizations localizations = AppLocalizations.of(context);

return switch (Uri.parse(iconUrl).pathSegments.last) {
'ecoscore-a.svg' => localizations.ecoscore_a,
'ecoscore-b.svg' => localizations.ecoscore_b,
'ecoscore-c.svg' => localizations.ecoscore_c,
'ecoscore-d.svg' => localizations.ecoscore_d,
'ecoscore-e.svg' => localizations.ecoscore_e,
'ecoscore-unknown.svg' => localizations.ecoscore_unknown,
'ecoscore-not-applicable.svg' => localizations.ecoscore_not_applicable,
'nova-group-1.svg' => localizations.nova_group_1,
'nova-group-2.svg' => localizations.nova_group_2,
'nova-group-3.svg' => localizations.nova_group_3,
'nova-group-4.svg' => localizations.nova_group_4,
'nova-group-unknown.svg' => localizations.nova_group_unknown,
'nutriscore-a.svg' => localizations.nutriscore_a,
'nutriscore-b.svg' => localizations.nutriscore_b,
'nutriscore-c.svg' => localizations.nutriscore_c,
'nutriscore-d.svg' => localizations.nutriscore_d,
'nutriscore-e.svg' => localizations.nutriscore_e,
'nutriscore-unknown.svg' => localizations.nutriscore_unknown,
'nutriscore-not-applicable.svg' => localizations.ecoscore_not_applicable,
_ => null,
};
}
}
72 changes: 44 additions & 28 deletions packages/smooth_app/lib/cards/data_cards/score_card.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:smooth_app/cards/category_cards/svg_cache.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/generic_lib/svg_icon_chip.dart';
import 'package:smooth_app/helpers/score_card_helper.dart';
Expand Down Expand Up @@ -89,39 +90,54 @@ class ScoreCard extends StatelessWidget {
final SvgIconChip? iconChip =
iconUrl == null ? null : SvgIconChip(iconUrl!, height: iconHeight);

return Padding(
padding: margin ?? const EdgeInsets.symmetric(vertical: SMALL_SPACE),
child: Ink(
padding: const EdgeInsets.all(SMALL_SPACE),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: ANGULAR_BORDER_RADIUS,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
if (iconChip != null)
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsetsDirectional.only(end: SMALL_SPACE),
child: iconChip,
return Semantics(
value: _generateSemanticsValue(context),
excludeSemantics: true,
button: true,
child: Padding(
padding: margin ?? const EdgeInsets.symmetric(vertical: SMALL_SPACE),
child: Ink(
padding: const EdgeInsets.all(SMALL_SPACE),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: ANGULAR_BORDER_RADIUS,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
if (iconChip != null)
Expanded(
flex: 1,
child: Padding(
padding: const EdgeInsetsDirectional.only(end: SMALL_SPACE),
child: iconChip,
),
),
),
Expanded(
flex: 3,
child: Center(
child: Text(
description,
style: themeData.textTheme.headlineMedium!
.apply(color: textColor),
Expanded(
flex: 3,
child: Center(
child: Text(
description,
style: themeData.textTheme.headlineMedium!
.apply(color: textColor),
),
),
),
),
if (isClickable) Icon(ConstantIcons.instance.getForwardIcon()),
],
if (isClickable) Icon(ConstantIcons.instance.getForwardIcon()),
],
),
),
),
);
}

String _generateSemanticsValue(BuildContext context) {
final String? iconLabel = SvgCache.getSemanticsLabel(context, iconUrl!);

if (iconLabel == null) {
return description;
} else {
return '$iconLabel: $description';
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:openfoodfacts/openfoodfacts.dart';
import 'package:provider/provider.dart';
import 'package:smooth_app/cards/category_cards/abstract_cache.dart';
import 'package:smooth_app/cards/category_cards/svg_cache.dart';
import 'package:smooth_app/data_models/user_preferences.dart';
import 'package:smooth_app/generic_lib/design_constants.dart';
import 'package:smooth_app/helpers/extension_on_text_helper.dart';
Expand Down Expand Up @@ -74,39 +75,44 @@ class KnowledgePanelTitleCard extends StatelessWidget {
top: VERY_SMALL_SPACE,
bottom: VERY_SMALL_SPACE,
),
child: Row(
children: <Widget>[
...iconWidget,
Expanded(
flex: IconWidgetSizer.getRemainingWidgetFlex(),
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Wrap(
direction: Axis.vertical,
children: <Widget>[
SizedBox(
width: constraints.maxWidth,
child: Text(
knowledgePanelTitleElement.title,
style: TextStyle(color: colorFromEvaluation),
),
),
if (knowledgePanelTitleElement.subtitle != null)
child: Semantics(
value: _generateSemanticsValue(context),
button: isClickable,
excludeSemantics: true,
child: Row(
children: <Widget>[
...iconWidget,
Expanded(
flex: IconWidgetSizer.getRemainingWidgetFlex(),
child: LayoutBuilder(
builder: (BuildContext context, BoxConstraints constraints) {
return Wrap(
direction: Axis.vertical,
children: <Widget>[
SizedBox(
width: constraints.maxWidth,
child: Text(
knowledgePanelTitleElement.subtitle!,
style:
WellSpacedTextHelper.TEXT_STYLE_WITH_WELL_SPACED,
).selectable(isSelectable: !isClickable),
knowledgePanelTitleElement.title,
style: TextStyle(color: colorFromEvaluation),
),
),
],
);
},
if (knowledgePanelTitleElement.subtitle != null)
SizedBox(
width: constraints.maxWidth,
child: Text(
knowledgePanelTitleElement.subtitle!,
style: WellSpacedTextHelper
.TEXT_STYLE_WITH_WELL_SPACED,
).selectable(isSelectable: !isClickable),
),
],
);
},
),
),
),
if (isClickable) Icon(ConstantIcons.instance.getForwardIcon()),
],
if (isClickable) Icon(ConstantIcons.instance.getForwardIcon()),
],
),
),
);
}
Expand Down Expand Up @@ -155,4 +161,25 @@ class KnowledgePanelTitleCard extends StatelessWidget {
return null;
}
}

String _generateSemanticsValue(BuildContext context) {
final StringBuffer buffer = StringBuffer();

if (knowledgePanelTitleElement.iconUrl != null) {
final String? label = SvgCache.getSemanticsLabel(
context,
knowledgePanelTitleElement.iconUrl!,
);
if (label != null) {
buffer.write('$label: ');
}
}

buffer.write(knowledgePanelTitleElement.title);
if (knowledgePanelTitleElement.subtitle != null) {
buffer.write('\n${knowledgePanelTitleElement.subtitle}');
}

return buffer.toString();
}
}
21 changes: 20 additions & 1 deletion packages/smooth_app/lib/l10n/app_en.arb
Original file line number Diff line number Diff line change
Expand Up @@ -2373,5 +2373,24 @@
"product_list_create_tooltip": "Create a new list",
"@product_list_create_tooltip": {
"description": "Button description to create a new list (long sentence)"
}
},
"nutriscore_a": "Nutri-Score A",
"nutriscore_b": "Nutri-Score B",
"nutriscore_c": "Nutri-Score C",
"nutriscore_d": "Nutri-Score D",
"nutriscore_e": "Nutri-Score E",
"nutriscore_unknown": "Unknown Nutri-Score",
"nutriscore_not_applicable": "Nutri-Score is not applicable",
"ecoscore_a": "Eco-Score A",
"ecoscore_b": "Eco-Score B",
"ecoscore_c": "Eco-Score C",
"ecoscore_d": "Eco-Score D",
"ecoscore_e": "Eco-Score E",
"ecoscore_unknown": "Unknown Eco-Score",
"ecoscore_not_applicable": "Eco-Score is not applicable",
"nova_group_1": "NOVA Group 1",
"nova_group_2": "NOVA Group 2",
"nova_group_3": "NOVA Group 3",
"nova_group_4": "NOVA Group 4",
"nova_group_unknown": "Unknown NOVA Group"
}

0 comments on commit fe7189c

Please sign in to comment.