Update TextField height calculations according to M3 spec.

M2 behavior: Padding determined the distance between the
top of the text field to the label's baseline, and from
the label baseline to the top of the input field.

M3 behavior: Padding determines the distance between the
top of the text field to the top of the label in focused
state. The input field is placed directly below the label.
Baseline is not considered at all.

Bug: b/250662016
Test: Updated TextFieldTest.kt, updated and cleaned up TextFieldDecorationBoxTest.kt
Change-Id: I85b92ebaee3673fbf49ef941758ab272cf65036f
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt
index 9e8f387..2be02b8 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldDecorationBoxTest.kt
@@ -20,6 +20,7 @@
 import androidx.compose.foundation.interaction.MutableInteractionSource
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.PaddingValues
+import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.size
 import androidx.compose.foundation.text.BasicTextField
 import androidx.compose.material3.TextFieldDefaults.OutlinedTextFieldDecorationBox
@@ -64,262 +65,267 @@
     val rule = createComposeRule()
 
     private val Density = Density(1f)
+    private val LabelHeight = 40.dp
     private val InnerTextFieldHeight = 50.dp
     private val InnerTextFieldWidth = 100.dp
 
     @Test
     fun outlinedTextFieldBox_overrideTopPadding_multiLine() {
         assertVerticalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(top = 10.dp),
-            false,
-            10.dp + InnerTextFieldHeight + TextFieldPadding,
-            10.dp
+            padding = TextFieldDefaults.outlinedTextFieldPadding(top = 10.dp),
+            singleLine = false,
+            expectedHeight = 10.dp + InnerTextFieldHeight + TextFieldPadding,
+            expectedPosition = 10.dp
         )
     }
 
     @Test
     fun outlinedTextFieldBox_overrideTopPadding_singleLine() {
         assertVerticalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(top = 10.dp),
-            true,
-            10.dp + InnerTextFieldHeight + TextFieldPadding,
-            (10.dp + TextFieldPadding) / 2
+            padding = TextFieldDefaults.outlinedTextFieldPadding(top = 10.dp),
+            singleLine = true,
+            expectedHeight = 10.dp + InnerTextFieldHeight + TextFieldPadding,
+            expectedPosition = (10.dp + TextFieldPadding) / 2
         )
     }
 
     @Test
     fun outlinedTextFieldBox_overrideBottomPadding_multiLine() {
         assertVerticalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(bottom = 10.dp),
-            false,
-            TextFieldPadding + InnerTextFieldHeight + 10.dp,
-            TextFieldPadding
+            padding = TextFieldDefaults.outlinedTextFieldPadding(bottom = 10.dp),
+            singleLine = false,
+            expectedHeight = TextFieldPadding + InnerTextFieldHeight + 10.dp,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun outlinedTextFieldBox_overrideBottomPadding_singleLine() {
         assertVerticalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(bottom = 10.dp),
-            true,
-            TextFieldPadding + InnerTextFieldHeight + 10.dp,
-            (10.dp + TextFieldPadding) / 2
+            padding = TextFieldDefaults.outlinedTextFieldPadding(bottom = 10.dp),
+            singleLine = true,
+            expectedHeight = TextFieldPadding + InnerTextFieldHeight + 10.dp,
+            expectedPosition = (10.dp + TextFieldPadding) / 2
         )
     }
 
     @Test
     fun outlinedTextFieldBox_overrideStartPadding() {
         assertHorizontalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(start = 10.dp),
-            false,
-            10.dp + InnerTextFieldWidth + TextFieldPadding,
-            10.dp
+            padding = TextFieldDefaults.outlinedTextFieldPadding(start = 10.dp),
+            rtl = false,
+            expectedWidth = 10.dp + InnerTextFieldWidth + TextFieldPadding,
+            expectedPosition = 10.dp
         )
     }
 
     @Test
     fun outlinedTextFieldBox_overrideStartPadding_rtl() {
         assertHorizontalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(start = 10.dp),
-            true,
-            10.dp + InnerTextFieldWidth + TextFieldPadding,
-            TextFieldPadding
+            padding = TextFieldDefaults.outlinedTextFieldPadding(start = 10.dp),
+            rtl = true,
+            expectedWidth = 10.dp + InnerTextFieldWidth + TextFieldPadding,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun outlinedTextFieldBox_overrideEndPadding() {
         assertHorizontalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(end = 20.dp),
-            false,
-            TextFieldPadding + InnerTextFieldWidth + 20.dp,
-            TextFieldPadding
+            padding = TextFieldDefaults.outlinedTextFieldPadding(end = 20.dp),
+            rtl = false,
+            expectedWidth = TextFieldPadding + InnerTextFieldWidth + 20.dp,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun outlinedTextFieldBox_overrideEndPadding_rtl() {
         assertHorizontalSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(end = 20.dp),
-            true,
-            TextFieldPadding + InnerTextFieldWidth + 20.dp,
-            20.dp
+            padding = TextFieldDefaults.outlinedTextFieldPadding(end = 20.dp),
+            rtl = true,
+            expectedWidth = TextFieldPadding + InnerTextFieldWidth + 20.dp,
+            expectedPosition = 20.dp
         )
     }
 
     @Test
     fun textFieldBox_overrideTopPadding_singleLine_withoutLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(top = 40.dp),
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(top = 40.dp),
             singleLine = true,
             hasLabel = false,
-            40.dp + InnerTextFieldHeight + TextFieldPadding,
-            (40.dp + TextFieldPadding) / 2
+            expectedHeight = 40.dp + InnerTextFieldHeight + TextFieldPadding,
+            expectedPosition = (40.dp + TextFieldPadding) / 2
         )
     }
 
     @Test
     fun textFieldBox_overrideTopPadding_singleLine_withLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(top = 40.dp),
+            padding = TextFieldDefaults.textFieldWithLabelPadding(top = 40.dp),
             singleLine = true,
             hasLabel = true,
-            40.dp + TextFieldTopPadding + InnerTextFieldHeight + TextFieldBottomPadding,
-            40.dp + TextFieldTopPadding
+            expectedHeight = 40.dp + LabelHeight + InnerTextFieldHeight +
+                TextFieldWithLabelVerticalPadding,
+            expectedPosition = 40.dp + LabelHeight
         )
     }
 
     @Test
     fun textFieldBox_overrideBottomPadding_singleLine_withoutLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(bottom = 40.dp),
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(bottom = 40.dp),
             singleLine = true,
             hasLabel = false,
-            TextFieldPadding + InnerTextFieldHeight + 40.dp,
-            (TextFieldPadding + 40.dp) / 2
+            expectedHeight = TextFieldPadding + InnerTextFieldHeight + 40.dp,
+            expectedPosition = (TextFieldPadding + 40.dp) / 2
         )
     }
 
     @Test
     fun textFieldBox_overrideBottomPadding_singleLine_withLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(bottom = 40.dp),
+            padding = TextFieldDefaults.textFieldWithLabelPadding(bottom = 40.dp),
             singleLine = true,
             hasLabel = true,
-            FirstBaselineOffset + TextFieldTopPadding + InnerTextFieldHeight + 40.dp,
-            FirstBaselineOffset + TextFieldTopPadding
+            expectedHeight = TextFieldWithLabelVerticalPadding + LabelHeight +
+                InnerTextFieldHeight + 40.dp,
+            expectedPosition = TextFieldWithLabelVerticalPadding + LabelHeight
         )
     }
 
     @Test
     fun textFieldBox_overrideTopPadding_multiLine_withoutLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(top = 40.dp),
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(top = 40.dp),
             singleLine = false,
             hasLabel = false,
-            40.dp + InnerTextFieldHeight + TextFieldPadding,
-            40.dp
+            expectedHeight = 40.dp + InnerTextFieldHeight + TextFieldPadding,
+            expectedPosition = 40.dp
         )
     }
 
     @Test
     fun textFieldBox_overrideTopPadding_multiLine_withLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(top = 40.dp),
+            padding = TextFieldDefaults.textFieldWithLabelPadding(top = 40.dp),
             singleLine = false,
             hasLabel = true,
-            40.dp + TextFieldTopPadding + InnerTextFieldHeight + TextFieldBottomPadding,
-            40.dp + TextFieldTopPadding
+            expectedHeight = 40.dp + LabelHeight + InnerTextFieldHeight +
+                TextFieldWithLabelVerticalPadding,
+            expectedPosition = 40.dp + LabelHeight
         )
     }
 
     @Test
     fun textFieldBox_overrideBottomPadding_multiLine_withoutLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(bottom = 40.dp),
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(bottom = 40.dp),
             singleLine = false,
             hasLabel = false,
-            TextFieldPadding + InnerTextFieldHeight + 40.dp,
-            TextFieldPadding
+            expectedHeight = TextFieldPadding + InnerTextFieldHeight + 40.dp,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun textFieldBox_overrideBottomPadding_multiLine_withLabel() {
         assertVerticalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(bottom = 40.dp),
+            padding = TextFieldDefaults.textFieldWithLabelPadding(bottom = 40.dp),
             singleLine = false,
             hasLabel = true,
-            FirstBaselineOffset + TextFieldTopPadding + InnerTextFieldHeight + 40.dp,
-            FirstBaselineOffset + TextFieldTopPadding
+            expectedHeight = TextFieldWithLabelVerticalPadding + LabelHeight +
+                InnerTextFieldHeight + 40.dp,
+            expectedPosition = TextFieldWithLabelVerticalPadding + LabelHeight
         )
     }
 
     @Test
     fun textFieldBox_overrideStartPadding_withLabel() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(start = 40.dp),
-            false,
+            padding = TextFieldDefaults.textFieldWithLabelPadding(start = 40.dp),
+            rtl = false,
             hasLabel = true,
-            40.dp + InnerTextFieldWidth + TextFieldPadding,
-            40.dp
+            expectedWidth = 40.dp + InnerTextFieldWidth + TextFieldPadding,
+            expectedPosition = 40.dp
         )
     }
 
     @Test
     fun textFieldBox_overrideStartPadding_withLabel_rtl() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(start = 40.dp),
-            true,
+            padding = TextFieldDefaults.textFieldWithLabelPadding(start = 40.dp),
+            rtl = true,
             hasLabel = true,
-            40.dp + InnerTextFieldWidth + TextFieldPadding,
-            TextFieldPadding
+            expectedWidth = 40.dp + InnerTextFieldWidth + TextFieldPadding,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun textFieldBox_overrideStartPadding_withoutLabel() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(start = 40.dp),
-            false,
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(start = 40.dp),
+            rtl = false,
             hasLabel = false,
-            40.dp + InnerTextFieldWidth + TextFieldPadding,
-            40.dp
+            expectedWidth = 40.dp + InnerTextFieldWidth + TextFieldPadding,
+            expectedPosition = 40.dp
         )
     }
 
     @Test
     fun textFieldBox_overrideStartPadding_withoutLabel_rtl() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(start = 40.dp),
-            true,
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(start = 40.dp),
+            rtl = true,
             hasLabel = false,
-            40.dp + InnerTextFieldWidth + TextFieldPadding,
-            TextFieldPadding
+            expectedWidth = 40.dp + InnerTextFieldWidth + TextFieldPadding,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun textFieldBox_overrideEndPadding_withLabel() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(end = 40.dp),
-            false,
+            padding = TextFieldDefaults.textFieldWithLabelPadding(end = 40.dp),
+            rtl = false,
             hasLabel = true,
-            TextFieldPadding + InnerTextFieldWidth + 40.dp,
-            TextFieldPadding
+            expectedWidth = TextFieldPadding + InnerTextFieldWidth + 40.dp,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun textFieldBox_overrideEndPadding_withLabel_rtl() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithLabelPadding(end = 40.dp),
-            true,
+            padding = TextFieldDefaults.textFieldWithLabelPadding(end = 40.dp),
+            rtl = true,
             hasLabel = true,
-            TextFieldPadding + InnerTextFieldWidth + 40.dp,
-            40.dp
+            expectedWidth = TextFieldPadding + InnerTextFieldWidth + 40.dp,
+            expectedPosition = 40.dp
         )
     }
 
     @Test
     fun textFieldBox_overrideEndPadding_withoutLabel() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(end = 40.dp),
-            false,
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(end = 40.dp),
+            rtl = false,
             hasLabel = false,
-            TextFieldPadding + InnerTextFieldWidth + 40.dp,
-            TextFieldPadding
+            expectedWidth = TextFieldPadding + InnerTextFieldWidth + 40.dp,
+            expectedPosition = TextFieldPadding
         )
     }
 
     @Test
     fun textFieldBox_overrideEndPadding_withoutLabel_rtl() {
         assertHorizontalSizeAndPosition_textField(
-            TextFieldDefaults.textFieldWithoutLabelPadding(end = 40.dp),
-            true,
+            padding = TextFieldDefaults.textFieldWithoutLabelPadding(end = 40.dp),
+            rtl = true,
             hasLabel = false,
-            TextFieldPadding + InnerTextFieldWidth + 40.dp,
-            40.dp
+            expectedWidth = TextFieldPadding + InnerTextFieldWidth + 40.dp,
+            expectedPosition = 40.dp
         )
     }
 
@@ -439,34 +445,35 @@
 
     @Test
     fun outlinedTextFieldBox_innerTextLocation_withMultilineLabel() {
-        val labelHeight = 60.dp
-        assertSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(),
-            false,
-            labelHeight / 2 + InnerTextFieldHeight + TextFieldPadding,
-            labelHeight / 2,
-            true,
+        assertSizeAndPosition(
+            padding = TextFieldDefaults.outlinedTextFieldPadding(),
+            singleLine = false,
+            expectedSize = LabelHeight / 2 + InnerTextFieldHeight + TextFieldPadding,
+            expectedPosition = LabelHeight / 2,
+            isVertical = true,
+            isOutlined = true,
             label = {
                 // imitates the multiline label
-                Box(Modifier.size(10.dp, labelHeight))
+                Box(Modifier.size(10.dp, LabelHeight))
             }
         )
-        }
+    }
 
     @Test
     fun outlinedTextFieldBox_singleLine_innerTextLocation_withMultilineLabel() {
-        val labelHeight = 60.dp
-        assertSizeAndPosition_outlinedTextField(
-            TextFieldDefaults.outlinedTextFieldPadding(),
-            true,
-            labelHeight / 2 + InnerTextFieldHeight + TextFieldPadding,
-            labelHeight / 2,
-            true,
+        assertSizeAndPosition(
+            padding = TextFieldDefaults.outlinedTextFieldPadding(),
+            singleLine = true,
+            expectedSize = LabelHeight / 2 + InnerTextFieldHeight + TextFieldPadding,
+            expectedPosition = LabelHeight / 2,
+            isVertical = true,
+            isOutlined = true,
             label = {
                 // imitates the multiline label
-                Box(Modifier.size(10.dp, labelHeight))
-            })
-        }
+                Box(Modifier.size(10.dp, LabelHeight))
+            }
+        )
+    }
 
     private fun assertVerticalSizeAndPosition_outlinedTextField(
         padding: PaddingValues,
@@ -474,12 +481,13 @@
         expectedHeight: Dp,
         expectedPosition: Dp
     ) {
-        assertSizeAndPosition_outlinedTextField(
-            padding,
-            singleLine,
-            expectedHeight,
-            expectedPosition,
-            true
+        assertSizeAndPosition(
+            padding = padding,
+            singleLine = singleLine,
+            expectedSize = expectedHeight,
+            expectedPosition = expectedPosition,
+            isVertical = true,
+            isOutlined = true,
         )
     }
 
@@ -489,82 +497,17 @@
         expectedWidth: Dp,
         expectedPosition: Dp
     ) {
-        assertSizeAndPosition_outlinedTextField(
-            padding,
-            true,
-            expectedWidth,
-            expectedPosition,
-            false,
-            if (rtl) LayoutDirection.Rtl else LayoutDirection.Ltr
+        assertSizeAndPosition(
+            padding = padding,
+            singleLine = true,
+            expectedSize = expectedWidth,
+            expectedPosition = expectedPosition,
+            isVertical = false,
+            isOutlined = true,
+            layoutDirection = if (rtl) LayoutDirection.Rtl else LayoutDirection.Ltr
         )
     }
 
-    private fun assertSizeAndPosition_outlinedTextField(
-        padding: PaddingValues,
-        singleLine: Boolean,
-        expectedSize: Dp,
-        expectedPosition: Dp,
-        vertical: Boolean,
-        layoutDirection: LayoutDirection = LayoutDirection.Ltr,
-        label: @Composable (() -> Unit)? = null
-    ) {
-        var size: IntSize? = null
-        var position: Offset? = null
-        rule.setMaterialContent(lightColorScheme()) {
-            CompositionLocalProvider(
-                LocalLayoutDirection provides layoutDirection,
-                LocalDensity provides Density
-            ) {
-                Box(Modifier.onSizeChanged { size = it }) {
-                    val value = ""
-                    val interactionSource = remember { MutableInteractionSource() }
-                    BasicTextField(
-                        value = value,
-                        onValueChange = {},
-                        singleLine = singleLine,
-                        interactionSource = interactionSource
-                    ) {
-                        OutlinedTextFieldDecorationBox(
-                            value = value,
-                            innerTextField = {
-                                Box(
-                                    Modifier
-                                        .size(InnerTextFieldWidth, InnerTextFieldHeight)
-                                        .onGloballyPositioned {
-                                            position = it.positionInRoot()
-                                        }
-                                ) { it() }
-                            },
-                            enabled = true,
-                            singleLine = singleLine,
-                            visualTransformation = VisualTransformation.None,
-                            interactionSource = interactionSource,
-                            contentPadding = padding,
-                            label = label
-                        )
-                    }
-                }
-            }
-        }
-
-        rule.runOnIdle {
-            with(Density) {
-                assertThat(size).isNotNull()
-                if (vertical) {
-                    assertThat(size!!.height).isEqualTo(expectedSize.roundToPx())
-                } else {
-                    assertThat(size!!.width).isEqualTo(expectedSize.roundToPx())
-                }
-                assertThat(position).isNotNull()
-                if (vertical) {
-                    assertThat(position!!.y.roundToInt()).isEqualTo(expectedPosition.roundToPx())
-                } else {
-                    assertThat(position!!.x.roundToInt()).isEqualTo(expectedPosition.roundToPx())
-                }
-            }
-        }
-    }
-
     private fun assertVerticalSizeAndPosition_textField(
         padding: PaddingValues,
         singleLine: Boolean,
@@ -572,13 +515,16 @@
         expectedHeight: Dp,
         expectedPosition: Dp
     ) {
-        assertSizeAndPosition_textField(
-            padding,
-            singleLine,
-            expectedHeight,
-            expectedPosition,
-            true,
-            hasLabel
+        assertSizeAndPosition(
+            padding = padding,
+            singleLine = singleLine,
+            expectedSize = expectedHeight,
+            expectedPosition = expectedPosition,
+            isVertical = true,
+            isOutlined = false,
+            label = if (hasLabel) {
+                { Text("Label", modifier = Modifier.height(LabelHeight)) }
+            } else { null },
         )
     }
 
@@ -589,25 +535,29 @@
         expectedWidth: Dp,
         expectedPosition: Dp
     ) {
-        assertSizeAndPosition_textField(
-            padding,
-            true,
-            expectedWidth,
-            expectedPosition,
-            false,
-            hasLabel,
-            if (rtl) LayoutDirection.Rtl else LayoutDirection.Ltr
+        assertSizeAndPosition(
+            padding = padding,
+            singleLine = true,
+            expectedSize = expectedWidth,
+            expectedPosition = expectedPosition,
+            isVertical = false,
+            isOutlined = false,
+            layoutDirection = if (rtl) LayoutDirection.Rtl else LayoutDirection.Ltr,
+            label = if (hasLabel) {
+                { Text("Label", modifier = Modifier.height(LabelHeight)) }
+            } else { null },
         )
     }
 
-    private fun assertSizeAndPosition_textField(
+    private fun assertSizeAndPosition(
         padding: PaddingValues,
         singleLine: Boolean,
         expectedSize: Dp,
         expectedPosition: Dp,
-        vertical: Boolean,
-        hasLabel: Boolean,
-        layoutDirection: LayoutDirection = LayoutDirection.Ltr
+        isVertical: Boolean,
+        isOutlined: Boolean,
+        layoutDirection: LayoutDirection = LayoutDirection.Ltr,
+        label: @Composable (() -> Unit)? = null,
     ) {
         var size: IntSize? = null
         var position: Offset? = null
@@ -625,27 +575,38 @@
                         singleLine = singleLine,
                         interactionSource = interactionSource
                     ) {
-                        val label: @Composable (() -> Unit)? = if (hasLabel) {
-                            @Composable { Text("Label") }
-                        } else null
-                        TextFieldDecorationBox(
-                            value = value,
-                            innerTextField = {
-                                Box(
-                                    Modifier
-                                        .size(InnerTextFieldWidth, InnerTextFieldHeight)
-                                        .onGloballyPositioned {
-                                            position = it.positionInRoot()
-                                        }
-                                ) { it() }
-                            },
-                            enabled = true,
-                            singleLine = singleLine,
-                            visualTransformation = VisualTransformation.None,
-                            interactionSource = interactionSource,
-                            contentPadding = padding,
-                            label = label
-                        )
+                        val innerTextField: @Composable () -> Unit = {
+                            Box(
+                                Modifier
+                                    .size(InnerTextFieldWidth, InnerTextFieldHeight)
+                                    .onGloballyPositioned {
+                                        position = it.positionInRoot()
+                                    }
+                            ) { it() }
+                        }
+                        if (isOutlined) {
+                            OutlinedTextFieldDecorationBox(
+                                value = value,
+                                innerTextField = innerTextField,
+                                enabled = true,
+                                singleLine = singleLine,
+                                visualTransformation = VisualTransformation.None,
+                                interactionSource = interactionSource,
+                                contentPadding = padding,
+                                label = label
+                            )
+                        } else {
+                            TextFieldDecorationBox(
+                                value = value,
+                                innerTextField = innerTextField,
+                                enabled = true,
+                                singleLine = singleLine,
+                                visualTransformation = VisualTransformation.None,
+                                interactionSource = interactionSource,
+                                contentPadding = padding,
+                                label = label
+                            )
+                        }
                     }
                 }
             }
@@ -654,13 +615,13 @@
         rule.runOnIdle {
             with(Density) {
                 assertThat(size).isNotNull()
-                if (vertical) {
+                if (isVertical) {
                     assertThat(size!!.height).isEqualTo(expectedSize.roundToPx())
                 } else {
                     assertThat(size!!.width).isEqualTo(expectedSize.roundToPx())
                 }
                 assertThat(position).isNotNull()
-                if (vertical) {
+                if (isVertical) {
                     assertThat(position!!.y.roundToInt()).isEqualTo(expectedPosition.roundToPx())
                 } else {
                     assertThat(position!!.x.roundToInt()).isEqualTo(expectedPosition.roundToPx())
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
index e8b7570..8f66a15 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/TextFieldTest.kt
@@ -54,7 +54,6 @@
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.layout.FirstBaseline
 import androidx.compose.ui.layout.onGloballyPositioned
 import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.node.Ref
@@ -120,8 +119,6 @@
     private val ExpectedDefaultTextFieldWidth = TextFieldDefaults.MinWidth
     private val ExpectedPadding = TextFieldPadding
     private val IconPadding = HorizontalIconPadding
-    private val ExpectedBaselineOffset = 20.dp
-    private val TopPaddingFilledTextField = 4.dp
     private val TextFieldTag = "textField"
 
     @get:Rule
@@ -446,7 +443,6 @@
     fun testTextField_labelPosition_whenFocused() {
         val labelSize = Ref<IntSize>()
         val labelPosition = Ref<Offset>()
-        val baseline = Ref<Float>()
         rule.setMaterialContent(lightColorScheme()) {
             Box {
                 TextField(
@@ -459,8 +455,6 @@
                             modifier = Modifier.onGloballyPositioned {
                                 labelPosition.value = it.positionInRoot()
                                 labelSize.value = it.size
-                                baseline.value = it[FirstBaseline].toFloat() +
-                                    labelPosition.value!!.y
                             }
                         )
                     }
@@ -476,12 +470,12 @@
             assertThat(labelSize.value).isNotNull()
             assertThat(labelSize.value?.height).isGreaterThan(0)
             assertThat(labelSize.value?.width).isGreaterThan(0)
-            // label's top position
+
             assertThat(labelPosition.value?.x).isEqualTo(
                 ExpectedPadding.roundToPx().toFloat()
             )
-            assertThat(baseline.value).isEqualTo(
-                ExpectedBaselineOffset.roundToPx().toFloat()
+            assertThat(labelPosition.value?.y).isEqualTo(
+                TextFieldWithLabelVerticalPadding.roundToPx().toFloat()
             )
         }
     }
@@ -490,7 +484,6 @@
     fun testTextField_labelPosition_whenInput() {
         val labelSize = Ref<IntSize>()
         val labelPosition = Ref<Offset>()
-        val baseline = Ref<Float>()
         rule.setMaterialContent(lightColorScheme()) {
             Box {
                 TextField(
@@ -502,8 +495,6 @@
                             modifier = Modifier.onGloballyPositioned {
                                 labelPosition.value = it.positionInRoot()
                                 labelSize.value = it.size
-                                baseline.value =
-                                    it[FirstBaseline].toFloat() + labelPosition.value!!.y
                             }
                         )
                     }
@@ -516,18 +507,19 @@
             assertThat(labelSize.value).isNotNull()
             assertThat(labelSize.value?.height).isGreaterThan(0)
             assertThat(labelSize.value?.width).isGreaterThan(0)
-            // label's top position
+
             assertThat(labelPosition.value?.x).isEqualTo(
                 ExpectedPadding.roundToPx().toFloat()
             )
-            assertThat(baseline.value).isEqualTo(
-                ExpectedBaselineOffset.roundToPx().toFloat()
+            assertThat(labelPosition.value?.y).isEqualTo(
+                TextFieldWithLabelVerticalPadding.roundToPx().toFloat()
             )
         }
     }
 
     @Test
     fun testTextField_placeholderPosition_withLabel() {
+        val labelSize = Ref<IntSize>()
         val placeholderSize = Ref<IntSize>()
         val placeholderPosition = Ref<Offset>()
         rule.setMaterialContent(lightColorScheme()) {
@@ -538,7 +530,14 @@
                         .testTag(TextFieldTag),
                     value = "",
                     onValueChange = {},
-                    label = { Text("label") },
+                    label = {
+                        Text(
+                            text = "label",
+                            modifier = Modifier.onGloballyPositioned {
+                                labelSize.value = it.size
+                            }
+                        )
+                    },
                     placeholder = {
                         Text(
                             text = "placeholder",
@@ -556,6 +555,7 @@
 
         rule.runOnIdleWithDensity {
             // size
+            assertThat(labelSize.value).isNotNull()
             assertThat(placeholderSize.value).isNotNull()
             assertThat(placeholderSize.value?.height).isGreaterThan(0)
             assertThat(placeholderSize.value?.width).isGreaterThan(0)
@@ -565,8 +565,8 @@
             )
             assertThat(placeholderPosition.value?.y)
                 .isEqualTo(
-                    (ExpectedBaselineOffset.roundToPx() + TopPaddingFilledTextField.roundToPx())
-                        .toFloat()
+                    TextFieldWithLabelVerticalPadding.toPx() +
+                        labelSize.value!!.height.toFloat()
                 )
         }
     }
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
index f33b5bc..1060966 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextField.kt
@@ -39,10 +39,8 @@
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.SolidColor
 import androidx.compose.ui.graphics.takeOrElse
-import androidx.compose.ui.layout.AlignmentLine
 import androidx.compose.ui.layout.IntrinsicMeasurable
 import androidx.compose.ui.layout.IntrinsicMeasureScope
-import androidx.compose.ui.layout.LastBaseline
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasurePolicy
@@ -475,8 +473,6 @@
         val topPaddingValue = paddingValues.calculateTopPadding().roundToPx()
         val bottomPaddingValue = paddingValues.calculateBottomPadding().roundToPx()
 
-        // padding between label and input text
-        val topPadding = TextFieldTopPadding.roundToPx()
         var occupiedSpaceHorizontally = 0
         var occupiedSpaceVertically = 0
 
@@ -506,18 +502,9 @@
             )
         val labelPlaceable =
             measurables.find { it.layoutId == LabelId }?.measure(labelConstraints)
-        val lastBaseline = labelPlaceable?.get(LastBaseline)?.let {
-            if (it != AlignmentLine.Unspecified) it else labelPlaceable.height
-        } ?: 0
-        val effectiveLabelBaseline = max(lastBaseline, topPaddingValue)
 
         // measure input field
-        // input field is laid out differently depending on whether the label is present or not
-        val effectiveTopOffset = if (labelPlaceable != null) {
-            effectiveLabelBaseline + topPadding
-        } else {
-            topPaddingValue
-        }
+        val effectiveTopOffset = topPaddingValue + heightOrZero(labelPlaceable)
         val verticalConstraintOffset = -effectiveTopOffset - bottomPaddingValue
         val textFieldConstraints = constraints
             .copy(minHeight = 0)
@@ -550,24 +537,24 @@
         val supportingHeight = heightOrZero(supportingPlaceable)
 
         val width = calculateWidth(
-            widthOrZero(leadingPlaceable),
-            widthOrZero(trailingPlaceable),
-            textFieldPlaceable.width,
-            widthOrZero(labelPlaceable),
-            widthOrZero(placeholderPlaceable),
-            constraints
+            leadingWidth = widthOrZero(leadingPlaceable),
+            trailingWidth = widthOrZero(trailingPlaceable),
+            textFieldWidth = textFieldPlaceable.width,
+            labelWidth = widthOrZero(labelPlaceable),
+            placeholderWidth = widthOrZero(placeholderPlaceable),
+            constraints = constraints,
         )
         val totalHeight = calculateHeight(
-            textFieldPlaceable.height,
-            labelPlaceable != null,
-            effectiveLabelBaseline,
-            heightOrZero(leadingPlaceable),
-            heightOrZero(trailingPlaceable),
-            heightOrZero(placeholderPlaceable),
-            heightOrZero(supportingPlaceable),
-            constraints,
-            density,
-            paddingValues
+            textFieldHeight = textFieldPlaceable.height,
+            labelHeight = heightOrZero(labelPlaceable),
+            leadingHeight = heightOrZero(leadingPlaceable),
+            trailingHeight = heightOrZero(trailingPlaceable),
+            placeholderHeight = heightOrZero(placeholderPlaceable),
+            supportingHeight = heightOrZero(supportingPlaceable),
+            isLabelFocused = animationProgress == 1f,
+            constraints = constraints,
+            density = density,
+            paddingValues = paddingValues,
         )
         val height = totalHeight - supportingHeight
 
@@ -582,37 +569,35 @@
 
         return layout(width, totalHeight) {
             if (labelPlaceable != null) {
-                // label's final position is always relative to the baseline
-                val labelEndPosition = (topPaddingValue - lastBaseline).coerceAtLeast(0)
                 placeWithLabel(
-                    width,
-                    totalHeight,
-                    textFieldPlaceable,
-                    labelPlaceable,
-                    placeholderPlaceable,
-                    leadingPlaceable,
-                    trailingPlaceable,
-                    containerPlaceable,
-                    supportingPlaceable,
-                    singleLine,
-                    labelEndPosition,
-                    effectiveLabelBaseline + topPadding,
-                    animationProgress,
-                    density
+                    width = width,
+                    totalHeight = totalHeight,
+                    textfieldPlaceable = textFieldPlaceable,
+                    labelPlaceable = labelPlaceable,
+                    placeholderPlaceable = placeholderPlaceable,
+                    leadingPlaceable = leadingPlaceable,
+                    trailingPlaceable = trailingPlaceable,
+                    containerPlaceable = containerPlaceable,
+                    supportingPlaceable = supportingPlaceable,
+                    singleLine = singleLine,
+                    labelEndPosition = topPaddingValue,
+                    textPosition = topPaddingValue + labelPlaceable.height,
+                    animationProgress = animationProgress,
+                    density = density,
                 )
             } else {
                 placeWithoutLabel(
-                    width,
-                    totalHeight,
-                    textFieldPlaceable,
-                    placeholderPlaceable,
-                    leadingPlaceable,
-                    trailingPlaceable,
-                    containerPlaceable,
-                    supportingPlaceable,
-                    singleLine,
-                    density,
-                    paddingValues
+                    width = width,
+                    totalHeight = totalHeight,
+                    textPlaceable = textFieldPlaceable,
+                    placeholderPlaceable = placeholderPlaceable,
+                    leadingPlaceable = leadingPlaceable,
+                    trailingPlaceable = trailingPlaceable,
+                    containerPlaceable = containerPlaceable,
+                    supportingPlaceable = supportingPlaceable,
+                    singleLine = singleLine,
+                    density = density,
+                    paddingValues = paddingValues
                 )
             }
         }
@@ -707,12 +692,12 @@
         } ?: 0
         return calculateHeight(
             textFieldHeight = textFieldHeight,
-            hasLabel = labelHeight > 0,
-            labelBaseline = labelHeight,
+            labelHeight = labelHeight,
             leadingHeight = leadingHeight,
             trailingHeight = trailingHeight,
             placeholderHeight = placeholderHeight,
             supportingHeight = supportingHeight,
+            isLabelFocused = animationProgress == 1f,
             constraints = ZeroConstraints,
             density = density,
             paddingValues = paddingValues
@@ -739,25 +724,28 @@
 
 private fun calculateHeight(
     textFieldHeight: Int,
-    hasLabel: Boolean,
-    labelBaseline: Int,
+    labelHeight: Int,
     leadingHeight: Int,
     trailingHeight: Int,
     placeholderHeight: Int,
     supportingHeight: Int,
+    isLabelFocused: Boolean,
     constraints: Constraints,
     density: Float,
     paddingValues: PaddingValues
 ): Int {
-    val paddingToLabel = TextFieldTopPadding.value * density
-    val topPaddingValue = paddingValues.calculateTopPadding().value * density
-    val bottomPaddingValue = paddingValues.calculateBottomPadding().value * density
-
-    val inputFieldHeight = max(textFieldHeight, placeholderHeight)
-    val middleSectionHeight = if (hasLabel) {
-        labelBaseline + paddingToLabel + inputFieldHeight + bottomPaddingValue
+    // Even though the padding is defined by the developer, it only affects the text field when the
+    // text field is focused. Otherwise, we use the default value.
+    val verticalPadding = density * if (isLabelFocused) {
+        (paddingValues.calculateTopPadding() + paddingValues.calculateBottomPadding()).value
     } else {
-        topPaddingValue + inputFieldHeight + bottomPaddingValue
+        (TextFieldPadding * 2).value
+    }
+
+    val middleSectionHeight = if (isLabelFocused) {
+        verticalPadding + labelHeight + max(textFieldHeight, placeholderHeight)
+    } else {
+        verticalPadding + maxOf(labelHeight, textFieldHeight, placeholderHeight)
     }
     return max(
         constraints.minHeight,
@@ -770,8 +758,8 @@
 }
 
 /**
- * Places the provided text field, placeholder and label with respect to the baseline offsets in
- * [TextField] when there is a label. When there is no label, [placeWithoutLabel] is used.
+ * Places the provided text field, placeholder, and label in the TextField given the PaddingValues
+ * when there is a label. When there is no label, [placeWithoutLabel] is used instead.
  */
 private fun Placeable.PlacementScope.placeWithLabel(
     width: Int,
@@ -811,9 +799,8 @@
         val startPosition = if (singleLine) {
             Alignment.CenterVertically.align(it.height, height)
         } else {
-            // even though the padding is defined by developer, it only affects text field when
-            // animation progress == 1, which is when text field is focused or non-empty input text.
-            // The start position of the label is always 16.dp.
+            // Even though the padding is defined by the developer, it only affects the text field
+            // when the text field is focused. Otherwise, we use the default value.
             (TextFieldPadding.value * density).roundToInt()
         }
         val distance = startPosition - labelEndPosition
@@ -867,10 +854,7 @@
     } else {
         topPadding
     }
-    textPlaceable.placeRelative(
-        widthOrZero(leadingPlaceable),
-        textVerticalPosition
-    )
+    textPlaceable.placeRelative(widthOrZero(leadingPlaceable), textVerticalPosition)
 
     // placeholder is placed similar to the text input above
     placeholderPlaceable?.let {
@@ -879,10 +863,7 @@
         } else {
             topPadding
         }
-        it.placeRelative(
-            widthOrZero(leadingPlaceable),
-            placeholderVerticalPosition
-        )
+        it.placeRelative(widthOrZero(leadingPlaceable), placeholderVerticalPosition)
     }
 
     supportingPlaceable?.placeRelative(0, height)
@@ -907,12 +888,6 @@
     }
 }
 
-/** Padding from the label's baseline to the top */
-internal val FirstBaselineOffset = 20.dp
-
-/** Padding from input field to the bottom */
-internal val TextFieldBottomPadding = 10.dp
-
-/** Padding from label's baseline (or FirstBaselineOffset) to the input field */
+/** Padding from text field top to label top, and from input field bottom to text field bottom */
 /*@VisibleForTesting*/
-internal val TextFieldTopPadding = 4.dp
\ No newline at end of file
+internal val TextFieldWithLabelVerticalPadding = 8.dp
\ No newline at end of file
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
index 0cb9f1e..cb61fe6 100644
--- a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/TextFieldDefaults.kt
@@ -44,7 +44,6 @@
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
 import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.layout.LastBaseline
 import androidx.compose.ui.platform.debugInspectorInfo
 import androidx.compose.ui.text.input.VisualTransformation
 import androidx.compose.ui.unit.Dp
@@ -199,19 +198,18 @@
     /**
      * Default content padding applied to [TextField] when there is a label.
      *
-     * Note that when label is present, the "top" padding (unlike rest of the paddings) is a
-     * distance between the label's last baseline and the top edge of the [TextField]. If the "top"
-     * value is smaller than the last baseline of the label, then there will be no space between
-     * the label and top edge of the [TextField].
+     * Note that when the label is present, the "top" padding is a distance between the top edge of
+     * the [TextField] and the top of the label, not to the top of the input field. The input field
+     * is placed directly beneath the label.
      *
-     * See [PaddingValues]
+     * See [PaddingValues] for more details.
      */
     @ExperimentalMaterial3Api
     fun textFieldWithLabelPadding(
         start: Dp = TextFieldPadding,
         end: Dp = TextFieldPadding,
-        top: Dp = FirstBaselineOffset,
-        bottom: Dp = TextFieldBottomPadding
+        top: Dp = TextFieldWithLabelVerticalPadding,
+        bottom: Dp = TextFieldWithLabelVerticalPadding
     ): PaddingValues = PaddingValues(start, top, end, bottom)
 
     /**
@@ -515,11 +513,12 @@
      * @param contentPadding the spacing values to apply internally between the internals of text
      * field and the decoration box container. You can use it to implement dense text fields or
      * simply to control horizontal padding. See [TextFieldDefaults.textFieldWithLabelPadding] and
-     * [TextFieldDefaults.textFieldWithoutLabelPadding]
+     * [TextFieldDefaults.textFieldWithoutLabelPadding].
      * Note that if there's a label in the text field, the [top][PaddingValues.calculateTopPadding]
-     * padding will mean the distance from label's [last baseline][LastBaseline] to the top edge of
-     * the container. All other paddings mean the distance from the corresponding edge of the
-     * container to the corresponding edge of the closest to it element
+     * padding represents the distance from the top edge of the container to the top of the label.
+     * Otherwise if label is null, it represents the distance from the top edge of the container to
+     * the top of the input field. All other paddings represent the distance from the corresponding
+     * edge of the container to the corresponding edge of the closest element.
      * @param container the container to be drawn behind the text field. By default, this includes
      * the bottom indicator line. Default colors for the container come from the [colors].
      */