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.runtime.Composable
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.Density import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.TextUnit import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.TextUnitType import androidx.compose.ui.unit.TextUnitType
import androidx.compose.ui.unit.sp
/** /**
* A function for converting pixels to [Dp] within a composable function. * A function for converting pixels to [Dp] within a composable function.
@ -49,3 +51,26 @@ fun Dp.toUnscaledTextUnit(): TextUnit {
val scalingFactor = LocalConfiguration.current.fontScale val scalingFactor = LocalConfiguration.current.fontScale
return TextUnit(value / scalingFactor, TextUnitType.Sp) 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.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity 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.Density
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
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.nullableTestTag
import com.bitwarden.ui.platform.base.util.toDp 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.components.segment.color.bitwardenSegmentedButtonColors
import com.bitwarden.ui.platform.theme.BitwardenTheme import com.bitwarden.ui.platform.theme.BitwardenTheme
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
private const val FONT_SCALE_THRESHOLD = 1.5f
/** /**
* Displays a Bitwarden styled row of segmented buttons. * Displays a Bitwarden styled row of segmented buttons.
* *
@ -107,12 +107,6 @@ fun SingleChoiceSegmentedButtonRowScope.SegmentedButtonOptionContent(
option: SegmentedButtonState, option: SegmentedButtonState,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
) { ) {
val fontScale = LocalConfiguration.current.fontScale
val labelVerticalPadding = if (fontScale > FONT_SCALE_THRESHOLD) {
8.dp
} else {
0.dp
}
SegmentedButton( SegmentedButton(
enabled = option.isEnabled, enabled = option.isEnabled,
selected = option.isChecked, selected = option.isChecked,
@ -123,13 +117,12 @@ fun SingleChoiceSegmentedButtonRowScope.SegmentedButtonOptionContent(
label = { label = {
Text( Text(
text = option.text, text = option.text,
style = BitwardenTheme.typography.labelLarge.copy( style = BitwardenTheme.typography.labelLarge
hyphens = Hyphens.Auto, .copy(lineBreak = LineBreak.Heading)
), .toMaxScale(maxScaleFactor = 2f),
modifier = Modifier.padding( maxLines = 2,
vertical = labelVerticalPadding, overflow = TextOverflow.Ellipsis,
horizontal = 4.dp, textAlign = TextAlign.Center,
),
) )
}, },
icon = { icon = {