2
0
mirror of https://github.com/fork-maintainers/iceraven-browser synced 2024-11-13 07:10:28 +00:00

Bug 1857537 - [a11y] Add heading structure to Review Checker

Review Checker BETA couldn't be navigated to by using TalkBack headings
shortcuts because it wasn't recognized as an heading. And when it was
focused it wasn't announced as a heading.
The same problems were found at the other sections too.

As solution, the semantics properties are used.
AdjustedProductRatingCard was declared as heading only and it will not
be announced by TalkBack as "Heading" because it makes harder to
understand the information, but it can be navigated as a heading.
This commit is contained in:
RebecaTudor 2023-11-08 18:12:41 +02:00 committed by mergify[bot]
parent 00b370107a
commit 6a5c26871e
7 changed files with 94 additions and 6 deletions

View File

@ -34,6 +34,8 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.layout.layout
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.PreviewParameter
@ -51,6 +53,7 @@ import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductR
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.AnalysisStatus
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.OptedIn.ProductReviewState.AnalysisPresent.HighlightsInfo
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.RecommendedProductState
import org.mozilla.fenix.shopping.ui.ext.headingResource
import org.mozilla.fenix.theme.FirefoxTheme
private val combinedParentHorizontalPadding = 32.dp
@ -203,7 +206,7 @@ private fun ReviewGradeCard(
reviewGrade: ReviewQualityCheckState.Grade,
modifier: Modifier = Modifier,
) {
ReviewQualityCheckCard(modifier = modifier.semantics(mergeDescendants = true) {}) {
ReviewQualityCheckCard(modifier = modifier.semantics(mergeDescendants = true) { heading() }) {
Text(
text = stringResource(R.string.review_quality_check_grade_title),
color = FirefoxTheme.colors.textPrimary,
@ -222,7 +225,7 @@ private fun AdjustedProductRatingCard(
rating: Float,
modifier: Modifier = Modifier,
) {
ReviewQualityCheckCard(modifier = modifier.semantics(mergeDescendants = true) {}) {
ReviewQualityCheckCard(modifier = modifier.semantics(mergeDescendants = true) { heading() }) {
FlowRow(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier.fillMaxWidth(),
@ -267,11 +270,16 @@ private fun HighlightsCard(
highlightsInfo.highlightsForCompactMode
}
}
val titleContentDescription = headingResource(id = R.string.review_quality_check_highlights_title)
Text(
text = stringResource(R.string.review_quality_check_highlights_title),
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.headline8,
modifier = Modifier.semantics {
heading()
contentDescription = titleContentDescription
},
)
Spacer(modifier = Modifier.height(16.dp))
@ -437,6 +445,7 @@ private fun ProductRecommendation(
ReviewQualityCheckCard(
modifier = Modifier
.fillMaxWidth()
.semantics { heading() }
.clickable {
onClick(product.aid, product.productUrl)
}

View File

@ -30,10 +30,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.shopping.ui.ext.headingResource
import org.mozilla.fenix.theme.FirefoxTheme
private val cardShape = RoundedCornerShape(8.dp)
@ -61,10 +65,13 @@ fun ReviewQualityCheckExpandableCard(
modifier = modifier,
contentPadding = PaddingValues(0.dp),
) {
val titleContentDescription = headingResource(title)
Row(
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
.semantics { heading() }
.clickable(
onClickLabel = if (isExpanded) {
stringResource(R.string.a11y_action_label_collapse)
@ -80,6 +87,9 @@ fun ReviewQualityCheckExpandableCard(
text = title,
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.headline8,
modifier = Modifier.semantics {
contentDescription = titleContentDescription
},
)
val chevronDrawable = if (isExpanded) {

View File

@ -16,6 +16,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
@ -29,6 +32,7 @@ import org.mozilla.fenix.compose.button.PrimaryButton
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState
import org.mozilla.fenix.shopping.store.ReviewQualityCheckState.ProductVendor
import org.mozilla.fenix.shopping.ui.ext.displayName
import org.mozilla.fenix.shopping.ui.ext.headingResource
import org.mozilla.fenix.theme.FirefoxTheme
const val PLACEHOLDER_URL = "www.fakespot.com"
@ -60,12 +64,18 @@ fun ReviewQualityCheckContextualOnboarding(
stringResource(id = R.string.review_quality_check_contextual_onboarding_privacy_policy_2)
val termsOfUseText =
stringResource(id = R.string.review_quality_check_contextual_onboarding_terms_use_2)
val titleContentDescription =
headingResource(R.string.review_quality_check_contextual_onboarding_title)
ReviewQualityCheckCard(modifier = Modifier.fillMaxWidth()) {
Text(
text = stringResource(R.string.review_quality_check_contextual_onboarding_title),
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.headline5,
modifier = Modifier.semantics {
heading()
contentDescription = titleContentDescription
},
)
Spacer(modifier = Modifier.height(16.dp))

View File

@ -22,6 +22,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@ -31,6 +34,7 @@ import org.mozilla.fenix.compose.LinkText
import org.mozilla.fenix.compose.LinkTextState
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.compose.button.PrimaryButton
import org.mozilla.fenix.shopping.ui.ext.headingResource
import org.mozilla.fenix.theme.FirefoxTheme
/**
@ -61,6 +65,8 @@ fun ReviewQualityCheckInfoCard(
),
elevation = 0.dp,
) {
val titleContentDescription = headingResource(title)
Row {
when (type) {
ReviewQualityCheckInfoType.Warning -> {
@ -90,6 +96,10 @@ fun ReviewQualityCheckInfoCard(
text = title,
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.headline8,
modifier = Modifier.semantics {
heading()
contentDescription = titleContentDescription
},
)
description?.let {

View File

@ -23,12 +23,17 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.heading
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.semantics.traversalIndex
import androidx.compose.ui.unit.dp
import org.mozilla.fenix.R
import org.mozilla.fenix.compose.BetaLabel
import org.mozilla.fenix.compose.BottomSheetHandle
import org.mozilla.fenix.compose.annotation.LightDarkPreview
import org.mozilla.fenix.shopping.ui.ext.headingResource
import org.mozilla.fenix.theme.FirefoxTheme
private val bottomSheetShape = RoundedCornerShape(topStart = 16.dp, topEnd = 16.dp)
@ -69,7 +74,8 @@ fun ReviewQualityCheckScaffold(
contentDescription = stringResource(R.string.review_quality_check_close_handle_content_description),
modifier = Modifier
.fillMaxWidth(BOTTOM_SHEET_HANDLE_WIDTH_PERCENT)
.align(Alignment.CenterHorizontally),
.align(Alignment.CenterHorizontally)
.semantics { traversalIndex = -1f },
)
Spacer(modifier = Modifier.height(16.dp))
@ -87,19 +93,27 @@ fun ReviewQualityCheckScaffold(
@Composable
private fun Header() {
val reviewCheckerFeatureName = stringResource(R.string.review_quality_check_feature_name_2)
val betaText = stringResource(R.string.review_quality_check_beta_flag)
val titleContentDescription = headingResource("$reviewCheckerFeatureName, $betaText")
Row(
modifier = Modifier.semantics(mergeDescendants = true) {},
modifier = Modifier.semantics(mergeDescendants = true) {
heading()
contentDescription = titleContentDescription
},
verticalAlignment = Alignment.CenterVertically,
) {
Text(
text = stringResource(R.string.review_quality_check_feature_name_2),
text = reviewCheckerFeatureName,
color = FirefoxTheme.colors.textPrimary,
style = FirefoxTheme.typography.headline6,
modifier = Modifier.clearAndSetSemantics {},
)
Spacer(modifier = Modifier.width(8.dp))
BetaLabel()
BetaLabel(modifier = Modifier.clearAndSetSemantics {})
}
}

View File

@ -0,0 +1,33 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.fenix.shopping.ui.ext
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.runtime.ReadOnlyComposable
import androidx.compose.ui.res.stringResource
import org.mozilla.fenix.R
/**
* Returns a string resource with the heading a11y suffix.
*
* @param id The string resource id.
*/
@Composable
@ReadOnlyComposable
fun headingResource(@StringRes id: Int): String {
return headingResource(text = stringResource(id = id))
}
/**
* Returns a string with the heading a11y suffix.
*
* @param text The string.
*/
@Composable
@ReadOnlyComposable
fun headingResource(text: String): String {
return stringResource(id = R.string.a11y_heading, text)
}

View File

@ -2287,4 +2287,6 @@
<string name="a11y_action_label_read_article">read the article</string>
<!-- Action label for links to the Firefox Pocket website. Talkback will append this to say "Double tap to open link to learn more". -->
<string name="a11y_action_label_pocket_learn_more">open link to learn more</string>
<!-- Talkback will announce the heading element as "Heading". -->
<string name="a11y_heading">%s, Heading</string>
</resources>