-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Sheet confirmValueChange callback #45
Comments
There is no similar functionality but it seems like a valid request. Let me have a look and I will let you know ASAP. |
PS: If you can share code of how you expect this to work, it would help tons. |
I'm not totally sure, because the M3 APIs don't support this exactly either, but what I want is roughly: @Stable
class State {
var formField by mutableStateOf("")
var showExitDialog by mutableStateOf(false)
var confirmedExit by mutableStateOf(false)
val showEvents = MutableSharedFlow<Boolean>()
fun hasChanged() = formField != ""
suspend fun show() { showEvents.emit(true) }
suspend fun hide() { showEvents.emit(false) }
}
@Composable
fun FormBottomSheetScaffold(state: State) {
Scaffold(...) {
val sheetState = rememberBottomSheetState(
initialDetent = SheetDetents.Hidden,
detents = listOf(SheetDetents.Hidden, SheetDetents.FullyExpanded),
)
LaunchedEffect(Unit) {
state.showEvents.collectLatest {
if (it) {
sheetState.animateTo(SheetDetents.FullyExpanded)
state.confirmedExit = false
} else {
sheetState.animateTo(SheetDetents.Hidden)
}
}
}
BottomSheet(
state = sheetState,
confirmValueChange = {
if (it == SheetDetents.FullyExpanded) {
true
} else if (state.hasChanged()) {
state.showExitDialog = true
false
} else {
true
}
}
) {
TextField(value = state.formField, onValueChanged = { state.formField = it })
}
if (state.showExitDialog) {
AlertDialog(
...,
onConfirm = {
state.confirmedExit = true
state.showExitDialog = false
},
onDismiss = { state.hide() },
)
}
}
}
|
What you shared is what I had in mind you needed 👍
what do you mean? It seems like the M3 api. is it different? |
M3's current It's possible I'm holding it wrong and somewhere in my hierarchy I have a recomposition or something which causes it to be called incorrectly. I've never bothered to dig into it, I just know the behavior broke several months ago so I hacked something together and ignored it for now. |
This is a highly awaited feature for our app. |
Working on this today. It is a bit more complex than expected because I think I bumped into the behavior @TheKeeperOfPie describes on the Material Compose one. Working on making the API and callbacks make sense, so you don't spend hours debugging it like the Material Compose one. I think it is doable tho |
Made Bottom Sheet's work nicely and predictably 👍 |
Oops, hopefully I caught you early enough, but this behavior works when using the M3 modal sheet. I actually recently migrated mine to modal just to have my tests work correctly. I haven't tried to do it using Composables Core, but with M3, this works:
But to be clear, there are distinct differences between the modal and scaffold approach, and I would really want the scaffold to work. It allows you to have the sheet content always in the composition tree, and it doesn't block interacting with the app content like a dialog does. |
Done. Will be released in the next version of the library |
The `confirmDetentChange()` allows you to block the dismissal of the sheet depending on a state. Fixes: #45
This is now available in 1.20.0 |
Wiring this up manually ended up being more complicated than I expected, and I can't get a working modal.
Essentially I have a persistent M3
BottomSheetScaffold
right now which is a form that the user submits. If the user makes a change and then swipes the sheet away, I use M3'sconfirmValueChange
to block the swipe down* and prompt them with a dialog to either confirm the exit or save the edits.I can't find an equivalent in Composables Core. It seems difficult to block
SheetDetents.Hidden
, which I think I can approximate by swapping thedetents
list, removing/adding.Hidden
as necessarily to disable the swipe down. But I actually don't want to block the swipe itself. If a user initiates a swipe, I want it to succeed and only prompt them after, so that swiping down is still a valid indication from the user to exit the form.*Note that this is currently broken in M3 from what I understand due to a bug, which is what caused me to look for alternatives and end up here. I have an extremely hacky solution right now observing the expand/hide requests and manually reversing them, but the UX isn't great.
The text was updated successfully, but these errors were encountered: