mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-04 10:32:34 +00:00
Improve focus rendering: now display a blue inset ring around the focused component.
Closes #6397
This commit is contained in:
@@ -16,7 +16,11 @@ import androidx.activity.enableEdgeToEdge
|
|||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
import androidx.compose.foundation.isSystemInDarkTheme
|
||||||
import androidx.compose.material3.ColorScheme
|
import androidx.compose.material3.ColorScheme
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.LocalRippleConfiguration
|
||||||
|
import androidx.compose.material3.LocalRippleThemeConfiguration
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
import androidx.compose.material3.RippleConfiguration
|
||||||
|
import androidx.compose.material3.RippleThemeConfiguration
|
||||||
import androidx.compose.material3.Typography
|
import androidx.compose.material3.Typography
|
||||||
import androidx.compose.material3.dynamicDarkColorScheme
|
import androidx.compose.material3.dynamicDarkColorScheme
|
||||||
import androidx.compose.material3.dynamicLightColorScheme
|
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.Color
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import androidx.compose.ui.graphics.toArgb
|
||||||
import androidx.compose.ui.platform.LocalContext
|
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.compoundTypography
|
||||||
import io.element.android.compound.tokens.generated.SemanticColors
|
import io.element.android.compound.tokens.generated.SemanticColors
|
||||||
import io.element.android.compound.tokens.generated.TypographyTokens
|
import io.element.android.compound.tokens.generated.TypographyTokens
|
||||||
@@ -159,6 +164,25 @@ fun ElementTheme(
|
|||||||
CompositionLocalProvider(
|
CompositionLocalProvider(
|
||||||
LocalCompoundColors provides currentCompoundColor,
|
LocalCompoundColors provides currentCompoundColor,
|
||||||
LocalContentColor provides colorScheme.onSurface,
|
LocalContentColor provides colorScheme.onSurface,
|
||||||
|
// Configure the keyboard focus style: Draw a blue inset ring around the focused component.
|
||||||
|
// 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.secondaryColor is used
|
||||||
|
LocalRippleConfiguration provides
|
||||||
|
RippleConfiguration(
|
||||||
|
focus = RippleConfiguration.Focus.InsetRing(
|
||||||
|
outerStrokeColor = ElementTheme.colors.borderFocused,
|
||||||
|
innerStrokeColor = Color.Transparent,
|
||||||
|
)
|
||||||
|
),
|
||||||
) {
|
) {
|
||||||
MaterialTheme(
|
MaterialTheme(
|
||||||
colorScheme = colorScheme,
|
colorScheme = colorScheme,
|
||||||
|
|||||||
+23
-6
@@ -28,13 +28,15 @@ import androidx.compose.foundation.shape.RoundedCornerShape
|
|||||||
import androidx.compose.material3.ButtonColors
|
import androidx.compose.material3.ButtonColors
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
import androidx.compose.material3.LocalContentColor
|
import androidx.compose.material3.LocalContentColor
|
||||||
|
import androidx.compose.material3.LocalRippleThemeConfiguration
|
||||||
|
import androidx.compose.material3.RippleThemeConfiguration
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.CompositionLocalProvider
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.RectangleShape
|
|
||||||
import androidx.compose.ui.graphics.isSpecified
|
import androidx.compose.ui.graphics.isSpecified
|
||||||
import androidx.compose.ui.graphics.painter.Painter
|
import androidx.compose.ui.graphics.painter.Painter
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
@@ -181,11 +183,8 @@ private fun ButtonInternal(
|
|||||||
ButtonSize.LargeLowPadding -> PaddingValues(horizontal = lowHorizontalPaddingValue, vertical = 13.dp)
|
ButtonSize.LargeLowPadding -> PaddingValues(horizontal = lowHorizontalPaddingValue, vertical = 13.dp)
|
||||||
}
|
}
|
||||||
|
|
||||||
val shape = when (style) {
|
// Apply the same shape to all buttons, so that the focus ring is consistent across styles.
|
||||||
ButtonStyle.Filled,
|
val shape = RoundedCornerShape(percent = 50)
|
||||||
ButtonStyle.Outlined -> RoundedCornerShape(percent = 50)
|
|
||||||
ButtonStyle.Text -> RectangleShape
|
|
||||||
}
|
|
||||||
|
|
||||||
val border = when (style) {
|
val border = when (style) {
|
||||||
ButtonStyle.Filled -> null
|
ButtonStyle.Filled -> null
|
||||||
@@ -202,6 +201,23 @@ private fun ButtonInternal(
|
|||||||
ButtonStyle.Text -> null
|
ButtonStyle.Text -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
)
|
||||||
|
),
|
||||||
|
) {
|
||||||
androidx.compose.material3.Button(
|
androidx.compose.material3.Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
if (!showProgress) {
|
if (!showProgress) {
|
||||||
@@ -245,6 +261,7 @@ private fun ButtonInternal(
|
|||||||
overflow = TextOverflow.Ellipsis,
|
overflow = TextOverflow.Ellipsis,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun ButtonSize.toMinHeight() = when (this) {
|
private fun ButtonSize.toMinHeight() = when (this) {
|
||||||
|
|||||||
+1
-1
@@ -139,7 +139,7 @@ private fun SearchFieldContainer(
|
|||||||
border = BorderStroke(
|
border = BorderStroke(
|
||||||
width = 1.dp,
|
width = 1.dp,
|
||||||
color = if (isFocused) {
|
color = if (isFocused) {
|
||||||
ElementTheme.colors.borderInteractiveHovered
|
ElementTheme.colors.borderFocused
|
||||||
} else {
|
} else {
|
||||||
ElementTheme.colors.borderInteractiveSecondary
|
ElementTheme.colors.borderInteractiveSecondary
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -293,8 +293,8 @@ private fun TextFieldContainer(
|
|||||||
width = if (isFocused) 2.dp else 1.dp,
|
width = if (isFocused) 2.dp else 1.dp,
|
||||||
color = when {
|
color = when {
|
||||||
!enabled -> ElementTheme.colors.borderDisabled
|
!enabled -> ElementTheme.colors.borderDisabled
|
||||||
|
isFocused -> ElementTheme.colors.borderFocused
|
||||||
isError -> ElementTheme.colors.borderCriticalPrimary
|
isError -> ElementTheme.colors.borderCriticalPrimary
|
||||||
isFocused -> ElementTheme.colors.borderInteractiveHovered
|
|
||||||
else -> ElementTheme.colors.borderInteractiveSecondary
|
else -> ElementTheme.colors.borderInteractiveSecondary
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user