Giter Site home page Giter Site logo

skydoves / flexiblebottomsheet Goto Github PK

View Code? Open in Web Editor NEW
680.0 4.0 30.0 19.24 MB

🐬 Advanced Compose Multiplatform bottom sheet for segmented sizing, non-modal type, and allows interaction behind the bottom sheet similar to Google Maps.

License: Apache License 2.0

Kotlin 100.00%
android animation bottomsheet jetpack-compose modal modal-bottom-sheets skydoves

flexiblebottomsheet's Introduction

FlexibleBottomSheet


License API Build Status Android Weekly Profile


🐬 FlexibleBottomSheet is an advanced Compose Multiplatform bottom sheet for segmented sizing, non-modal type, and allows interaction behind the bottom sheet similar to Google Maps. It also offers additional conveniences, including specifying sheet sizes, monitoring sheet states, and more customization.


Download

Maven Central

Gradle

Add the dependency below to your module's build.gradle file:

dependencies {
    // compose material
    implementation("com.github.skydoves:flexible-bottomsheet-material:0.1.3")

    // compose material3
    implementation("com.github.skydoves:flexible-bottomsheet-material3:0.1.3")
}

For Kotlin Multiplatform, add the dependency below to your module's build.gradle.kts file:

sourceSets {
    val commonMain by getting {
        dependencies {
            // compose material
            implementation("com.github.skydoves:flexible-bottomsheet-material:$version")
            
            // compose material3
            implementation("com.github.skydoves:flexible-bottomsheet-material3:$version")
        }
    }
}

Usage

You can implement a flexible bottom sheet with FlexibleBottomSheet, similar to the ModalBottomSheet provided by Compose Material 3. Essentially, you can achieve the same behavior as ModalBottomSheet by not altering any properties.

FlexibleBottomSheet

This is a basic example of the FlexibleBottomSheet, which is modal, allowing customized sheet sizes for each expanded status, and offers three different expanded statuses (fully, intermediately, slightly):

FlexibleBottomSheet(
  onDismissRequest = onDismissRequest,
  sheetState = rememberFlexibleBottomSheetState(
    flexibleSheetSize = FlexibleSheetSize(
      fullyExpanded = 0.9f,
      intermediatelyExpanded = 0.5f,
      slightlyExpanded = 0.15f,
    ),
    isModal = true,
    skipSlightlyExpanded = false,
  ),
  containerColor = Color.Black,
) {
  Text(
    modifier = Modifier
      .fillMaxWidth()
      .padding(8.dp),
    text = "This is Flexible Bottom Sheet",
    textAlign = TextAlign.Center,
    color = Color.White,
  )
}

FlexibleBottomSheetState

FlexibleBottomSheetState is a crucial concept that must be bound to FlexibleBottomSheet to manage its state changes. It also enables you to customize UI/UX behaviors for the bottom sheet and take manual control over expanding/hiding the bottom sheet. You can remember the FlexibleBottomSheetState by using rememberFlexibleBottomSheetState as demonstrated in the example below:

FlexibleBottomSheet(
  onDismissRequest = onDismissRequest,
  sheetState = rememberFlexibleBottomSheetState(
    skipSlightlyExpanded = false,
    skipIntermediatelyExpanded = false,
    isModal = true,
    containSystemBars = false,
    allowNestedScroll = true,
    flexibleSheetSize = FlexibleSheetSize(
      fullyExpanded = 1.0f,
      intermediatelyExpanded = 0.5f,
      slightlyExpanded = 0.25f
    )
  ),
) {
  ..
}

You can expand or hide the bottom sheet manually by utilizing the FlexibleBottomSheetState like the code below:

val scope = rememberCoroutineScope()
val sheetState = rememberFlexibleBottomSheetState(
  flexibleSheetSize = FlexibleSheetSize(fullyExpanded = 0.9f),
  isModal = true,
  skipSlightlyExpanded = false,
)

FlexibleBottomSheet(
  sheetState = sheetState,
  containerColor = Color.Black,
  onDismissRequest = onDismissRequest
) {
  Button(
    modifier = Modifier.align(Alignment.CenterHorizontally),
    onClick = {
      scope.launch {
        when (sheetState.swipeableState.currentValue) {
          FlexibleSheetValue.SlightlyExpanded -> sheetState.intermediatelyExpand()
          FlexibleSheetValue.IntermediatelyExpanded -> sheetState.fullyExpand()
          else -> sheetState.hide()
        }
      }
    },
  ) {
    Text(text = "Expand Or Hide")
  }
}

BottomSheet Expanded Status

The flexible bottom sheet offers four primary sheet statuses known as FlexibleValues:

  • Fully Expanded: The sheet is visible at its fully-expanded height. This is mandatory and cannot be skipped.
  • Intermediately Expanded: The sheet is visible at an intermediate expanded height. This can be skipped by setting skipIntermediatelyExpanded to true.
  • Slightly Expanded: The sheet is visible at a slightly expanded height. This is skipped by default but can be enabled by setting skipSlightlyExpanded to false.
  • Hidden: The sheet is completely not visible on the screen. If you never want to dismiss and keep displaying the bottom sheet, you can give skipHiddenState to true.

You have the option to skip the Intermediately Expanded and Slightly Expanded states, as demonstrated below:

FlexibleBottomSheet(
  onDismissRequest = onDismissRequest,
  sheetState = rememberFlexibleBottomSheetState(
    skipSlightlyExpanded = false,
    skipIntermediatelyExpanded = false
  ),
) {
  ..
}

Expanded Sizes

FlexibleBottomSheet offers you to customize the expanded size the content size of bottom sheet based on its states. These constraints are calculated by multiplying the ratio with the maximum display height excluding the systembars (status and navigation bars). You can simply customize the expanded sheet size by setting FlexibleSheetSize to the rememberFlexibleBottomSheetState like the code below:

FlexibleBottomSheet(
  onDismissRequest = onDismissRequest,
  sheetState = rememberFlexibleBottomSheetState(
    flexibleSheetSize = FlexibleSheetSize(
      fullyExpanded = 0.85f,
      intermediatelyExpanded = 0.45f,
      slightlyExpanded = 0.15f,
    ),
  )
) {
  ..
}
Fully (0.85) Intermediately (0.45) Slightly (0.15)

Non-Modal BottomSheet

If you need to interact outside of the bottom sheet while the sheet is displayed on the screen, similar to the Google Maps style, you can easily achieve this by setting the isModal as false property for the FlexibleBottomSheet composable, as shown below:

FlexibleBottomSheet(
  onDismissRequest = onDismissRequest,
  sheetState = rememberFlexibleBottomSheetState(
    isModal = false,
    skipSlightlyExpanded = false,
  ),
) {
  ..
}

You will see the result below:

Dynamic Content By Monitoring Value Changes

You can dynamically compose your bottom sheet content by tracking the bottom sheet state changes. The sample code below demonstrates how you can easily observe the sheet state and adjust the text size accordingly:

var currentSheetTarget by remember { 
  mutableStateOf(FlexibleSheetValue.IntermediatelyExpanded) 
}

FlexibleBottomSheet(
  onDismissRequest = onDismissRequest,
  sheetState = rememberFlexibleBottomSheetState(
    skipSlightlyExpanded = false
  ),
  onTargetChanges = { sheetValue ->
    currentSheetTarget = sheetValue
  },
  containerColor = Color.Black,
) {
  Text(
    modifier = Modifier
      .fillMaxWidth()
      .padding(8.dp),
    text = "This is Flexible Bottom Sheet",
    textAlign = TextAlign.Center,
    color = Color.White,
    fontSize = when (currentSheetTarget) {
      FlexibleSheetValue.FullyExpanded -> 28.sp
      FlexibleSheetValue.IntermediatelyExpanded -> 20.sp
      else -> 12.sp
    },
  )
}

You can also implement dynamical content by utilizing with Compose animation library Orbital.

Nested Scroll

FlexibleBottomSheet inherently supports nested scrolling, allowing seamless integration with components like LazyColumn, LazyRow, and others. However, if you wish to disable nested scrolling, you can achieve this by setting allowNestedScroll to false within the rememberFlexibleBottomSheetState.

FlexibleBottomSheet(
  onDismissRequest = onDismissRequest,
  sheetState = rememberFlexibleBottomSheetState(
    allowNestedScroll = false
  ),
) {
  ..
}

You will see the difference below:

Enabled Disabled

Find this repository useful? ❀️

Support it by joining stargazers for this repository. ⭐
Also, follow me on GitHub for my next creations! 🀩

License

Designed and developed by 2023 skydoves (Jaewoong Eum)

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.

flexiblebottomsheet's People

Contributors

hgarciaalberto avatar ignatberesnev avatar limsaehyun avatar skydoves avatar

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

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:

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λ₯Ό λ‹€λ₯΄κ²Œν•˜μ—¬ λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

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.

[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.

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.

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.

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?

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 ?

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 (?).

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.

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

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)

Bottom Sheet visibility bug when dismissing

Please complete the following information:

  • Library Version [e.g. v1.0.0] : latest commit 1c0e68f
  • Affected Device(s) [e.g. Samsung Galaxy s10 with Android 9.0]
    OppoCPH1803 , Samsung A510F, Iphone
    Describe the Bug:

Add a clear description about the problem.
When dismissing the sheet using a drag gesture, the bottom sheet disappears for a split second then just before completely hiding it reappears again and hides fully. Also, in this state of the sheet "disappearing" if I drag the sheet up instead of down it reappears again.
Expected Behavior:

A clear description of what you expected to happen.

The sheet should always be visible on screen as long as I'm dragging it and it should only fully disappear when I fully drag it downwards.

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.

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.

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.