Git Product home page Git Product logo

flexiblebottomsheet's Introduction

Google Developer Expert Google Developers Medium Speaker
Sponsors Twitter Mastodon YouTube

GitHub Status

flexiblebottomsheet's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

flexiblebottomsheet's Issues

Allow expansion to be skipped when the sheet is added

Is your feature request related to a problem?

We'd like have the bottom sheet not automatically expand to intermediate height.

Describe the solution you'd like:

Add a new, optional parameter e.g. skipShow = false to the FlexibleBottomSheet constructor and use the parameter in the LaunchedEffect at the bottom of the file

if (!skipShow && sheetState.hasFullyExpandedState) {
        LaunchedEffect(sheetState) {
            sheetState.slightlyExpand()
        }
    }

Describe alternatives you've considered:

I've tried snapping to the desired target as a launched effect but it only works with a delay.

Scrim doesn't contain statusbar

Please complete the following information:

  • Library Version 0.1.0
  • Affected Device(s) Samsung Galaxy s23 with Android 13]

Describe the Bug:
With only Horizontal sides' insets scrim doesn't contain status bar ๐Ÿง

windowInsets = BottomSheetDefaults.windowInsets.only(WindowInsetsSides.Horizontal)

Expected Behavior:

A clear description of what you expected to happen.

StatusBar dim is not Showing

  • Library Version
    -v0.1.2
  • Affected Device(s)
    • Samsung Galaxy zflip4 with Android 14.0 Pixel5(emulator)

Describe the Bug:
In the case of M3 ModalBottomSheet, Dim processing is possible in the Status Bar area when BottomSheet is on the screen by specifying windowInsets = WindowInsets(top = 0).
But FlexibleBottomSheet not working by by specifying windowInsets = WindowInsets(top = 0).

Add a clear description about the problem.

M3 ModalBottomSheet FlexibleBottomSheet

full code is here.
https://github.com/Project-Unifest/unifest-android/blob/develop/core/ui/src/main/kotlin/com/unifest/android/core/ui/component/FestivalBottomSheet.kt

Expected Behavior:
I hope dim processing is applied to the Status Bar area.

Initial state not working and not able to be set.

  • Library Version : com.github.skydoves:flexible-bottomsheet-material3:0.1.2
  • Affected Device(s) : Pixel 8 Pro SDK 34

Initial state not working or not able to be set.

Tracing the library code, calling rememberFlexibleBottomSheetState calls a private function rememberFlexibleSheetState which has a default parameter of initialValue: FlexibleSheetValue = FlexibleSheetValue.Hidden. The public method does not take that parameter, however, the initial state should evaluate to hidden regardless.

In my most basic implementation, the sheet always starts off a not hidden, intermediately expanded.

 val sheetState = rememberFlexibleBottomSheetState(
      isModal = false
 )

FlexibleBottomSheet(
        windowInsets = WindowInsets(0, 0, 0, 0),
        onDismissRequest = { },
        sheetState = sheetState,
      ) {
        CircularProgressIndicator()
      }
}

It's not clear how to set the initial state, or if it's supported. Am I missing something obvious?

Wrapping the entire FlexibleBottomSheet in an if statement and check some state before showing works, but then it gets awkward to have a nice animation to hide it when that state changes, it would just abruptly disappear.

Expected Behaviour:

  • there is a way to set the initial state value
  • initial state value is respected.

sheetState isModal not updating

  • Library Version [0.1.1]
  • Affected Device(s) [Xiaomi Redmi 8 with Android 10]

sheetState isModal is not updating when changed during onTargetChanges function

        val scope = rememberCoroutineScope()
        var isModal : Boolean by remember { mutableStateOf(true) }
        val sheetState = rememberFlexibleBottomSheetState(
            flexibleSheetSize = FlexibleSheetSize(
                fullyExpanded = 1.0f,
                intermediatelyExpanded = 0.5f,
                slightlyExpanded = 0f
            ),
            isModal = isModal,
            skipSlightlyExpanded = false,
        )
        FlexibleBottomSheet(
            onDismissRequest = {
                scope.launch {
                    sheetState.hide()
                }
            },
            sheetState = sheetState,
            onTargetChanges = { sheetValue ->
                isModal = sheetValue.ordinal != 0
                println("$TAG Sheet SheetValue: $sheetValue || IsModal:: $isModal || sheetModal :: ${sheetState.isModal}")                
            },
        ) {
            Text(text = "Bottom Sheeeet!!!")
        }

