Merge changes from topic "edm" into androidx-main

* changes:
  Add ExposedDropdownMenu to Material 3.
  Fork M2 ExposedDropdownMenu files to M3.
  Add component tokens for M3 ExposedDropdownMenu/Autocomplete.
diff --git a/compose/material3/material3/api/current.txt b/compose/material3/material3/api/current.txt
index bea3208..34d2acc 100644
--- a/compose/material3/material3/api/current.txt
+++ b/compose/material3/material3/api/current.txt
@@ -193,6 +193,9 @@
   public final class ElevationKt {
   }
 
+  public final class ExposedDropdownMenuKt {
+  }
+
   public final class FloatingActionButtonDefaults {
     method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
     method public float getLargeIconSize();
@@ -572,3 +575,10 @@
 
 }
 
+package androidx.compose.material3.internal {
+
+  public final class ExposedDropdownMenuPopupKt {
+  }
+
+}
+
diff --git a/compose/material3/material3/api/public_plus_experimental_current.txt b/compose/material3/material3/api/public_plus_experimental_current.txt
index e072c12..9664055 100644
--- a/compose/material3/material3/api/public_plus_experimental_current.txt
+++ b/compose/material3/material3/api/public_plus_experimental_current.txt
@@ -245,6 +245,22 @@
   @kotlin.RequiresOptIn(message="This material API is experimental and is likely to change or to be removed in" + " the future.") public @interface ExperimentalMaterial3Api {
   }
 
+  @androidx.compose.material3.ExperimentalMaterial3Api public interface ExposedDropdownMenuBoxScope {
+    method @androidx.compose.runtime.Composable public default void ExposedDropdownMenu(boolean expanded, kotlin.jvm.functions.Function0<kotlin.Unit> onDismissRequest, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.foundation.layout.ColumnScope,kotlin.Unit> content);
+    method public androidx.compose.ui.Modifier exposedDropdownSize(androidx.compose.ui.Modifier, optional boolean matchTextFieldWidth);
+  }
+
+  @androidx.compose.material3.ExperimentalMaterial3Api public final class ExposedDropdownMenuDefaults {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public void TrailingIcon(boolean expanded, optional kotlin.jvm.functions.Function0<kotlin.Unit> onIconClick);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors outlinedTextFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedBorderColor, optional long unfocusedBorderColor, optional long disabledBorderColor, optional long errorBorderColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    method @androidx.compose.runtime.Composable public androidx.compose.material3.TextFieldColors textFieldColors(optional long textColor, optional long disabledTextColor, optional long backgroundColor, optional long cursorColor, optional long errorCursorColor, optional long focusedIndicatorColor, optional long unfocusedIndicatorColor, optional long disabledIndicatorColor, optional long errorIndicatorColor, optional long focusedLeadingIconColor, optional long unfocusedLeadingIconColor, optional long disabledLeadingIconColor, optional long errorLeadingIconColor, optional long focusedTrailingIconColor, optional long unfocusedTrailingIconColor, optional long disabledTrailingIconColor, optional long errorTrailingIconColor, optional long focusedLabelColor, optional long unfocusedLabelColor, optional long disabledLabelColor, optional long errorLabelColor, optional long placeholderColor, optional long disabledPlaceholderColor);
+    field public static final androidx.compose.material3.ExposedDropdownMenuDefaults INSTANCE;
+  }
+
+  public final class ExposedDropdownMenuKt {
+    method @androidx.compose.material3.ExperimentalMaterial3Api @androidx.compose.runtime.Composable public static void ExposedDropdownMenuBox(boolean expanded, kotlin.jvm.functions.Function1<? super java.lang.Boolean,kotlin.Unit> onExpandedChange, optional androidx.compose.ui.Modifier modifier, kotlin.jvm.functions.Function1<? super androidx.compose.material3.ExposedDropdownMenuBoxScope,kotlin.Unit> content);
+  }
+
   @androidx.compose.material3.ExperimentalMaterial3Api public final inline class FabPosition {
     ctor public FabPosition();
   }
@@ -673,3 +689,10 @@
 
 }
 
+package androidx.compose.material3.internal {
+
+  public final class ExposedDropdownMenuPopupKt {
+  }
+
+}
+
diff --git a/compose/material3/material3/api/restricted_current.txt b/compose/material3/material3/api/restricted_current.txt
index bea3208..34d2acc 100644
--- a/compose/material3/material3/api/restricted_current.txt
+++ b/compose/material3/material3/api/restricted_current.txt
@@ -193,6 +193,9 @@
   public final class ElevationKt {
   }
 
+  public final class ExposedDropdownMenuKt {
+  }
+
   public final class FloatingActionButtonDefaults {
     method @androidx.compose.runtime.Composable public androidx.compose.material3.FloatingActionButtonElevation elevation(optional float defaultElevation, optional float pressedElevation, optional float focusedElevation, optional float hoveredElevation);
     method public float getLargeIconSize();
@@ -572,3 +575,10 @@
 
 }
 
+package androidx.compose.material3.internal {
+
+  public final class ExposedDropdownMenuPopupKt {
+  }
+
+}
+
diff --git a/compose/material3/material3/build.gradle b/compose/material3/material3/build.gradle
index 1e71dee..b41dc26 100644
--- a/compose/material3/material3/build.gradle
+++ b/compose/material3/material3/build.gradle
@@ -48,6 +48,11 @@
         api("androidx.compose.ui:ui:1.1.0-rc01")
         api("androidx.compose.ui:ui-text:1.0.1")
 
+        // TODO: remove next 3 dependencies when b/202810604 is fixed
+        implementation("androidx.savedstate:savedstate:1.1.0")
+        implementation("androidx.lifecycle:lifecycle-runtime:2.3.0")
+        implementation("androidx.lifecycle:lifecycle-viewmodel:2.3.0")
+
         testImplementation(libs.testRules)
         testImplementation(libs.testRunner)
         testImplementation(libs.junit)
@@ -63,6 +68,7 @@
         androidTestImplementation(libs.dexmakerMockito)
         androidTestImplementation(libs.mockitoCore)
         androidTestImplementation(libs.mockitoKotlin)
+        androidTestImplementation(libs.testUiautomator)
     }
 }
 
@@ -94,6 +100,11 @@
 
             androidMain.dependencies {
                 api("androidx.annotation:annotation:1.1.0")
+
+                // TODO: remove next 3 dependencies when b/202810604 is fixed
+                implementation("androidx.savedstate:savedstate:1.1.0")
+                implementation("androidx.lifecycle:lifecycle-runtime:2.3.0")
+                implementation("androidx.lifecycle:lifecycle-viewmodel:2.3.0")
             }
 
             desktopMain.dependencies {
@@ -123,6 +134,7 @@
                 implementation(libs.dexmakerMockito)
                 implementation(libs.mockitoCore)
                 implementation(libs.mockitoKotlin)
+                implementation(libs.testUiautomator)
             }
         }
     }
diff --git a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
index 57c1b3d..b1b736f 100644
--- a/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
+++ b/compose/material3/material3/integration-tests/material3-catalog/src/main/java/androidx/compose/material3/catalog/library/model/Examples.kt
@@ -35,11 +35,13 @@
 import androidx.compose.material3.samples.ClickableElevatedCardSample
 import androidx.compose.material3.samples.ClickableOutlinedCardSample
 import androidx.compose.material3.samples.DismissibleNavigationDrawerSample
+import androidx.compose.material3.samples.EditableExposedDropdownMenuSample
 import androidx.compose.material3.samples.ElevatedButtonSample
 import androidx.compose.material3.samples.ElevatedCardSample
 import androidx.compose.material3.samples.EnterAlwaysSmallTopAppBar
 import androidx.compose.material3.samples.ExitUntilCollapsedLargeTopAppBar
 import androidx.compose.material3.samples.ExitUntilCollapsedMediumTopAppBar
+import androidx.compose.material3.samples.ExposedDropdownMenuSample
 import androidx.compose.material3.samples.ExtendedFloatingActionButtonSample
 import androidx.compose.material3.samples.ExtendedFloatingActionButtonTextSample
 import androidx.compose.material3.samples.FancyTabs
@@ -323,7 +325,21 @@
         sourceUrl = MenusExampleSourceUrl
     ) {
         MenuSample()
-    }
+    },
+    Example(
+        name = ::ExposedDropdownMenuSample.name,
+        description = MenusExampleDescription,
+        sourceUrl = MenusExampleSourceUrl
+    ) {
+        ExposedDropdownMenuSample()
+    },
+    Example(
+        name = ::EditableExposedDropdownMenuSample.name,
+        description = MenusExampleDescription,
+        sourceUrl = MenusExampleSourceUrl
+    ) {
+        EditableExposedDropdownMenuSample()
+    },
 )
 
 private const val NavigationBarExampleDescription = "Navigation bar examples"
diff --git a/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ExposedDropdownMenuSamples.kt b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ExposedDropdownMenuSamples.kt
new file mode 100644
index 0000000..37d0ab2
--- /dev/null
+++ b/compose/material3/material3/samples/src/main/java/androidx/compose/material3/samples/ExposedDropdownMenuSamples.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.samples
+
+import androidx.annotation.Sampled
+import androidx.compose.material3.DropdownMenuItem
+import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExposedDropdownMenuBox
+import androidx.compose.material3.ExposedDropdownMenuDefaults
+import androidx.compose.material3.Text
+import androidx.compose.material3.TextField
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Sampled
+@Composable
+fun ExposedDropdownMenuSample() {
+    val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
+    var expanded by remember { mutableStateOf(false) }
+    var selectedOptionText by remember { mutableStateOf(options[0]) }
+    // We want to react on tap/press on TextField to show menu
+    ExposedDropdownMenuBox(
+        expanded = expanded,
+        onExpandedChange = { expanded = !expanded },
+    ) {
+        TextField(
+            readOnly = true,
+            value = selectedOptionText,
+            onValueChange = {},
+            label = { Text("Label") },
+            trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
+            colors = ExposedDropdownMenuDefaults.textFieldColors(),
+        )
+        ExposedDropdownMenu(
+            expanded = expanded,
+            onDismissRequest = { expanded = false },
+        ) {
+            options.forEach { selectionOption ->
+                DropdownMenuItem(
+                    text = { Text(selectionOption) },
+                    onClick = {
+                        selectedOptionText = selectionOption
+                        expanded = false
+                    }
+                )
+            }
+        }
+    }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Sampled
+@Composable
+fun EditableExposedDropdownMenuSample() {
+    val options = listOf("Option 1", "Option 2", "Option 3", "Option 4", "Option 5")
+    var expanded by remember { mutableStateOf(false) }
+    var selectedOptionText by remember { mutableStateOf("") }
+    ExposedDropdownMenuBox(
+        expanded = expanded,
+        onExpandedChange = { expanded = !expanded },
+    ) {
+        TextField(
+            value = selectedOptionText,
+            onValueChange = { selectedOptionText = it },
+            label = { Text("Label") },
+            trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = expanded) },
+            colors = ExposedDropdownMenuDefaults.textFieldColors(),
+        )
+        // filter options based on text field value
+        val filteringOptions = options.filter { it.contains(selectedOptionText, ignoreCase = true) }
+        if (filteringOptions.isNotEmpty()) {
+            ExposedDropdownMenu(
+                expanded = expanded,
+                onDismissRequest = { expanded = false },
+            ) {
+                filteringOptions.forEach { selectionOption ->
+                    DropdownMenuItem(
+                        text = { Text(selectionOption) },
+                        onClick = {
+                            selectedOptionText = selectionOption
+                            expanded = false
+                        }
+                    )
+                }
+            }
+        }
+    }
+}
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt
new file mode 100644
index 0000000..3b92a5c
--- /dev/null
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ExposedDropdownMenuTest.kt
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3
+
+import android.widget.FrameLayout
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.size
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Rect
+import androidx.compose.ui.layout.boundsInRoot
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.platform.testTag
+import androidx.compose.ui.test.assertIsDisplayed
+import androidx.compose.ui.test.assertIsFocused
+import androidx.compose.ui.test.assertTextContains
+import androidx.compose.ui.test.junit4.createComposeRule
+import androidx.compose.ui.test.onNodeWithTag
+import androidx.compose.ui.test.performClick
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.viewinterop.AndroidView
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.uiautomator.UiDevice
+import com.google.common.truth.Truth.assertThat
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@OptIn(ExperimentalMaterial3Api::class)
+@MediumTest
+@RunWith(AndroidJUnit4::class)
+class ExposedDropdownMenuTest {
+
+    @get:Rule
+    val rule = createComposeRule()
+
+    private val EDMBoxTag = "ExposedDropdownMenuBoxTag"
+    private val TFTag = "TextFieldTag"
+    private val TrailingIconTag = "TrailingIconTag"
+    private val EDMTag = "ExposedDropdownMenuTag"
+    private val MenuItemTag = "MenuItemTag"
+    private val OptionName = "Option 1"
+
+    @Test
+    fun expandedBehaviour_expandsOnClickAndCollapsesOnOutside() {
+        var textFieldBounds = Rect.Zero
+        rule.setMaterialContent(lightColorScheme()) {
+            var expanded by remember { mutableStateOf(false) }
+            ExposedDropdownMenuForTest(
+                expanded = expanded,
+                onExpandChange = { expanded = it },
+                onTextFieldBoundsChanged = {
+                    textFieldBounds = it
+                }
+            )
+        }
+
+        rule.onNodeWithTag(TFTag).assertIsDisplayed()
+        rule.onNodeWithTag(EDMTag).assertDoesNotExist()
+
+        // Click on the TextField
+        rule.onNodeWithTag(TFTag).performClick()
+
+        rule.onNodeWithTag(MenuItemTag).assertIsDisplayed()
+
+        // Click outside EDM
+        UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()).click(
+            (textFieldBounds.right + 1).toInt(),
+            (textFieldBounds.bottom + 1).toInt(),
+        )
+
+        rule.onNodeWithTag(MenuItemTag).assertDoesNotExist()
+    }
+
+    @Test
+    fun expandedBehaviour_collapseOnTextFieldClick() {
+        rule.setMaterialContent(lightColorScheme()) {
+            var expanded by remember { mutableStateOf(true) }
+            ExposedDropdownMenuForTest(
+                expanded = expanded,
+                onExpandChange = { expanded = it }
+            )
+        }
+
+        rule.onNodeWithTag(TFTag).assertIsDisplayed()
+        rule.onNodeWithTag(EDMTag).assertIsDisplayed()
+        rule.onNodeWithTag(MenuItemTag).assertIsDisplayed()
+
+        // Click on the TextField
+        rule.onNodeWithTag(TFTag).performClick()
+
+        rule.onNodeWithTag(MenuItemTag).assertDoesNotExist()
+    }
+
+    @Test
+    fun expandedBehaviour_expandsAndFocusesTextFieldOnTrailingIconClick() {
+        rule.setMaterialContent(lightColorScheme()) {
+            var expanded by remember { mutableStateOf(false) }
+            ExposedDropdownMenuForTest(
+                expanded = expanded,
+                onExpandChange = { expanded = it },
+            )
+        }
+
+        rule.onNodeWithTag(TFTag).assertIsDisplayed()
+        rule.onNodeWithTag(TrailingIconTag, useUnmergedTree = true).assertIsDisplayed()
+
+        // Click on the Trailing Icon
+        rule.onNodeWithTag(TrailingIconTag, useUnmergedTree = true).performClick()
+
+        rule.onNodeWithTag(TFTag).assertIsFocused()
+        rule.onNodeWithTag(MenuItemTag).assertIsDisplayed()
+    }
+
+    @Test
+    fun uiProperties_menuMatchesTextWidth() {
+        var textFieldBounds by mutableStateOf(Rect.Zero)
+        var menuBounds by mutableStateOf(Rect.Zero)
+        rule.setMaterialContent(lightColorScheme()) {
+            var expanded by remember { mutableStateOf(true) }
+            ExposedDropdownMenuForTest(
+                expanded = expanded,
+                onExpandChange = { expanded = it },
+                onTextFieldBoundsChanged = {
+                    textFieldBounds = it
+                },
+                onMenuBoundsChanged = {
+                    menuBounds = it
+                }
+            )
+        }
+
+        rule.onNodeWithTag(TFTag).assertIsDisplayed()
+        rule.onNodeWithTag(MenuItemTag).assertIsDisplayed()
+
+        rule.runOnIdle {
+            assertThat(menuBounds.width).isEqualTo(textFieldBounds.width)
+        }
+    }
+
+    @Test
+    fun EDMBehaviour_rightOptionIsChosen() {
+        rule.setMaterialContent(lightColorScheme()) {
+            var expanded by remember { mutableStateOf(true) }
+            ExposedDropdownMenuForTest(
+                expanded = expanded,
+                onExpandChange = { expanded = it }
+            )
+        }
+
+        rule.onNodeWithTag(TFTag).assertIsDisplayed()
+        rule.onNodeWithTag(MenuItemTag).assertIsDisplayed()
+
+        // Choose the option
+        rule.onNodeWithTag(MenuItemTag).performClick()
+
+        // Menu should collapse
+        rule.onNodeWithTag(MenuItemTag).assertDoesNotExist()
+        rule.onNodeWithTag(TFTag).assertTextContains(OptionName)
+    }
+
+    @Test
+    fun doesNotCrashWhenAnchorDetachedFirst() {
+        var parent: FrameLayout? = null
+        rule.setContent {
+            AndroidView(
+                factory = { context ->
+                    FrameLayout(context).apply {
+                        addView(ComposeView(context).apply {
+                            setContent {
+                                Box {
+                                    ExposedDropdownMenuBox(expanded = true, onExpandedChange = {}) {
+                                        Box(Modifier.size(20.dp))
+                                    }
+                                }
+                            }
+                        })
+                    }.also { parent = it }
+                }
+            )
+        }
+
+        rule.runOnIdle {
+            parent!!.removeAllViews()
+        }
+
+        rule.waitForIdle()
+
+        // Should not have crashed.
+    }
+
+    @Composable
+    fun ExposedDropdownMenuForTest(
+        expanded: Boolean,
+        onExpandChange: (Boolean) -> Unit,
+        onTextFieldBoundsChanged: ((Rect) -> Unit)? = null,
+        onMenuBoundsChanged: ((Rect) -> Unit)? = null
+    ) {
+        var selectedOptionText by remember { mutableStateOf("") }
+        Box(Modifier.fillMaxSize()) {
+            ExposedDropdownMenuBox(
+                modifier = Modifier.testTag(EDMBoxTag).align(Alignment.Center),
+                expanded = expanded,
+                onExpandedChange = { onExpandChange(!expanded) }
+            ) {
+                TextField(
+                    modifier = Modifier.testTag(TFTag)
+                        .onGloballyPositioned {
+                            onTextFieldBoundsChanged?.invoke(it.boundsInRoot())
+                        },
+                    value = selectedOptionText,
+                    onValueChange = { selectedOptionText = it },
+                    label = { Text("Label") },
+                    trailingIcon = {
+                        Box(
+                            modifier = Modifier.testTag(TrailingIconTag)
+                        ) {
+                            ExposedDropdownMenuDefaults.TrailingIcon(
+                                expanded = expanded
+                            )
+                        }
+                    },
+                    colors = ExposedDropdownMenuDefaults.textFieldColors()
+                )
+                ExposedDropdownMenu(
+                    modifier = Modifier.testTag(EDMTag).onGloballyPositioned {
+                        onMenuBoundsChanged?.invoke(it.boundsInRoot())
+                    },
+                    expanded = expanded,
+                    onDismissRequest = { onExpandChange(false) }
+                ) {
+                    DropdownMenuItem(
+                        text = { Text(OptionName) },
+                        onClick = {
+                            selectedOptionText = OptionName
+                            onExpandChange(false)
+                        },
+                        modifier = Modifier.testTag(MenuItemTag)
+                    )
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
new file mode 100644
index 0000000..f8f9dbe
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ExposedDropdownMenu.kt
@@ -0,0 +1,579 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3
+
+import android.graphics.Rect
+import android.view.View
+import android.view.ViewTreeObserver
+import androidx.compose.animation.core.MutableTransitionState
+import androidx.compose.foundation.gestures.forEachGesture
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.foundation.layout.heightIn
+import androidx.compose.foundation.layout.width
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowDropDown
+import androidx.compose.material3.internal.ExposedDropdownMenuPopup
+import androidx.compose.material3.tokens.FilledAutocompleteTokens
+import androidx.compose.material3.tokens.OutlinedAutocompleteTokens
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.SideEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.rotate
+import androidx.compose.ui.focus.FocusRequester
+import androidx.compose.ui.focus.focusRequester
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.TransformOrigin
+import androidx.compose.ui.input.pointer.PointerEvent
+import androidx.compose.ui.input.pointer.PointerEventPass
+import androidx.compose.ui.input.pointer.changedToUp
+import androidx.compose.ui.input.pointer.pointerInput
+import androidx.compose.ui.layout.LayoutCoordinates
+import androidx.compose.ui.layout.boundsInWindow
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.node.Ref
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.semantics.clearAndSetSemantics
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.onClick
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.DpOffset
+import androidx.compose.ui.util.fastAll
+import kotlin.math.max
+import kotlinx.coroutines.coroutineScope
+
+/**
+ * <a href="https://m3.material.io/components/menus/overview" class="external" target="_blank">Material Design Exposed Dropdown Menu</a>.
+ *
+ * Exposed dropdown menus display the currently selected item in a text field above the menu. In
+ * some cases, it can accept and display user input (whether or not it’s listed as a menu choice).
+ * If the text field input is used to filter results in the menu, the component is also known as
+ * "autocomplete" or a "combobox".
+ *
+ * The [ExposedDropdownMenuBox] is expected to contain a [TextField] (or [OutlinedTextField]) and
+ * [ExposedDropdownMenuBoxScope.ExposedDropdownMenu] as content.
+ *
+ * An example of read-only Exposed Dropdown Menu:
+ * @sample androidx.compose.material3.samples.ExposedDropdownMenuSample
+ *
+ * An example of editable Exposed Dropdown Menu:
+ * @sample androidx.compose.material3.samples.EditableExposedDropdownMenuSample
+ *
+ * @param expanded Whether the dropdown menu is expanded or not.
+ * @param onExpandedChange Executes when the user clicks on the ExposedDropdownMenuBox and the
+ * expansion state changes.
+ * @param modifier The modifier to apply to this layout.
+ * @param content The content to be displayed inside ExposedDropdownMenuBox.
+ */
+@ExperimentalMaterial3Api
+@Composable
+fun ExposedDropdownMenuBox(
+    expanded: Boolean,
+    onExpandedChange: (Boolean) -> Unit,
+    modifier: Modifier = Modifier,
+    content: @Composable ExposedDropdownMenuBoxScope.() -> Unit
+) {
+    val density = LocalDensity.current
+    val view = LocalView.current
+    var width by remember { mutableStateOf(0) }
+    var menuHeight by remember { mutableStateOf(0) }
+    val verticalMarginInPx = with(density) { MenuVerticalMargin.roundToPx() }
+    val coordinates = remember { Ref<LayoutCoordinates>() }
+
+    val scope = remember(density, menuHeight, width) {
+        object : ExposedDropdownMenuBoxScope {
+            override fun Modifier.exposedDropdownSize(matchTextFieldWidth: Boolean): Modifier {
+                return with(density) {
+                    heightIn(max = menuHeight.toDp()).let {
+                        if (matchTextFieldWidth) {
+                            it.width(width.toDp())
+                        } else it
+                    }
+                }
+            }
+        }
+    }
+    val focusRequester = remember { FocusRequester() }
+
+    Box(
+        modifier.onGloballyPositioned {
+            width = it.size.width
+            coordinates.value = it
+            updateHeight(
+                view.rootView,
+                coordinates.value,
+                verticalMarginInPx
+            ) { newHeight ->
+                menuHeight = newHeight
+            }
+        }.expandable(
+            onExpandedChange = { onExpandedChange(!expanded) },
+            menuLabel = getString(Strings.ExposedDropdownMenu)
+        ).focusRequester(focusRequester)
+    ) {
+        scope.content()
+    }
+
+    SideEffect {
+        if (expanded) focusRequester.requestFocus()
+    }
+
+    DisposableEffect(view) {
+        val listener = OnGlobalLayoutListener(view) {
+            // We want to recalculate the menu height on relayout - e.g. when keyboard shows up.
+            updateHeight(
+                view.rootView,
+                coordinates.value,
+                verticalMarginInPx
+            ) { newHeight ->
+                menuHeight = newHeight
+            }
+        }
+        onDispose { listener.dispose() }
+    }
+}
+
+/**
+ * Subscribes to onGlobalLayout and correctly removes the callback when the View is detached.
+ * Logic copied from AndroidPopup.android.kt.
+ */
+private class OnGlobalLayoutListener(
+    private val view: View,
+    private val onGlobalLayoutCallback: () -> Unit
+) : View.OnAttachStateChangeListener, ViewTreeObserver.OnGlobalLayoutListener {
+    private var isListeningToGlobalLayout = false
+
+    init {
+        view.addOnAttachStateChangeListener(this)
+        registerOnGlobalLayoutListener()
+    }
+
+    override fun onViewAttachedToWindow(p0: View?) = registerOnGlobalLayoutListener()
+
+    override fun onViewDetachedFromWindow(p0: View?) = unregisterOnGlobalLayoutListener()
+
+    override fun onGlobalLayout() = onGlobalLayoutCallback()
+
+    private fun registerOnGlobalLayoutListener() {
+        if (isListeningToGlobalLayout || !view.isAttachedToWindow) return
+        view.viewTreeObserver.addOnGlobalLayoutListener(this)
+        isListeningToGlobalLayout = true
+    }
+
+    private fun unregisterOnGlobalLayoutListener() {
+        if (!isListeningToGlobalLayout) return
+        view.viewTreeObserver.removeOnGlobalLayoutListener(this)
+        isListeningToGlobalLayout = false
+    }
+
+    fun dispose() {
+        unregisterOnGlobalLayoutListener()
+        view.removeOnAttachStateChangeListener(this)
+    }
+}
+
+/**
+ * Scope for [ExposedDropdownMenuBox].
+ */
+@ExperimentalMaterial3Api
+interface ExposedDropdownMenuBoxScope {
+    /**
+     * Modifier which should be applied to an [ExposedDropdownMenu]
+     * placed inside the scope. It's responsible for
+     * setting the width of the [ExposedDropdownMenu], which
+     * will match the width of the [TextField]
+     * (if [matchTextFieldWidth] is set to true).
+     * Also it'll change the height of [ExposedDropdownMenu], so
+     * it'll take the largest possible height to not overlap
+     * the [TextField] and the software keyboard.
+     *
+     * @param matchTextFieldWidth Whether menu should match
+     * the width of the text field to which it's attached.
+     * If set to true the width will match the width
+     * of the text field.
+     */
+    fun Modifier.exposedDropdownSize(
+        matchTextFieldWidth: Boolean = true
+    ): Modifier
+
+    /**
+     * Popup which contains content for Exposed Dropdown Menu.
+     * Should be used inside the content of [ExposedDropdownMenuBox].
+     *
+     * @param expanded Whether the menu is currently open and visible to the user
+     * @param onDismissRequest Called when the user requests to dismiss the menu, such as by
+     * tapping outside the menu's bounds
+     * @param modifier The modifier to apply to this layout
+     * @param content The content of the [ExposedDropdownMenu]
+     */
+    @Composable
+    fun ExposedDropdownMenu(
+        expanded: Boolean,
+        onDismissRequest: () -> Unit,
+        modifier: Modifier = Modifier,
+        content: @Composable ColumnScope.() -> Unit
+    ) {
+        // TODO(b/202810604): use DropdownMenu when PopupProperties constructor is stable
+        // return DropdownMenu(
+        //     expanded = expanded,
+        //     onDismissRequest = onDismissRequest,
+        //     modifier = modifier.exposedDropdownSize(),
+        //     properties = ExposedDropdownMenuDefaults.PopupProperties,
+        //     content = content
+        // )
+
+        val expandedStates = remember { MutableTransitionState(false) }
+        expandedStates.targetState = expanded
+
+        if (expandedStates.currentState || expandedStates.targetState) {
+            val transformOriginState = remember { mutableStateOf(TransformOrigin.Center) }
+            val density = LocalDensity.current
+            val popupPositionProvider = DropdownMenuPositionProvider(
+                DpOffset.Zero,
+                density
+            ) { parentBounds, menuBounds ->
+                transformOriginState.value = calculateTransformOrigin(parentBounds, menuBounds)
+            }
+
+            ExposedDropdownMenuPopup(
+                onDismissRequest = onDismissRequest,
+                popupPositionProvider = popupPositionProvider
+            ) {
+                DropdownMenuContent(
+                    expandedStates = expandedStates,
+                    transformOriginState = transformOriginState,
+                    modifier = modifier.exposedDropdownSize(),
+                    content = content
+                )
+            }
+        }
+    }
+}
+
+/**
+ * Contains default values used by Exposed Dropdown Menu.
+ */
+@ExperimentalMaterial3Api
+object ExposedDropdownMenuDefaults {
+    /**
+     * Default trailing icon for Exposed Dropdown Menu.
+     *
+     * @param expanded Whether [ExposedDropdownMenuBoxScope.ExposedDropdownMenu]
+     * is expanded or not. Affects the appearance of the icon.
+     * @param onIconClick Called when the icon was clicked.
+     */
+    @ExperimentalMaterial3Api
+    @Composable
+    fun TrailingIcon(
+        expanded: Boolean,
+        onIconClick: () -> Unit = {}
+    ) {
+        // Clear semantics here as otherwise icon will be a11y focusable but without an
+        // action. When there's an API to check if Talkback is on, developer will be able to
+        // expand the menu on icon click in a11y mode only esp. if using their own custom
+        // trailing icon.
+        IconButton(onClick = onIconClick, modifier = Modifier.clearAndSetSemantics { }) {
+            Icon(
+                Icons.Filled.ArrowDropDown,
+                "Trailing icon for exposed dropdown menu",
+                Modifier.rotate(
+                    if (expanded)
+                        180f
+                    else
+                        360f
+                )
+            )
+        }
+    }
+
+    /**
+     * Creates a [TextFieldColors] that represents the default input text, background and content
+     * (including label, placeholder, leading and trailing icons) colors used in a [TextField].
+     *
+     * @param textColor Represents the color used for the input text of this text field.
+     * @param disabledTextColor Represents the color used for the input text of this text field when
+     * it's disabled.
+     * @param backgroundColor Represents the background color for this text field.
+     * @param cursorColor Represents the cursor color for this text field.
+     * @param errorCursorColor Represents the cursor color for this text field when it's in error
+     * state.
+     * @param focusedIndicatorColor Represents the indicator color for this text field when it's
+     * focused.
+     * @param unfocusedIndicatorColor Represents the indicator color for this text field when it's
+     * not focused.
+     * @param disabledIndicatorColor Represents the indicator color for this text field when it's
+     * disabled.
+     * @param errorIndicatorColor Represents the indicator color for this text field when it's in
+     * error state.
+     * @param focusedLeadingIconColor Represents the leading icon color for this text field when
+     * it's focused.
+     * @param unfocusedLeadingIconColor Represents the leading icon color for this text field when
+     * it's not focused.
+     * @param disabledLeadingIconColor Represents the leading icon color for this text field when
+     * it's disabled.
+     * @param errorLeadingIconColor Represents the leading icon color for this text field when it's
+     * in error state.
+     * @param focusedTrailingIconColor Represents the trailing icon color for this text field when
+     * it's focused.
+     * @param unfocusedTrailingIconColor Represents the trailing icon color for this text field when
+     * it's not focused.
+     * @param disabledTrailingIconColor Represents the trailing icon color for this text field when
+     * it's disabled.
+     * @param errorTrailingIconColor Represents the trailing icon color for this text field when
+     * it's in error state.
+     * @param focusedLabelColor Represents the label color for this text field when it's focused.
+     * @param unfocusedLabelColor Represents the label color for this text field when it's not
+     * focused.
+     * @param disabledLabelColor Represents the label color for this text field when it's disabled.
+     * @param errorLabelColor Represents the label color for this text field when it's in error
+     * state.
+     * @param placeholderColor Represents the placeholder color for this text field.
+     * @param disabledPlaceholderColor Represents the placeholder color for this text field when
+     * it's disabled.
+     */
+    @Composable
+    fun textFieldColors(
+        textColor: Color = FilledAutocompleteTokens.FieldInputTextColor.toColor(),
+        disabledTextColor: Color = FilledAutocompleteTokens.FieldDisabledInputTextColor.toColor()
+            .copy(alpha = FilledAutocompleteTokens.FieldDisabledInputTextOpacity),
+        backgroundColor: Color = FilledAutocompleteTokens.TextFieldContainerColor.toColor(),
+        cursorColor: Color = FilledAutocompleteTokens.TextFieldCaretColor.toColor(),
+        errorCursorColor: Color = FilledAutocompleteTokens.TextFieldErrorFocusCaretColor.toColor(),
+        focusedIndicatorColor: Color =
+            FilledAutocompleteTokens.TextFieldFocusActiveIndicatorColor.toColor(),
+        unfocusedIndicatorColor: Color =
+            FilledAutocompleteTokens.TextFieldActiveIndicatorColor.toColor(),
+        disabledIndicatorColor: Color =
+            FilledAutocompleteTokens.TextFieldDisabledActiveIndicatorColor.toColor()
+                .copy(alpha = FilledAutocompleteTokens.TextFieldDisabledActiveIndicatorOpacity),
+        errorIndicatorColor: Color =
+            FilledAutocompleteTokens.TextFieldErrorActiveIndicatorColor.toColor(),
+        focusedLeadingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldFocusLeadingIconColor.toColor(),
+        unfocusedLeadingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldLeadingIconColor.toColor(),
+        disabledLeadingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldDisabledLeadingIconColor.toColor()
+                .copy(alpha = FilledAutocompleteTokens.TextFieldDisabledLeadingIconOpacity),
+        errorLeadingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldErrorLeadingIconColor.toColor(),
+        focusedTrailingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldFocusTrailingIconColor.toColor(),
+        unfocusedTrailingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldTrailingIconColor.toColor(),
+        disabledTrailingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldDisabledTrailingIconColor.toColor()
+                .copy(alpha = FilledAutocompleteTokens.TextFieldDisabledTrailingIconOpacity),
+        errorTrailingIconColor: Color =
+            FilledAutocompleteTokens.TextFieldErrorTrailingIconColor.toColor(),
+        focusedLabelColor: Color = FilledAutocompleteTokens.FieldFocusLabelTextColor.toColor(),
+        unfocusedLabelColor: Color = FilledAutocompleteTokens.FieldLabelTextColor.toColor(),
+        disabledLabelColor: Color = FilledAutocompleteTokens.FieldDisabledLabelTextColor.toColor(),
+        errorLabelColor: Color = FilledAutocompleteTokens.FieldErrorLabelTextColor.toColor(),
+        placeholderColor: Color = FilledAutocompleteTokens.FieldSupportingTextColor.toColor(),
+        disabledPlaceholderColor: Color =
+            FilledAutocompleteTokens.FieldDisabledInputTextColor.toColor()
+                .copy(alpha = FilledAutocompleteTokens.FieldDisabledInputTextOpacity)
+    ): TextFieldColors =
+        TextFieldDefaults.textFieldColors(
+            textColor = textColor,
+            disabledTextColor = disabledTextColor,
+            cursorColor = cursorColor,
+            errorCursorColor = errorCursorColor,
+            focusedIndicatorColor = focusedIndicatorColor,
+            unfocusedIndicatorColor = unfocusedIndicatorColor,
+            errorIndicatorColor = errorIndicatorColor,
+            disabledIndicatorColor = disabledIndicatorColor,
+            focusedLeadingIconColor = focusedLeadingIconColor,
+            unfocusedLeadingIconColor = unfocusedLeadingIconColor,
+            disabledLeadingIconColor = disabledLeadingIconColor,
+            errorLeadingIconColor = errorLeadingIconColor,
+            focusedTrailingIconColor = focusedTrailingIconColor,
+            unfocusedTrailingIconColor = unfocusedTrailingIconColor,
+            disabledTrailingIconColor = disabledTrailingIconColor,
+            errorTrailingIconColor = errorTrailingIconColor,
+            backgroundColor = backgroundColor,
+            focusedLabelColor = focusedLabelColor,
+            unfocusedLabelColor = unfocusedLabelColor,
+            disabledLabelColor = disabledLabelColor,
+            errorLabelColor = errorLabelColor,
+            placeholderColor = placeholderColor,
+            disabledPlaceholderColor = disabledPlaceholderColor
+        )
+
+    /**
+     * Creates a [TextFieldColors] that represents the default input text, background and content
+     * (including label, placeholder, leading and trailing icons) colors used in an
+     * [OutlinedTextField].
+     *
+     * @param textColor Represents the color used for the input text of this text field.
+     * @param disabledTextColor Represents the color used for the input text of this text field when
+     * it's disabled.
+     * @param backgroundColor Represents the background color for this text field.
+     * @param cursorColor Represents the cursor color for this text field.
+     * @param errorCursorColor Represents the cursor color for this text field when it's in error
+     * state.
+     * @param focusedBorderColor Represents the border color for this text field when it's focused.
+     * @param unfocusedBorderColor Represents the border color for this text field when it's not
+     * focused.
+     * @param disabledBorderColor Represents the border color for this text field when it's
+     * disabled.
+     * @param errorBorderColor Represents the border color for this text field when it's in error
+     * state.
+     * @param focusedLeadingIconColor Represents the leading icon color for this text field when
+     * it's focused.
+     * @param unfocusedLeadingIconColor Represents the leading icon color for this text field when
+     * it's not focused.
+     * @param disabledLeadingIconColor Represents the leading icon color for this text field when
+     * it's disabled.
+     * @param errorLeadingIconColor Represents the leading icon color for this text field when it's
+     * in error state.
+     * @param focusedTrailingIconColor Represents the trailing icon color for this text field when
+     * it's focused.
+     * @param unfocusedTrailingIconColor Represents the trailing icon color for this text field when
+     * it's not focused.
+     * @param disabledTrailingIconColor Represents the trailing icon color for this text field when
+     * it's disabled.
+     * @param errorTrailingIconColor Represents the trailing icon color for this text field when
+     * it's in error state.
+     * @param focusedLabelColor Represents the label color for this text field when it's focused.
+     * @param unfocusedLabelColor Represents the label color for this text field when it's not
+     * focused.
+     * @param disabledLabelColor Represents the label color for this text field when it's disabled.
+     * @param errorLabelColor Represents the label color for this text field when it's in error
+     * state.
+     * @param placeholderColor Represents the placeholder color for this text field.
+     * @param disabledPlaceholderColor Represents the placeholder color for this text field when
+     * it's disabled.
+     */
+    @Composable
+    fun outlinedTextFieldColors(
+        textColor: Color = OutlinedAutocompleteTokens.FieldInputTextColor.toColor(),
+        disabledTextColor: Color = OutlinedAutocompleteTokens.FieldDisabledInputTextColor.toColor()
+            .copy(alpha = OutlinedAutocompleteTokens.FieldDisabledInputTextOpacity),
+        backgroundColor: Color = Color.Transparent,
+        cursorColor: Color = OutlinedAutocompleteTokens.TextFieldCaretColor.toColor(),
+        errorCursorColor: Color =
+            OutlinedAutocompleteTokens.TextFieldErrorFocusCaretColor.toColor(),
+        focusedBorderColor: Color = OutlinedAutocompleteTokens.TextFieldFocusOutlineColor.toColor(),
+        unfocusedBorderColor: Color = OutlinedAutocompleteTokens.TextFieldOutlineColor.toColor(),
+        disabledBorderColor: Color =
+            OutlinedAutocompleteTokens.TextFieldDisabledOutlineColor.toColor()
+                .copy(alpha = OutlinedAutocompleteTokens.TextFieldDisabledOutlineOpacity),
+        errorBorderColor: Color = OutlinedAutocompleteTokens.TextFieldErrorOutlineColor.toColor(),
+        focusedLeadingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldFocusLeadingIconColor.toColor(),
+        unfocusedLeadingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldLeadingIconColor.toColor(),
+        disabledLeadingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldDisabledLeadingIconColor.toColor()
+                .copy(alpha = OutlinedAutocompleteTokens.TextFieldDisabledLeadingIconOpacity),
+        errorLeadingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldErrorLeadingIconColor.toColor(),
+        focusedTrailingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldFocusTrailingIconColor.toColor(),
+        unfocusedTrailingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldTrailingIconColor.toColor(),
+        disabledTrailingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldDisabledTrailingIconColor.toColor()
+                .copy(alpha = OutlinedAutocompleteTokens.TextFieldDisabledTrailingIconOpacity),
+        errorTrailingIconColor: Color =
+            OutlinedAutocompleteTokens.TextFieldErrorTrailingIconColor.toColor(),
+        focusedLabelColor: Color = OutlinedAutocompleteTokens.FieldFocusLabelTextColor.toColor(),
+        unfocusedLabelColor: Color = OutlinedAutocompleteTokens.FieldLabelTextColor.toColor(),
+        disabledLabelColor: Color = OutlinedAutocompleteTokens.FieldDisabledLabelTextColor.toColor()
+            .copy(alpha = OutlinedAutocompleteTokens.FieldDisabledLabelTextOpacity),
+        errorLabelColor: Color = OutlinedAutocompleteTokens.FieldErrorLabelTextColor.toColor(),
+        placeholderColor: Color = OutlinedAutocompleteTokens.FieldSupportingTextColor.toColor(),
+        disabledPlaceholderColor: Color =
+            OutlinedAutocompleteTokens.FieldDisabledInputTextColor.toColor()
+                .copy(alpha = OutlinedAutocompleteTokens.FieldDisabledInputTextOpacity)
+    ): TextFieldColors =
+        TextFieldDefaults.outlinedTextFieldColors(
+            textColor = textColor,
+            disabledTextColor = disabledTextColor,
+            cursorColor = cursorColor,
+            errorCursorColor = errorCursorColor,
+            focusedBorderColor = focusedBorderColor,
+            unfocusedBorderColor = unfocusedBorderColor,
+            errorBorderColor = errorBorderColor,
+            disabledBorderColor = disabledBorderColor,
+            focusedLeadingIconColor = focusedLeadingIconColor,
+            unfocusedLeadingIconColor = unfocusedLeadingIconColor,
+            disabledLeadingIconColor = disabledLeadingIconColor,
+            errorLeadingIconColor = errorLeadingIconColor,
+            focusedTrailingIconColor = focusedTrailingIconColor,
+            unfocusedTrailingIconColor = unfocusedTrailingIconColor,
+            disabledTrailingIconColor = disabledTrailingIconColor,
+            errorTrailingIconColor = errorTrailingIconColor,
+            backgroundColor = backgroundColor,
+            focusedLabelColor = focusedLabelColor,
+            unfocusedLabelColor = unfocusedLabelColor,
+            disabledLabelColor = disabledLabelColor,
+            errorLabelColor = errorLabelColor,
+            placeholderColor = placeholderColor,
+            disabledPlaceholderColor = disabledPlaceholderColor
+        )
+}
+
+private fun Modifier.expandable(
+    onExpandedChange: () -> Unit,
+    menuLabel: String
+) = pointerInput(Unit) {
+    forEachGesture {
+        coroutineScope {
+            awaitPointerEventScope {
+                var event: PointerEvent
+                do {
+                    event = awaitPointerEvent(PointerEventPass.Initial)
+                } while (
+                    !event.changes.fastAll { it.changedToUp() }
+                )
+                onExpandedChange.invoke()
+            }
+        }
+    }
+}.semantics {
+    contentDescription = menuLabel // this should be a localised string
+    onClick {
+        onExpandedChange()
+        true
+    }
+}
+
+private fun updateHeight(
+    view: View,
+    coordinates: LayoutCoordinates?,
+    verticalMarginInPx: Int,
+    onHeightUpdate: (Int) -> Unit
+) {
+    coordinates ?: return
+    val visibleWindowBounds = Rect().let {
+        view.getWindowVisibleDisplayFrame(it)
+        it
+    }
+    val heightAbove = coordinates.boundsInWindow().top - visibleWindowBounds.top
+    val heightBelow =
+        visibleWindowBounds.bottom - visibleWindowBounds.top - coordinates.boundsInWindow().bottom
+    onHeightUpdate(max(heightAbove, heightBelow).toInt() - verticalMarginInPx)
+}
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.kt
new file mode 100644
index 0000000..81e7a36
--- /dev/null
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/internal/ExposedDropdownMenuPopup.kt
@@ -0,0 +1,470 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.compose.material3.internal
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.graphics.Outline
+import android.graphics.PixelFormat
+import android.graphics.Rect
+import android.view.Gravity
+import android.view.KeyEvent
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewOutlineProvider
+import android.view.ViewTreeObserver
+import android.view.WindowManager
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.CompositionContext
+import androidx.compose.runtime.DisposableEffect
+import androidx.compose.runtime.SideEffect
+import androidx.compose.runtime.compositionLocalOf
+import androidx.compose.runtime.derivedStateOf
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.rememberCompositionContext
+import androidx.compose.runtime.rememberUpdatedState
+import androidx.compose.runtime.saveable.rememberSaveable
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.R
+import androidx.compose.ui.draw.alpha
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.onGloballyPositioned
+import androidx.compose.ui.layout.onSizeChanged
+import androidx.compose.ui.layout.positionInWindow
+import androidx.compose.ui.platform.AbstractComposeView
+import androidx.compose.ui.platform.LocalDensity
+import androidx.compose.ui.platform.LocalLayoutDirection
+import androidx.compose.ui.platform.LocalView
+import androidx.compose.ui.platform.ViewRootForInspector
+import androidx.compose.ui.semantics.popup
+import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Density
+import androidx.compose.ui.unit.IntOffset
+import androidx.compose.ui.unit.IntRect
+import androidx.compose.ui.unit.IntSize
+import androidx.compose.ui.unit.LayoutDirection
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.util.fastMap
+import androidx.compose.ui.window.PopupPositionProvider
+import androidx.lifecycle.ViewTreeLifecycleOwner
+import androidx.lifecycle.ViewTreeViewModelStoreOwner
+import androidx.savedstate.ViewTreeSavedStateRegistryOwner
+import java.util.UUID
+import kotlin.math.roundToInt
+
+/**
+ * Popup specific for exposed dropdown menus. Should not be used in other components.
+ * See b/202810604.
+ */
+@Composable
+internal fun ExposedDropdownMenuPopup(
+    onDismissRequest: (() -> Unit)? = null,
+    popupPositionProvider: PopupPositionProvider,
+    content: @Composable () -> Unit
+) {
+    val view = LocalView.current
+    val density = LocalDensity.current
+    val testTag = LocalPopupTestTag.current
+    val layoutDirection = LocalLayoutDirection.current
+    val parentComposition = rememberCompositionContext()
+    val currentContent by rememberUpdatedState(content)
+    val popupId = rememberSaveable { UUID.randomUUID() }
+    val popupLayout = remember {
+        PopupLayout(
+            onDismissRequest = onDismissRequest,
+            testTag = testTag,
+            composeView = view,
+            density = density,
+            initialPositionProvider = popupPositionProvider,
+            popupId = popupId
+        ).apply {
+            setContent(parentComposition) {
+                SimpleStack(
+                    Modifier
+                        .semantics { this.popup() }
+                        // Get the size of the content
+                        .onSizeChanged {
+                            popupContentSize = it
+                            updatePosition()
+                        }
+                        // Hide the popup while we can't position it correctly
+                        .alpha(if (canCalculatePosition) 1f else 0f)
+                ) {
+                    currentContent()
+                }
+            }
+        }
+    }
+
+    DisposableEffect(popupLayout) {
+        popupLayout.show()
+        popupLayout.updateParameters(
+            onDismissRequest = onDismissRequest,
+            testTag = testTag,
+            layoutDirection = layoutDirection
+        )
+        onDispose {
+            popupLayout.disposeComposition()
+            // Remove the window
+            popupLayout.dismiss()
+        }
+    }
+
+    SideEffect {
+        popupLayout.updateParameters(
+            onDismissRequest = onDismissRequest,
+            testTag = testTag,
+            layoutDirection = layoutDirection
+        )
+    }
+
+    DisposableEffect(popupPositionProvider) {
+        popupLayout.positionProvider = popupPositionProvider
+        popupLayout.updatePosition()
+        onDispose {}
+    }
+
+    // TODO(soboleva): Look at module arrangement so that Box can be
+    //  used instead of this custom Layout
+    // Get the parent's position, size and layout direction
+    Layout(
+        content = {},
+        modifier = Modifier.onGloballyPositioned { childCoordinates ->
+            val coordinates = childCoordinates.parentLayoutCoordinates!!
+            val layoutSize = coordinates.size
+
+            val position = coordinates.positionInWindow()
+            val layoutPosition = IntOffset(position.x.roundToInt(), position.y.roundToInt())
+
+            popupLayout.parentBounds = IntRect(layoutPosition, layoutSize)
+            // Update the popup's position
+            popupLayout.updatePosition()
+        }
+    ) { _, _ ->
+        popupLayout.parentLayoutDirection = layoutDirection
+        layout(0, 0) {}
+    }
+}
+
+// TODO(b/139861182): This is a hack to work around Popups not using Semantics for test tags
+//  We should either remove it, or come up with an abstracted general solution that isn't specific
+//  to Popup
+internal val LocalPopupTestTag = compositionLocalOf { "DEFAULT_TEST_TAG" }
+
+// TODO(soboleva): Look at module dependencies so that we can get code reuse between
+// Popup's SimpleStack and Box.
+@Suppress("NOTHING_TO_INLINE")
+@Composable
+private inline fun SimpleStack(modifier: Modifier, noinline content: @Composable () -> Unit) {
+    Layout(content = content, modifier = modifier) { measurables, constraints ->
+        when (measurables.size) {
+            0 -> layout(0, 0) {}
+            1 -> {
+                val p = measurables[0].measure(constraints)
+                layout(p.width, p.height) {
+                    p.placeRelative(0, 0)
+                }
+            }
+            else -> {
+                val placeables = measurables.fastMap { it.measure(constraints) }
+                var width = 0
+                var height = 0
+                for (i in 0..placeables.lastIndex) {
+                    val p = placeables[i]
+                    width = maxOf(width, p.width)
+                    height = maxOf(height, p.height)
+                }
+                layout(width, height) {
+                    for (i in 0..placeables.lastIndex) {
+                        val p = placeables[i]
+                        p.placeRelative(0, 0)
+                    }
+                }
+            }
+        }
+    }
+}
+
+/**
+ * The layout the popup uses to display its content.
+ *
+ * @param composeView The parent view of the popup which is the AndroidComposeView.
+ */
+@SuppressLint("ViewConstructor")
+private class PopupLayout(
+    private var onDismissRequest: (() -> Unit)?,
+    var testTag: String,
+    private val composeView: View,
+    density: Density,
+    initialPositionProvider: PopupPositionProvider,
+    popupId: UUID
+) : AbstractComposeView(composeView.context),
+    ViewRootForInspector,
+    ViewTreeObserver.OnGlobalLayoutListener {
+    private val windowManager =
+        composeView.context.getSystemService(Context.WINDOW_SERVICE) as WindowManager
+    private val params = createLayoutParams()
+
+    /** The logic of positioning the popup relative to its parent. */
+    var positionProvider = initialPositionProvider
+
+    // Position params
+    var parentLayoutDirection: LayoutDirection = LayoutDirection.Ltr
+    var parentBounds: IntRect? by mutableStateOf(null)
+    var popupContentSize: IntSize? by mutableStateOf(null)
+
+    // Track parent bounds and content size; only show popup once we have both
+    val canCalculatePosition by derivedStateOf { parentBounds != null && popupContentSize != null }
+
+    private val maxSupportedElevation = 30.dp
+
+    // The window visible frame used for the last popup position calculation.
+    private val previousWindowVisibleFrame = Rect()
+    private val tmpWindowVisibleFrame = Rect()
+
+    override val subCompositionView: AbstractComposeView get() = this
+
+    // Specific to exposed dropdown menus.
+    private val dismissOnOutsideClick = { offset: Offset?, bounds: IntRect ->
+        if (offset == null) false
+        else {
+            offset.x < bounds.left || offset.x > bounds.right ||
+                offset.y < bounds.top || offset.y > bounds.bottom
+        }
+    }
+
+    init {
+        id = android.R.id.content
+        ViewTreeLifecycleOwner.set(this, ViewTreeLifecycleOwner.get(composeView))
+        ViewTreeViewModelStoreOwner.set(this, ViewTreeViewModelStoreOwner.get(composeView))
+        ViewTreeSavedStateRegistryOwner.set(this, ViewTreeSavedStateRegistryOwner.get(composeView))
+        composeView.viewTreeObserver.addOnGlobalLayoutListener(this)
+        // Set unique id for AbstractComposeView. This allows state restoration for the state
+        // defined inside the Popup via rememberSaveable()
+        setTag(R.id.compose_view_saveable_id_tag, "Popup:$popupId")
+
+        // Enable children to draw their shadow by not clipping them
+        clipChildren = false
+        // Allocate space for elevation
+        with(density) { elevation = maxSupportedElevation.toPx() }
+        // Simple outline to force window manager to allocate space for shadow.
+        // Note that the outline affects clickable area for the dismiss listener. In case of shapes
+        // like circle the area for dismiss might be to small (rectangular outline consuming clicks
+        // outside of the circle).
+        outlineProvider = object : ViewOutlineProvider() {
+            override fun getOutline(view: View, result: Outline) {
+                result.setRect(0, 0, view.width, view.height)
+                // We set alpha to 0 to hide the view's shadow and let the composable to draw its
+                // own shadow. This still enables us to get the extra space needed in the surface.
+                result.alpha = 0f
+            }
+        }
+    }
+
+    private var content: @Composable () -> Unit by mutableStateOf({})
+
+    override var shouldCreateCompositionOnAttachedToWindow: Boolean = false
+        private set
+
+    fun show() {
+        windowManager.addView(this, params)
+    }
+
+    fun setContent(parent: CompositionContext, content: @Composable () -> Unit) {
+        setParentCompositionContext(parent)
+        this.content = content
+        shouldCreateCompositionOnAttachedToWindow = true
+    }
+
+    @Composable
+    override fun Content() {
+        content()
+    }
+
+    /**
+     * Taken from PopupWindow
+     */
+    override fun dispatchKeyEvent(event: KeyEvent): Boolean {
+        if (event.keyCode == KeyEvent.KEYCODE_BACK) {
+            if (keyDispatcherState == null) {
+                return super.dispatchKeyEvent(event)
+            }
+            if (event.action == KeyEvent.ACTION_DOWN && event.repeatCount == 0) {
+                val state = keyDispatcherState
+                state?.startTracking(event, this)
+                return true
+            } else if (event.action == KeyEvent.ACTION_UP) {
+                val state = keyDispatcherState
+                if (state != null && state.isTracking(event) && !event.isCanceled) {
+                    onDismissRequest?.invoke()
+                    return true
+                }
+            }
+        }
+        return super.dispatchKeyEvent(event)
+    }
+
+    fun updateParameters(
+        onDismissRequest: (() -> Unit)?,
+        testTag: String,
+        layoutDirection: LayoutDirection
+    ) {
+        this.onDismissRequest = onDismissRequest
+        this.testTag = testTag
+        superSetLayoutDirection(layoutDirection)
+    }
+
+    /**
+     * Updates the position of the popup based on current position properties.
+     */
+    fun updatePosition() {
+        val parentBounds = parentBounds ?: return
+        val popupContentSize = popupContentSize ?: return
+
+        val windowSize = previousWindowVisibleFrame.let {
+            composeView.getWindowVisibleDisplayFrame(it)
+            val bounds = it.toIntBounds()
+            IntSize(width = bounds.width, height = bounds.height)
+        }
+
+        val popupPosition = positionProvider.calculatePosition(
+            parentBounds,
+            windowSize,
+            parentLayoutDirection,
+            popupContentSize
+        )
+
+        params.x = popupPosition.x
+        params.y = popupPosition.y
+
+        windowManager.updateViewLayout(this, params)
+    }
+
+    /**
+     * Remove the view from the [WindowManager].
+     */
+    fun dismiss() {
+        ViewTreeLifecycleOwner.set(this, null)
+        composeView.viewTreeObserver.removeOnGlobalLayoutListener(this)
+        windowManager.removeViewImmediate(this)
+    }
+
+    /**
+     * Handles touch screen motion events and calls [onDismissRequest] when the
+     * users clicks outside the popup.
+     */
+    override fun onTouchEvent(event: MotionEvent?): Boolean {
+        event ?: return super.onTouchEvent(event)
+
+        // Note that this implementation is taken from PopupWindow. It actually does not seem to
+        // matter whether we return true or false as some upper layer decides on whether the
+        // event is propagated to other windows or not. So for focusable the event is consumed but
+        // for not focusable it is propagated to other windows.
+        if (
+            (
+                (event.action == MotionEvent.ACTION_DOWN) &&
+                    (
+                        (event.x < 0) ||
+                            (event.x >= width) ||
+                            (event.y < 0) ||
+                            (event.y >= height)
+                        )
+                ) ||
+            event.action == MotionEvent.ACTION_OUTSIDE
+        ) {
+            val parentBounds = parentBounds
+            val shouldDismiss = parentBounds == null || dismissOnOutsideClick(
+                if (event.x != 0f || event.y != 0f) {
+                    Offset(
+                        params.x + event.x,
+                        params.y + event.y
+                    )
+                } else null,
+                parentBounds
+            )
+            if (shouldDismiss) {
+                onDismissRequest?.invoke()
+                return true
+            }
+        }
+        return super.onTouchEvent(event)
+    }
+
+    override fun setLayoutDirection(layoutDirection: Int) {
+        // Do nothing. ViewRootImpl will call this method attempting to set the layout direction
+        // from the context's locale, but we have one already from the parent composition.
+    }
+
+    // Sets the "real" layout direction for our content that we obtain from the parent composition.
+    private fun superSetLayoutDirection(layoutDirection: LayoutDirection) {
+        val direction = when (layoutDirection) {
+            LayoutDirection.Ltr -> android.util.LayoutDirection.LTR
+            LayoutDirection.Rtl -> android.util.LayoutDirection.RTL
+        }
+        super.setLayoutDirection(direction)
+    }
+
+    /**
+     * Initialize the LayoutParams specific to [android.widget.PopupWindow].
+     */
+    private fun createLayoutParams(): WindowManager.LayoutParams {
+        return WindowManager.LayoutParams().apply {
+            // Start to position the popup in the top left corner, a new position will be calculated
+            gravity = Gravity.START or Gravity.TOP
+
+            // Flags specific to exposed dropdown menu.
+            flags = WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH or
+                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
+                WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+            softInputMode = WindowManager.LayoutParams.SOFT_INPUT_STATE_UNCHANGED
+
+            type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL
+
+            // Get the Window token from the parent view
+            token = composeView.applicationWindowToken
+
+            // Wrap the frame layout which contains composable content
+            width = WindowManager.LayoutParams.WRAP_CONTENT
+            height = WindowManager.LayoutParams.WRAP_CONTENT
+
+            format = PixelFormat.TRANSLUCENT
+
+            // accessibilityTitle is not exposed as a public API therefore we set popup window
+            // title which is used as a fallback by a11y services
+            title = composeView.context.resources.getString(R.string.default_popup_window_title)
+        }
+    }
+
+    private fun Rect.toIntBounds() = IntRect(
+        left = left,
+        top = top,
+        right = right,
+        bottom = bottom
+    )
+
+    override fun onGlobalLayout() {
+        // Update the position of the popup, in case getWindowVisibleDisplayFrame has changed.
+        composeView.getWindowVisibleDisplayFrame(tmpWindowVisibleFrame)
+        if (tmpWindowVisibleFrame != previousWindowVisibleFrame) {
+            updatePosition()
+        }
+    }
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/FilledAutocompleteTokens.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/FilledAutocompleteTokens.kt
new file mode 100644
index 0000000..391c91c6
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/FilledAutocompleteTokens.kt
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// VERSION: v0_90
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+package androidx.compose.material3.tokens
+
+import androidx.compose.ui.unit.dp
+
+internal object FilledAutocompleteTokens {
+    val MenuContainerColor = ColorSchemeKeyTokens.Surface
+    val MenuContainerElevation = ElevationTokens.Level2
+    val MenuContainerShape = ShapeTokens.CornerExtraSmall
+    val MenuContainerSurfaceTintLayerColor = ColorSchemeKeyTokens.SurfaceTint
+    val MenuDividerColor = ColorSchemeKeyTokens.SurfaceVariant
+    val MenuDividerHeight = 1.0.dp
+    val MenuListItemContainerHeight = 48.0.dp
+    val MenuListItemLabelTextColor = ColorSchemeKeyTokens.OnSurface
+    val MenuListItemLabelTextFont = TypographyKeyTokens.LabelLarge
+    val MenuListItemSelectedContainerColor = ColorSchemeKeyTokens.SurfaceVariant
+    val TextFieldActiveIndicatorColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldActiveIndicatorHeight = 1.0.dp
+    val TextFieldCaretColor = ColorSchemeKeyTokens.Primary
+    val TextFieldContainerColor = ColorSchemeKeyTokens.SurfaceVariant
+    val TextFieldContainerHeight = 56.0.dp
+    val TextFieldContainerShape = ShapeTokens.CornerExtraSmallTop
+    val TextFieldDisabledActiveIndicatorColor = ColorSchemeKeyTokens.OnSurface
+    val TextFieldDisabledActiveIndicatorHeight = 1.0.dp
+    const val TextFieldDisabledActiveIndicatorOpacity = 0.38f
+    val TextFieldDisabledContainerColor = ColorSchemeKeyTokens.OnSurface
+    const val TextFieldDisabledContainerOpacity = 0.04f
+    val FieldDisabledInputTextColor = ColorSchemeKeyTokens.OnSurface
+    const val FieldDisabledInputTextOpacity = 0.38f
+    val FieldDisabledLabelTextColor = ColorSchemeKeyTokens.OnSurface
+    const val FieldDisabledLabelTextOpacity = 0.38f
+    val TextFieldDisabledLeadingIconColor = ColorSchemeKeyTokens.OnSurface
+    const val TextFieldDisabledLeadingIconOpacity = 0.38f
+    val FieldDisabledSupportingTextColor = ColorSchemeKeyTokens.OnSurface
+    const val FieldDisabledSupportingTextOpacity = 0.38f
+    val TextFieldDisabledTrailingIconColor = ColorSchemeKeyTokens.OnSurface
+    const val TextFieldDisabledTrailingIconOpacity = 0.38f
+    val TextFieldErrorActiveIndicatorColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorFocusActiveIndicatorColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorFocusCaretColor = ColorSchemeKeyTokens.Error
+    val FieldErrorFocusInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorFocusLabelTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorFocusLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldErrorFocusSupportingTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorFocusTrailingIconColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorHoverActiveIndicatorColor = ColorSchemeKeyTokens.OnErrorContainer
+    val FieldErrorHoverInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorHoverLabelTextColor = ColorSchemeKeyTokens.OnErrorContainer
+    val TextFieldErrorHoverLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldErrorHoverStateLayerColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorHoverSupportingTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorHoverTrailingIconColor = ColorSchemeKeyTokens.OnErrorContainer
+    val FieldErrorInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorLabelTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldErrorSupportingTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorTrailingIconColor = ColorSchemeKeyTokens.Error
+    val TextFieldFocusActiveIndicatorColor = ColorSchemeKeyTokens.Primary
+    val TextFieldFocusActiveIndicatorHeight = 2.0.dp
+    val FieldFocusInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldFocusLabelTextColor = ColorSchemeKeyTokens.Primary
+    val TextFieldFocusLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldFocusSupportingTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldFocusTrailingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldHoverActiveIndicatorColor = ColorSchemeKeyTokens.OnSurface
+    val TextFieldHoverActiveIndicatorHeight = 1.0.dp
+    val FieldHoverInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldHoverLabelTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldHoverLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldHoverStateLayerColor = ColorSchemeKeyTokens.OnSurface
+    val FieldHoverSupportingTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldHoverTrailingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldInputTextFont = TypographyKeyTokens.BodyLarge
+    val FieldLabelTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldLabelTextFont = TypographyKeyTokens.BodyLarge
+    val TextFieldLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldLeadingIconSize = 20.0.dp
+    val FieldSupportingTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldSupportingTextFont = TypographyKeyTokens.BodySmall
+    val TextFieldTrailingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldTrailingIconSize = 24.0.dp
+}
diff --git a/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/OutlinedAutocompleteTokens.kt b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/OutlinedAutocompleteTokens.kt
new file mode 100644
index 0000000..c7dc9bd
--- /dev/null
+++ b/compose/material3/material3/src/commonMain/kotlin/androidx/compose/material3/tokens/OutlinedAutocompleteTokens.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+// VERSION: v0_90
+// GENERATED CODE - DO NOT MODIFY BY HAND
+
+package androidx.compose.material3.tokens
+
+import androidx.compose.ui.unit.dp
+
+internal object OutlinedAutocompleteTokens {
+    val MenuContainerColor = ColorSchemeKeyTokens.Surface
+    val MenuContainerElevation = ElevationTokens.Level2
+    val MenuContainerShape = ShapeTokens.CornerExtraSmall
+    val MenuContainerSurfaceTintLayerColor = ColorSchemeKeyTokens.SurfaceTint
+    val MenuDividerColor = ColorSchemeKeyTokens.SurfaceVariant
+    val MenuDividerHeight = 1.0.dp
+    val MenuListItemContainerHeight = 48.0.dp
+    val MenuListItemLabelTextColor = ColorSchemeKeyTokens.OnSurface
+    val MenuListItemLabelTextFont = TypographyKeyTokens.LabelLarge
+    val MenuListItemSelectedContainerColor = ColorSchemeKeyTokens.SurfaceVariant
+    val TextFieldCaretColor = ColorSchemeKeyTokens.Primary
+    val TextFieldContainerColor = ColorSchemeKeyTokens.SurfaceVariant
+    val TextFieldContainerHeight = 56.0.dp
+    val TextFieldContainerShape = ShapeTokens.CornerExtraSmallTop
+    val FieldDisabledInputTextColor = ColorSchemeKeyTokens.OnSurface
+    const val FieldDisabledInputTextOpacity = 0.38f
+    val FieldDisabledLabelTextColor = ColorSchemeKeyTokens.OnSurface
+    const val FieldDisabledLabelTextOpacity = 0.38f
+    val TextFieldDisabledLeadingIconColor = ColorSchemeKeyTokens.OnSurface
+    const val TextFieldDisabledLeadingIconOpacity = 0.38f
+    val TextFieldDisabledOutlineColor = ColorSchemeKeyTokens.OnSurface
+    const val TextFieldDisabledOutlineOpacity = 0.12f
+    val TextFieldDisabledOutlineWidth = 1.0.dp
+    val FieldDisabledSupportingTextColor = ColorSchemeKeyTokens.OnSurface
+    const val FieldDisabledSupportingTextOpacity = 0.38f
+    val TextFieldDisabledTrailingIconColor = ColorSchemeKeyTokens.OnSurface
+    const val TextFieldDisabledTrailingIconOpacity = 0.38f
+    val TextFieldErrorFocusCaretColor = ColorSchemeKeyTokens.Error
+    val FieldErrorFocusInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorFocusLabelTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorFocusLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldErrorFocusOutlineColor = ColorSchemeKeyTokens.Error
+    val FieldErrorFocusSupportingTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorFocusTrailingIconColor = ColorSchemeKeyTokens.Error
+    val FieldErrorHoverInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorHoverLabelTextColor = ColorSchemeKeyTokens.OnErrorContainer
+    val TextFieldErrorHoverLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldErrorHoverOutlineColor = ColorSchemeKeyTokens.OnErrorContainer
+    val TextFieldErrorHoverStateLayerColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorHoverSupportingTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorHoverTrailingIconColor = ColorSchemeKeyTokens.OnErrorContainer
+    val FieldErrorInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldErrorLabelTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldErrorOutlineColor = ColorSchemeKeyTokens.Error
+    val FieldErrorSupportingTextColor = ColorSchemeKeyTokens.Error
+    val TextFieldErrorTrailingIconColor = ColorSchemeKeyTokens.Error
+    val FieldFocusInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldFocusLabelTextColor = ColorSchemeKeyTokens.Primary
+    val TextFieldFocusLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldFocusOutlineColor = ColorSchemeKeyTokens.Primary
+    val TextFieldFocusOutlineWidth = 2.0.dp
+    val FieldFocusSupportingTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldFocusTrailingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldHoverInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldHoverLabelTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldHoverLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldHoverOutlineColor = ColorSchemeKeyTokens.OnSurface
+    val TextFieldHoverOutlineWidth = 1.0.dp
+    val TextFieldHoverStateLayerColor = ColorSchemeKeyTokens.OnSurface
+    val FieldHoverSupportingTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldHoverTrailingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldInputTextColor = ColorSchemeKeyTokens.OnSurface
+    val FieldInputTextFont = TypographyKeyTokens.BodyLarge
+    val FieldLabelTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldLabelTextFont = TypographyKeyTokens.BodyLarge
+    val TextFieldLeadingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldLeadingIconSize = 24.0.dp
+    val TextFieldOutlineColor = ColorSchemeKeyTokens.Outline
+    val TextFieldOutlineWidth = 1.0.dp
+    val FieldSupportingTextColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val FieldSupportingTextFont = TypographyKeyTokens.BodySmall
+    val TextFieldTrailingIconColor = ColorSchemeKeyTokens.OnSurfaceVariant
+    val TextFieldTrailingIconSize = 24.0.dp
+}