mirror of
https://github.com/bitwarden/android.git
synced 2026-11-10 01:15:13 -06:00
PM-44005: bug: Add focus state to hypertext links (#7455)
This commit is contained in:
@@ -5,6 +5,7 @@ import androidx.compose.runtime.ReadOnlyComposable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import com.bitwarden.ui.platform.theme.BitwardenTheme
|
||||
|
||||
/**
|
||||
@@ -67,3 +68,17 @@ val bitwardenClickableTextSpanStyle: SpanStyle
|
||||
color = BitwardenTheme.colorScheme.text.interaction,
|
||||
textStyle = BitwardenTheme.typography.labelMedium,
|
||||
)
|
||||
|
||||
/**
|
||||
* A [SpanStyle] representing "clickable" text in the focused state using the background alert
|
||||
* color and the underlined label medium font.
|
||||
*/
|
||||
val bitwardenClickableTextFocusSpanStyle: SpanStyle
|
||||
@Composable
|
||||
@ReadOnlyComposable
|
||||
get() = spanStyleOf(
|
||||
color = BitwardenTheme.colorScheme.background.alert,
|
||||
textStyle = BitwardenTheme.typography.labelMedium.copy(
|
||||
textDecoration = TextDecoration.Underline,
|
||||
),
|
||||
)
|
||||
|
||||
@@ -26,6 +26,8 @@ import androidx.core.text.getSpans
|
||||
* with the "emphasis" annotation.
|
||||
* @param linkHighlightStyle Style to apply to part of the resource that has been annotated with
|
||||
* the "link" annotation.
|
||||
* @param linkHighlightFocusStyle Style to apply to part of the resource that has been annotated
|
||||
* with the "link" annotation and is currently focused.
|
||||
* @param resources The resources used to access the strings.
|
||||
* @param onAnnotationClick Callback to invoke when a link annotation is clicked. Will pass back
|
||||
* the value of the annotation as a string to allow for delineation if there are multiple callbacks
|
||||
@@ -52,6 +54,7 @@ fun @receiver:StringRes Int.toAnnotatedString(
|
||||
style: SpanStyle = bitwardenDefaultSpanStyle,
|
||||
emphasisHighlightStyle: SpanStyle = bitwardenBoldSpanStyle,
|
||||
linkHighlightStyle: SpanStyle = bitwardenClickableTextSpanStyle,
|
||||
linkHighlightFocusStyle: SpanStyle = bitwardenClickableTextFocusSpanStyle,
|
||||
resources: Resources = LocalResources.current,
|
||||
onAnnotationClick: ((annotationKey: String) -> Unit)? = null,
|
||||
): AnnotatedString = remember(
|
||||
@@ -60,6 +63,7 @@ fun @receiver:StringRes Int.toAnnotatedString(
|
||||
style,
|
||||
emphasisHighlightStyle,
|
||||
linkHighlightStyle,
|
||||
linkHighlightFocusStyle,
|
||||
onAnnotationClick,
|
||||
) {
|
||||
val spannedString = try {
|
||||
@@ -73,6 +77,7 @@ fun @receiver:StringRes Int.toAnnotatedString(
|
||||
style = style,
|
||||
emphasisHighlightStyle = emphasisHighlightStyle,
|
||||
linkHighlightStyle = linkHighlightStyle,
|
||||
linkHighlightFocusStyle = linkHighlightFocusStyle,
|
||||
onAnnotationClick = onAnnotationClick,
|
||||
)
|
||||
}
|
||||
@@ -90,6 +95,8 @@ fun @receiver:StringRes Int.toAnnotatedString(
|
||||
* with the "emphasis" annotation.
|
||||
* @param linkHighlightStyle Style to apply to part of the resource that has been annotated with
|
||||
* the "link" annotation.
|
||||
* @param linkHighlightFocusStyle Style to apply to part of the resource that has been annotated
|
||||
* with the "link" annotation and is currently focused.
|
||||
* @param resources The resources used to access the strings.
|
||||
* @param onAnnotationClick Callback to invoke when a link annotation is clicked. Will pass back
|
||||
* the value of the annotation as a string to allow for delineation if there are multiple callbacks
|
||||
@@ -105,6 +112,7 @@ fun @receiver:PluralsRes Int.toAnnotatedPluralsString(
|
||||
style: SpanStyle = bitwardenDefaultSpanStyle,
|
||||
emphasisHighlightStyle: SpanStyle = bitwardenBoldSpanStyle,
|
||||
linkHighlightStyle: SpanStyle = bitwardenClickableTextSpanStyle,
|
||||
linkHighlightFocusStyle: SpanStyle = bitwardenClickableTextFocusSpanStyle,
|
||||
resources: Resources = LocalResources.current,
|
||||
onAnnotationClick: ((annotationKey: String) -> Unit)? = null,
|
||||
): AnnotatedString = remember(
|
||||
@@ -114,6 +122,7 @@ fun @receiver:PluralsRes Int.toAnnotatedPluralsString(
|
||||
style,
|
||||
emphasisHighlightStyle,
|
||||
linkHighlightStyle,
|
||||
linkHighlightFocusStyle,
|
||||
onAnnotationClick,
|
||||
) {
|
||||
val spannedString = try {
|
||||
@@ -129,6 +138,7 @@ fun @receiver:PluralsRes Int.toAnnotatedPluralsString(
|
||||
style = style,
|
||||
emphasisHighlightStyle = emphasisHighlightStyle,
|
||||
linkHighlightStyle = linkHighlightStyle,
|
||||
linkHighlightFocusStyle = linkHighlightFocusStyle,
|
||||
onAnnotationClick = onAnnotationClick,
|
||||
)
|
||||
}
|
||||
@@ -138,11 +148,13 @@ fun @receiver:PluralsRes Int.toAnnotatedPluralsString(
|
||||
* `arg` annotations with the corresponding [args] entry then applies emphasis and link styles
|
||||
* to the resulting [AnnotatedString].
|
||||
*/
|
||||
@Suppress("LongParameterList")
|
||||
private fun SpannedString.buildAnnotatedString(
|
||||
args: Array<out CharSequence>,
|
||||
style: SpanStyle,
|
||||
emphasisHighlightStyle: SpanStyle,
|
||||
linkHighlightStyle: SpanStyle,
|
||||
linkHighlightFocusStyle: SpanStyle,
|
||||
onAnnotationClick: ((annotationKey: String) -> Unit)?,
|
||||
): AnnotatedString {
|
||||
// The spannableBuilder is used to help parse through the annotations in the string resource.
|
||||
@@ -181,6 +193,8 @@ private fun SpannedString.buildAnnotatedString(
|
||||
tag = annotation.value.orEmpty(),
|
||||
styles = TextLinkStyles(
|
||||
style = linkHighlightStyle,
|
||||
focusedStyle = linkHighlightFocusStyle,
|
||||
hoveredStyle = linkHighlightFocusStyle,
|
||||
),
|
||||
) {
|
||||
onAnnotationClick?.invoke(annotation.value.orEmpty())
|
||||
|
||||
+9
-6
@@ -1,6 +1,7 @@
|
||||
package com.bitwarden.ui.platform.components.text
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.focusable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
@@ -71,6 +72,7 @@ fun BitwardenClickableText(
|
||||
modifier = modifier
|
||||
.defaultMinSize(minHeight = 48.dp)
|
||||
.clip(shape = shape)
|
||||
.focusable(enabled = isEnabled)
|
||||
.clickable(
|
||||
indication = ripple(color = BitwardenTheme.colorScheme.background.pressed),
|
||||
interactionSource = interactionSource,
|
||||
@@ -88,15 +90,16 @@ fun BitwardenClickableText(
|
||||
contentDescription = formattedAccessibilityString
|
||||
},
|
||||
) {
|
||||
val foregroundColor = if (isEnabled) {
|
||||
color
|
||||
} else {
|
||||
BitwardenTheme.colorScheme.filledButton.foregroundDisabled
|
||||
}
|
||||
leadingIcon?.let {
|
||||
Icon(
|
||||
painter = leadingIcon,
|
||||
contentDescription = null,
|
||||
tint = if (isEnabled) {
|
||||
color
|
||||
} else {
|
||||
BitwardenTheme.colorScheme.filledButton.foregroundDisabled
|
||||
},
|
||||
tint = foregroundColor,
|
||||
modifier = Modifier.size(size = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(width = 8.dp))
|
||||
@@ -104,7 +107,7 @@ fun BitwardenClickableText(
|
||||
Text(
|
||||
text = label,
|
||||
textAlign = TextAlign.Start,
|
||||
color = color,
|
||||
color = foregroundColor,
|
||||
style = style,
|
||||
modifier = Modifier.semantics { hideFromAccessibility() },
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user