Merge pull request #7182 from element-hq/feature/bma/focussedButton
[A11y] Improve rendering on focused UI items
This commit is contained in:
@@ -16,7 +16,11 @@ import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.LocalRippleConfiguration
|
||||
import androidx.compose.material3.LocalRippleThemeConfiguration
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.RippleConfiguration
|
||||
import androidx.compose.material3.RippleThemeConfiguration
|
||||
import androidx.compose.material3.Typography
|
||||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.material3.dynamicLightColorScheme
|
||||
@@ -28,6 +32,7 @@ import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.compound.tokens.compoundTypography
|
||||
import io.element.android.compound.tokens.generated.SemanticColors
|
||||
import io.element.android.compound.tokens.generated.TypographyTokens
|
||||
@@ -159,6 +164,26 @@ fun ElementTheme(
|
||||
CompositionLocalProvider(
|
||||
LocalCompoundColors provides currentCompoundColor,
|
||||
LocalContentColor provides colorScheme.onSurface,
|
||||
// Configure the keyboard focus style: Draw a blue inset ring around the focused component.
|
||||
// Ref: https://www.figma.com/design/hlbsmSekQorGRN1t2R9JEy/Accessibility-checks?node-id=271-42066
|
||||
// By default, a semi-transparent black overlay is used
|
||||
LocalRippleThemeConfiguration provides RippleThemeConfiguration(
|
||||
RippleThemeConfiguration.Focus.InsetRing(
|
||||
outerStrokeInset = 0.dp,
|
||||
outerStrokeWidth = 2.dp,
|
||||
innerStrokeInset = 0.dp,
|
||||
innerStrokeWidth = 0.dp,
|
||||
)
|
||||
),
|
||||
// Configure the keyboard focus color.
|
||||
// By default, ColorScheme.secondary is used
|
||||
LocalRippleConfiguration provides
|
||||
RippleConfiguration(
|
||||
focus = RippleConfiguration.Focus.InsetRing(
|
||||
outerStrokeColor = ElementTheme.colors.borderFocused,
|
||||
innerStrokeColor = Color.Transparent,
|
||||
)
|
||||
),
|
||||
) {
|
||||
MaterialTheme(
|
||||
colorScheme = colorScheme,
|
||||
|
||||
+65
-48
@@ -28,13 +28,15 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.ButtonColors
|
||||
import androidx.compose.material3.ButtonDefaults
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.LocalRippleThemeConfiguration
|
||||
import androidx.compose.material3.RippleThemeConfiguration
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.graphics.isSpecified
|
||||
import androidx.compose.ui.graphics.painter.Painter
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
@@ -181,11 +183,8 @@ private fun ButtonInternal(
|
||||
ButtonSize.LargeLowPadding -> PaddingValues(horizontal = lowHorizontalPaddingValue, vertical = 13.dp)
|
||||
}
|
||||
|
||||
val shape = when (style) {
|
||||
ButtonStyle.Filled,
|
||||
ButtonStyle.Outlined -> RoundedCornerShape(percent = 50)
|
||||
ButtonStyle.Text -> RectangleShape
|
||||
}
|
||||
// Apply the same shape to all buttons, so that the focus ring is consistent across styles.
|
||||
val shape = RoundedCornerShape(percent = 50)
|
||||
|
||||
val border = when (style) {
|
||||
ButtonStyle.Filled -> null
|
||||
@@ -202,48 +201,66 @@ private fun ButtonInternal(
|
||||
ButtonStyle.Text -> null
|
||||
}
|
||||
|
||||
androidx.compose.material3.Button(
|
||||
onClick = {
|
||||
if (!showProgress) {
|
||||
onClick()
|
||||
}
|
||||
},
|
||||
modifier = modifier.heightIn(min = minHeight),
|
||||
enabled = enabled,
|
||||
shape = shape,
|
||||
colors = colors,
|
||||
elevation = null,
|
||||
border = border,
|
||||
contentPadding = contentPadding,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
// Reduce outerStrokeInset on Filled buttons so that it's displayed around the button
|
||||
val outerStrokeInset = when (style) {
|
||||
ButtonStyle.Filled -> (-4).dp
|
||||
ButtonStyle.Outlined,
|
||||
ButtonStyle.Text -> 0.dp
|
||||
}
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalRippleThemeConfiguration provides RippleThemeConfiguration(
|
||||
RippleThemeConfiguration.Focus.InsetRing(
|
||||
outerStrokeInset = outerStrokeInset,
|
||||
outerStrokeWidth = 2.dp,
|
||||
innerStrokeInset = 0.dp,
|
||||
innerStrokeWidth = 0.dp,
|
||||
)
|
||||
),
|
||||
) {
|
||||
when {
|
||||
showProgress -> {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.progressSemantics()
|
||||
.size(20.dp),
|
||||
color = LocalContentColor.current,
|
||||
strokeWidth = 2.dp,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
leadingIcon != null -> {
|
||||
Icon(
|
||||
painter = leadingIcon.getPainter(),
|
||||
contentDescription = null,
|
||||
tint = LocalContentColor.current,
|
||||
modifier = Modifier.size(20.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
androidx.compose.material3.Button(
|
||||
onClick = {
|
||||
if (!showProgress) {
|
||||
onClick()
|
||||
}
|
||||
},
|
||||
modifier = modifier.heightIn(min = minHeight),
|
||||
enabled = enabled,
|
||||
shape = shape,
|
||||
colors = colors,
|
||||
elevation = null,
|
||||
border = border,
|
||||
contentPadding = contentPadding,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
) {
|
||||
when {
|
||||
showProgress -> {
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier
|
||||
.progressSemantics()
|
||||
.size(20.dp),
|
||||
color = LocalContentColor.current,
|
||||
strokeWidth = 2.dp,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
leadingIcon != null -> {
|
||||
Icon(
|
||||
painter = leadingIcon.getPainter(),
|
||||
contentDescription = null,
|
||||
tint = LocalContentColor.current,
|
||||
modifier = Modifier.size(20.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
}
|
||||
}
|
||||
Text(
|
||||
text = text,
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
Text(
|
||||
text = text,
|
||||
style = ElementTheme.typography.fontBodyLgMedium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -294,7 +311,7 @@ internal enum class ButtonStyle {
|
||||
|
||||
@Composable
|
||||
fun getColors(destructive: Boolean): ButtonColors = when (this) {
|
||||
Filled -> ButtonDefaults.buttonColors(
|
||||
Filled -> ButtonDefaults.filledTonalButtonColors(
|
||||
containerColor = getPrimaryColor(destructive),
|
||||
contentColor = ElementTheme.materialColors.onPrimary,
|
||||
disabledContainerColor = if (destructive) {
|
||||
@@ -304,13 +321,13 @@ internal enum class ButtonStyle {
|
||||
},
|
||||
disabledContentColor = ElementTheme.colors.textOnSolidPrimary
|
||||
)
|
||||
Outlined -> ButtonDefaults.buttonColors(
|
||||
Outlined -> ButtonDefaults.outlinedButtonColors(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor = getPrimaryColor(destructive),
|
||||
disabledContainerColor = Color.Transparent,
|
||||
disabledContentColor = getDisabledContentColor(destructive),
|
||||
)
|
||||
Text -> ButtonDefaults.buttonColors(
|
||||
Text -> ButtonDefaults.textButtonColors(
|
||||
containerColor = Color.Transparent,
|
||||
contentColor = if (destructive) {
|
||||
ElementTheme.colors.textCriticalPrimary
|
||||
|
||||
+1
-1
@@ -139,7 +139,7 @@ private fun SearchFieldContainer(
|
||||
border = BorderStroke(
|
||||
width = 1.dp,
|
||||
color = if (isFocused) {
|
||||
ElementTheme.colors.borderInteractiveHovered
|
||||
ElementTheme.colors.borderFocused
|
||||
} else {
|
||||
ElementTheme.colors.borderInteractiveSecondary
|
||||
}
|
||||
|
||||
+1
-1
@@ -293,8 +293,8 @@ private fun TextFieldContainer(
|
||||
width = if (isFocused) 2.dp else 1.dp,
|
||||
color = when {
|
||||
!enabled -> ElementTheme.colors.borderDisabled
|
||||
isFocused -> ElementTheme.colors.borderFocused
|
||||
isError -> ElementTheme.colors.borderCriticalPrimary
|
||||
isFocused -> ElementTheme.colors.borderInteractiveHovered
|
||||
else -> ElementTheme.colors.borderInteractiveSecondary
|
||||
}
|
||||
)
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:839c24d04f7008a3b33be3624c71f19f01554a78903cc5d8e5337ab90d0fc41b
|
||||
size 8268
|
||||
oid sha256:76632bda4afa1bc900b1174fe68a09a3d757d6f3227b4f541e0198219875c90c
|
||||
size 8275
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:032efe4da3ebda3dcc92a6027604822dabf6062073c4e556242e755adf38e717
|
||||
size 11803
|
||||
oid sha256:b40de4a02b67814007f201cea9383e8ab30f2b7b56fb1efcdd2348ee207f4815
|
||||
size 11814
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a448f6810521acc7d85904ba71ee4a3153d2eeb2c40d132b889eda774e0a6fdf
|
||||
size 7956
|
||||
oid sha256:04473b9423b916f25920837e07b2b22ba495daa5d4f2de4070b70d3dd571072c
|
||||
size 7975
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:effa92f7695f9643efeebf929db6fdac31bd608a449ab306511897e8b2197b82
|
||||
size 10939
|
||||
oid sha256:7cf8f0f420c2eb69bc6a56e9238fb720d6fada2c250ae7b2dbdb8f431dfd9668
|
||||
size 10944
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b5dc5c492ed3fd552e77c0be85b639d55bc7e976f15b761f927b0b80ecca601d
|
||||
size 12115
|
||||
oid sha256:195338046951366fd2345fdc8471e3e2b2786723c8bfffa9fa9057929c608afb
|
||||
size 12113
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:e7ce8a8c6b4d1692e4b127b7f17f507552666c631893025082c385b93d835a73
|
||||
size 11726
|
||||
oid sha256:4ef1b643a16b5a94c75f8bb845c36d3cbc7f7ed96a0cac32fdb9f0b09d26b4d1
|
||||
size 11747
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:8b93c08531efbeacb55f84b17ac793a7b226e5a2db7bc5072e94bc040cd1e9bc
|
||||
size 11386
|
||||
oid sha256:ce754ce205fd864e01828659aff42ab19dccf7c921c1c733ed1757f1b2122309
|
||||
size 11403
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:20742175a23c7116089cec7b9886ad567db50d899dd5dca4388534d6120d73ce
|
||||
size 60252
|
||||
oid sha256:8f8ef2430abd11b31b3e90976f85bd4578e667bd0acc0851544ee4d16358479d
|
||||
size 60237
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ee1ee7ae5a0350ca808b1839d7f033cb83947d33305a5cb5ff9a9faa4a5dadbf
|
||||
size 58345
|
||||
oid sha256:8265b9acc3932df6f0e1eee5e85c2b16d13060c4164c3fbb5b1b0b598745770c
|
||||
size 58326
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a4b18fc1dffd0b62b81d9e9ec5de8588919e27b18af178bfba474771cafd9800
|
||||
size 42717
|
||||
oid sha256:37f8e05e435b8d531c72a180ff87183dcec2aa319473bc540e19c9fdd0e5346a
|
||||
size 42673
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7813a6da740ee5a83c56ac4883b2905582482b6d5d17254b30b895a242f85b60
|
||||
size 42752
|
||||
oid sha256:ffe628766efb7b932c82749546d5c9a6dd271a4ffe2cf162dbc36796538fce12
|
||||
size 42723
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a4b18fc1dffd0b62b81d9e9ec5de8588919e27b18af178bfba474771cafd9800
|
||||
size 42717
|
||||
oid sha256:37f8e05e435b8d531c72a180ff87183dcec2aa319473bc540e19c9fdd0e5346a
|
||||
size 42673
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c081116bbbb293635b599ae4d4d25505cf442a0feae7fbded69f7772fec7d96f
|
||||
size 42850
|
||||
oid sha256:ff352e5d173cc05b74d4086e5412d467b378239fa7f75b3c17c11b7f024047c1
|
||||
size 42823
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:fdfe5a8f3e42c503560f32835237ab0f340b0a82a9dea7945d6cf19ed1845c93
|
||||
size 42868
|
||||
oid sha256:8ce5baff8faa00bec873dd65a22415d9bdba0c69f68168fb893036684ce2b0dc
|
||||
size 42882
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:928165a963ba3dadd278c8fee183fb5d6398b28369f28f782c9f08dbc69df52c
|
||||
size 14235
|
||||
oid sha256:ad303cbc4984982a5d3e6fe341c611483d76a3cd4bf15705864c5c20443f9b4d
|
||||
size 14226
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b5ca516e5f7bc8a2231b5fa7535a80b03eb6ff44b2d83e66163b010a1802fa7e
|
||||
size 32464
|
||||
oid sha256:ccc9c9c95b9a56bb6c453aea4b13be812b64ad5b7352f169a32208166ff70b9f
|
||||
size 32449
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:97e41908816ae4f32eeb85f00125dcd7eb28810d9157441f535a228de3ff31bd
|
||||
size 13774
|
||||
oid sha256:70193284306460b8f9c333849c8d5e1b5b1e95c3ce446307ccff482c90c2d09a
|
||||
size 13775
|
||||
|
||||
+1
-1
@@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:5cd30c16ff85d4140d25b738916948bf4180b49341b650886a318080c8697fd6
|
||||
oid sha256:0284751ecc89b295784fab1eb4a85e4615015ef915c9492a59ad8671f2805806
|
||||
size 31606
|
||||
|
||||
Reference in New Issue
Block a user