While printing the logs i found below result
SheetValue: Hidden || IsModal:: false || sheetModal :: true

I want my bottom sheet to behave as Modal only when it is not hidden i.e., visible
If I set isModal as true, then I am not able to access the background content when the sheet is hidden/removed by the user.

Am i missing anything?

Implementing Bottom Sheet Scrim Display Upon Expansion

Is your feature request related to a problem?

When we pull down the bottom sheet and hold it, even though the bottom sheet exists, it is possible to click behind it and navigate to another page, and then reopen the bottom sheet again, even if it is a modal bottom sheet.

Describe the solution you'd like:

Describe alternatives you've considered:

Adding support for โ€œexpand to wrap contentโ€ state

Is your feature request related to a problem?
No, not really.

A clear and concise description of what the problem is.

The current implementation does not support expanding until the sheet wraps its content.

Describe the solution you'd like:

It would be great if there was a parameter or extra sheet state that could be specified so that the bottom sheet can expand until it wraps all of its content.

Describe alternatives you've considered:

Although I have not yet tried it myself, this could potentially be achieved using the onGloballyPosition modifier (?).

Skip Hidden State

ํ˜„์žฌ ์นด์นด์˜ค ํ‹ฐ ์•ฑ์˜ ์ฃผ์ฐจ ๊ธฐ๋Šฅ์—์„œ ์ฒ˜๋Ÿผ flexibleํ•œ bottom sheet + No Hidden State์ธ BottomSheet ๊ตฌํ˜„์„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ skipHiddenState์— ๋Œ€ํ•ด์„œ ์ œ์•ˆ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

@Composable
fun rememberFlexibleBottomSheetState(
    skipIntermediatelyExpanded: Boolean = false,
    skipSlightlyExpanded: Boolean = true,
    skipHiddenState: Boolean = false,
    isModal: Boolean = false,
    containSystemBars: Boolean = false,
    allowNestedScroll: Boolean = true,
    animateSpec: AnimationSpec<Float> = SwipeableV2Defaults.AnimationSpec,
    flexibleSheetSize: FlexibleSheetSize = FlexibleSheetSize(),
    confirmValueChange: (FlexibleSheetValue) -> Boolean = { true },
    initialValue: FlexibleSheetValue = FlexibleSheetValue.IntermediatelyExpanded,
): FlexibleSheetState = rememberFlexibleSheetState(
    skipIntermediatelyExpanded = skipIntermediatelyExpanded,
    skipSlightlyExpanded = skipSlightlyExpanded,
    isModal = isModal,
    animateSpec = animateSpec,
    confirmValueChange = confirmValueChange,
    flexibleSheetSize = flexibleSheetSize,
    containSystemBars = containSystemBars,
    allowNestedScroll = allowNestedScroll,
    initialValue = initialValue,
    skipHiddenState = skipHiddenState,
)

private rememberFlexibleBottomSheetState()์˜ ๊ฒฝ์šฐ์—๋Š” skipHiddenState์— ํ•ด๋‹นํ•˜๋Š” ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์žˆ๋˜๋ฐ public rememberFlexibleBottomSheetState()์˜ ๊ฒฝ์šฐ์—๋Š” skipHiddenState๊ฐ€ ํŒŒ๋ผ๋ฏธํ„ฐ์— ์—†์–ด ์ถ”๊ฐ€๋ฅผ ํ•˜์˜€์Šต๋‹ˆ๋‹ค.

