M3 TextFields change their height ever so slightly...
# compose-android
z
M3 TextFields change their height ever so slightly when they receive their first input (~1.dp difference). Does anyone know a simple way to work around this? Afaik, its due to the font.
The closest Ive gotten to a fix (this breaks hints, unfortunately):
Copy code
private class EmptyLineOutput(
    private val inner: OutputTransformation?,
) : OutputTransformation {
    override fun TextFieldBuffer.transformOutput() {
        inner?.run { transformOutput() }
        if (length == 0) append(ZERO_WIDTH_SPACE)
    }
}

private const val ZERO_WIDTH_SPACE = "\u200B"
s
does giving them a min height, or wrapping them in a box with a min height, help? either way, smells like a bug to report upstream
z
MinHeight directly on the input field doesnt work. Maybe a Box wrapper would, but I managed to solve it with the transformation above - just conditionally applying it when theres no hint.
h
We try to prevent this by calculating the empty height from the text "HHHHHHHHHH" in BasicTextField. However it is not foolproof because not every font has stable glyph heights and another uppercase character might produce a slightly taller text layout. Did you try this with BasicTextField? Does it also show the same behavior for the same font and text style?
d
I ran into this same problem a long time ago (years probably now?) and never managed to find a fix that I am happy with. I wasn't sure if it's my font file being "broken" or something in Compose itself. I ended up assigning a minHeight with a fudge factor, something like
verticalPadding (2x) + floatingLabelLineHeight + 4 + textLineHeight
where 4 is that magical fudge number that seemed to work for me to stop any weird resizing... Looks like I left references to https://github.com/JetBrains/compose-multiplatform/issues/1895 and https://bugs.chromium.org/p/skia/issues/detail?id=11321 as possible root causes (or my font) but never really had the time to confirm if that's really the case. Btw it seemed to only happen when the text field has a (floating) label.
z
BasicTextField
has it too. It comes from the text styles line height afaik, doing this is also a solution (not sure about side effects, but none of my tests complain):
Copy code
textStyle =
    textStyle.copy(
        lineHeight = if (singleLine) Unspecified else textStyle.lineHeight,
    ),
Roughly 2.dp larger without lineHeight in my case (22 sp Noto)
s
Instead of calculating the height from "HHH…", perhaps calculate from “ABC…abc…1234567890” or something would be a bit more flexible? Also why several H's after each other and not just a single one? Does “HH” and “H” differ in height?
j
I would think using
BasicTextField
would fix it because you can customize the “decorationBox” that holds the actual rendered text. It’s there that you should apply a Modifier that enforces the
minHeight
to be the tallest possible value (capture this from the layout inspector).