PM-24544: Update Segmented Control to handle large font better (#5748)

This commit is contained in:
David Perez 2025-08-20 09:59:40 -05:00 committed by GitHub
parent 5f42c9bb39
commit b3528249e9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 35 additions and 17 deletions

View File

@ -3,12 +3,14 @@ package com.bitwarden.ui.platform.base.util
import androidx.compose.runtime.Composable
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.sp
/**
* A function for converting pixels to [Dp] within a composable function.
@ -49,3 +51,26 @@ fun Dp.toUnscaledTextUnit(): TextUnit {
val scalingFactor = LocalConfiguration.current.fontScale
return TextUnit(value / scalingFactor, TextUnitType.Sp)
}
/**
* Modifies the [TextUnit] value to have a maximum scale factor for accessibility.
*/
@Composable
fun TextUnit.maxScaledSp(maxScaleFactor: Float): TextUnit {
val scaleFactor = LocalConfiguration.current.fontScale
val adjustedScaleFactor = scaleFactor.coerceAtMost(maximumValue = maxScaleFactor)
val adjustedValue = (this.value / scaleFactor) * adjustedScaleFactor
return adjustedValue.sp
}
/**
* Creates a copy of the [TextStyle] that has a maximum scale factor.
*/
@Composable
fun TextStyle.toMaxScale(
maxScaleFactor: Float,
): TextStyle = this.copy(
fontSize = this.fontSize.maxScaledSp(maxScaleFactor = maxScaleFactor),
lineHeight = this.lineHeight.maxScaledSp(maxScaleFactor = maxScaleFactor),
letterSpacing = this.letterSpacing.maxScaledSp(maxScaleFactor = maxScaleFactor),
)

View File

@ -26,20 +26,20 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.style.Hyphens
import androidx.compose.ui.text.style.LineBreak
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import com.bitwarden.ui.platform.base.util.nullableTestTag
import com.bitwarden.ui.platform.base.util.toDp
import com.bitwarden.ui.platform.base.util.toMaxScale
import com.bitwarden.ui.platform.components.segment.color.bitwardenSegmentedButtonColors
import com.bitwarden.ui.platform.theme.BitwardenTheme
import kotlinx.collections.immutable.ImmutableList
private const val FONT_SCALE_THRESHOLD = 1.5f
/**
* Displays a Bitwarden styled row of segmented buttons.
*
@ -107,12 +107,6 @@ fun SingleChoiceSegmentedButtonRowScope.SegmentedButtonOptionContent(
option: SegmentedButtonState,
modifier: Modifier = Modifier,
) {
val fontScale = LocalConfiguration.current.fontScale
val labelVerticalPadding = if (fontScale > FONT_SCALE_THRESHOLD) {
8.dp
} else {
0.dp
}
SegmentedButton(
enabled = option.isEnabled,
selected = option.isChecked,
@ -123,13 +117,12 @@ fun SingleChoiceSegmentedButtonRowScope.SegmentedButtonOptionContent(
label = {
Text(
text = option.text,
style = BitwardenTheme.typography.labelLarge.copy(
hyphens = Hyphens.Auto,
),
modifier = Modifier.padding(
vertical = labelVerticalPadding,
horizontal = 4.dp,
),
style = BitwardenTheme.typography.labelLarge
.copy(lineBreak = LineBreak.Heading)
.toMaxScale(maxScaleFactor = 2f),
maxLines = 2,
overflow = TextOverflow.Ellipsis,
textAlign = TextAlign.Center,
)
},
icon = {