fun Modifier.flexibleBottomSheetSwipeable(
    sheetState: FlexibleSheetState,
    flexibleSheetSize: FlexibleSheetSize,
    anchorChangeHandler: AnchorChangeHandler<FlexibleSheetValue>,
    sheetFullHeight: Float,
    sheetConstraintHeight: Float,
    screenMaxHeight: Float,
    isModal: Boolean,
    onDragStarted: suspend CoroutineScope.(startedPosition: Offset) -> Unit = {},
    onDragStopped: CoroutineScope.(velocity: Float) -> Unit,
): Modifier = draggable(
    state = sheetState.swipeableState.swipeDraggableState,
    orientation = Orientation.Vertical,
    enabled = sheetState.isVisible,
    startDragImmediately = sheetState.swipeableState.isAnimationRunning,
    onDragStarted = onDragStarted,
    onDragStopped = onDragStopped,
)
    .swipeAnchors(
        state = sheetState.swipeableState,
        anchorChangeHandler = anchorChangeHandler,
        possibleValues = if (sheetState.skipHiddenState) {
            setOf(
                FlexibleSheetValue.IntermediatelyExpanded,
                FlexibleSheetValue.SlightlyExpanded,
                FlexibleSheetValue.FullyExpanded,
            )
        } else {
            setOf(
                FlexibleSheetValue.Hidden,
                FlexibleSheetValue.IntermediatelyExpanded,
                FlexibleSheetValue.SlightlyExpanded,
                FlexibleSheetValue.FullyExpanded,
            )
        },
    ) { value, sheetSize ->

.... ์ƒ๋žต

skipHiddenState์˜ ๊ฐ’์—๋”ฐ๋ผ possibleValues๋ฅผ ๋‹ค๋ฅด๊ฒŒํ•˜์—ฌ ๋ณด์•˜์Šต๋‹ˆ๋‹ค.

Keyboard not displayed

Please complete the following information:

  • Library Version : v0.1.2
  • Affected Device(s) : Pixel

Describe the Bug:

I've added a text field to the content of the bottom flexible sheet.
When clicked, the keyboard is not displayed.

is it possible to show the keyboard below the text field in the bottom sheet ?

BottomSheet not fully hidden

  • Library Version [0.1.1]
  • Affected Device(s) [Samsung Galaxy a13 with Android 13.0]

Bottom Sheet is slightly visible at the bottom when it's hidden. You can see the WHITE line at the end of the photo

FlexibleBottomSheet(
        sheetState = sheetState,
        windowInsets = WindowInsets.waterfall,
        tonalElevation = 0.dp,
        shape = RectangleShape,
        onDismissRequest = {
            //NOOP
        },
        containerColor = White,
)
FlexibleSheetState(
                flexibleSheetSize = FlexibleSheetSize(fullyExpanded = fullyExpandedRatio),
                isModal = false,
                skipSlightlyExpanded = true,
                skipIntermediatelyExpanded = true,
                containSystemBars = true,
                allowNestedScroll = true,
                animateSpec = SwipeableV2Defaults.AnimationSpec,
)

FlexibleBottomSheet

When the bottom sheet is expanded, the issue of the navigation bar on the underlying screen being visible

Please complete the following information:

  • Library Version
    current latest version(0.1.2)

  • Affected Device(s) [e.g. Samsung Galaxy s10 with Android 9.0]

  • Galaxy zflip4 and also Pixel5(emulator)

Describe the Bug:
image

When I expand the bottomSheet, there is a problem that can see the behind NavigationBar at the bottom.

code

package com.unifest.android.core.ui.component

import androidx.annotation.StringRes
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.asPaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text2.input.TextFieldState
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ModalBottomSheet
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.material3.VerticalDivider
import androidx.compose.material3.rememberModalBottomSheetState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.skydoves.flexible.bottomsheet.material3.FlexibleBottomSheet
import com.skydoves.flexible.core.FlexibleSheetSize
import com.skydoves.flexible.core.rememberFlexibleBottomSheetState
import com.unifest.android.core.designsystem.ComponentPreview
import com.unifest.android.core.designsystem.R
import com.unifest.android.core.designsystem.component.FestivalSearchTextField
import com.unifest.android.core.designsystem.component.InterestedFestivalDeleteDialog
import com.unifest.android.core.designsystem.theme.Content3
import com.unifest.android.core.designsystem.theme.UnifestTheme
import com.unifest.android.core.domain.entity.Festival
import kotlinx.coroutines.launch

@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun FestivalSearchBottomSheet(
    @StringRes searchTextHintRes: Int,
    setFestivalSearchBottomSheetVisible: (Boolean) -> Unit,
    interestedFestivals: MutableList<Festival>,
    initSearchText: () -> Unit,
    setEnableSearchMode: () -> Unit,
    isSearchMode: Boolean,
    setEnableEditMode: () -> Unit,
    isInterestedFestivalDeleteDialogVisible: Boolean,
    setInterestedFestivalDeleteDialogVisible: (Boolean) -> Unit,
    isEditMode: Boolean = false,
) {
    val selectedFestivals = remember { mutableStateListOf<Festival>() }
    val bottomSheetState = rememberFlexibleBottomSheetState(
        containSystemBars = true,
        flexibleSheetSize = FlexibleSheetSize(),
        isModal = true,
        skipSlightlyExpanded = false,
    )
    FlexibleBottomSheet(
        onDismissRequest = {
            setFestivalSearchBottomSheetVisible(false)
        },
        sheetState = bottomSheetState,
        containerColor = Color.White,
        dragHandle = {
            Column(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(top = 10.dp),
                horizontalAlignment = Alignment.CenterHorizontally,
            ) {
                VerticalDivider(
                    modifier = Modifier
                        .width(80.dp)
                        .height(5.dp)
                        .clip(RoundedCornerShape(43.dp))
                        .background(Color(0xFFA0A0A0)),
                )
            }
        },
    ) {
        Box {
            Column(
                modifier = Modifier
                    .fillMaxSize()
                    .background(Color.White)
                    .padding(
                        bottom = WindowInsets.navigationBars
                            .asPaddingValues()
                            .calculateBottomPadding(),
                    ),
            ) {
                Spacer(modifier = Modifier.height(24.dp))
                FestivalSearchTextField(
                    searchText = TextFieldState(),
                    searchTextHintRes = searchTextHintRes,
                    onSearch = {},
                    initSearchText = initSearchText,
                    setEnableSearchMode = setEnableSearchMode,
                    isSearchMode = isSearchMode,
                    modifier = Modifier
                        .height(46.dp)
                        .fillMaxWidth()
                        .padding(horizontal = 20.dp),
                )
                if (!isSearchMode) {
                    Spacer(modifier = Modifier.height(39.dp))
                    VerticalDivider(
                        modifier = Modifier
                            .fillMaxWidth()
                            .height(8.dp)
                            .background(Color(0xFFF1F3F7)),
                    )
                    Spacer(modifier = Modifier.height(21.dp))
                    InterestedFestivalsGrid(
                        selectedFestivals = interestedFestivals,
                        onFestivalSelected = { school ->
                            selectedFestivals.remove(school)
                        },
                        isEditMode = isEditMode,
                        setInterestedFestivalDeleteDialogVisible = setInterestedFestivalDeleteDialogVisible,
                    ) {
                        TextButton(
                            onClick = setEnableEditMode,
                        ) {
                            Text(
                                text = stringResource(id = R.string.edit),
                                color = Color.Black,
                                style = Content3,
                            )
                        }
                    }
                }
            }
            if (isInterestedFestivalDeleteDialogVisible) {
                InterestedFestivalDeleteDialog(
                    onCancelClick = {
                        setInterestedFestivalDeleteDialogVisible(false)
                    },
                    onConfirmClick = {
                        setInterestedFestivalDeleteDialogVisible(false)
                    },
                )
            }
        }
    }
}

@ComponentPreview
@Composable
fun SchoolSearchBottomSheetPreview() {
    UnifestTheme {
        FestivalSearchBottomSheet(
            searchTextHintRes = R.string.festival_search_text_field_hint,
            setFestivalSearchBottomSheetVisible = {},
            interestedFestivals = mutableListOf(
                Festival("https://picsum.photos/36", "์„œ์šธ๋Œ€ํ•™๊ต", "์„ค๋Œ€์ถ•์ œ", "05.06-05.08"),
                Festival("https://picsum.photos/36", "์—ฐ์„ธ๋Œ€ํ•™๊ต", "์—ฐ๋Œ€์ถ•์ œ", "05.06-05.08"),
                Festival("https://picsum.photos/36", "๊ณ ๋ ค๋Œ€ํ•™๊ต", "๊ณ ๋Œ€์ถ•์ œ", "05.06-05.08"),
                Festival("https://picsum.photos/36", "๊ฑด๊ตญ๋Œ€ํ•™๊ต", "๋…น์ƒ‰์ง€๋Œ€", "05.06-05.08"),
                Festival("https://picsum.photos/36", "์„ฑ๊ท ๊ด€๋Œ€ํ•™๊ต", "์„ฑ๋Œ€์ถ•์ œ", "05.06-05.08"),
            ),
            initSearchText = {},
            setEnableSearchMode = {},
            isSearchMode = false,
            setEnableEditMode = {},
            isInterestedFestivalDeleteDialogVisible = false,
            isEditMode = false,
            setInterestedFestivalDeleteDialogVisible = {},
        )
    }
}

The above problem also occurred even when the bottomPadding value related to WindowInsets was removed

Expected Behavior:
Even when the bottomSheet is extended, the Navigation Bar located behind the screen should not be visible.

Show non-modal sheet above and under a BottomAppBar

Is your feature request related to a problem?

I am trying to use FlexibleBottomSheet on a screen that uses Scaffold and bottomBar. When I add the FlexibleBottomSheet to the screen it sits on top of the NavigationBar.

image

Using the following state:

rememberFlexibleBottomSheetState(
      isModal = false,
      skipSlightlyExpanded = true,
       flexibleSheetSize = FlexibleSheetSize().copy(
          fullyExpanded = 0.5f,
          intermediatelyExpanded = 0.05f, 
     )
)

Describe the solution you'd like:

I would like the sheet to be displayed below and above the NavigationBar. Basically sitting on top of it with a tiny amount visible, then expanding when the user drags up.

Describe alternatives you've considered:

I've tried adding Modifier.padding() but that causes the whole thing to vanish. I'm looking into setting the WindowInsets next.

Make bottom sheet fullscreen (without Android status bar)

In my app I want the status bar from Android at the top of the screen (where time and battery status are shown) to not be visible.
Unfortunately, I didn't find a working solution to expand to the status bar area in the FullyExpanded sheet state.
Instead, on top of the bottom sheet there is some space (where normally the top bar is placed) and there is no way to close the space and make the bottom sheet to fully expand to the top of the screen.

I already tried:

  • setting containSystemBars in FlexibleSheetState
  • setting WindowInsets in FlexibleBottomSheet (top = 0.dp)

[NestedScroll] BottomSheet doesn't hide/dismiss when dragging/flinging via the nested scroll area

  • Library Version [0.1.1]
  • Affected Device(s) [Samsung Galaxy A13 with Android 13.0]

I have made the bottom sheet to just fully expand for my needed case.

flexibleSheetSize = FlexibleSheetSize(
                    fullyExpanded = fullyExpandedRatio,
                    intermediatelyExpanded = 0f,
                    slightlyExpanded = 0f,
 ),
 FlexibleSheetState(
                flexibleSheetSize = flexibleSheetSize,
                isModal = false,
                skipSlightlyExpanded = true,
                skipIntermediatelyExpanded = true,
                containSystemBars = true,
                allowNestedScroll = true,
                animateSpec = SwipeableV2Defaults.AnimationSpec,
)

When I use a scrollable composable like a LazyColumn or a vertically scrollable Column, with allowNestedScroll = true, I can drag/fling the bottom sheet down to try dismiss it but it doesn't hide it. I more exact words, let's say I'm dragging/flinging it down, when I release the finger the sheet goes right back up to fullyExpanded automatically. I don't have this problem when I don't use a scrollable component. I can't share any images/videos due to the project I'm working on.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.