M3 ModalBottomSheet swipe to dismiss fix.

In the M3 AnchoredDraggable migration of ModalBottomSheet one custom implementation of draggable was removed in favor of anchoredDraggable. This generated a bug where swipe to dismiss actions were not calling onDismissRequest after hiding the sheet.

Test: Added tests to verify the new behavior.
Fixes: 298648794
Relnote: Fixed a bug where ModalBottomSheet was not calling onDismissedRequest when dismissing it by swiping down on the sheet.
Change-Id: Idfdd8b490caed6486292ae244ba9e4e9fb813f96
diff --git a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt
index 85a2ddc..6d2d0b7 100644
--- a/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt
+++ b/compose/material3/material3/src/androidAndroidTest/kotlin/androidx/compose/material3/ModalBottomSheetTest.kt
@@ -144,6 +144,42 @@
     }
 
     @Test
+    fun modalBottomSheet_isDismissedOnSwipeDown() {
+        var showBottomSheet by mutableStateOf(true)
+        val sheetState = SheetState(skipPartiallyExpanded = false, density = rule.density)
+
+        rule.setContent {
+            val windowInsets = if (edgeToEdgeWrapper.edgeToEdgeEnabled)
+                WindowInsets(0) else BottomSheetDefaults.windowInsets
+
+            if (showBottomSheet) {
+                ModalBottomSheet(
+                    sheetState = sheetState,
+                    onDismissRequest = { showBottomSheet = false },
+                    windowInsets = windowInsets
+                ) {
+                    Box(
+                        Modifier
+                            .size(sheetHeight)
+                            .testTag(sheetTag)
+                    )
+                }
+            }
+        }
+
+        assertThat(sheetState.isVisible).isTrue()
+
+        // Swipe Down
+        rule.onNodeWithTag(sheetTag).performTouchInput {
+            swipeDown()
+        }
+        rule.waitForIdle()
+
+        // Bottom sheet should not exist
+        rule.onNodeWithTag(sheetTag).assertDoesNotExist()
+    }
+
+    @Test
     fun modalBottomSheet_fillsScreenWidth() {
         var boxWidth = 0
         var screenWidth by mutableStateOf(0)
diff --git a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt
index 85e41b3..771d739 100644
--- a/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt
+++ b/compose/material3/material3/src/androidMain/kotlin/androidx/compose/material3/ModalBottomSheet.android.kt
@@ -28,6 +28,7 @@
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.gestures.detectTapGestures
+import androidx.compose.foundation.gestures.draggable
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.Column
@@ -198,10 +199,12 @@
                             )
                         }
                     )
-                    .anchoredDraggable(
-                        state = sheetState.anchoredDraggableState,
+                    .draggable(
+                        state = sheetState.anchoredDraggableState.draggableState,
                         orientation = Orientation.Vertical,
-                        enabled = sheetState.isVisible
+                        enabled = sheetState.isVisible,
+                        startDragImmediately = sheetState.anchoredDraggableState.isAnimationRunning,
+                        onDragStopped = { settleToDismiss(it) }
                     )
                     .modalBottomSheetAnchors(
                         sheetState = sheetState,