Skip to content
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

Popup Placement is Inconsistent in FlexibleBottomSheet #50

Open
moicompsci opened this issue Aug 19, 2024 · 0 comments
Open

Popup Placement is Inconsistent in FlexibleBottomSheet #50

moicompsci opened this issue Aug 19, 2024 · 0 comments

Comments

@moicompsci
Copy link

moicompsci commented Aug 19, 2024

Tested on API 30 (Samsung S23) and API 34 (Pixel 7a).

In my FlexibleBottomSheet, I am showing a Popup (in my example code the Popup/tooltip can be shown when holding/pressing on the button).

1.
When isModal is set to false, the tooltip does not remain in place consistently in all of its "expanded/slightly-expanded" layouts:
isModalFalse0

After sliding the bottom sheet: (Notice the offset between the button)
isModalFalse1

2.
When isModal is set to true, and comparing to Material 3's ModalBottomSheet and BottomSheetScaffold, the Popup has an unexpected offset (the offset is not happening in the Material 3's ModalBottomSheet and BottomSheetScaffold).

Flexible Bottom Sheet (isModal = true):
isModalTrue0

Material 3 BottomSheetScaffold:
bottomsheetScaffold0

Material 3 ModalBottomSheet:
modalBottomSheet0

Here is my relavant code:

import androidx.compose.foundation.interaction.HoverInteraction
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.PressInteraction
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.BottomSheetScaffold
import androidx.compose.material3.Button
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
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.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
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.window.Popup
import androidx.compose.ui.window.PopupPositionProvider
import com.skydoves.flexible.bottomsheet.material3.FlexibleBottomSheet
import com.skydoves.flexible.core.FlexibleSheetSize
import com.skydoves.flexible.core.rememberFlexibleBottomSheetState

@Preview
@Composable
fun FlexibleBottomSheetExample() {
    val sheetSize = FlexibleSheetSize(
        fullyExpanded = 1f,
        intermediatelyExpanded = 0.5f,
        slightlyExpanded = 0.10f,
    )
    val sheetState  = rememberFlexibleBottomSheetState(
        flexibleSheetSize = sheetSize,
        containSystemBars = false,
        isModal = true,
        skipSlightlyExpanded = true,
        confirmValueChange = { true }
    )
    FlexibleBottomSheet(
        onDismissRequest = {},
        sheetState = sheetState,
        content = {
            LazyColumn {
                item {
                    Spacer(modifier = Modifier.height(24.dp))
                    ButtonWithTooltip()
                    Spacer(modifier = Modifier.height(64.dp))
                }
            }
        }
    )
}

@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun BottomSheetScaffoldExample() {
    BottomSheetScaffold(
        sheetContent = {
            Spacer(modifier = Modifier.height(24.dp))
            ButtonWithTooltip()
            Spacer(modifier = Modifier.height(64.dp))
        },
        sheetPeekHeight = 140.dp
    ) {
    }
}

@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Composable
fun ModalBottomSheetExample() {
    ModalBottomSheet(
        onDismissRequest = {},
        content = {
            Spacer(modifier = Modifier.height(24.dp))
            ButtonWithTooltip()
            Spacer(modifier = Modifier.height(64.dp))
        },
    )
}

@Composable
fun ButtonWithTooltip() {
    var showTooltip by remember { mutableStateOf(false) }
    val interactionSource = remember { MutableInteractionSource() }

    LaunchedEffect(interactionSource) {
        interactionSource.interactions.collect { interaction ->
            when (interaction) {
                is PressInteraction.Press -> showTooltip = true
                is PressInteraction.Release,
                is PressInteraction.Cancel -> showTooltip = false
                is HoverInteraction.Enter -> showTooltip = true
                is HoverInteraction.Exit -> showTooltip = false
            }
        }
    }
    Box {
        Button(
            onClick = { },
            interactionSource = interactionSource
        ) {
            Text(text = "Button")
        }
        if (showTooltip) {
            Popup(
                popupPositionProvider = object : PopupPositionProvider {
                    override fun calculatePosition(
                        anchorBounds: IntRect,
                        windowSize: IntSize,
                        layoutDirection: LayoutDirection,
                        popupContentSize: IntSize
                    ): IntOffset {
                        val x = anchorBounds.left
                        val y = anchorBounds.top - popupContentSize.height
                        return IntOffset(x, y)
                    }
                }
            ) {
                Surface(
                    shape = RoundedCornerShape(4.dp),
                    color = if (isSystemInDarkTheme()) Color.White else Color.Black,
                ) {
                    Text(
                        text = "Tooltip",
                        color = if (isSystemInDarkTheme()) Color.Black else Color.White,
                        modifier = Modifier.padding(8.dp)
                    )
                }
            }
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant