{"id":16465039,"url":"https://github.com/morfly/advanced-bottomsheet-compose","last_synced_at":"2026-03-14T08:42:29.110Z","repository":{"id":236198126,"uuid":"792119814","full_name":"Morfly/advanced-bottomsheet-compose","owner":"Morfly","description":"Advanced Bottom Sheet component for Compose with flexible configuration abilities.","archived":false,"fork":false,"pushed_at":"2025-03-24T01:23:59.000Z","size":21699,"stargazers_count":78,"open_issues_count":4,"forks_count":7,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-12T22:54:50.565Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Morfly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-26T02:40:50.000Z","updated_at":"2025-04-02T12:34:48.000Z","dependencies_parsed_at":"2024-05-07T01:29:05.309Z","dependency_job_id":"92b0b559-a66f-47d7-ab8c-42b87c70b068","html_url":"https://github.com/Morfly/advanced-bottomsheet-compose","commit_stats":null,"previous_names":["morfly/multistate-bottomsheet","morfly/multi-state-bottom-sheet","morfly/multistate-bottom-sheet","morfly/configurable-bottomsheet-compose","morfly/advanced-bottomsheet-compose"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morfly%2Fadvanced-bottomsheet-compose","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morfly%2Fadvanced-bottomsheet-compose/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morfly%2Fadvanced-bottomsheet-compose/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Morfly%2Fadvanced-bottomsheet-compose/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Morfly","download_url":"https://codeload.github.com/Morfly/advanced-bottomsheet-compose/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248643048,"owners_count":21138353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-11T11:31:44.935Z","updated_at":"2026-03-14T08:42:29.060Z","avatar_url":"https://github.com/Morfly.png","language":"Kotlin","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003ch1 align=\"center\"\u003eAdvanced Bottom Sheet for Compose\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://opensource.org/licenses/Apache-2.0\"\u003e\u003cimg alt=\"Apache 2.0 license\" src=\"https://img.shields.io/badge/License-Apache%202.0-blue.svg\"/\u003e\u003c/a\u003e\n  \u003ca href=\"https://search.maven.org/search?q=g:%22io.morfly.compose%22%20AND%20a:%22advanced-bottomsheet-material3%22\"\u003e\u003cimg alt=\"Maven Central\" src=\"https://img.shields.io/maven-central/v/io.morfly.compose/advanced-bottomsheet-material3.svg?label=Maven%20Central\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\u003cbr\u003e\n\n\u003cp align=\"center\"\u003e\n\u003cb\u003eAdvanced Bottom Sheet\u003c/b\u003e provides an implementation of a \u003ca href=\"https://m3.material.io/components/bottom-sheets/overview\"\u003eMaterial3 Standard Bottom Sheet\u003c/a\u003e component for Compose with flexible configuration abilities. \n\u003c/p\u003e\u003cbr\u003e\n\n\n![Bottom sheet demo](demos/demo_cover.png)\n\nThe purpose of this repository is to lift the limitations of the original Material 3 bottom sheet by providing a more flexible API for configuring bottom sheet states. With **Advanced Bottom Sheet** you can implement more sophisticated use cases for your designs that rely on bottom sheets. \n\n## Installation\n[![Maven Central](https://img.shields.io/maven-central/v/io.morfly.compose/advanced-bottomsheet-material3.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22io.morfly.compose%22%20AND%20a:%22advanced-bottomsheet-material3%22)\n\n#### Gradle\nAdd the dependency below to the `build.gradle.kts` file of your module. The **Advanced Bottom Sheet** is compatible with [Compose Material3](https://developer.android.com/jetpack/androidx/releases/compose-material3).\n```kotlin\ndependencies {\n    implementation(\"io.morfly.compose:advanced-bottomsheet-material3:\u003cversion\u003e\")\n}\n```\n\n## How to use\nAdvanced Bottom Sheet follows the API of `BottomSheetScaffold` component from the official Material3 implementation as close as possible while adding advanced configuration abilities for bottom sheets.\n\nFolow the following 3 steps to implement a bottom sheet in your app.\n\n#### Step 1\nDefine an `enum class` that represents the values (states) of your bottom sheet.\n\n```kotlin\nenum class SheetValue { Collapsed, PartiallyExpanded, Expanded }\n```\n\n#### Step 2\nCreate an instance of a `BottomSheetState` using `rememberBottomSheetState` function.\n\n```kotlin\nval sheetState = rememberBottomSheetState(\n    initialValue = SheetValue.PartiallyExpanded,\n    defineValues = {\n        // Bottom sheet height is 100 dp.\n        SheetValue.Collapsed at height(100.dp)\n        // Bottom sheet offset is 60%, meaning it takes 40% of the screen.\n        SheetValue.PartiallyExpanded at offset(percent = 60)\n        // Bottom sheet height is equal to its content height.\n        SheetValue.Expanded at contentHeight\n    }\n)\n```\n\nUse `defineValues` lambda to configure bottom sheet values by mapping them to corresponding positions using `height`, `offset` or `contentHeight` and specify the `initialValue` of the bottom sheet.\n\nCheck [bottom sheet values](#bottom-sheet-values) section to learn more.\n\n#### Step 3\n\n\n```kotlin\nval scaffoldState = rememberBottomSheetScaffoldState(sheetState)\n\nBottomSheetScaffold(\n    scaffoldState = scaffoldState,\n    sheetContent = {\n        // Bottom sheet content\n    },\n    content = {\n        // Screen content\n    }\n)\n```\n\n### Comparing with Google's implementation\nThis project mitigates 2 constraints of the original Material 3 bottom sheet implementation from Google.\n- **More than 2 expanded states**. The original implementation allows the maximum of 2 expanded states. The **advanced bottom sheet** provides a convenient API for declaring as many states as you like.\n- **Dynamic state changes**. It also enables the ability to dynamically change the number of states whyle the bottom sheet is being used including mid-animation cases when it's being dragged.\n\n### Bottom sheet values\nYou can have as many bottom sheet values as you like and be able to easily configure the position of each of them. \n\n\u003e State and value are used interchangeably in this context.\n\nYou can configure the bottom sheet values during the initialization of a `BottomSheetState` instance in `defineValues` lambda. There are a few available options to configure bottom sheet values.\n\n```kotlin\nval sheetState = rememberBottomSheetState(\n    initialValue = SheetValue.PartiallyExpanded,\n    defineValues = {\n        SheetValue.Collapsed at height(...)\n        SheetValue.PartiallyExpanded at offset(...)\n        SheetValue.Expanded at contentHeight\n    }\n)\n```\n\nDefine bottom sheet position using the offset from the top of the screen.\n\n- `offset(px = 200f)` — bottom sheet offset in `Float` pixels.\n\n- `offset(dp = 56.dp)` — bottom sheet offset in dp.\n\n- `offset(percent = 60)` — bottom sheet offset as percentage of the screen height. (E.g. a 60% offset means the bottom sheet takes 40% of the screen height)\n\nDefine bottom sheet position using its height.\n\n- `height(px = 200f)` — bottom sheet height in `Float` pixels.\n\n- `height(dp = 56.dp)` — bottom sheet height in dp.\n\n- `height(percent = 40)` — bottom sheet height as a percentage of the screen height. (It takes 40% of the screen height in this case)\n\nFinally, use `contentHeight` if you want the bottom sheet to wrap it's content.\n\n### Dynamically reconfigure values\nIn some cases, you might need to add, update or remove the bottom sheet values while you're using it mid-animation.\n\nImagine a use case when your bottom sheet has 3 values, `Collapsed`, `PartiallyExpanded` and `Expanded`. You need the mid value `PartiallyExpanded` to be present when you open the screen. However, once the user drags the bottom sheet you need to remove it so that only `Collapsed` and `PartiallyExpanded` values are present.\n\nThe `BottomSheetState` instance provides a `refreshValues` function that upon calling will invoke the `defineValues` lambda again.\n\n```kotlin\nvar isInitialState by remember { mutableStateOf(true) }\n\nval sheetState = rememberBottomSheetState(\n    initialValue = SheetValue.PartiallyExpanded,\n    defineValues = {\n        SheetValue.Collapsed at height(100.dp)\n        if (isInitialState) {\n            SheetValue.PartiallyExpanded at offset(percent = 60)\n        }\n        SheetValue.Expanded at contentHeight\n    },\n    confirmValueChange = {\n        if (isInitialState) {\n            isInitialState = false\n            // Invokes defineValues lambda again.\n            refreshValues()\n        }\n        true\n    }\n)\n```\nAs an example, the `confirmValueChange` lambda is invoked every time the bottom sheet value is about to be changed. This is a good place to update the variable that impacts the bottom sheet configuration.\n\n### Observing bottom sheet state\nYou can easily observe in realtime the position and the dimensions of the bottom sheet.\n\nA common use case is when your bottom sheet is displayed on top of a map. You might need to adjust the map UI controls or comply with the [Terms of Service](https://developers.google.com/maps/documentation/places/android-sdk/policies#logo) and display the Google logo while the bottom sheet is being dragged.\n\n```kotlin\nval sheetState = rememberBottomSheetState(...)\nval scaffoldState = rememberBottomSheetScaffoldState(sheetState)\n\nBottomSheetScaffold(\n    scaffoldState = scaffoldState,\n    sheetContent = { ... },\n    content = {\n        // Observe the height of the visible part of the bottom sheet \n        // while its being dragged.\n        val bottomPadding by remember {\n            derivedStateOf { sheetState.requireSheetVisibleHeightDp() }\n        }\n\n        val cameraPositionState = rememberCameraPositionState()\n        GoogleMap(\n            cameraPositionState = cameraPositionState,\n            // Adjust the map content padding based on the current\n            // bottom sheet height.\n            contentPadding = remember(bottomPadding) { \n                PaddingValues(bottom = bottomPadding)\n            }\n        )\n    },\n)\n```\nBy using `derivedStateOf` you will get realtime updates once the bottom sheet is being dragged. Here is the list of properties of `BottomSheetState` you could observe.\n\n`offset`, `offsetDp` — bottom sheet offset from the top of the screen in pixels and dp.\n\n`layoutHeight`, `layoutHeightDp` — height of the containing layout in pixels and dp.\n\n`sheetFullHeight`, `sheetFullHeightDp` — full height of the bottom sheet including the offscreen part in pixels and dp.\n\n`sheetVisibleHeight`, `sheetVisibleHeightDp` — visible height of the bottom sheet in pixels and dp.\n\nFor each of the properties above a function with `require...` prefix is available which is preferred way to retrieve these values. For instance `requireOffset()`, `requireOffsetDp()`, etc.\n\n## License\n```\nCopyright 2024 morfly (Pavlo Stavytskyi).\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   https://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorfly%2Fadvanced-bottomsheet-compose","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmorfly%2Fadvanced-bottomsheet-compose","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmorfly%2Fadvanced-bottomsheet-compose/lists"}